From 872421daead8e975f64394d54f4f83ff9757ce4a Mon Sep 17 00:00:00 2001 From: Mark Abraham Date: Mon, 4 Sep 2017 09:49:59 +0200 Subject: [PATCH] Introduce type-safe GPU emulation variables It's less clearly correct to pass around many variables of bool type, as often happens in the high-level code. Change-Id: I9ddb35fa8789e3eb5726fc0143a580493737bc29 --- src/gromacs/mdlib/forcerec.cpp | 10 +++++----- src/gromacs/mdlib/nb_verlet.h | 11 ++++++++++- src/gromacs/mdlib/sim_util.cpp | 2 +- src/programs/mdrun/runner.cpp | 24 +++++++++++++----------- 4 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/gromacs/mdlib/forcerec.cpp b/src/gromacs/mdlib/forcerec.cpp index 02010c7db9..07b9eea073 100644 --- a/src/gromacs/mdlib/forcerec.cpp +++ b/src/gromacs/mdlib/forcerec.cpp @@ -1707,7 +1707,7 @@ static void pick_nbnxn_kernel(FILE *fp, const gmx::MDLogger &mdlog, gmx_bool use_simd_kernels, gmx_bool bUseGPU, - bool emulateGpu, + EmulateGpuNonbonded emulateGpu, const t_inputrec *ir, int *kernel_type, int *ewald_excl, @@ -1718,7 +1718,7 @@ static void pick_nbnxn_kernel(FILE *fp, *kernel_type = nbnxnkNotSet; *ewald_excl = ewaldexclTable; - if (emulateGpu) + if (emulateGpu == EmulateGpuNonbonded::Yes) { *kernel_type = nbnxnk8x8x8_PlainC; @@ -2051,10 +2051,10 @@ static void init_nb_verlet(FILE *fp, nbv = new nonbonded_verlet_t(); - nbv->emulateGpu = (getenv("GMX_EMULATE_GPU") != nullptr); + nbv->emulateGpu = ((getenv("GMX_EMULATE_GPU") != nullptr) ? EmulateGpuNonbonded::Yes : EmulateGpuNonbonded::No); nbv->bUseGPU = deviceInfo != nullptr; - GMX_RELEASE_ASSERT(!(nbv->emulateGpu && nbv->bUseGPU), "When GPU emulation is active, there cannot be a GPU assignment"); + GMX_RELEASE_ASSERT(!(nbv->emulateGpu == EmulateGpuNonbonded::Yes && nbv->bUseGPU), "When GPU emulation is active, there cannot be a GPU assignment"); if (nbv->bUseGPU) { @@ -2086,7 +2086,7 @@ static void init_nb_verlet(FILE *fp, { /* Use GPU for local, select a CPU kernel for non-local */ pick_nbnxn_kernel(fp, mdlog, fr->use_simd_kernels, - FALSE, false, ir, + FALSE, EmulateGpuNonbonded::No, ir, &nbv->grp[i].kernel_type, &nbv->grp[i].ewald_excl, fr->bNonbonded); diff --git a/src/gromacs/mdlib/nb_verlet.h b/src/gromacs/mdlib/nb_verlet.h index 0b692333b6..9d744b7f59 100644 --- a/src/gromacs/mdlib/nb_verlet.h +++ b/src/gromacs/mdlib/nb_verlet.h @@ -103,6 +103,15 @@ #include "gromacs/mdlib/nbnxn_gpu_types.h" #include "gromacs/mdlib/nbnxn_pairlist.h" +//! Help pass GPU-emulation parameters with type safety. +enum class EmulateGpuNonbonded : bool +{ + //! Do not emulate GPUs. + No, + //! Do emulate GPUs. + Yes +}; + #ifdef __cplusplus extern "C" { #endif @@ -187,7 +196,7 @@ typedef struct nonbonded_verlet_t { nonbonded_verlet_group_t grp[2]; /**< local and non-local interaction group */ gmx_bool bUseGPU; /**< TRUE when non-bonded interactions are computed on a physical GPU */ - bool emulateGpu; /**< true when non-bonded interactions are computed on the CPU using GPU-style pair lists */ + EmulateGpuNonbonded emulateGpu; /**< true when non-bonded interactions are computed on the CPU using GPU-style pair lists */ gmx_nbnxn_gpu_t *gpu_nbv; /**< pointer to GPU nb verlet data */ int min_ci_balanced; /**< pair list balancing parameter used for the 8x8x8 GPU kernels */ diff --git a/src/gromacs/mdlib/sim_util.cpp b/src/gromacs/mdlib/sim_util.cpp index 3761078dea..ba75a097f2 100644 --- a/src/gromacs/mdlib/sim_util.cpp +++ b/src/gromacs/mdlib/sim_util.cpp @@ -741,7 +741,7 @@ static void do_force_cutsVERLET(FILE *fplog, t_commrec *cr, bCalcCGCM = (bFillGrid && !DOMAINDECOMP(cr)); bDoForces = (flags & GMX_FORCE_FORCES); bUseGPU = fr->nbv->bUseGPU; - bUseOrEmulGPU = bUseGPU || fr->nbv->emulateGpu; + bUseOrEmulGPU = bUseGPU || (fr->nbv->emulateGpu == EmulateGpuNonbonded::Yes); /* At a search step we need to start the first balancing region * somewhere early inside the step after communication during domain diff --git a/src/programs/mdrun/runner.cpp b/src/programs/mdrun/runner.cpp index e6dbbeffcd..9fb82dfcae 100644 --- a/src/programs/mdrun/runner.cpp +++ b/src/programs/mdrun/runner.cpp @@ -84,6 +84,7 @@ #include "gromacs/mdlib/mdatoms.h" #include "gromacs/mdlib/mdrun.h" #include "gromacs/mdlib/minimize.h" +#include "gromacs/mdlib/nb_verlet.h" #include "gromacs/mdlib/nbnxn_search.h" #include "gromacs/mdlib/nbnxn_tuning.h" #include "gromacs/mdlib/qmmm.h" @@ -320,10 +321,10 @@ namespace gmx { //! Halt the run if there are inconsistences between user choices to run with GPUs and/or hardware detection. -static void exitIfCannotForceGpuRun(bool requirePhysicalGpu, - bool emulateGpu, - bool useVerletScheme, - bool compatibleGpusFound) +static void exitIfCannotForceGpuRun(bool requirePhysicalGpu, + EmulateGpuNonbonded emulateGpuNonbonded, + bool useVerletScheme, + bool compatibleGpusFound) { /* Was GPU acceleration either explicitly (-nb gpu) or implicitly * (gpu ID passed) requested? */ @@ -338,7 +339,7 @@ static void exitIfCannotForceGpuRun(bool requirePhysicalGpu, gmx::getProgramContext().displayName()); } - if (emulateGpu) + if (emulateGpuNonbonded == EmulateGpuNonbonded::Yes) { gmx_fatal(FARGS, "GPU emulation cannot be requested together with GPU acceleration!"); } @@ -473,14 +474,15 @@ int Mdrunner::mdrunner() /* Handle GPU-related user options. Later, we check consistency * with things like whether support is compiled, or tMPI thread * count. */ - bool emulateGpu = getenv("GMX_EMULATE_GPU") != nullptr; - bool forceUseCpu = (strncmp(nbpu_opt, "cpu", 3) == 0); + EmulateGpuNonbonded emulateGpuNonbonded = (getenv("GMX_EMULATE_GPU") != nullptr ? + EmulateGpuNonbonded::Yes : EmulateGpuNonbonded::No); + bool forceUseCpu = (strncmp(nbpu_opt, "cpu", 3) == 0); if (!hw_opt.gpuIdTaskAssignment.empty() && forceUseCpu) { gmx_fatal(FARGS, "GPU IDs were specified, and short-ranged interactions were assigned to the CPU. Make no more than one of these choices."); } bool forceUsePhysicalGpu = (strncmp(nbpu_opt, "gpu", 3) == 0) || !hw_opt.gpuIdTaskAssignment.empty(); - bool tryUsePhysicalGpu = (strncmp(nbpu_opt, "auto", 4) == 0) && hw_opt.gpuIdTaskAssignment.empty() && !emulateGpu; + bool tryUsePhysicalGpu = (strncmp(nbpu_opt, "auto", 4) == 0) && hw_opt.gpuIdTaskAssignment.empty() && (emulateGpuNonbonded == EmulateGpuNonbonded::No); GMX_RELEASE_ASSERT(!(forceUsePhysicalGpu && tryUsePhysicalGpu), "Must either force use of " "GPUs for short-ranged interactions, or try to use them, not both."); @@ -515,7 +517,7 @@ int Mdrunner::mdrunner() read_tpx_state(ftp2fn(efTPR, nfile, fnm), inputrec, state, mtop); exitIfCannotForceGpuRun(forceUsePhysicalGpu, - emulateGpu, + emulateGpuNonbonded, inputrec->cutoff_scheme == ecutsVERLET, compatibleGpusFound(hwinfo->gpu_info)); @@ -764,8 +766,8 @@ int Mdrunner::mdrunner() /* Update rlist and nstlist. */ if (inputrec->cutoff_scheme == ecutsVERLET) { - prepare_verlet_scheme(fplog, cr, inputrec, nstlist_cmdline, mtop, - box, nonbondedOnGpu || emulateGpu, *hwinfo->cpuInfo); + prepare_verlet_scheme(fplog, cr, inputrec, nstlist_cmdline, mtop, box, + nonbondedOnGpu || (emulateGpuNonbonded == EmulateGpuNonbonded::Yes), *hwinfo->cpuInfo); } if (PAR(cr) && !(EI_TPI(inputrec->eI) || -- 2.11.4.GIT