Unify handling of GMX_ENABLE_GPU_TIMING and GMX_DISABLE_GPU_TIMING
authorAndrey Alekseenko <al42and@gmail.com>
Wed, 3 Nov 2021 20:08:15 +0000 (20:08 +0000)
committerMark Abraham <mark.j.abraham@gmail.com>
Wed, 3 Nov 2021 20:08:15 +0000 (20:08 +0000)
docs/user-guide/environment-variables.rst
src/gromacs/gpu_utils/gpu_utils.cpp
src/gromacs/gpu_utils/gpu_utils.h
src/gromacs/mdrun/runner.cpp
src/gromacs/nbnxm/nbnxm_gpu_data_mgmt.cpp

index 1698fcedb260d307b15f8c9c182f17e920165895..1f323174e1124da09523dbf792d20286fd844d23 100644 (file)
@@ -82,8 +82,8 @@ Output Control
         files. Set to 0 for quiet operation.
 
 ``GMX_ENABLE_GPU_TIMING``
-        Enables GPU timings in the log file for CUDA. Note that CUDA timings
-        are incorrect with multiple streams, as happens with domain
+        Enables GPU timings in the log file for CUDA and SYCL. Note that CUDA
+        timings are incorrect with multiple streams, as happens with domain
         decomposition or with both non-bondeds and PME on the GPU (this is
         also the main reason why they are not turned on by default).
 
@@ -211,6 +211,7 @@ Performance and Run Control
 ``GMX_DISABLE_GPU_TIMING``
         timing of asynchronously executed GPU operations can have a
         non-negligible overhead with short step times. Disabling timing can improve performance in these cases.
+        Timings are disabled by default with CUDA and SYCL.
 
 ``GMX_DISABLE_GPU_DETECTION``
         when set, disables GPU detection even if :ref:`gmx mdrun` was compiled
index 501d6b625fc8ff9b0aeea6478e64c232e9950a78..2d8846caa334f827ad6c3ed6846b87694a0c4b17 100644 (file)
@@ -59,3 +59,26 @@ const char* enumValueToString(GpuApiCallBehavior enumValue)
     };
     return s_gpuApiCallBehaviorNames[enumValue];
 }
+
+bool decideGpuTimingsUsage()
+{
+    if (GMX_GPU_CUDA || GMX_GPU_SYCL)
+    {
+        /* CUDA: timings are incorrect with multiple streams.
+         * This is the main reason why they are disabled by default.
+         * TODO: Consider turning on by default when we can detect nr of streams.
+         *
+         * SYCL: compilers and runtimes change rapidly, so we disable timings by default
+         * to avoid any possible overhead. */
+        return (getenv("GMX_ENABLE_GPU_TIMING") != nullptr);
+    }
+    else if (GMX_GPU_OPENCL)
+    {
+        return (getenv("GMX_DISABLE_GPU_TIMING") == nullptr);
+    }
+    else
+    {
+        // CPU-only build
+        return false;
+    }
+}
index f9c5353b748ce43e05a18e11968fe99b6f19a7d9..c5651b6b602432baeb1f31e798842e50c59bec29 100644 (file)
@@ -129,4 +129,12 @@ 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
index 313b4ebb3409d37d90631281a3121e7e7a661bec..8fc6d89a721e29cbc1980bf169c54bbe71f3b71c 100644 (file)
@@ -1403,22 +1403,6 @@ int Mdrunner::mdrunner()
     int                deviceId   = -1;
     DeviceInformation* deviceInfo = gpuTaskAssignments.initDevice(&deviceId);
 
-    // timing enabling - TODO put this in gpu_utils (even though generally this is just option handling?)
-    bool useTiming = true;
-
-    if (GMX_GPU_CUDA)
-    {
-        /* WARNING: CUDA timings are incorrect with multiple streams.
-         *          This is the main reason why they are disabled by default.
-         */
-        // TODO: Consider turning on by default when we can detect nr of streams.
-        useTiming = (getenv("GMX_ENABLE_GPU_TIMING") != nullptr);
-    }
-    else if (GMX_GPU_OPENCL)
-    {
-        useTiming = (getenv("GMX_DISABLE_GPU_TIMING") == nullptr);
-    }
-
     // TODO Currently this is always built, yet DD partition code
     // checks if it is built before using it. Probably it should
     // become an MDModule that is made only when another module
@@ -1506,8 +1490,9 @@ int Mdrunner::mdrunner()
         {
             dd_setup_dlb_resource_sharing(cr, deviceId);
         }
-        deviceStreamManager = std::make_unique<DeviceStreamManager>(
-                *deviceInfo, havePPDomainDecomposition(cr), runScheduleWork.simulationWork, useTiming);
+        const bool useGpuTiming = decideGpuTimingsUsage();
+        deviceStreamManager     = std::make_unique<DeviceStreamManager>(
+                *deviceInfo, havePPDomainDecomposition(cr), runScheduleWork.simulationWork, useGpuTiming);
     }
 
     // If the user chose a task assignment, give them some hints
index 874f9a614f190c4c38023bc3e3ec05ce80e5ba32..2263593cb842d5e43f302c83f4584a371ad908f7 100644 (file)
@@ -431,18 +431,7 @@ NbnxmGpu* gpu_init(const gmx::DeviceStreamManager& deviceStreamManager,
     nb->timers = new Nbnxm::GpuTimers();
     snew(nb->timings, 1);
 
-    /* WARNING: CUDA timings are incorrect with multiple streams.
-     * This is the main reason why they are disabled by default.
-     * Can be enabled by setting GMX_ENABLE_GPU_TIMING environment variable.
-     * TODO: Consider turning on by default when we can detect nr of streams.
-     *
-     * OpenCL timing is enabled by default and can be disabled by
-     * GMX_DISABLE_GPU_TIMING environment variable.
-     *
-     * Timing is disabled in SYCL.
-     */
-    nb->bDoTime = (GMX_GPU_CUDA && (getenv("GMX_ENABLE_GPU_TIMING") != nullptr))
-                  || (GMX_GPU_OPENCL && (getenv("GMX_DISABLE_GPU_TIMING") == nullptr));
+    nb->bDoTime = decideGpuTimingsUsage();
 
     if (nb->bDoTime)
     {