Split canDetectGpus()
authorBerk Hess <hess@kth.se>
Mon, 22 Jul 2019 09:24:35 +0000 (11:24 +0200)
committerMark Abraham <mark.j.abraham@gmail.com>
Thu, 25 Jul 2019 14:25:23 +0000 (16:25 +0200)
The function canDetectGpus() was used in a higher and lower level
fashion. The original canDetectGpus() is renamed to
isGpuDetectionFunctional(). Added canPerformGpuDetection() which also
checks for a GPU build and the env.var. GMX_DISABLE_GPU_DETECTION.

This also fixes an inconsistency error in the PME GPU unit tests
when running with GMX_DISABLE_GPU_DETECTION.

Change-Id: If762b2a108eedeb1bda0a2af9afa8a418aa93e14

src/gromacs/gpu_utils/gpu_utils.cpp
src/gromacs/gpu_utils/gpu_utils.cu
src/gromacs/gpu_utils/gpu_utils.h
src/gromacs/gpu_utils/gpu_utils_ocl.cpp
src/gromacs/gpu_utils/tests/gputest.cpp
src/gromacs/hardware/detecthardware.cpp
src/gromacs/mdlib/tests/constr.cpp
src/gromacs/mdlib/tests/leapfrog.cpp
src/gromacs/mdlib/tests/settle.cpp
src/programs/mdrun/tests/pmetest.cpp

index 81778c01117dab175d108695b609017c04d32b09..d47abb3b176bb8aedadfbfa06d7680445969e414 100644 (file)
 #include "gromacs/utility/smalloc.h"
 #include "gromacs/utility/stringutil.h"
 
-#if !GMX_GPU
+#ifdef _MSC_VER
+#pragma warning(disable: 6237)
+#endif
+
+//! Constant used to help minimize preprocessed code
+static constexpr bool c_binarySupportsGpus = (GMX_GPU != GMX_GPU_NONE);
+
+bool canPerformGpuDetection()
+{
+    if (c_binarySupportsGpus &&
+        getenv("GMX_DISABLE_GPU_DETECTION") == nullptr)
+    {
+        return isGpuDetectionFunctional(nullptr);
+    }
+    else
+    {
+        return false;
+    }
+}
+
+#if GMX_GPU == GMX_GPU_NONE
 int gpu_info_get_stat(const gmx_gpu_info_t & /*unused*/, int /*unused*/)
 {
     return egpuNonexistent;
@@ -109,7 +129,7 @@ bool buildSupportsNonbondedOnGpu(std::string *error)
     {
         errorReasons.emplace_back("double precision");
     }
-    if (GMX_GPU == GMX_GPU_NONE)
+    if (!c_binarySupportsGpus)
     {
         errorReasons.emplace_back("non-GPU build of GROMACS");
     }
index b356f54a04128ceb1b4a1e5fffef8a65ce9507e5..8db9065d43414f30055a4aec1522932c911f43e2 100644 (file)
@@ -330,7 +330,7 @@ static int is_gmx_supported_gpu_id(int                   deviceId,
     return egpuCompatible;
 }
 
-bool canDetectGpus(std::string *errorMessage)
+bool isGpuDetectionFunctional(std::string *errorMessage)
 {
     cudaError_t        stat;
     int                driverVersion = -1;
index 8869338e47e4aad1e06b23a0a65fedc3a30c68f6..eca657e257106a26914f23a0115034b4cc1ece41 100644 (file)
@@ -75,6 +75,14 @@ enum class GpuTaskCompletion
 };
 
 /*! \brief Return whether GPUs can be detected
+ *
+ * Returns true when this is a build of \Gromacs configured to support
+ * GPU usage, GPU detection is not disabled by an environment variable
+ * and a valid device driver, ICD, and/or runtime was detected.
+ * Does not throw. */
+bool canPerformGpuDetection();
+
+/*! \brief Return whether GPU detection is functioning correctly
  *
  * Returns true when this is a build of \Gromacs configured to support
  * GPU usage, and a valid device driver, ICD, and/or runtime was detected.
@@ -90,13 +98,13 @@ enum class GpuTaskCompletion
  *
  * Does not throw. */
 GPU_FUNC_QUALIFIER
-bool canDetectGpus(std::string *GPU_FUNC_ARGUMENT(errorMessage)) GPU_FUNC_TERM_WITH_RETURN(false);
+bool isGpuDetectionFunctional(std::string *GPU_FUNC_ARGUMENT(errorMessage)) GPU_FUNC_TERM_WITH_RETURN(false);
 
 /*! \brief Find all GPUs in the system.
  *
- *  Will detect every GPU supported by the device driver in use. Must
- *  only be called if canDetectGpus() has returned true. This routine
- *  also checks for the compatibility of each and fill the
+ *  Will detect every GPU supported by the device driver in use.
+ *  Must only be called if canPerformGpuDetection() has returned true.
+ *  This routine also checks 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.
  *
index a2173ad75035561655d3c160f7856e0ca7c85d50..8c695549f636f585416b68ec43a647758d57b78a 100644 (file)
@@ -316,9 +316,7 @@ static ocl_vendor_id_t get_vendor_id(char *vendor_name)
     return OCL_VENDOR_UNKNOWN;
 }
 
-
-//! This function is documented in the header file
-bool canDetectGpus(std::string *errorMessage)
+bool isGpuDetectionFunctional(std::string *errorMessage)
 {
     cl_uint numPlatforms;
     cl_int  status       = clGetPlatformIDs(0, nullptr, &numPlatforms);
@@ -345,7 +343,6 @@ bool canDetectGpus(std::string *errorMessage)
     return foundPlatform;
 }
 
-//! This function is documented in the header file
 void findGpus(gmx_gpu_info_t *gpu_info)
 {
     cl_uint         ocl_platform_count;
@@ -518,7 +515,6 @@ void findGpus(gmx_gpu_info_t *gpu_info)
     sfree(ocl_platform_ids);
 }
 
-//! This function is documented in the header file
 void get_gpu_device_info_string(char *s, const gmx_gpu_info_t &gpu_info, int index)
 {
     assert(s);
@@ -563,7 +559,6 @@ bool areAllGpuDevicesFromAmd(const gmx_gpu_info_t &gpuInfo)
     return result;
 }
 
-//! This function is documented in the header file
 void init_gpu(const gmx_device_info_t *deviceInfo)
 {
     assert(deviceInfo);
@@ -586,7 +581,6 @@ void init_gpu(const gmx_device_info_t *deviceInfo)
     }
 }
 
-//! This function is documented in the header file
 gmx_device_info_t *getDeviceInfo(const gmx_gpu_info_t &gpu_info,
                                  int                   deviceId)
 {
@@ -597,7 +591,6 @@ gmx_device_info_t *getDeviceInfo(const gmx_gpu_info_t &gpu_info,
     return &gpu_info.gpu_dev[deviceId];
 }
 
-//! This function is documented in the header file
 size_t sizeof_gpu_dev_info()
 {
     return sizeof(gmx_device_info_t);
index 6308a5424692209bc916fd4ddbea1d2cb26f4489..13044a5d72e141f29d6455481613c5ac924fa86e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2017,2018, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019, 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.
@@ -56,7 +56,7 @@ namespace test
 GpuTest::GpuTest()
 {
     snew(gpuInfo_, 1);
-    if (canDetectGpus(nullptr))
+    if (isGpuDetectionFunctional(nullptr))
     {
         findGpus(gpuInfo_);
     }
index 53951b105b05c75756ed756c84637929dd725bb2..7b952c1697d5779ebef4a6739c60109335894e1c 100644 (file)
@@ -94,9 +94,6 @@ namespace gmx
 #    define _SC_NPROCESSORS_CONF _SC_NPROC_CONF
 #endif
 
-//! Constant used to help minimize preprocessed code
-static const bool bGPUBinary     = GMX_GPU != GMX_GPU_NONE;
-
 /*! \brief Information about the hardware of all nodes (common to all threads in this process).
  *
  * This information is constructed only when required, but thereafter
@@ -114,8 +111,8 @@ static void gmx_detect_gpus(const gmx::MDLogger              &mdlog,
                             const PhysicalNodeCommunicator   &physicalNodeComm,
                             compat::not_null<gmx_hw_info_t *> hardwareInfo)
 {
-    hardwareInfo->gpu_info.bDetectGPUs =
-        (bGPUBinary && getenv("GMX_DISABLE_GPU_DETECTION") == nullptr);
+    hardwareInfo->gpu_info.bDetectGPUs = canPerformGpuDetection();
+
     if (!hardwareInfo->gpu_info.bDetectGPUs)
     {
         return;
@@ -139,7 +136,7 @@ static void gmx_detect_gpus(const gmx::MDLogger              &mdlog,
     if (isMasterRankOfPhysicalNode || allRanksMustDetectGpus)
     {
         std::string errorMessage;
-        gpusCanBeDetected = canDetectGpus(&errorMessage);
+        gpusCanBeDetected = isGpuDetectionFunctional(&errorMessage);
         if (!gpusCanBeDetected)
         {
             GMX_LOG(mdlog.info).asParagraph().appendTextFormatted(
index a20e3d74d4d5b10a60d8590ffc7fb871371179e5..2b14d9e73d410a30aff6fe7f3a8e73e8a8cf3d02 100644 (file)
@@ -312,8 +312,8 @@ std::vector<std::string> getAlgorithmsNames()
 {
     algorithmsNames.emplace_back("SHAKE");
     algorithmsNames.emplace_back("LINCS");
-    std::string errorMessage;
-    if (GMX_GPU == GMX_GPU_CUDA && canDetectGpus(&errorMessage))
+    // TODO: Here we should check that at least 1 suitable GPU is available
+    if (GMX_GPU == GMX_GPU_CUDA && canPerformGpuDetection())
     {
         algorithmsNames.emplace_back("LINCS_CUDA");
     }
index 16f0ad970c2978b03b590915489cd98b9fb354d6..319bb41efd9f5743f751a062526e1b0f01e05ef3 100644 (file)
@@ -168,10 +168,10 @@ class IntegratorTest : public ::testing::TestWithParam<IntegratorTestParameters>
 
 };
 
-TEST_P(IntegratorTest, SimpleIntegration){
-    // Do nothing if it is a CUDA build but there are no CUDA-capable GPUs
-    std::string errorMessage;
-    if (!canDetectGpus(&errorMessage))
+TEST_P(IntegratorTest, SimpleIntegration)
+{
+    // TODO: Here we should check that at least 1 suitable GPU is available
+    if (!canPerformGpuDetection())
     {
         return;
     }
index 9cb6b20b9da256df5a81aab96832090f5f3118a3..f0f1865ea516e1f0da2affd5065f701a19f0823b 100644 (file)
@@ -287,8 +287,8 @@ TEST_P(SettleTest, SatisfiesConstraints)
     // 1. The code was compiled with cuda
     // 2. There is a CUDA-capable GPU in a system
 #if GMX_GPU == GMX_GPU_CUDA
-    std::string errorMessage;
-    if (canDetectGpus(&errorMessage))
+    // TODO: Here we should check that at least 1 suitable GPU is available
+    if (canPerformGpuDetection())
     {
         // Run the CUDA code and check if it gives identical results to CPU code
         t_idef                        idef;
index 960ccbf276b7cae493b6d6f9cab372dac221f9e0..1ab8fa444bee11d1430b8cec76ca61b56de3ddd0 100644 (file)
@@ -104,7 +104,7 @@ void PmeTest::SetUpTestCase()
     // there is no GPU support in the build.
     //
     // TODO report any error messages gracefully.
-    if (canDetectGpus(nullptr))
+    if (canPerformGpuDetection())
     {
         findGpus(&gpuInfo);
         s_hasCompatibleGpus = (gpuInfo.n_dev_compatible > 0);