Unify handling of GMX_ENABLE_GPU_TIMING and GMX_DISABLE_GPU_TIMING
[alexxy/gromacs.git] / src / gromacs / gpu_utils / gpu_utils.h
index f485abb0fb4f1ff8b7b7661ff8c713180ab3919f..c5651b6b602432baeb1f31e798842e50c59bec29 100644 (file)
@@ -3,7 +3,8 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2010, The GROMACS development team.
- * Copyright (c) 2012,2013,2014,2015,2016, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team.
+ * Copyright (c) 2017,2018,2019,2020,2021, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
 
 #include <cstdio>
 
+#include <string>
+#include <vector>
+
 #include "gromacs/gpu_utils/gpu_macros.h"
 #include "gromacs/utility/basedefinitions.h"
 
-struct gmx_gpu_info_t;
-struct gmx_gpu_opt_t;
-
-/*! \brief Detect all GPUs in the system.
- *
- *  Will detect every GPU supported by the device driver in use. Also
- *  check for the compatibility of each and fill the gpu_info->gpu_dev array
- *  with the required information on each the device: ID, device properties,
- *  status.
- *
- *  \param[in] gpu_info    pointer to structure holding GPU information.
- *  \param[out] err_str    The error message of any GPU API error that caused
- *                         the detection to fail (if there was any). The memory
- *                         the pointer points to should be managed externally.
- *  \returns               non-zero if the detection encountered a failure, zero otherwise.
- */
-GPU_FUNC_QUALIFIER
-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)
-
-/*! \brief Select the compatible GPUs
- *
- * This function selects the compatible gpus and initializes
- * gpu_info->dev_use and gpu_info->n_dev_use.
- *
- * Given the list of GPUs available in the system check each device in
- * gpu_info->gpu_dev and place the indices of the compatible GPUs into
- * dev_use with this marking the respective GPUs as "available for use."
- * Note that \p detect_gpus must have been called before.
- *
- * \param[in]     gpu_info    pointer to structure holding GPU information
- * \param[in,out] gpu_opt     pointer to structure holding GPU options
- */
-GPU_FUNC_QUALIFIER
-void pick_compatible_gpus(const struct gmx_gpu_info_t *GPU_FUNC_ARGUMENT(gpu_info),
-                          gmx_gpu_opt_t *GPU_FUNC_ARGUMENT(gpu_opt)) GPU_FUNC_TERM
-
-/*! \brief Check the existence/compatibility of a set of GPUs specified by their device IDs.
- *
- * Given the a list of gpu_opt->n_dev_use GPU device IDs stored in
- * gpu_opt->dev_use check the existence and compatibility
- * of the respective GPUs. Also provide the caller with an array containing
- * the result of checks in \p checkres.
- *
- * \param[out]  checkres    check result for each ID passed in requested_devs
- * \param[in]   gpu_info    pointer to structure holding GPU information
- * \param[out]  gpu_opt     pointer to structure holding GPU options
- * \returns                 TRUE if every the requested GPUs are compatible
- */
-GPU_FUNC_QUALIFIER
-gmx_bool check_selected_gpus(int *GPU_FUNC_ARGUMENT(checkres),
-                             const struct gmx_gpu_info_t *GPU_FUNC_ARGUMENT(gpu_info),
-                             gmx_gpu_opt_t *GPU_FUNC_ARGUMENT(gpu_opt)) GPU_FUNC_TERM_WITH_RETURN(-1)
-
-/*! \brief Frees the gpu_dev and dev_use array fields of \p gpu_info.
- *
- * \param[in]    gpu_info    pointer to structure holding GPU information
- */
-GPU_FUNC_QUALIFIER
-void free_gpu_info(const struct gmx_gpu_info_t *GPU_FUNC_ARGUMENT(gpu_info)) GPU_FUNC_TERM
-
-/*! \brief Initializes the GPU with the given index.
- *
- * The varible \p mygpu is the index of the GPU to initialize in the
- * gpu_info.gpu_dev array.
- *
- * \param[out] fplog        log file to write to
- * \param[in]  mygpu        index of the GPU to initialize
- * \param[out] result_str   the message related to the error that occurred
- *                          during the initialization (if there was any).
- * \param[in] gpu_info      GPU info of all detected devices in the system.
- * \param[in] gpu_opt       options for using the GPUs in gpu_info
- * \returns                 true if no error occurs during initialization.
- */
-GPU_FUNC_QUALIFIER
-gmx_bool init_gpu(FILE *GPU_FUNC_ARGUMENT(fplog),
-                  int GPU_FUNC_ARGUMENT(mygpu),
-                  char *GPU_FUNC_ARGUMENT(result_str),
-                  const struct gmx_gpu_info_t *GPU_FUNC_ARGUMENT(gpu_info),
-                  const gmx_gpu_opt_t *GPU_FUNC_ARGUMENT(gpu_opt)) GPU_FUNC_TERM_WITH_RETURN(-1)
-
-/*! \brief Frees up the CUDA GPU used by the active context at the time of calling.
- *
- * The context is explicitly destroyed and therefore all data uploaded to the GPU
- * is lost. This should only be called when none of this data is required anymore.
- *
- * \param[in]  mygpu        index of the GPU clean up for
- * \param[out] result_str   the message related to the error that occurred
- *                          during the initialization (if there was any).
- * \param[in] gpu_info      GPU info of all detected devices in the system.
- * \param[in] gpu_opt       options for using the GPUs in gpu_info
- * \returns                 true if no error occurs during the freeing.
- */
-CUDA_FUNC_QUALIFIER
-gmx_bool free_cuda_gpu(int CUDA_FUNC_ARGUMENT(mygpu),
-                       char *CUDA_FUNC_ARGUMENT(result_str),
-                       const gmx_gpu_info_t *CUDA_FUNC_ARGUMENT(gpu_info),
-                       const gmx_gpu_opt_t *CUDA_FUNC_ARGUMENT(gpu_opt)) CUDA_FUNC_TERM_WITH_RETURN(TRUE)
-
-/*! \brief Returns the device ID of the CUDA GPU currently in use.
- *
- * The GPU used is the one that is active at the time of the call in the active context.
- *
- * \returns                 device ID of the GPU in use at the time of the call
- */
-CUDA_FUNC_QUALIFIER
-int get_current_cuda_gpu_device_id(void) CUDA_FUNC_TERM_WITH_RETURN(-1)
-
-/*! \brief Returns an identifier for the GPU with a given index into the array of used GPUs.
- *
- * Getter function which, given an index into the array of GPUs in use
- * (dev_use) -- typically an MPI rank --, returns an identifier of the
- * respective GPU.
- *
- * \param[in]    gpu_info   Pointer to structure holding GPU information
- * \param[in]    gpu_opt    Pointer to structure holding GPU options
- * \param[in]    idx        Index into the array of used GPUs
- * \returns                 device ID of the requested GPU
- */
-GPU_FUNC_QUALIFIER
-int get_gpu_device_id(const struct gmx_gpu_info_t *GPU_FUNC_ARGUMENT(gpu_info),
-                      const gmx_gpu_opt_t *GPU_FUNC_ARGUMENT(gpu_opt),
-                      int GPU_FUNC_ARGUMENT(idx)) GPU_FUNC_TERM_WITH_RETURN(-1)
-
-/*! \brief Returns the name for the OpenCL GPU with a given index into the array of used GPUs.
- *
- * Getter function which, given an index into the array of GPUs in use
- * (dev_use) -- typically a tMPI/MPI rank --, returns the device name for the
- * respective OpenCL GPU.
- *
- * \param[in]    gpu_info   Pointer to structure holding GPU information
- * \param[in]    gpu_opt    Pointer to structure holding GPU options
- * \param[in]    idx        Index into the array of used GPUs
- * \returns                 A string with the name of the requested OpenCL GPU
- */
-OPENCL_FUNC_QUALIFIER
-char* get_ocl_gpu_device_name(const struct gmx_gpu_info_t *OPENCL_FUNC_ARGUMENT(gpu_info),
-                              const gmx_gpu_opt_t  *OPENCL_FUNC_ARGUMENT(gpu_opt),
-                              int                  OPENCL_FUNC_ARGUMENT(idx)) OPENCL_FUNC_TERM_WITH_RETURN(NULL)
-
-/*! \brief Formats and returns a device information string for a given GPU.
- *
- * Given an index *directly* into the array of available GPUs (gpu_dev)
- * returns a formatted info string for the respective GPU which includes
- * ID, name, compute capability, and detection status.
- *
- * \param[out]  s           pointer to output string (has to be allocated externally)
- * \param[in]   gpu_info    pointer to structure holding GPU information
- * \param[in]   index       an index *directly* into the array of available GPUs
- */
-GPU_FUNC_QUALIFIER
-void get_gpu_device_info_string(char *GPU_FUNC_ARGUMENT(s),
-                                const struct gmx_gpu_info_t *GPU_FUNC_ARGUMENT(gpu_info),
-                                int GPU_FUNC_ARGUMENT(index)) GPU_FUNC_TERM
-
-/*! \brief Returns the size of the gpu_dev_info struct.
- *
- * The size of gpu_dev_info can be used for allocation and communication.
- *
- * \returns                 size in bytes of gpu_dev_info
- */
-GPU_FUNC_QUALIFIER
-size_t sizeof_gpu_dev_info(void) GPU_FUNC_TERM_WITH_RETURN(0)
-
-/*! \brief Returns a pointer *ptr to page-locked memory of size nbytes.
- *
- * The allocated memory is suitable to be used for data transfers between host
- * and GPU.
- * Error handling should be done within this function.
- */
-typedef void gmx_host_alloc_t (void **ptr, size_t nbytes);
-
-/*! \brief Frees page-locked memory pointed to by *ptr.
- *
- * NULL should not be passed to this function.
- */
-typedef void gmx_host_free_t (void *ptr);
-
-/*! \brief Set page-locked memory allocation functions used by the GPU host. */
-void gpu_set_host_malloc_and_free(bool               bUseGpuKernels,
-                                  gmx_host_alloc_t **nb_alloc,
-                                  gmx_host_free_t  **nb_free);
-
-
+namespace gmx
+{
+class MDLogger;
+}
+
+//! Enum which is only used to describe transfer calls at the moment
+enum class GpuApiCallBehavior : int
+{
+    //! Synchronous
+    Sync,
+    //! Asynchronous
+    Async,
+    //! Size of the enumeration
+    Count
+};
+
+//! String corresponding to GPU API call behavior
+const char* enumValueToString(GpuApiCallBehavior enumValue);
+
+//! Types of actions associated to waiting or checking the completion of GPU tasks
+enum class GpuTaskCompletion
+{
+    Wait, /*<< Issue a blocking wait for the task */
+    Check /*<< Only check whether the task has completed */
+};
 
 /*! \brief Starts the GPU profiler if mdrun is being profiled.
  *
@@ -243,7 +89,7 @@ void gpu_set_host_malloc_and_free(bool               bUseGpuKernels,
  *  Note that this is implemented only for the CUDA API.
  */
 CUDA_FUNC_QUALIFIER
-void startGpuProfiler(void) CUDA_FUNC_TERM
+void startGpuProfiler() CUDA_FUNC_TERM;
 
 
 /*! \brief Resets the GPU profiler if mdrun is being profiled.
@@ -257,7 +103,7 @@ void startGpuProfiler(void) CUDA_FUNC_TERM
  * Note that this is implemented only for the CUDA API.
  */
 CUDA_FUNC_QUALIFIER
-void resetGpuProfiler(void) CUDA_FUNC_TERM
+void resetGpuProfiler() CUDA_FUNC_TERM;
 
 
 /*! \brief Stops the CUDA profiler if mdrun is being profiled.
@@ -269,7 +115,26 @@ void resetGpuProfiler(void) CUDA_FUNC_TERM
  *  Note that this is implemented only for the CUDA API.
  */
 CUDA_FUNC_QUALIFIER
-void stopGpuProfiler(void) CUDA_FUNC_TERM
+void stopGpuProfiler() CUDA_FUNC_TERM;
 
+//! Tells whether the host buffer was pinned for non-blocking transfers. Only implemented for CUDA.
+CUDA_FUNC_QUALIFIER
+bool isHostMemoryPinned(const void* CUDA_FUNC_ARGUMENT(h_ptr)) CUDA_FUNC_TERM_WITH_RETURN(false);
+
+/*! \brief Enable peer access between GPUs where supported
+ * \param[in] gpuIdsToUse   List of GPU IDs in use
+ * \param[in] mdlog         Logger object
+ */
+CUDA_FUNC_QUALIFIER
+void setupGpuDevicePeerAccess(const std::vector<int>& CUDA_FUNC_ARGUMENT(gpuIdsToUse),
+                              const gmx::MDLogger&    CUDA_FUNC_ARGUMENT(mdlog)) CUDA_FUNC_TERM;
+
+/*! \brief Check the platform-defaults and environment variable to decide whether GPU timings
+ * should be enabled.
+ *
+ * Currently, timings are enabled for OpenCL, but disabled for CUDA and SYCL. This can be overridden
+ * by \c GMX_ENABLE_GPU_TIMING and \c GMX_DISABLE_GPU_TIMING environment variables.
+ */
+bool decideGpuTimingsUsage();
 
 #endif