From 6cebf79cf858982922edc4d582a12cbb9a613e51 Mon Sep 17 00:00:00 2001 From: Berk Hess Date: Mon, 22 Jul 2019 11:24:35 +0200 Subject: [PATCH] Split canDetectGpus() 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 | 24 ++++++++++++++++++++++-- src/gromacs/gpu_utils/gpu_utils.cu | 2 +- src/gromacs/gpu_utils/gpu_utils.h | 16 ++++++++++++---- src/gromacs/gpu_utils/gpu_utils_ocl.cpp | 9 +-------- src/gromacs/gpu_utils/tests/gputest.cpp | 4 ++-- src/gromacs/hardware/detecthardware.cpp | 9 +++------ src/gromacs/mdlib/tests/constr.cpp | 4 ++-- src/gromacs/mdlib/tests/leapfrog.cpp | 8 ++++---- src/gromacs/mdlib/tests/settle.cpp | 4 ++-- src/programs/mdrun/tests/pmetest.cpp | 2 +- 10 files changed, 50 insertions(+), 32 deletions(-) diff --git a/src/gromacs/gpu_utils/gpu_utils.cpp b/src/gromacs/gpu_utils/gpu_utils.cpp index 81778c0111..d47abb3b17 100644 --- a/src/gromacs/gpu_utils/gpu_utils.cpp +++ b/src/gromacs/gpu_utils/gpu_utils.cpp @@ -50,7 +50,27 @@ #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"); } diff --git a/src/gromacs/gpu_utils/gpu_utils.cu b/src/gromacs/gpu_utils/gpu_utils.cu index b356f54a04..8db9065d43 100644 --- a/src/gromacs/gpu_utils/gpu_utils.cu +++ b/src/gromacs/gpu_utils/gpu_utils.cu @@ -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; diff --git a/src/gromacs/gpu_utils/gpu_utils.h b/src/gromacs/gpu_utils/gpu_utils.h index 8869338e47..eca657e257 100644 --- a/src/gromacs/gpu_utils/gpu_utils.h +++ b/src/gromacs/gpu_utils/gpu_utils.h @@ -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. * diff --git a/src/gromacs/gpu_utils/gpu_utils_ocl.cpp b/src/gromacs/gpu_utils/gpu_utils_ocl.cpp index a2173ad750..8c695549f6 100644 --- a/src/gromacs/gpu_utils/gpu_utils_ocl.cpp +++ b/src/gromacs/gpu_utils/gpu_utils_ocl.cpp @@ -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); diff --git a/src/gromacs/gpu_utils/tests/gputest.cpp b/src/gromacs/gpu_utils/tests/gputest.cpp index 6308a54246..13044a5d72 100644 --- a/src/gromacs/gpu_utils/tests/gputest.cpp +++ b/src/gromacs/gpu_utils/tests/gputest.cpp @@ -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_); } diff --git a/src/gromacs/hardware/detecthardware.cpp b/src/gromacs/hardware/detecthardware.cpp index 53951b105b..7b952c1697 100644 --- a/src/gromacs/hardware/detecthardware.cpp +++ b/src/gromacs/hardware/detecthardware.cpp @@ -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 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( diff --git a/src/gromacs/mdlib/tests/constr.cpp b/src/gromacs/mdlib/tests/constr.cpp index a20e3d74d4..2b14d9e73d 100644 --- a/src/gromacs/mdlib/tests/constr.cpp +++ b/src/gromacs/mdlib/tests/constr.cpp @@ -312,8 +312,8 @@ std::vector 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"); } diff --git a/src/gromacs/mdlib/tests/leapfrog.cpp b/src/gromacs/mdlib/tests/leapfrog.cpp index 16f0ad970c..319bb41efd 100644 --- a/src/gromacs/mdlib/tests/leapfrog.cpp +++ b/src/gromacs/mdlib/tests/leapfrog.cpp @@ -168,10 +168,10 @@ class IntegratorTest : public ::testing::TestWithParam }; -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; } diff --git a/src/gromacs/mdlib/tests/settle.cpp b/src/gromacs/mdlib/tests/settle.cpp index 9cb6b20b9d..f0f1865ea5 100644 --- a/src/gromacs/mdlib/tests/settle.cpp +++ b/src/gromacs/mdlib/tests/settle.cpp @@ -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; diff --git a/src/programs/mdrun/tests/pmetest.cpp b/src/programs/mdrun/tests/pmetest.cpp index 960ccbf276..1ab8fa444b 100644 --- a/src/programs/mdrun/tests/pmetest.cpp +++ b/src/programs/mdrun/tests/pmetest.cpp @@ -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); -- 2.22.0