Merge branch release-2019 into release-2020
authorPaul Bauer <paul.bauer.q@gmail.com>
Fri, 28 Feb 2020 09:56:27 +0000 (10:56 +0100)
committerPaul Bauer <paul.bauer.q@gmail.com>
Fri, 28 Feb 2020 09:56:27 +0000 (10:56 +0100)
Resolved Conflicts:
cmake/gmxVersionInfo.cmake
src/gromacs/ewald/pme.cpp
src/gromacs/gmxana/gmx_disre.cpp
src/gromacs/gpu_utils/gpu_utils.cu
src/gromacs/hardware/gpu_hw_info.cpp
src/gromacs/hardware/gpu_hw_info.h
src/gromacs/mdrun/rerun.cpp

Change-Id: I2a89270a1321a51e0bc25e2b6890245f562945a2

docs/release-notes/2019/2019.6.rst
src/gromacs/ewald/pme.cpp
src/gromacs/gmxana/gmx_disre.cpp
src/gromacs/gpu_utils/gpu_utils.cu
src/gromacs/hardware/gpu_hw_info.cpp
src/gromacs/hardware/gpu_hw_info.h
src/gromacs/mdrun/rerun.cpp

index 5218a809e991b2b3b02441cbd8fcfb66d1104bf2..bf676ce57fabaa607f3c24289694f4cc0f4d05a6 100644 (file)
@@ -1,7 +1,7 @@
 GROMACS 2019.6 release notes
 ----------------------------
 
-This version was released on TODO, 2020. These release notes
+This version was released on February 28th, 2020. These release notes
 document the changes that have taken place in GROMACS since the
 previous 2019.5 version, to fix known issues. It also incorporates all
 fixes made in version 2018.8 and earlier, which you can find described
@@ -16,9 +16,40 @@ in the :ref:`release-notes`.
 Fixes where mdrun could behave incorrectly
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+Actually fix PME forces with FE without perturbed q/LJ
+""""""""""""""""""""""""""""""""""""""""""""""""""""""
+
+PME would incorrectly ignore the mesh forces on perturbed atoms when
+no charges or LJ atom types were actually perturbed. Note that this
+is a rather uncommon scenario.
+
+:issue:`2640`
+:issue:`3359`
+
+Avoid overzealous program abort with orientation restraints
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+
+It could happen that mdrun would abort on checking orientation
+restraints in multiple molecules even though no restraints where
+applied to them.
+
+:issue:`3375`
+
+Calculate Coulomb and LJ reciprocal terms in rerun
+""""""""""""""""""""""""""""""""""""""""""""""""""
+
+Reruns would not calculate Coulomb and LJ reciprocal terms, leading
+to wrong potential energies. This bug only showed up if GROMACS was
+compiled without GPU support.
+
+:issue:`3400`
+
 Fixes for ``gmx`` tools
 ^^^^^^^^^^^^^^^^^^^^^^^
 
+Added check for inconsistent input of distance restraint labels
+in gmx disre.
+
 Fixes that affect portability
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -31,3 +62,9 @@ Compilation was failing with ``mcpcom: core dumped`` for the file :file:`pulluti
 Miscellaneous
 ^^^^^^^^^^^^^
 
+Avoid cryptic GPU detection errors when devices are unavailable or out of memory
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+
+:issue:`3178`
+:issue:`3399`
+
index ed9eaa9ff2a7940778f8f915e048278dbc875af8..91b22e7e5e7578f02e26f15805d46a179a6cdf7f 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
+ * Copyright (c) 2013,2014,2015,2016,2017 The GROMACS development team.
  * Copyright (c) 2018,2019,2020, 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
index 66a79e7276350f1aeec58d8a40c7ac4b9d020d07..608677f69fdc572f32c9b7009f0c0c681f5cb47c 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016,2017,2018,2019,2020, 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.
@@ -181,11 +181,33 @@ static void check_viol(FILE*       log,
         vvindex[j] = 0;
     }
     nat = interaction_function[F_DISRES].nratoms + 1;
+    // Check internal consistency of disres.label
+    // The label for a distance restraint should be at most one larger
+    // than the previous label.
+    int label_old = forceparams[forceatoms[0]].disres.label;
+    for (i = 0; (i < disres->nr); i += nat)
+    {
+        type  = forceatoms[i];
+        label = forceparams[type].disres.label;
+        if ((label == label_old) || (label == label_old + 1))
+        {
+            label_old = label;
+        }
+        else
+        {
+            gmx_fatal(FARGS,
+                      "Label mismatch in distance restrains. Label for restraint %d is %d, "
+                      "expected it to be either %d or %d",
+                      i / nat, label, label_old, label_old + 1);
+        }
+    }
+    // Get offset for label index
+    label_old = forceparams[forceatoms[0]].disres.label;
     for (i = 0; (i < disres->nr);)
     {
         type  = forceatoms[i];
         n     = 0;
-        label = forceparams[type].disres.label;
+        label = forceparams[type].disres.label - label_old;
         if (debug)
         {
             fprintf(debug, "DISRE: ndr = %d, label = %d  i=%d, n =%d\n", ndr, label, i, n);
@@ -193,7 +215,8 @@ static void check_viol(FILE*       log,
         do
         {
             n += nat;
-        } while (((i + n) < disres->nr) && (forceparams[forceatoms[i + n]].disres.label == label));
+        } while (((i + n) < disres->nr)
+                 && (forceparams[forceatoms[i + n]].disres.label == label + label_old));
 
         calc_disres_R_6(nullptr, nullptr, n, &forceatoms[i], x, pbc, fcd, nullptr);
 
index b7e5e0f77ead42f116484c55e26a20a5fcce2cc8..216a930b67243c194feebecaf8948052d73ed397 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2010-2018, The GROMACS development team.
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015,2016, The GROMACS development team.
+ * Copyright (c) 2017,2018,2019,2020, 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.
@@ -75,28 +75,25 @@ static bool cudaProfilerRun = ((getenv("NVPROF_ID") != nullptr));
 /** Dummy kernel used for sanity checking. */
 static __global__ void k_dummy_test(void) {}
 
-static void checkCompiledTargetCompatibility(int deviceId, const cudaDeviceProp& deviceProp)
+static cudaError_t checkCompiledTargetCompatibility(int deviceId, const cudaDeviceProp& deviceProp)
 {
     cudaFuncAttributes attributes;
     cudaError_t        stat = cudaFuncGetAttributes(&attributes, k_dummy_test);
 
     if (cudaErrorInvalidDeviceFunction == stat)
     {
-        gmx_fatal(FARGS,
-                  "The %s binary does not include support for the CUDA architecture of a "
-                  "detected GPU: %s, ID #%d (compute capability %d.%d). "
-                  "By default, GROMACS supports all architectures of compute "
-                  "capability >= 3.0, so your GPU "
-                  "might be rare, or some architectures were disabled in the build. "
-                  "Consult the install guide for how to use the GMX_CUDA_TARGET_SM and "
-                  "GMX_CUDA_TARGET_COMPUTE CMake variables to add this architecture. "
-                  "To work around this error, use the CUDA_VISIBLE_DEVICES environment"
-                  "variable to pass a list of GPUs that excludes the ID %d.",
-                  gmx::getProgramContext().displayName(), deviceProp.name, deviceId,
-                  deviceProp.major, deviceProp.minor, deviceId);
-    }
-
-    CU_RET_ERR(stat, "cudaFuncGetAttributes failed");
+        fprintf(stderr,
+                "\nWARNING: The %s binary does not include support for the CUDA architecture of "
+                "the GPU ID #%d (compute capability %d.%d) detected during detection. "
+                "By default, GROMACS supports all architectures of compute "
+                "capability >= 3.0, so your GPU "
+                "might be rare, or some architectures were disabled in the build. \n"
+                "Consult the install guide for how to use the GMX_CUDA_TARGET_SM and "
+                "GMX_CUDA_TARGET_COMPUTE CMake variables to add this architecture. \n",
+                gmx::getProgramContext().displayName(), deviceId, deviceProp.major, deviceProp.minor);
+    }
+
+    return stat;
 }
 
 bool isHostMemoryPinned(const void* h_ptr)
@@ -129,7 +126,7 @@ bool isHostMemoryPinned(const void* h_ptr)
  *
  * \param[in]  dev_id      the device ID of the GPU or -1 if the device has already been initialized
  * \param[in]  dev_prop    The device properties structure
- * \returns                0 if the device looks OK
+ * \returns                0 if the device looks OK, -1 if it sanity checks failed, and -2 if the device is busy
  *
  * TODO: introduce errors codes and handle errors more smoothly.
  */
@@ -200,13 +197,36 @@ static int do_sanity_checks(int dev_id, const cudaDeviceProp& dev_prop)
         }
     }
 
+    cu_err = checkCompiledTargetCompatibility(dev_id, dev_prop);
+    // Avoid triggering an error if GPU devices are in exclusive or prohibited mode;
+    // it is enough to check for cudaErrorDevicesUnavailable only here because
+    // if we encounter it that will happen in cudaFuncGetAttributes in the above function.
+    if (cu_err == cudaErrorDevicesUnavailable)
+    {
+        return -2;
+    }
+    else if (cu_err != cudaSuccess)
+    {
+        return -1;
+    }
+
     /* try to execute a dummy kernel */
-    checkCompiledTargetCompatibility(dev_id, dev_prop);
+    try
+    {
+        KernelLaunchConfig config;
+        config.blockSize[0]       = 512;
+        const auto dummyArguments = prepareGpuKernelArguments(k_dummy_test, config);
+        launchGpuKernel(k_dummy_test, config, nullptr, "Dummy kernel", dummyArguments);
+    }
+    catch (gmx::GromacsException& ex)
+    {
+        // launchGpuKernel error is not fatal and should continue with marking the device bad
+        fprintf(stderr,
+                "Error occurred while running dummy kernel sanity check on device #%d:\n %s\n", id,
+                formatExceptionMessageToString(ex).c_str());
+        return -1;
+    }
 
-    KernelLaunchConfig config;
-    config.blockSize[0]       = 512;
-    const auto dummyArguments = prepareGpuKernelArguments(k_dummy_test, config);
-    launchGpuKernel(k_dummy_test, config, nullptr, "Dummy kernel", dummyArguments);
     if (cudaDeviceSynchronize() != cudaSuccess)
     {
         return -1;
@@ -315,12 +335,16 @@ static int is_gmx_supported_gpu_id(int deviceId, const cudaDeviceProp& devicePro
      * the dummy test kernel fails to execute with a "device busy message" we
      * should appropriately report that the device is busy instead of insane.
      */
-    if (do_sanity_checks(deviceId, deviceProp) != 0)
+    const int checkResult = do_sanity_checks(deviceId, deviceProp);
+    switch (checkResult)
     {
-        return egpuInsane;
+        case 0: return egpuCompatible;
+        case -1: return egpuInsane;
+        case -2: return egpuUnavailable;
+        default:
+            GMX_RELEASE_ASSERT(false, "Invalid do_sanity_checks() return value");
+            return egpuCompatible;
     }
-
-    return egpuCompatible;
 }
 
 bool isGpuDetectionFunctional(std::string* errorMessage)
index cf913ed041b79a30cc7a94aa6065a5909abd9654..8c79bf432028c32c3f5475729ac81c6c0f73099f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2020, 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.
@@ -46,6 +46,7 @@
 // move to a single place in gpu_utils.
 /* Names of the GPU detection/check results (see e_gpu_detect_res_t in hw_info.h). */
 const char* const gpu_detect_res_str[egpuNR] = {
-    "compatible", "nonexistent", "incompatible",
-    "incompatible (please recompile with GMX_OPENCL_NB_CLUSTER_SIZE=4)", "insane"
+    "compatible",   "nonexistent",
+    "incompatible", "incompatible (please recompile with GMX_OPENCL_NB_CLUSTER_SIZE=4)",
+    "insane",       "unavailable"
 };
index 471eeb81e2e7160c3b185d39b3909099cc703a2c..a8b3144ee5b32f88c52a24a30d4e8eda8f7fb569 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2012,2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015,2017,2018,2019,2020, 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.
@@ -43,7 +43,10 @@ struct gmx_device_info_t;
  *
  * The egpuInsane value means that during the sanity checks an error
  * occurred that indicates malfunctioning of the device, driver, or
- * incompatible driver/runtime. */
+ * incompatible driver/runtime.
+ * eGpuUnavailable indicates that CUDA devices are busy or unavailable
+ * typically due to use of cudaComputeModeExclusive, cudaComputeModeProhibited modes.
+ */
 typedef enum
 {
     egpuCompatible = 0,
@@ -51,6 +54,7 @@ typedef enum
     egpuIncompatible,
     egpuIncompatibleClusterSize,
     egpuInsane,
+    egpuUnavailable,
     egpuNR
 } e_gpu_detect_res_t;
 
index 39b76695e825312a821cd871106e05715ef87af8..956bd1ab1cbdd33e3ca7e8f673e5ebe4586607b9 100644 (file)
@@ -41,8 +41,6 @@
  */
 #include "gmxpre.h"
 
-#include "config.h"
-
 #include <cinttypes>
 #include <cmath>
 #include <cstdio>
@@ -544,7 +542,7 @@ void gmx::LegacySimulator::do_rerun()
         }
 
         force_flags = (GMX_FORCE_STATECHANGED | GMX_FORCE_DYNAMICBOX | GMX_FORCE_ALLFORCES
-                       | (GMX_GPU ? GMX_FORCE_VIRIAL : 0) | // TODO: Get rid of this once #2649 is solved
+                       | GMX_FORCE_VIRIAL | // TODO: Get rid of this once #2649 and #3400 are solved
                        GMX_FORCE_ENERGY | (doFreeEnergyPerturbation ? GMX_FORCE_DHDL : 0));
 
         if (shellfc)