2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5 * Copyright (c) 2001-2010, The GROMACS development team.
6 * Copyright (c) 2012,2013,2014,2015,2016, by the GROMACS development team, led by
7 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
8 * and including many others, as listed in the AUTHORS file in the
9 * top-level source directory and at http://www.gromacs.org.
11 * GROMACS is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation; either version 2.1
14 * of the License, or (at your option) any later version.
16 * GROMACS is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with GROMACS; if not, see
23 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 * If you want to redistribute modifications to GROMACS, please
27 * consider that scientific software is very special. Version
28 * control is crucial - bugs must be traceable. We will be happy to
29 * consider code for inclusion in the official distribution, but
30 * derived work must not be called official GROMACS. Details are found
31 * in the README & COPYING files - if they are missing, get the
32 * official version at http://www.gromacs.org.
34 * To help us fund GROMACS development, we humbly ask that you cite
35 * the research papers on the package. Check out http://www.gromacs.org.
37 /*! \libinternal \file
38 * \brief Declare functions for detection and initialization for GPU devices.
40 * \author Szilard Pall <pall.szilard@gmail.com>
41 * \author Mark Abraham <mark.j.abraham@gmail.com>
45 #ifndef GMX_GPU_UTILS_GPU_UTILS_H
46 #define GMX_GPU_UTILS_GPU_UTILS_H
50 #include "gromacs/gpu_utils/gpu_macros.h"
51 #include "gromacs/utility/basedefinitions.h"
53 struct gmx_gpu_info_t
;
56 /*! \brief Detect all GPUs in the system.
58 * Will detect every GPU supported by the device driver in use. Also
59 * check for the compatibility of each and fill the gpu_info->gpu_dev array
60 * with the required information on each the device: ID, device properties,
63 * \param[in] gpu_info pointer to structure holding GPU information.
64 * \param[out] err_str The error message of any GPU API error that caused
65 * the detection to fail (if there was any). The memory
66 * the pointer points to should be managed externally.
67 * \returns non-zero if the detection encountered a failure, zero otherwise.
70 int detect_gpus(struct gmx_gpu_info_t
*GPU_FUNC_ARGUMENT(gpu_info
), char *GPU_FUNC_ARGUMENT(err_str
)) GPU_FUNC_TERM_WITH_RETURN(-1)
72 /*! \brief Select the compatible GPUs
74 * This function selects the compatible gpus and initializes
75 * gpu_info->dev_use and gpu_info->n_dev_use.
77 * Given the list of GPUs available in the system check each device in
78 * gpu_info->gpu_dev and place the indices of the compatible GPUs into
79 * dev_use with this marking the respective GPUs as "available for use."
80 * Note that \p detect_gpus must have been called before.
82 * \param[in] gpu_info pointer to structure holding GPU information
83 * \param[in,out] gpu_opt pointer to structure holding GPU options
86 void pick_compatible_gpus(const struct gmx_gpu_info_t
*GPU_FUNC_ARGUMENT(gpu_info
),
87 gmx_gpu_opt_t
*GPU_FUNC_ARGUMENT(gpu_opt
)) GPU_FUNC_TERM
89 /*! \brief Check the existence/compatibility of a set of GPUs specified by their device IDs.
91 * Given the a list of gpu_opt->n_dev_use GPU device IDs stored in
92 * gpu_opt->dev_use check the existence and compatibility
93 * of the respective GPUs. Also provide the caller with an array containing
94 * the result of checks in \p checkres.
96 * \param[out] checkres check result for each ID passed in requested_devs
97 * \param[in] gpu_info pointer to structure holding GPU information
98 * \param[out] gpu_opt pointer to structure holding GPU options
99 * \returns TRUE if every the requested GPUs are compatible
102 gmx_bool
check_selected_gpus(int *GPU_FUNC_ARGUMENT(checkres
),
103 const struct gmx_gpu_info_t
*GPU_FUNC_ARGUMENT(gpu_info
),
104 gmx_gpu_opt_t
*GPU_FUNC_ARGUMENT(gpu_opt
)) GPU_FUNC_TERM_WITH_RETURN(-1)
106 /*! \brief Frees the gpu_dev and dev_use array fields of \p gpu_info.
108 * \param[in] gpu_info pointer to structure holding GPU information
111 void free_gpu_info(const struct gmx_gpu_info_t
*GPU_FUNC_ARGUMENT(gpu_info
)) GPU_FUNC_TERM
113 /*! \brief Initializes the GPU with the given index.
115 * The varible \p mygpu is the index of the GPU to initialize in the
116 * gpu_info.gpu_dev array.
118 * \param[out] fplog log file to write to
119 * \param[in] mygpu index of the GPU to initialize
120 * \param[out] result_str the message related to the error that occurred
121 * during the initialization (if there was any).
122 * \param[in] gpu_info GPU info of all detected devices in the system.
123 * \param[in] gpu_opt options for using the GPUs in gpu_info
124 * \returns true if no error occurs during initialization.
127 gmx_bool
init_gpu(FILE *GPU_FUNC_ARGUMENT(fplog
),
128 int GPU_FUNC_ARGUMENT(mygpu
),
129 char *GPU_FUNC_ARGUMENT(result_str
),
130 const struct gmx_gpu_info_t
*GPU_FUNC_ARGUMENT(gpu_info
),
131 const gmx_gpu_opt_t
*GPU_FUNC_ARGUMENT(gpu_opt
)) GPU_FUNC_TERM_WITH_RETURN(-1)
133 /*! \brief Frees up the CUDA GPU used by the active context at the time of calling.
135 * The context is explicitly destroyed and therefore all data uploaded to the GPU
136 * is lost. This should only be called when none of this data is required anymore.
138 * \param[in] mygpu index of the GPU clean up for
139 * \param[out] result_str the message related to the error that occurred
140 * during the initialization (if there was any).
141 * \param[in] gpu_info GPU info of all detected devices in the system.
142 * \param[in] gpu_opt options for using the GPUs in gpu_info
143 * \returns true if no error occurs during the freeing.
146 gmx_bool
free_cuda_gpu(int CUDA_FUNC_ARGUMENT(mygpu
),
147 char *CUDA_FUNC_ARGUMENT(result_str
),
148 const gmx_gpu_info_t
*CUDA_FUNC_ARGUMENT(gpu_info
),
149 const gmx_gpu_opt_t
*CUDA_FUNC_ARGUMENT(gpu_opt
)) CUDA_FUNC_TERM_WITH_RETURN(TRUE
)
151 /*! \brief Returns the device ID of the CUDA GPU currently in use.
153 * The GPU used is the one that is active at the time of the call in the active context.
155 * \returns device ID of the GPU in use at the time of the call
158 int get_current_cuda_gpu_device_id(void) CUDA_FUNC_TERM_WITH_RETURN(-1)
160 /*! \brief Returns an identifier for the GPU with a given index into the array of used GPUs.
162 * Getter function which, given an index into the array of GPUs in use
163 * (dev_use) -- typically an MPI rank --, returns an identifier of the
166 * \param[in] gpu_info Pointer to structure holding GPU information
167 * \param[in] gpu_opt Pointer to structure holding GPU options
168 * \param[in] idx Index into the array of used GPUs
169 * \returns device ID of the requested GPU
172 int get_gpu_device_id(const struct gmx_gpu_info_t
*GPU_FUNC_ARGUMENT(gpu_info
),
173 const gmx_gpu_opt_t
*GPU_FUNC_ARGUMENT(gpu_opt
),
174 int GPU_FUNC_ARGUMENT(idx
)) GPU_FUNC_TERM_WITH_RETURN(-1)
176 /*! \brief Returns the name for the OpenCL GPU with a given index into the array of used GPUs.
178 * Getter function which, given an index into the array of GPUs in use
179 * (dev_use) -- typically a tMPI/MPI rank --, returns the device name for the
180 * respective OpenCL GPU.
182 * \param[in] gpu_info Pointer to structure holding GPU information
183 * \param[in] gpu_opt Pointer to structure holding GPU options
184 * \param[in] idx Index into the array of used GPUs
185 * \returns A string with the name of the requested OpenCL GPU
187 OPENCL_FUNC_QUALIFIER
188 char* get_ocl_gpu_device_name(const struct gmx_gpu_info_t
*OPENCL_FUNC_ARGUMENT(gpu_info
),
189 const gmx_gpu_opt_t
*OPENCL_FUNC_ARGUMENT(gpu_opt
),
190 int OPENCL_FUNC_ARGUMENT(idx
)) OPENCL_FUNC_TERM_WITH_RETURN(NULL
)
192 /*! \brief Formats and returns a device information string for a given GPU.
194 * Given an index *directly* into the array of available GPUs (gpu_dev)
195 * returns a formatted info string for the respective GPU which includes
196 * ID, name, compute capability, and detection status.
198 * \param[out] s pointer to output string (has to be allocated externally)
199 * \param[in] gpu_info pointer to structure holding GPU information
200 * \param[in] index an index *directly* into the array of available GPUs
203 void get_gpu_device_info_string(char *GPU_FUNC_ARGUMENT(s
),
204 const struct gmx_gpu_info_t
*GPU_FUNC_ARGUMENT(gpu_info
),
205 int GPU_FUNC_ARGUMENT(index
)) GPU_FUNC_TERM
207 /*! \brief Returns the size of the gpu_dev_info struct.
209 * The size of gpu_dev_info can be used for allocation and communication.
211 * \returns size in bytes of gpu_dev_info
214 size_t sizeof_gpu_dev_info(void) GPU_FUNC_TERM_WITH_RETURN(0)
216 /*! \brief Returns a pointer *ptr to page-locked memory of size nbytes.
218 * The allocated memory is suitable to be used for data transfers between host
220 * Error handling should be done within this function.
222 typedef void gmx_host_alloc_t (void **ptr
, size_t nbytes
);
224 /*! \brief Frees page-locked memory pointed to by *ptr.
226 * NULL should not be passed to this function.
228 typedef void gmx_host_free_t (void *ptr
);
230 /*! \brief Set page-locked memory allocation functions used by the GPU host. */
231 void gpu_set_host_malloc_and_free(bool bUseGpuKernels
,
232 gmx_host_alloc_t
**nb_alloc
,
233 gmx_host_free_t
**nb_free
);
237 /*! \brief Starts the GPU profiler if mdrun is being profiled.
239 * When a profiler run is in progress (based on the presence of the NVPROF_ID
240 * env. var.), the profiler is started to begin collecting data during the
241 * rest of the run (or until stopGpuProfiler is called).
243 * Note that this is implemented only for the CUDA API.
246 void startGpuProfiler(void) CUDA_FUNC_TERM
249 /*! \brief Resets the GPU profiler if mdrun is being profiled.
251 * When a profiler run is in progress (based on the presence of the NVPROF_ID
252 * env. var.), the profiler data is restet in order to eliminate the data collected
253 * from the preceding part fo the run.
255 * This function should typically be called at the mdrun counter reset time.
257 * Note that this is implemented only for the CUDA API.
260 void resetGpuProfiler(void) CUDA_FUNC_TERM
263 /*! \brief Stops the CUDA profiler if mdrun is being profiled.
265 * This function can be called at cleanup when skipping recording
266 * recording subsequent API calls from being traces/profiled is desired,
267 * e.g. before uninitialization.
269 * Note that this is implemented only for the CUDA API.
272 void stopGpuProfiler(void) CUDA_FUNC_TERM