Access the device status directly, remove the getter
[alexxy/gromacs.git] / src / gromacs / hardware / device_management.h
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2012,2013,2014,2015,2016, by the GROMACS development team.
5  * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
6  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
7  * and including many others, as listed in the AUTHORS file in the
8  * top-level source directory and at http://www.gromacs.org.
9  *
10  * GROMACS is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public License
12  * as published by the Free Software Foundation; either version 2.1
13  * of the License, or (at your option) any later version.
14  *
15  * GROMACS is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with GROMACS; if not, see
22  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
24  *
25  * If you want to redistribute modifications to GROMACS, please
26  * consider that scientific software is very special. Version
27  * control is crucial - bugs must be traceable. We will be happy to
28  * consider code for inclusion in the official distribution, but
29  * derived work must not be called official GROMACS. Details are found
30  * in the README & COPYING files - if they are missing, get the
31  * official version at http://www.gromacs.org.
32  *
33  * To help us fund GROMACS development, we humbly ask that you cite
34  * the research papers on the package. Check out http://www.gromacs.org.
35  */
36 /*! \libinternal \file
37  *  \brief Declares functions to manage GPU resources.
38  *
39  *  This has several implementations: one for each supported GPU platform,
40  *  and a stub implementation if the build does not support GPUs.
41  *
42  *  \author Anca Hamuraru <anca@streamcomputing.eu>
43  *  \author Dimitrios Karkoulis <dimitris.karkoulis@gmail.com>
44  *  \author Teemu Virolainen <teemu@streamcomputing.eu>
45  *  \author Mark Abraham <mark.j.abraham@gmail.com>
46  *  \author Szilárd Páll <pall.szilard@gmail.com>
47  *  \author Artem Zhmurov <zhmurov@gmail.com>
48  *
49  * \inlibraryapi
50  * \ingroup module_hardware
51  */
52 #ifndef GMX_HARDWARE_DEVICE_MANAGEMENT_H
53 #define GMX_HARDWARE_DEVICE_MANAGEMENT_H
54
55 #include <memory>
56 #include <string>
57 #include <vector>
58
59 #include "gromacs/utility/basedefinitions.h"
60 #include "gromacs/utility/iserializer.h"
61
62 struct DeviceInformation;
63
64 /*! \brief Return whether GPUs can be detected.
65  *
66  * Returns true when this is a build of GROMACS configured to support
67  * GPU usage, GPU detection is not disabled by \c GMX_DISABLE_GPU_DETECTION
68  * environment variable and a valid device driver, ICD, and/or runtime was
69  * detected. Does not throw.
70  *
71  * \param[out] errorMessage  When returning false on a build configured with
72  *                           GPU support and non-nullptr was passed,
73  *                           the string contains a descriptive message about
74  *                           why GPUs cannot be detected.
75  */
76 bool canPerformDeviceDetection(std::string* errorMessage);
77
78 /*! \brief Return whether GPU detection is functioning correctly
79  *
80  * Returns true when this is a build of GROMACS configured to support
81  * GPU usage, and a valid device driver, ICD, and/or runtime was detected.
82  *
83  * This function is not intended to be called from build
84  * configurations that do not support GPUs, and there will be no
85  * descriptive message in that case.
86  *
87  * \param[out] errorMessage  When returning false on a build configured with
88  *                           GPU support and non-nullptr was passed,
89  *                           the string contains a descriptive message about
90  *                           why GPUs cannot be detected.
91  *
92  * Does not throw.
93  */
94 bool isDeviceDetectionFunctional(std::string* errorMessage);
95
96 /*! \brief Checks if one can compute on the GPU
97  *
98  * \returns  True if the build supports GPUs and there are at least one available.
99  */
100 bool canComputeOnDevice();
101
102 /*! \brief Find all GPUs in the system.
103  *
104  *  Will detect every GPU supported by the device driver in use.
105  *  Must only be called if \c canPerformDeviceDetection() has returned true.
106  *  This routine also checks for the compatibility of each device and fill the
107  *  deviceInfo array with the required information on each device: ID, device
108  *  properties, status.
109  *
110  *  Note that this function leaves the GPU runtime API error state clean;
111  *  this is implemented ATM in the CUDA flavor.
112  *
113  *  \todo:  Check if errors do propagate in OpenCL as they do in CUDA and
114  *          whether there is a mechanism to "clear" them.
115  *
116  * \return  Standard vector with the list of devices found
117  *
118  *  \throws InternalError if a GPU API returns an unexpected failure (because
119  *          the call to canDetectGpus() should always prevent this occuring)
120  */
121 std::vector<std::unique_ptr<DeviceInformation>> findDevices();
122
123 /*! \brief Return a container of the detected GPU ids that are compatible.
124  *
125  * This function filters the result of the detection for compatible
126  * GPUs, based on the previously run compatibility tests.
127  *
128  * \param[in] deviceInfoList An information on available devices.
129  *
130  * \return  Vector of DeviceInformations on GPUs recorded as compatible
131  */
132 std::vector<std::reference_wrapper<DeviceInformation>>
133 getCompatibleDevices(const std::vector<std::unique_ptr<DeviceInformation>>& deviceInfoList);
134
135 /*! \brief Set the active GPU.
136  *
137  * This sets the device for which the device information is passed active. Essential in CUDA, where
138  * the device buffers and kernel launches are not connected to the device context. In OpenCL, checks
139  * the device vendor and makes vendor-specific performance adjustments.
140  *
141  * \param[in] deviceInfo Information on the device to be set.
142  *
143  * Issues a fatal error for any critical errors that occur during
144  * initialization.
145  */
146 void setActiveDevice(const DeviceInformation& deviceInfo);
147
148 /*! \brief Releases the GPU device used by the active context at the time of calling (CUDA only).
149  *
150  * If \c deviceInfo is nullptr, then it is understood that no device
151  * was selected so no context is active to be freed. Otherwise, the
152  * context is explicitly destroyed and therefore all data uploaded to
153  * the GPU is lost. This must only be called when none of this data is
154  * required anymore, because subsequent attempts to free memory
155  * associated with the context will otherwise fail.
156  *
157  * Calls \c gmx_warning upon errors.
158  *
159  * \todo This should go through all the devices, not only the one currently active.
160  *       Reseting only one device will not work, e.g. in CUDA tests.
161  *
162  * \param[in] deviceInfo Information on the device to be released.
163  */
164 void releaseDevice(DeviceInformation* deviceInfo);
165
166 /*! \brief Formats and returns a device information string for a given GPU.
167  *
168  * Given an index *directly* into the array of available GPUs, returns
169  * a formatted info string for the respective GPU which includes ID, name,
170  * compute capability, and detection status.
171  *
172  * \param[in] deviceInfo  An information on device that is to be set.
173  *
174  * \returns A string describing the device.
175  */
176 std::string getDeviceInformationString(const DeviceInformation& deviceInfo);
177
178 /*! \brief Return a string describing how compatible the GPU with given \c deviceId is.
179  *
180  * \param[in] deviceInfoList An information on available devices.
181  * \param[in] deviceId       An index of the device to check
182  * \returns                  A string describing the compatibility status, useful for error messages.
183  */
184 std::string getDeviceCompatibilityDescription(const std::vector<std::unique_ptr<DeviceInformation>>& deviceInfoList,
185                                               int deviceId);
186
187 /*! \brief Serialization of information on devices for MPI broadcasting.
188  *
189  * \param[in] deviceInfoList  The vector with device informations to serialize.
190  * \param[in] serializer      Serializing object.
191  */
192 void serializeDeviceInformations(const std::vector<std::unique_ptr<DeviceInformation>>& deviceInfoList,
193                                  gmx::ISerializer*                                      serializer);
194
195 /*! \brief Deserialization of information on devices after MPI broadcasting.
196  *
197  * \param[in] serializer Serializing object.
198  *
199  * \return deviceInfoList   Deserialized vector with device informations.
200  */
201 std::vector<std::unique_ptr<DeviceInformation>> deserializeDeviceInformations(gmx::ISerializer* serializer);
202
203 #endif // GMX_HARDWARE_DEVICE_MANAGEMENT_H