ed86982c672bc405e3e3dcd16a8621d6121edfbe
[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) 2020, by the GROMACS development team, led by
5  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6  * and including many others, as listed in the AUTHORS file in the
7  * top-level source directory and at http://www.gromacs.org.
8  *
9  * GROMACS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1
12  * of the License, or (at your option) any later version.
13  *
14  * GROMACS is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with GROMACS; if not, see
21  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
23  *
24  * If you want to redistribute modifications to GROMACS, please
25  * consider that scientific software is very special. Version
26  * control is crucial - bugs must be traceable. We will be happy to
27  * consider code for inclusion in the official distribution, but
28  * derived work must not be called official GROMACS. Details are found
29  * in the README & COPYING files - if they are missing, get the
30  * official version at http://www.gromacs.org.
31  *
32  * To help us fund GROMACS development, we humbly ask that you cite
33  * the research papers on the package. Check out http://www.gromacs.org.
34  */
35 /*! \libinternal \file
36  *
37  * \brief Implements the device management for OpenCL.
38  *
39  * \author Artem Zhmurov <zhmurov@gmail.com>
40  *
41  * \inlibraryapi
42  * \ingroup module_hardware
43  */
44 #ifndef GMX_HARDWARE_DEVICE_MANAGEMENT_H
45 #define GMX_HARDWARE_DEVICE_MANAGEMENT_H
46
47 #include "gmxpre.h"
48
49 #include <string>
50 #include <vector>
51
52 #include "gromacs/hardware/device_information.h"
53
54 struct DeviceInformation;
55 enum class DeviceStatus : int;
56 struct gmx_gpu_info_t;
57
58 /*! \brief Return whether GPUs can be detected
59  *
60  * Returns true when this is a build of \Gromacs configured to support
61  * GPU usage, GPU detection is not disabled by an environment variable
62  * and a valid device driver, ICD, and/or runtime was detected.
63  * Does not throw. */
64 bool canPerformGpuDetection();
65
66 /*! \brief Return whether GPU detection is functioning correctly
67  *
68  * Returns true when this is a build of \Gromacs configured to support
69  * GPU usage, and a valid device driver, ICD, and/or runtime was detected.
70  *
71  * This function is not intended to be called from build
72  * configurations that do not support GPUs, and there will be no
73  * descriptive message in that case.
74  *
75  * \param[out] errorMessage  When returning false on a build configured with
76  *                           GPU support and non-nullptr was passed,
77  *                           the string contains a descriptive message about
78  *                           why GPUs cannot be detected.
79  *
80  * Does not throw. */
81 bool isGpuDetectionFunctional(std::string* errorMessage);
82
83 /*! \brief Find all GPUs in the system.
84  *
85  *  Will detect every GPU supported by the device driver in use.
86  *  Must only be called if canPerformGpuDetection() has returned true.
87  *  This routine also checks for the compatibility of each and fill the
88  *  gpu_info->deviceInfo array with the required information on each the
89  *  device: ID, device properties, status.
90  *
91  *  Note that this function leaves the GPU runtime API error state clean;
92  *  this is implemented ATM in the CUDA flavor.
93  *  TODO: check if errors do propagate in OpenCL as they do in CUDA and
94  *  whether there is a mechanism to "clear" them.
95  *
96  *  \param[in] gpu_info    pointer to structure holding GPU information.
97  *
98  *  \throws                InternalError if a GPU API returns an unexpected failure (because
99  *                         the call to canDetectGpus() should always prevent this occuring)
100  */
101 void findGpus(gmx_gpu_info_t* gpu_info);
102
103 /*! \brief Return a container of the detected GPUs that are compatible.
104  *
105  * This function filters the result of the detection for compatible
106  * GPUs, based on the previously run compatibility tests.
107  *
108  * \param[in]     gpu_info    Information detected about GPUs, including compatibility.
109  * \return                    vector of IDs of GPUs already recorded as compatible */
110 std::vector<int> getCompatibleGpus(const gmx_gpu_info_t& gpu_info);
111
112 /*! \brief Return a string describing how compatible the GPU with given \c index is.
113  *
114  * \param[in]   gpu_info    Information about detected GPUs
115  * \param[in]   index       index of GPU to ask about
116  * \returns                 A null-terminated C string describing the compatibility status, useful for error messages.
117  */
118 const char* getGpuCompatibilityDescription(const gmx_gpu_info_t& gpu_info, int index);
119
120 /*! \brief Frees the gpu_dev and dev_use array fields of \p gpu_info.
121  *
122  * \param[in]    gpu_info    pointer to structure holding GPU information
123  */
124 void free_gpu_info(const gmx_gpu_info_t* gpu_info);
125
126 /*! \brief Initializes the GPU described by \c deviceInfo.
127  *
128  * TODO Doxygen complains about these - probably a Doxygen bug, since
129  * the patterns here are the same as elsewhere in this header.
130  *
131  * \param[in]    deviceInfo   device info of the GPU to initialize
132  *
133  * Issues a fatal error for any critical errors that occur during
134  * initialization.
135  */
136 void init_gpu(const DeviceInformation* deviceInfo);
137
138 /*! \brief Frees up the CUDA GPU used by the active context at the time of calling.
139  *
140  * If \c deviceInfo is nullptr, then it is understood that no device
141  * was selected so no context is active to be freed. Otherwise, the
142  * context is explicitly destroyed and therefore all data uploaded to
143  * the GPU is lost. This must only be called when none of this data is
144  * required anymore, because subsequent attempts to free memory
145  * associated with the context will otherwise fail.
146  *
147  * Calls gmx_warning upon errors.
148  *
149  * \param[in]  deviceInfo   device info of the GPU to clean up for
150  *
151  * \returns                 true if no error occurs during the freeing.
152  */
153 void free_gpu(const DeviceInformation* deviceInfo);
154
155 /*! \brief Return a pointer to the device info for \c deviceId
156  *
157  * \param[in] gpu_info      GPU info of all detected devices in the system.
158  * \param[in] deviceId      ID for the GPU device requested.
159  *
160  * \returns                 Pointer to the device info for \c deviceId.
161  */
162 DeviceInformation* getDeviceInfo(const gmx_gpu_info_t& gpu_info, int deviceId);
163
164 /*! \brief Formats and returns a device information string for a given GPU.
165  *
166  * Given an index *directly* into the array of available GPUs (gpu_dev)
167  * returns a formatted info string for the respective GPU which includes
168  * ID, name, compute capability, and detection status.
169  *
170  * \param[out]  s           pointer to output string (has to be allocated externally)
171  * \param[in]   gpu_info    Information about detected GPUs
172  * \param[in]   index       an index *directly* into the array of available GPUs
173  */
174 void get_gpu_device_info_string(char* s, const gmx_gpu_info_t& gpu_info, int index);
175
176
177 /*! \brief Returns the size of the gpu_dev_info struct.
178  *
179  * The size of gpu_dev_info can be used for allocation and communication.
180  *
181  * \returns                 size in bytes of gpu_dev_info
182  */
183 size_t sizeof_gpu_dev_info();
184
185 //! Get status of device with specified index
186 DeviceStatus gpu_info_get_stat(const gmx_gpu_info_t& info, int index);
187
188 #endif // GMX_HARDWARE_DEVICE_MANAGEMENT_H