Merge branch release-2019
authorMark Abraham <mark.j.abraham@gmail.com>
Wed, 2 Jan 2019 10:56:32 +0000 (11:56 +0100)
committerPaul Bauer <paul.bauer.q@gmail.com>
Wed, 2 Jan 2019 11:22:29 +0000 (12:22 +0100)
Change-Id: I71d9bc751e14f821392f802ee9222b864f1e69b6

28 files changed:
CMakeLists.txt
admin/builds/gromacs.py
cmake/gmxManageClangCudaConfig.cmake
cmake/gmxManageNvccConfig.cmake
cmake/gmxVersionInfo.cmake
docs/CMakeLists.txt
docs/dev-manual/known-issues.rst
docs/release-notes/2018/2018.5.rst
docs/release-notes/2019/2019.1.rst [new file with mode: 0644]
docs/release-notes/2019/major/highlights.rst
docs/release-notes/2019/major/performance.rst
docs/release-notes/index.rst
src/api/cpp/tests/CMakeLists.txt
src/api/cpp/workflow/tests/CMakeLists.txt
src/config.h.cmakein
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/oclraii.h [new file with mode: 0644]
src/gromacs/mdlib/md_support.cpp
src/gromacs/mdlib/md_support.h
src/gromacs/mdlib/update.cpp
src/gromacs/mdrun/md.cpp
src/gromacs/mdrun/runner.cpp
src/gromacs/taskassignment/decidegpuusage.cpp
src/gromacs/taskassignment/decidegpuusage.h
src/gromacs/timing/cyclecounter.cpp

index 90c253920d1af8a3b8baf8ea236835354fb7702f..59dc5a7f42ca2389623b01de96af763450d21d1c 100644 (file)
@@ -1,7 +1,7 @@
 #
 # This file is part of the GROMACS molecular simulation package.
 #
-# Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by
+# Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2016,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.
@@ -217,7 +217,9 @@ endif()
 set(REQUIRED_CUDA_COMPUTE_CAPABILITY 3.0)
 
 # OpenCL required version: 1.2 or newer
-set(REQUIRED_OPENCL_MIN_VERSION 1.2)
+set(REQUIRED_OPENCL_MIN_VERSION_MAJOR 1)
+set(REQUIRED_OPENCL_MIN_VERSION_MINOR 2)
+set(REQUIRED_OPENCL_MIN_VERSION ${REQUIRED_OPENCL_MIN_VERSION_MAJOR}.${REQUIRED_OPENCL_MIN_VERSION_MINOR})
 
 if(NOT GMX_USE_OPENCL)
     # CUDA detection is done only if GMX_USE_OPENCL is OFF.
index c4776b7b27863eb13e8f754f16fb94b4a78cf6bc..ec6fa73a5cd74e0decd1ce2e6f9823ef91ec49ca 100644 (file)
@@ -1,7 +1,7 @@
 #
 # This file is part of the GROMACS molecular simulation package.
 #
-# Copyright (c) 2015,2016,2017,2018, by the GROMACS development team, led by
+# Copyright (c) 2015,2016,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.
@@ -125,6 +125,8 @@ def do_build(context):
         cmake_opts['GMX_FFT_LIBRARY'] = 'fftpack'
     elif context.opts.buildfftw:
         cmake_opts['GMX_BUILD_OWN_FFTW'] = 'ON'
+        cmake_opts['GMX_BUILD_OWN_FFTW_URL'] = 'ftp://ftp.gromacs.org/misc/fftw-3.3.8.tar.gz'
+        cmake_opts['GMX_BUILD_OWN_FFTW_MD5'] = '8aac833c943d8e90d51b697b27d4384d'
     if context.opts.mkl or context.opts.atlas or context.opts.armpl:
         cmake_opts['GMX_EXTERNAL_BLAS'] = 'ON'
         cmake_opts['GMX_EXTERNAL_LAPACK'] = 'ON'
index 542674d56c477a2240838c20a622df33ade1899c..4d8f45510801f1219fe175135a2096ef4af4ed75 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.
@@ -79,6 +79,10 @@ else()
     if (NOT CUDA_VERSION VERSION_LESS 9.0)
         list(APPEND _CUDA_CLANG_GENCODE_FLAGS "--cuda-gpu-arch=sm_70")
     endif()
+    # Enable this when clang (8.0 ?) introduces sm_75 support
+    #if (NOT CUDA_VERSION VERSION_LESS 10.0)
+    #    list(APPEND _CUDA_CLANG_GENCODE_FLAGS "--cuda-gpu-arch=sm_75")
+    #endif()
 endif()
 if (GMX_CUDA_TARGET_SM)
     set_property(CACHE GMX_CUDA_TARGET_SM PROPERTY HELPSTRING "List of CUDA GPU architecture codes to compile for (without the sm_ prefix)")
index 5704baaff32c09f663d799ee232fcae60859af77..8a021d67ac5a57151fb9a8597e4b2732a8016bac 100644 (file)
@@ -1,7 +1,7 @@
 #
 # This file is part of the GROMACS molecular simulation package.
 #
-# Copyright (c) 2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by
+# Copyright (c) 2012,2013,2014,2015,2016,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.
@@ -142,8 +142,10 @@ else()
     elseif(CUDA_VERSION VERSION_LESS "9.0")
         list (APPEND GMX_CUDA_NVCC_GENCODE_FLAGS "-gencode;arch=compute_60,code=compute_60")
         list (APPEND GMX_CUDA_NVCC_GENCODE_FLAGS "-gencode;arch=compute_61,code=compute_61")
-    else() # version >= 9.0
+    elseif(CUDA_VERSION VERSION_LESS "10.0")
         list (APPEND GMX_CUDA_NVCC_GENCODE_FLAGS "-gencode;arch=compute_70,code=compute_70")
+    else() # version >= 10.0
+        list (APPEND GMX_CUDA_NVCC_GENCODE_FLAGS "-gencode;arch=compute_75,code=compute_75")
     endif()
 endif()
 
index 00c28c65a07f50895a41fb3b903a255deb55362b..6531d44d3eeaa86b592cb307a71d206532043094 100644 (file)
@@ -1,7 +1,7 @@
 #
 # This file is part of the GROMACS molecular simulation package.
 #
-# Copyright (c) 2014,2015,2016,2017,2018, by the GROMACS development team, led by
+# Copyright (c) 2014,2015,2016,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.
@@ -259,8 +259,8 @@ endif()
 # from Zenodo for the manual and source code
 # Has to be done by hand before every final release
 # Use force to override anything given as a cmake command line input
-set(GMX_MANUAL_DOI "" CACHE INTERNAL "reserved doi for GROMACS manual" FORCE)
-set(GMX_SOURCE_DOI "" CACHE INTERNAL "reserved doi for GROMACS source code" FORCE)
+set(GMX_MANUAL_DOI "10.5281/zenodo.2424486" CACHE INTERNAL "reserved doi for GROMACS manual" FORCE)
+set(GMX_SOURCE_DOI "10.5281/zenodo.2424363" CACHE INTERNAL "reserved doi for GROMACS source code" FORCE)
 
 #####################################################################
 # git version info management
index 5c4fc632c7c67abc8838564c64c7f4b6b86324b2..e9742372813c54b8746bf16972bc9f0e0c0fe821 100644 (file)
@@ -1,7 +1,7 @@
 #
 # This file is part of the GROMACS molecular simulation package.
 #
-# Copyright (c) 2014,2015,2016,2017,2018, by the GROMACS development team, led by
+# Copyright (c) 2014,2015,2016,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.
@@ -376,6 +376,7 @@ if (SPHINX_FOUND)
         release-notes/deprecated-functionality.rst
         release-notes/portability.rst
         release-notes/miscellaneous.rst
+        release-notes/2019/2019.1.rst
         release-notes/2019/major/highlights.rst
         release-notes/2019/major/features.rst
         release-notes/2019/major/performance.rst
index 5f77b0a616598a6d5b2486566d09d1f376ef5637..20c321fc41162d1be9aea99171a1ecfa19b13066 100644 (file)
@@ -15,3 +15,11 @@ When using CUDA 7.0 in a ``Debug`` build, if the PME FFT task is offloaded
 to a GPU, a floating point exception will abort the :ref:`mdrun <gmx mdrun>` execution.
 The exception originates from the CUDA FFT (cuFFT) library.
 To avoid this issue, we advise using a later CUDA version.
+
+Issues with GPU timer with OpenCL
+---------------------------------
+
+When building using OpenCL in ``Debug`` mode, it can happen that the GPU timer state gets
+corrupted, leading to an assertion failure during the :ref:`mdrun <gmx mdrun>`.
+This seems to be related to the load of other, unrelated tasks on the GPU.
+
index d1649a948a76c16e115e0b32edfeb8569000d4ab..61573df4dd3bf66cdfa03f178ea1afd3629969e5 100644 (file)
@@ -19,6 +19,33 @@ was reduced to near machine precision. The change does not affect
 the results for non-polarizable systems, such as proteins or small
 molecules.
 
+Make large PME grids work on GPU
+"""""""""""""""""""""""""""""""""""""""""""
+
+PME grids with size along Z larger than 511 would make mdrun exit
+with a cryptic CUDA error.
+
+:issue: `2779`
+
+Fix LINCS accuracy with OpenMP when constraint triangles are present
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+
+Constraint triangles, which usually only occur when replacing hydrogens
+by virtual interaction sites in CH3 and NH3 groups, need double the number
+of iterations as normal constraints. With OpenMP this would only happen
+when the last OpenMP thread has at least one such triangle. This would
+cause a slight loss of accuracy in inhomogeneous systems.
+
+:issue: `2808`
+
+Fix acceleration with ``cos-acceleration``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+A factor of 2 was missing from the acceleration value, leading to incorrect
+results when e.g. calculating viscosities.
+
+:issue: `2572`
+
 Fixes for ``gmx`` tools
 ^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/docs/release-notes/2019/2019.1.rst b/docs/release-notes/2019/2019.1.rst
new file mode 100644 (file)
index 0000000..8be5e1a
--- /dev/null
@@ -0,0 +1,20 @@
+GROMACS 2019.1 release notes
+----------------------------
+
+This version was released on TODO, 2019. These release notes
+document the changes that have taken place in GROMACS since the
+initial version 2019, to fix known issues. It also incorporates all
+fixes made in version 2018.5 and earlier, which you can find described
+in the :ref:`release-notes`.
+
+Fixes where mdrun could behave incorrectly
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Fixes for ``gmx`` tools
+^^^^^^^^^^^^^^^^^^^^^^^
+
+Fixes to improve portability
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Miscellaneous
+^^^^^^^^^^^^^
index 4007329bfae79243bb01ae68f8e6c7f2916f71d5..75a3a7557e50bb5993bedda1cab6407c8a8c71f3 100644 (file)
@@ -1,7 +1,7 @@
 Highlights
 ^^^^^^^^^^
 
-|Gromacs| 2019 was released on INSERT DATE HERE. Patch releases may
+|Gromacs| 2019 was released on December 31st, 2018. Patch releases may
 have been made since then, please use the updated versions!  Here are
 some highlights of what you can expect, along with more detail in the
 links below!
@@ -15,8 +15,8 @@ simulations and hardware. They are:
   coordinate updates have only intra-group dependencies. These can
   include both constraints and virtual sites. This improves performance
   by eliminating overheads during the update, at no cost.
-* Intel integrated GPUs are now supported with OpenCL.
+* Intel integrated GPUs are now supported with OpenCL for offloading
+  non-bonded interactions.
 * PME long-ranged interactions can now also run on a single AMD GPU
   using OpenCL, which means many fewer CPU cores are needed for good
   performance with such hardware.
-* TODO Other stuff
index 26f376d2fde50b7f717ca528d20e789ac97f8533..ecd0a5f48b334d3880c2a4a1802491a2392dd946 100644 (file)
@@ -40,3 +40,9 @@ Bonded interactions are now supported for CUDA GPU offload
 Common types of bonded and LJ-14 interactions found can now run on
 NVIDIA GPUs with CUDA, with and without domain decomposition.
 Interactions with perturbed parameters are not supported.
+
+Added code generation support for NVIDIA Turing GPUs
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+With CUDA 10.0 NVIDIA Turing GPUs can be directly targeted by the nvcc
+compiler. We now generate the appropriate set of flags for the Turing architecture
+by default when using CUDA 10 (or later).
index efa62f1b555acbc1d64ea676c3d93defe2cd0801..41afbdde4633ed9e3a69879c45e950859cc36def 100644 (file)
@@ -46,6 +46,8 @@ Patch releases
 .. toctree::
    :maxdepth: 1
 
+   2019/2019.1
+
 Major release
 ^^^^^^^^^^^^^
 
index 726ce22753b5a04e814c144548a098ac7fd1196f..c4c733d253ff8aba4895e088c9b294a0b14716b9 100644 (file)
@@ -1,7 +1,7 @@
 #
 # This file is part of the GROMACS molecular simulation package.
 #
-# Copyright (c) 2018, by the GROMACS development team, led by
+# Copyright (c) 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.
@@ -73,7 +73,7 @@ target_include_directories(gmxapi-test PRIVATE
 # Link against the gmxapi libraries and get access to its public (installed) headers.
 target_link_libraries(gmxapi-test Gromacs::gmxapi)
 
-gmx_register_gtest_test(GmxapiExternalInterfaceTests gmxapi-test INTEGRATION_TEST)
+gmx_register_gtest_test(GmxapiExternalInterfaceTests gmxapi-test OPENMP_THREADS 2 INTEGRATION_TEST)
 
 set_tests_properties(GmxapiExternalInterfaceTests PROPERTIES
                      WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
@@ -105,4 +105,4 @@ target_include_directories(gmxapi-mpi-test PRIVATE
                            ${CMAKE_CURRENT_SOURCE_DIR})
 target_link_libraries(gmxapi-mpi-test Gromacs::gmxapi)
 
-gmx_register_gtest_test(GmxapiMpiTests gmxapi-mpi-test MPI_RANKS 2 INTEGRATION_TEST)
+gmx_register_gtest_test(GmxapiMpiTests gmxapi-mpi-test MPI_RANKS 2 OPENMP_THREADS 2 INTEGRATION_TEST)
index 80f3e448319d8383b90f3759525fd21aace26709..b37ecdb7d2aa48b0048d3d5e9a330f890307bd41 100644 (file)
@@ -1,7 +1,7 @@
 #
 # This file is part of the GROMACS molecular simulation package.
 #
-# Copyright (c) 2018, by the GROMACS development team, led by
+# Copyright (c) 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.
@@ -47,7 +47,7 @@ gmx_add_gtest_executable(
 
 target_link_libraries(workflow-details-test Gromacs::gmxapi gmxapi-detail)
 
-gmx_register_gtest_test(GmxapiInternalInterfaceTests workflow-details-test INTEGRATION_TEST)
+gmx_register_gtest_test(GmxapiInternalInterfaceTests workflow-details-test OPENMP_THREADS 2 INTEGRATION_TEST)
 
 set_tests_properties(GmxapiInternalInterfaceTests PROPERTIES
                      WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
@@ -67,7 +67,4 @@ gmx_add_gtest_executable(
 
 target_link_libraries(workflow-details-mpi-test Gromacs::gmxapi gmxapi-detail)
 
-# Tests that specify MPI_RANKS will be passed a ``-ntmpi`` command-line option
-# when GMX_THREAD_MPI is true, but the test executables in this directory do not
-# yet understand that command-line option.
-gmx_register_gtest_test(GmxapiInternalsMpiTests workflow-details-mpi-test MPI_RANKS 2 INTEGRATION_TEST)
+gmx_register_gtest_test(GmxapiInternalsMpiTests workflow-details-mpi-test MPI_RANKS 2 OPENMP_THREADS 2 INTEGRATION_TEST)
index 5fdeeb61f10cb78a02c86724c8d1e73f0712188f..2723c0511756b5cb27af8358be7d799c07fd595f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by
+ * Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2016,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.
 /* Define relative path to OpenCL kernels */
 #define GMX_INSTALL_OCLDIR "@GMX_INSTALL_OCLDIR@"
 
+/* Minimum required OpenCL version support (both API and device) - split into integer components for convenience */
+#define REQUIRED_OPENCL_MIN_VERSION_MAJOR @REQUIRED_OPENCL_MIN_VERSION_MAJOR@
+#define REQUIRED_OPENCL_MIN_VERSION_MINOR @REQUIRED_OPENCL_MIN_VERSION_MINOR@
+
 /* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
 #cmakedefine01 HAVE_FSEEKO
 
index 753c5d88484c8d3fe15e184db592688d8d4683d3..7105b498c2ec16ef74aaf77eddcb0ff938ee925d 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2014,2015,2017,2018, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015,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.
@@ -46,7 +46,9 @@
 #include <cassert>
 
 #include "gromacs/hardware/gpu_hw_info.h"
+#include "gromacs/utility/arrayref.h"
 #include "gromacs/utility/smalloc.h"
+#include "gromacs/utility/stringutil.h"
 
 #if !GMX_GPU
 /*! \brief Set allocation functions used by the GPU host
@@ -95,3 +97,33 @@ const char *getGpuCompatibilityDescription(const gmx_gpu_info_t &gpu_info,
             gpu_detect_res_str[egpuNonexistent] :
             gpu_detect_res_str[gpu_info_get_stat(gpu_info, index)]);
 }
+/*! \brief Help build a descriptive message in \c error if there are
+ * \c errorReasons why nonbondeds on a GPU are not supported.
+ *
+ * \returns Whether the lack of errorReasons indicate there is support. */
+static bool
+addMessageIfNotSupported(gmx::ArrayRef <const std::string> errorReasons,
+                         std::string                      *error)
+{
+    bool isSupported = errorReasons.empty();
+    if (!isSupported && error)
+    {
+        *error  = "Nonbonded interactions cannot run on GPUs: ";
+        *error += joinStrings(errorReasons, "; ") + ".";
+    }
+    return isSupported;
+}
+
+bool buildSupportsNonbondedOnGpu(std::string *error)
+{
+    std::vector<std::string> errorReasons;
+    if (GMX_DOUBLE)
+    {
+        errorReasons.emplace_back("double precision");
+    }
+    if (GMX_GPU == GMX_GPU_NONE)
+    {
+        errorReasons.emplace_back("non-GPU build of GROMACS");
+    }
+    return addMessageIfNotSupported(errorReasons, error);
+}
index 307cdcd99d90c02daccc48791ecc43a61e33cb68..9fbde4f09aa287368e70c8abb5ff6be091f6c4eb 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,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.
@@ -75,25 +75,26 @@ static __global__ void k_dummy_test(void)
 {
 }
 
-static void checkCompiledTargetCompatibility(const gmx_device_info_t *devInfo)
+static void checkCompiledTargetCompatibility(int                   deviceId,
+                                             const cudaDeviceProp &deviceProp)
 {
-    assert(devInfo);
-
     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 the selected GPU (device ID #%d, compute capability %d.%d). "
+                  "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. "
                   "Consult the install guide for how to use the GMX_CUDA_TARGET_SM and "
-                  "GMX_CUDA_TARGET_COMPUTE CMake variables to add this architecture.",
-                  gmx::getProgramContext().displayName(), devInfo->id,
-                  devInfo->prop.major, devInfo->prop.minor);
+                  "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(), deviceId,
+                  deviceProp.major, deviceProp.minor, deviceId);
     }
 
     CU_RET_ERR(stat, "cudaFuncGetAttributes failed");
@@ -129,16 +130,14 @@ bool isHostMemoryPinned(const void *h_ptr)
  *
  * Runs a series of checks to determine that the given GPU and underlying CUDA
  * driver/runtime functions properly.
- * Returns properties of a device with given ID or the one that has
- * already been initialized earlier in the case if of \dev_id == -1.
  *
  * \param[in]  dev_id      the device ID of the GPU or -1 if the device has already been initialized
- * \param[out] dev_prop    pointer to the structure in which the device properties will be returned
+ * \param[in]  dev_prop    The device properties structure
  * \returns                0 if the device looks OK
  *
  * TODO: introduce errors codes and handle errors more smoothly.
  */
-static int do_sanity_checks(int dev_id, cudaDeviceProp *dev_prop)
+static int do_sanity_checks(int dev_id, const cudaDeviceProp &dev_prop)
 {
     cudaError_t cu_err;
     int         dev_count, id;
@@ -184,22 +183,13 @@ static int do_sanity_checks(int dev_id, cudaDeviceProp *dev_prop)
         }
     }
 
-    memset(dev_prop, 0, sizeof(cudaDeviceProp));
-    cu_err = cudaGetDeviceProperties(dev_prop, id);
-    if (cu_err != cudaSuccess)
-    {
-        fprintf(stderr, "Error %d while querying device properties: %s\n", cu_err,
-                cudaGetErrorString(cu_err));
-        return -1;
-    }
-
     /* both major & minor is 9999 if no CUDA capable devices are present */
-    if (dev_prop->major == 9999 && dev_prop->minor == 9999)
+    if (dev_prop.major == 9999 && dev_prop.minor == 9999)
     {
         return -1;
     }
     /* we don't care about emulation mode */
-    if (dev_prop->major == 0)
+    if (dev_prop.major == 0)
     {
         return -1;
     }
@@ -216,6 +206,8 @@ static int do_sanity_checks(int dev_id, cudaDeviceProp *dev_prop)
     }
 
     /* try to execute a dummy kernel */
+    checkCompiledTargetCompatibility(dev_id, dev_prop);
+
     KernelLaunchConfig config;
     config.blockSize[0] = 512;
     const auto         dummyArguments = prepareGpuKernelArguments(k_dummy_test, config);
@@ -252,8 +244,6 @@ void init_gpu(const gmx_device_info_t *deviceInfo)
     {
         fprintf(stderr, "Initialized GPU ID #%d: %s\n", deviceInfo->id, deviceInfo->prop.name);
     }
-
-    checkCompiledTargetCompatibility(deviceInfo);
 }
 
 void free_gpu(const gmx_device_info_t *deviceInfo)
@@ -300,40 +290,31 @@ gmx_device_info_t *getDeviceInfo(const gmx_gpu_info_t &gpu_info,
  * \returns             true if the GPU properties passed indicate a compatible
  *                      GPU, otherwise false.
  */
-static bool is_gmx_supported_gpu(const cudaDeviceProp *dev_prop)
+static bool is_gmx_supported_gpu(const cudaDeviceProp &dev_prop)
 {
-    return (dev_prop->major >= 3);
+    return (dev_prop.major >= 3);
 }
 
 /*! \brief Checks if a GPU with a given ID is supported by the native GROMACS acceleration.
  *
  *  Returns a status value which indicates compatibility or one of the following
- *  errors: incompatibility, insistence, or insanity (=unexpected behavior).
- *  It also returns the respective device's properties in \dev_prop (if applicable).
+ *  errors: incompatibility or insanity (=unexpected behavior).
  *
  *  As the error handling only permits returning the state of the GPU, this function
  *  does not clear the CUDA runtime API status allowing the caller to inspect the error
  *  upon return. Note that this also means it is the caller's responsibility to
  *  reset the CUDA runtime state.
  *
- *  \param[in]  dev_id   the ID of the GPU to check.
- *  \param[out] dev_prop the CUDA device properties of the device checked.
- *  \returns             the status of the requested device
+ *  \param[in]  deviceId   the ID of the GPU to check.
+ *  \param[in]  deviceProp the CUDA device properties of the device checked.
+ *  \returns               the status of the requested device
  */
-static int is_gmx_supported_gpu_id(int dev_id, cudaDeviceProp *dev_prop)
+static int is_gmx_supported_gpu_id(int                   deviceId,
+                                   const cudaDeviceProp &deviceProp)
 {
-    cudaError_t stat;
-    int         ndev;
-
-    stat = cudaGetDeviceCount(&ndev);
-    if (stat != cudaSuccess)
+    if (!is_gmx_supported_gpu(deviceProp))
     {
-        return egpuInsane;
-    }
-
-    if (dev_id > ndev - 1)
-    {
-        return egpuNonexistent;
+        return egpuIncompatible;
     }
 
     /* TODO: currently we do not make a distinction between the type of errors
@@ -341,21 +322,12 @@ static int is_gmx_supported_gpu_id(int dev_id, cudaDeviceProp *dev_prop)
      * 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(dev_id, dev_prop) == 0)
-    {
-        if (is_gmx_supported_gpu(dev_prop))
-        {
-            return egpuCompatible;
-        }
-        else
-        {
-            return egpuIncompatible;
-        }
-    }
-    else
+    if (do_sanity_checks(deviceId, deviceProp) != 0)
     {
         return egpuInsane;
     }
+
+    return egpuCompatible;
 }
 
 bool canDetectGpus(std::string *errorMessage)
@@ -432,13 +404,24 @@ void findGpus(gmx_gpu_info_t *gpu_info)
     for (int i = 0; i < ndev; i++)
     {
         cudaDeviceProp prop;
-        int            checkres = is_gmx_supported_gpu_id(i, &prop);
+        memset(&prop, 0, sizeof(cudaDeviceProp));
+        stat = cudaGetDeviceProperties(&prop, i);
+        int checkResult;
+        if (stat != cudaSuccess)
+        {
+            // Will handle the error reporting below
+            checkResult = egpuInsane;
+        }
+        else
+        {
+            checkResult = is_gmx_supported_gpu_id(i, prop);
+        }
 
         devs[i].id   = i;
         devs[i].prop = prop;
-        devs[i].stat = checkres;
+        devs[i].stat = checkResult;
 
-        if (checkres == egpuCompatible)
+        if (checkResult == egpuCompatible)
         {
             gpu_info->n_dev_compatible++;
         }
index 69e8ee410cb2ca205c01049f021f68b00410a10f..6755f1c587929412e3d8ce0f7ab26a4e84184618 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2010, The GROMACS development team.
- * Copyright (c) 2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015,2016,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.
@@ -249,6 +249,13 @@ void gpu_set_host_malloc_and_free(bool               bUseGpuKernels,
 //! Get status of device with specified index
 int gpu_info_get_stat(const gmx_gpu_info_t &info, int index);
 
+/*! \brief Check if GROMACS has been built with GPU support.
+ *
+ * \param[in] error Pointer to error string or nullptr.
+ * \todo Move this to NB module once it exists.
+ */
+bool buildSupportsNonbondedOnGpu(std::string *error);
+
 /*! \brief Starts the GPU profiler if mdrun is being profiled.
  *
  *  When a profiler run is in progress (based on the presence of the NVPROF_ID
index a9fea0d2840cef5c4b59761d34e7d2007c55e087..83536a257113b5abeab70085377ff92ad0b7c0ac 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015,2016,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.
@@ -38,6 +38,8 @@
  *  \author Anca Hamuraru <anca@streamcomputing.eu>
  *  \author Dimitrios Karkoulis <dimitris.karkoulis@gmail.com>
  *  \author Teemu Virolainen <teemu@streamcomputing.eu>
+ *  \author Mark Abraham <mark.j.abraham@gmail.com>
+ *  \author Szilárd Páll <pall.szilard@gmail.com>
  */
 
 #include "gmxpre.h"
@@ -48,6 +50,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+
+#include <cstdio>
 #ifdef __APPLE__
 #    include <sys/sysctl.h>
 #endif
@@ -56,6 +60,7 @@
 
 #include "gromacs/gpu_utils/gpu_utils.h"
 #include "gromacs/gpu_utils/ocl_compiler.h"
+#include "gromacs/gpu_utils/oclraii.h"
 #include "gromacs/gpu_utils/oclutils.h"
 #include "gromacs/hardware/hw_info.h"
 #include "gromacs/utility/cstringutil.h"
@@ -97,20 +102,141 @@ runningOnCompatibleOSForAmd()
 #endif
 }
 
-/*! \brief Returns true if the gpu characterized by the device properties is
- *  supported by the native gpu acceleration.
- * \returns             true if the GPU properties passed indicate a compatible
- *                      GPU, otherwise false.
+namespace gmx
+{
+
+/*! \brief Make an error string following an OpenCL API call.
+ *
+ *  It is meant to be called with \p status != CL_SUCCESS, but it will
+ *  work correctly even if it is called with no OpenCL failure.
+ *
+ * \param[in]  message  Supplies context, e.g. the name of the API call that returned the error.
+ * \param[in]  status   OpenCL API status code
+ * \returns             A string describing the OpenCL error.
+ */
+static std::string
+makeOpenClInternalErrorString(const char *message, cl_int status)
+{
+    if (message != nullptr)
+    {
+        return formatString("%s did %ssucceed %d: %s",
+                            message,
+                            ((status != CL_SUCCESS) ? "not " : ""),
+                            status, ocl_get_error_string(status).c_str());
+    }
+    else
+    {
+        return formatString("%sOpenCL error encountered %d: %s",
+                            ((status != CL_SUCCESS) ? "" : "No "),
+                            status, ocl_get_error_string(status).c_str());
+    }
+}
+
+/*!
+ * \brief Checks that device \c devInfo is sane (ie can run a kernel).
+ *
+ * Compiles and runs a dummy kernel to determine whether the given
+ * OpenCL device functions properly.
+ *
+ *
+ * \param[in]  devInfo         The device info pointer.
+ * \param[out] errorMessage    An error message related to a failing OpenCL API call.
+ * \throws     std::bad_alloc  When out of memory.
+ * \returns                    Whether the device passed sanity checks
+ */
+static bool isDeviceSane(const gmx_device_info_t *devInfo,
+                         std::string             *errorMessage)
+{
+    cl_context_properties properties[] = {
+        CL_CONTEXT_PLATFORM,
+        (cl_context_properties) devInfo->ocl_gpu_id.ocl_platform_id,
+        0
+    };
+    // uncrustify spacing
+
+    cl_int    status;
+    auto      deviceId = devInfo->ocl_gpu_id.ocl_device_id;
+    ClContext context(clCreateContext(properties, 1, &deviceId, nullptr, nullptr, &status));
+    if (status != CL_SUCCESS)
+    {
+        errorMessage->assign(makeOpenClInternalErrorString("clCreateContext", status));
+        return false;
+    }
+    ClCommandQueue commandQueue(clCreateCommandQueue(context, deviceId, 0, &status));
+    if (status != CL_SUCCESS)
+    {
+        errorMessage->assign(makeOpenClInternalErrorString("clCreateCommandQueue", status));
+        return false;
+    }
+
+    const char *lines[] = { "__kernel void dummyKernel(){}" };
+    ClProgram   program(clCreateProgramWithSource(context, 1, lines, nullptr, &status));
+    if (status != CL_SUCCESS)
+    {
+        errorMessage->assign(makeOpenClInternalErrorString("clCreateProgramWithSource", status));
+        return false;
+    }
+
+    if ((status = clBuildProgram(program, 0, nullptr, nullptr, nullptr, nullptr)) != CL_SUCCESS)
+    {
+        errorMessage->assign(makeOpenClInternalErrorString("clBuildProgram", status));
+        return false;
+    }
+
+    ClKernel kernel(clCreateKernel(program, "dummyKernel", &status));
+    if (status != CL_SUCCESS)
+    {
+        errorMessage->assign(makeOpenClInternalErrorString("clCreateKernel", status));
+        return false;
+    }
+
+    const size_t localWorkSize = 1, globalWorkSize = 1;
+    if ((status =
+             clEnqueueNDRangeKernel(commandQueue, kernel, 1, nullptr,
+                                    &globalWorkSize, &localWorkSize, 0, nullptr, nullptr)) != CL_SUCCESS)
+    {
+        errorMessage->assign(makeOpenClInternalErrorString("clEnqueueNDRangeKernel", status));
+        return false;
+    }
+    return true;
+}
+
+/*!
+ * \brief Checks that device \c devInfo is compatible with GROMACS.
+ *
+ *  Vendor and OpenCL version support checks are executed an the result
+ *  of these returned.
+ *
+ * \param[in]  devInfo         The device info pointer.
+ * \returns                    The result of the compatibility checks.
  */
-static int is_gmx_supported_gpu_id(gmx_device_info_t *ocl_gpu_device)
+static int isDeviceSupported(const gmx_device_info_t *devInfo)
 {
-    if ((getenv("GMX_OCL_DISABLE_COMPATIBILITY_CHECK")) != nullptr)
+    if (getenv("GMX_OCL_DISABLE_COMPATIBILITY_CHECK") != nullptr)
     {
+        // Assume the device is compatible because checking has been disabled.
         return egpuCompatible;
     }
 
+    // OpenCL device version check, ensure >= REQUIRED_OPENCL_MIN_VERSION
+    constexpr unsigned int minVersionMajor = REQUIRED_OPENCL_MIN_VERSION_MAJOR;
+    constexpr unsigned int minVersionMinor = REQUIRED_OPENCL_MIN_VERSION_MINOR;
+
+    // Based on the OpenCL spec we're checking the version supported by
+    // the device which has the following format:
+    //      OpenCL<space><major_version.minor_version><space><vendor-specific information>
+    unsigned int deviceVersionMinor, deviceVersionMajor;
+    const int    valuesScanned      = std::sscanf(devInfo->device_version, "OpenCL %u.%u", &deviceVersionMajor, &deviceVersionMinor);
+    const bool   versionLargeEnough = ((valuesScanned == 2) &&
+                                       ((deviceVersionMajor > minVersionMajor) ||
+                                        (deviceVersionMajor == minVersionMajor && deviceVersionMinor >= minVersionMinor)));
+    if (!versionLargeEnough)
+    {
+        return egpuIncompatible;
+    }
+
     /* Only AMD, Intel, and NVIDIA GPUs are supported for now */
-    switch (ocl_gpu_device->vendor_e)
+    switch (devInfo->vendor_e)
     {
         case OCL_VENDOR_NVIDIA:
             return egpuCompatible;
@@ -124,6 +250,41 @@ static int is_gmx_supported_gpu_id(gmx_device_info_t *ocl_gpu_device)
 }
 
 
+
+/*! \brief Check whether the \c ocl_gpu_device is suitable for use by mdrun
+ *
+ * Runs sanity checks: checking that the runtime can compile a dummy kernel
+ * and this can be executed;
+ * Runs compatibility checks verifying the device OpenCL version requirement
+ * and vendor/OS support.
+ *
+ * \param[in]  deviceId      The runtime-reported numeric ID of the device.
+ * \param[in]  deviceInfo    The device info pointer.
+ * \returns  An e_gpu_detect_res_t to indicate how the GPU coped with
+ *           the sanity and compatibility check.
+ */
+static int checkGpu(size_t                   deviceId,
+                    const gmx_device_info_t *deviceInfo)
+{
+
+    int supportStatus = isDeviceSupported(deviceInfo);
+    if (supportStatus != egpuCompatible)
+    {
+        return supportStatus;
+    }
+
+    std::string errorMessage;
+    if (!isDeviceSane(deviceInfo, &errorMessage))
+    {
+        gmx_warning((formatString("While sanity checking device #%zu, ", deviceId) + errorMessage).c_str());
+        return egpuInsane;
+    }
+
+    return egpuCompatible;
+}
+
+} // namespace
+
 /*! \brief Returns an ocl_vendor_id_t value corresponding to the input OpenCL vendor name.
  *
  *  \param[in] vendor_name String with OpenCL vendor name.
@@ -290,7 +451,7 @@ void findGpus(gmx_gpu_info_t *gpu_info)
 
                     clGetDeviceInfo(ocl_device_ids[j], CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(size_t), &gpu_info->gpu_dev[device_index].maxWorkGroupSize, nullptr);
 
-                    gpu_info->gpu_dev[device_index].stat = is_gmx_supported_gpu_id(gpu_info->gpu_dev + device_index);
+                    gpu_info->gpu_dev[device_index].stat = gmx::checkGpu(device_index, gpu_info->gpu_dev + device_index);
 
                     if (egpuCompatible == gpu_info->gpu_dev[device_index].stat)
                     {
diff --git a/src/gromacs/gpu_utils/oclraii.h b/src/gromacs/gpu_utils/oclraii.h
new file mode 100644 (file)
index 0000000..227ba84
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 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.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \libinternal \file
+ * \brief Declare RAII helpers for OpenCL types, along with
+ * supporting type traits.
+ *
+ * \author Mark Abraham <mark.j.abraham@gmail.com>
+ * \inlibraryapi
+ */
+#ifndef GMX_GPU_UTILS_OCLRAII_H
+#define GMX_GPU_UTILS_OCLRAII_H
+
+#include "gromacs/gpu_utils/gmxopencl.h"
+
+namespace gmx
+{
+
+/*! \libinternal \brief Stub for OpenCL type traits */
+template <typename cl_type>
+struct OpenClTraits;
+
+/*! \libinternal \brief Implements common trait infrastructure for OpenCL types. */
+template <typename cl_type>
+struct OpenClTraitsBase
+{
+    //! Type of the function that will release a handle of this type.
+    using ReleaserType = cl_int(*)(cl_type);
+};
+
+/*! \libinternal \brief Implements traits for cl_context. */
+template <>
+struct OpenClTraits<cl_context> : public OpenClTraitsBase<cl_context>
+{
+    //! Function that will release a handle of this type.
+    static constexpr ReleaserType releaser = clReleaseContext;
+};
+
+/*! \libinternal \brief Implements traits for cl_command_queue. */
+template <>
+struct OpenClTraits<cl_command_queue> : public OpenClTraitsBase<cl_command_queue>
+{
+    //! Function that will release a handle of this type.
+    static constexpr ReleaserType releaser = clReleaseCommandQueue;
+};
+
+/*! \libinternal \brief Implements traits for cl_program. */
+template <>
+struct OpenClTraits<cl_program> : public OpenClTraitsBase<cl_program>
+{
+    //! Function that will release a handle of this type.
+    static constexpr ReleaserType releaser = clReleaseProgram;
+};
+
+/*! \libinternal \brief Implements traits for cl_kernel. */
+template <>
+struct OpenClTraits<cl_kernel> : public OpenClTraitsBase<cl_kernel>
+{
+    //! Function that will release a handle of this type.
+    static constexpr ReleaserType releaser = clReleaseKernel;
+};
+
+/*! \libinternal \brief Wrapper of OpenCL type \c cl_type to implement RAII.
+ *
+ * Works by calling the releaser function associated with cl_type
+ * by OpenClTraits.
+ *
+ * Simple copying and assignment are not supported, because there's no
+ * need for that, and would require OpenCL API calls for deep copies
+ * if they were needed. Move and move assignment are fine, however. */
+template <typename cl_type>
+class ClHandle
+{
+    public:
+        //! Constructor that takes an already created handle.
+        explicit ClHandle(cl_type handle) : handle_(handle) {}
+        //! Destructor that calls the releaser associated with cl_type.
+        ~ClHandle() { OpenClTraits<cl_type>::releaser(handle_); }
+        //! Deleted default constructor.
+        ClHandle()                            = delete;
+        //! Deleted assignment operator.
+        ClHandle &operator=(const ClHandle &) = delete;
+        //! Deleted copy constructor.
+        ClHandle(const ClHandle &)            = delete;
+        //! Default move assignment operator.
+        ClHandle &operator=(ClHandle &&)      = default;
+        //! Default copy constructor.
+        ClHandle(ClHandle &&)                 = default;
+        /*! \brief Convenience conversion operator so the wrapper type
+         * can simply convert to the wrapped type. */
+        operator cl_type() const { return handle_; }
+    private:
+        //! The wrapped object.
+        cl_type handle_;
+};
+
+//! Convenience declarations.
+/*! @{ */
+using ClContext      = ClHandle<cl_context>;
+using ClCommandQueue = ClHandle<cl_command_queue>;
+using ClProgram      = ClHandle<cl_program>;
+using ClKernel       = ClHandle<cl_kernel>;
+/*! @} */
+
+} // namespace
+
+#endif
index 85fac9fa337f725876684c61f46b8c78f9630e23..f87fe607c78bb4a3e948d70e9fd10fdcae56a969 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, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016,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.
@@ -445,7 +445,7 @@ static int lcd4(int i1, int i2, int i3, int i4)
     return nst;
 }
 
-int check_nstglobalcomm(const gmx::MDLogger &mdlog, int nstglobalcomm, t_inputrec *ir)
+int check_nstglobalcomm(const gmx::MDLogger &mdlog, int nstglobalcomm, t_inputrec *ir, const t_commrec * cr)
 {
     if (!EI_DYNAMICS(ir->eI))
     {
@@ -528,9 +528,13 @@ int check_nstglobalcomm(const gmx::MDLogger &mdlog, int nstglobalcomm, t_inputre
         ir->nstcomm = nstglobalcomm;
     }
 
-    GMX_LOG(mdlog.info).appendTextFormatted(
-            "Intra-simulation communication will occur every %d steps.\n", nstglobalcomm);
+    if (cr->nnodes > 1)
+    {
+        GMX_LOG(mdlog.info).appendTextFormatted(
+                "Intra-simulation communication will occur every %d steps.\n", nstglobalcomm);
+    }
     return nstglobalcomm;
+
 }
 
 void rerun_parallel_comm(t_commrec *cr, t_trxframe *fr,
index 5e57ce7c19906e6fab79023a62c2d7113c791401..eb6c45d615ceeef5f7d98b885a33a65458b6a4fe 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, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016,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.
@@ -95,7 +95,8 @@ class SimulationSignaller;
  * inputrec and the value of mdrun -gcom. */
 int check_nstglobalcomm(const gmx::MDLogger &mdlog,
                         int                  nstglobalcomm,
-                        t_inputrec          *ir);
+                        t_inputrec          *ir,
+                        const t_commrec    * cr);
 
 /*! \brief Return true if the \p value is equal across the set of multi-simulations
  *
index 80aba49efa53b8d1f1d02cdd4309c62aba835495..2f6c8aedf45f1b367b34a8eb436d3deaff6e89fc 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, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016,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.
@@ -452,6 +452,8 @@ updateMDLeapfrogGeneral(int                         start,
     int  gt       = 0;
     real factorNH = 0;
 
+    real omega_Z  = 2*static_cast<real>(M_PI)/box[ZZ][ZZ];
+
     for (int n = start; n < nrend; n++)
     {
         if (cTC)
@@ -479,7 +481,7 @@ updateMDLeapfrogGeneral(int                         start,
                 rvec_sub(v[n], grpstat[ga].u, vRel);
                 break;
             case AccelerationType::cosine:
-                cosineZ = std::cos(x[n][ZZ]*static_cast<real>(M_PI)/box[ZZ][ZZ]);
+                cosineZ = std::cos(x[n][ZZ]*omega_Z);
                 vCosine = cosineZ*ekind->cosacc.vcos;
                 /* Avoid scaling the cosine profile velocity */
                 copy_rvec(v[n], vRel);
index 050eb74284e51bdc810545131d7d775866fb6db0..7da1d2e46bf8176fb3a516ef755c00629ab87d99 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) 2011,2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by
+ * Copyright (c) 2011,2012,2013,2014,2015,2016,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.
@@ -234,7 +234,7 @@ void gmx::Integrator::do_md()
     const bool bRerunMD      = false;
     int        nstglobalcomm = mdrunOptions.globalCommunicationInterval;
 
-    nstglobalcomm   = check_nstglobalcomm(mdlog, nstglobalcomm, ir);
+    nstglobalcomm   = check_nstglobalcomm(mdlog, nstglobalcomm, ir, cr);
     bGStatEveryStep = (nstglobalcomm == 1);
 
     groups = &top_global->groups;
index 81ae467a68d7c03153a299c4578d95495b51852b..6f2657b02f3f6c2ccab52eec797b154dc164972d 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) 2011,2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by
+ * Copyright (c) 2011,2012,2013,2014,2015,2016,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.
@@ -614,9 +614,10 @@ int Mdrunner::mdrunner()
             // If the user specified the number of ranks, then we must
             // respect that, but in default mode, we need to allow for
             // the number of GPUs to choose the number of ranks.
-
+            auto canUseGpuForNonbonded = buildSupportsNonbondedOnGpu(nullptr);
             useGpuForNonbonded = decideWhetherToUseGpusForNonbondedWithThreadMpi
                     (nonbondedTarget, gpuIdsToUse, userGpuTaskAssignment, emulateGpuNonbonded,
+                    canUseGpuForNonbonded,
                     inputrec->cutoff_scheme == ecutsVERLET,
                     gpuAccelerationOfNonbondedIsUseful(mdlog, inputrec, GMX_THREAD_MPI),
                     hw_opt.nthreads_tmpi);
@@ -682,10 +683,13 @@ int Mdrunner::mdrunner()
         // different nodes, which is the user's responsibilty to
         // handle. If unsuitable, we will notice that during task
         // assignment.
-        bool gpusWereDetected  = hwinfo->ngpu_compatible_tot > 0;
-        bool usingVerletScheme = inputrec->cutoff_scheme == ecutsVERLET;
+        bool gpusWereDetected      = hwinfo->ngpu_compatible_tot > 0;
+        bool usingVerletScheme     = inputrec->cutoff_scheme == ecutsVERLET;
+        auto canUseGpuForNonbonded = buildSupportsNonbondedOnGpu(nullptr);
         useGpuForNonbonded = decideWhetherToUseGpusForNonbonded(nonbondedTarget, userGpuTaskAssignment,
-                                                                emulateGpuNonbonded, usingVerletScheme,
+                                                                emulateGpuNonbonded,
+                                                                canUseGpuForNonbonded,
+                                                                usingVerletScheme,
                                                                 gpuAccelerationOfNonbondedIsUseful(mdlog, inputrec, !GMX_THREAD_MPI),
                                                                 gpusWereDetected);
         auto canUseGpuForPme   = pme_gpu_supports_build(*hwinfo, nullptr) && pme_gpu_supports_input(*inputrec, mtop, nullptr);
index 4488f8d5893dc47df9cbda9e294669a9b52c2ec0..b10f236a1e61247a3d2e771e00780fab42083120 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2015,2016,2017,2018, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,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.
@@ -105,6 +105,7 @@ decideWhetherToUseGpusForNonbondedWithThreadMpi(const TaskTarget          nonbon
                                                 const std::vector<int>   &gpuIdsToUse,
                                                 const std::vector<int>   &userGpuTaskAssignment,
                                                 const EmulateGpuNonbonded emulateGpuNonbonded,
+                                                const bool                buildSupportsNonbondedOnGpu,
                                                 const bool                usingVerletScheme,
                                                 const bool                nonbondedOnGpuIsUseful,
                                                 const int                 numRanksPerSimulation)
@@ -113,7 +114,8 @@ decideWhetherToUseGpusForNonbondedWithThreadMpi(const TaskTarget          nonbon
     if (nonbondedTarget == TaskTarget::Cpu ||
         emulateGpuNonbonded == EmulateGpuNonbonded::Yes ||
         !usingVerletScheme ||
-        !nonbondedOnGpuIsUseful)
+        !nonbondedOnGpuIsUseful ||
+        !buildSupportsNonbondedOnGpu)
     {
         // If the user required NB on GPUs, we issue an error later.
         return false;
@@ -235,6 +237,7 @@ decideWhetherToUseGpusForPmeWithThreadMpi(const bool              useGpuForNonbo
 bool decideWhetherToUseGpusForNonbonded(const TaskTarget           nonbondedTarget,
                                         const std::vector<int>    &userGpuTaskAssignment,
                                         const EmulateGpuNonbonded  emulateGpuNonbonded,
+                                        const bool                 buildSupportsNonbondedOnGpu,
                                         const bool                 usingVerletScheme,
                                         const bool                 nonbondedOnGpuIsUseful,
                                         const bool                 gpusWereDetected)
@@ -251,6 +254,15 @@ bool decideWhetherToUseGpusForNonbonded(const TaskTarget           nonbondedTarg
         return false;
     }
 
+    if (!buildSupportsNonbondedOnGpu && nonbondedTarget == TaskTarget::Gpu)
+    {
+        GMX_THROW(InconsistentInputError
+                      ("Nonbonded interactions on the GPU were requested with -nb gpu, "
+                      "but the GROMACS binary has been built without GPU support. "
+                      "Either run without selecting GPU options, or recompile GROMACS "
+                      "with GPU support enabled"));
+    }
+
     // TODO refactor all these TaskTarget::Gpu checks into one place?
     // e.g. use a subfunction that handles only the cases where
     // TaskTargets are not Cpu?
index 3f67d36f3dd278e09508bcab74f08474e54b900e..ac2fe27478218d17c854e43ad788fb9073f12e98 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.
@@ -68,11 +68,12 @@ enum class TaskTarget : int
  * user. So we need to consider this before any automated choice of
  * the number of thread-MPI ranks.
  *
- * \param[in]  nonbondedTarget           The user's choice for mdrun -nb for where to assign short-ranged nonbonded interaction tasks.
- * \param[in]  gpuIdsToUse               The compatible GPUs that the user permitted us to use.
- * \param[in]  userGpuTaskAssignment     The user-specified assignment of GPU tasks to device IDs.
- * \param[in]  emulateGpuNonbonded       Whether we will emulate GPU calculation of nonbonded interactions.
- * \param[in]  usingVerletScheme         Whether the nonbondeds are using the Verlet scheme.
+ * \param[in]  nonbondedTarget             The user's choice for mdrun -nb for where to assign short-ranged nonbonded interaction tasks.
+ * \param[in]  gpuIdsToUse                 The compatible GPUs that the user permitted us to use.
+ * \param[in]  userGpuTaskAssignment       The user-specified assignment of GPU tasks to device IDs.
+ * \param[in]  emulateGpuNonbonded         Whether we will emulate GPU calculation of nonbonded interactions.
+ * \param[in]  buildSupportsNonbondedOnGpu Whether GROMACS was built with GPU support.
+ * \param[in]  usingVerletScheme           Whether the nonbondeds are using the Verlet scheme.
  * \param[in]  nonbondedOnGpuIsUseful    Whether computing nonbonded interactions on a GPU is useful for this calculation.
  * \param[in]  numRanksPerSimulation     The number of ranks in each simulation.
  *
@@ -80,13 +81,14 @@ enum class TaskTarget : int
  *
  * \throws     std::bad_alloc          If out of memory
  *             InconsistentInputError  If the user requirements are inconsistent. */
-bool decideWhetherToUseGpusForNonbondedWithThreadMpi(TaskTarget                nonbondedTarget,
-                                                     const std::vector<int>   &gpuIdsToUse,
-                                                     const std::vector<int>   &userGpuTaskAssignment,
-                                                     EmulateGpuNonbonded       emulateGpuNonbonded,
-                                                     bool                      usingVerletScheme,
-                                                     bool                      nonbondedOnGpuIsUseful,
-                                                     int                       numRanksPerSimulation);
+bool decideWhetherToUseGpusForNonbondedWithThreadMpi(TaskTarget              nonbondedTarget,
+                                                     const std::vector<int> &gpuIdsToUse,
+                                                     const std::vector<int> &userGpuTaskAssignment,
+                                                     EmulateGpuNonbonded     emulateGpuNonbonded,
+                                                     bool                    buildSupportsNonbondedOnGpu,
+                                                     bool                    usingVerletScheme,
+                                                     bool                    nonbondedOnGpuIsUseful,
+                                                     int                     numRanksPerSimulation);
 
 /*! \brief Decide whether this thread-MPI simulation will run
  * PME tasks on GPUs.
@@ -132,23 +134,25 @@ bool decideWhetherToUseGpusForPmeWithThreadMpi(bool                    useGpuFor
  * decision is made in this routine, along with many more
  * consistency checks.
  *
- * \param[in]  nonbondedTarget           The user's choice for mdrun -nb for where to assign short-ranged nonbonded interaction tasks.
- * \param[in]  userGpuTaskAssignment     The user-specified assignment of GPU tasks to device IDs.
- * \param[in]  emulateGpuNonbonded       Whether we will emulate GPU calculation of nonbonded interactions.
- * \param[in]  usingVerletScheme         Whether the nonbondeds are using the Verlet scheme.
- * \param[in]  nonbondedOnGpuIsUseful    Whether computing nonbonded interactions on a GPU is useful for this calculation.
- * \param[in]  gpusWereDetected          Whether compatible GPUs were detected on any node.
+ * \param[in]  nonbondedTarget             The user's choice for mdrun -nb for where to assign short-ranged nonbonded interaction tasks.
+ * \param[in]  userGpuTaskAssignment       The user-specified assignment of GPU tasks to device IDs.
+ * \param[in]  emulateGpuNonbonded         Whether we will emulate GPU calculation of nonbonded interactions.
+ * \param[in]  buildSupportsNonbondedOnGpu Whether GROMACS was build with GPU support.
+ * \param[in]  usingVerletScheme           Whether the nonbondeds are using the Verlet scheme.
+ * \param[in]  nonbondedOnGpuIsUseful      Whether computing nonbonded interactions on a GPU is useful for this calculation.
+ * \param[in]  gpusWereDetected            Whether compatible GPUs were detected on any node.
  *
  * \returns    Whether the simulation will run nonbonded and PME tasks, respectively, on GPUs.
  *
  * \throws     std::bad_alloc          If out of memory
  *             InconsistentInputError  If the user requirements are inconsistent. */
-bool decideWhetherToUseGpusForNonbonded(TaskTarget                 nonbondedTarget,
-                                        const std::vector<int>    &userGpuTaskAssignment,
-                                        EmulateGpuNonbonded        emulateGpuNonbonded,
-                                        bool                       usingVerletScheme,
-                                        bool                       nonbondedOnGpuIsUseful,
-                                        bool                       gpusWereDetected);
+bool decideWhetherToUseGpusForNonbonded(TaskTarget              nonbondedTarget,
+                                        const std::vector<int> &userGpuTaskAssignment,
+                                        EmulateGpuNonbonded     emulateGpuNonbonded,
+                                        bool                    buildSupportsNonbondedOnGpu,
+                                        bool                    usingVerletScheme,
+                                        bool                    nonbondedOnGpuIsUseful,
+                                        bool                    gpusWereDetected);
 
 /*! \brief Decide whether the simulation will try to run tasks of
  * different types on GPUs.
index 46757699746271b829c049a49ab2027b0cb399f5..6778a9d48463a70ff78d145820fde57e24877d42 100644 (file)
@@ -2,7 +2,7 @@
  * This file is part of the GROMACS molecular simulation package.
  *
  * Copyright (c) 1991-2006 David van der Spoel, Erik Lindahl, Berk Hess, University of Groningen.
- * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016,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.
@@ -48,6 +48,8 @@
 #include <windows.h>
 #endif
 
+#include "gromacs/utility/basedefinitions.h"
+
 /*! \brief Calculate number of seconds per cycle tick on host
  *
  *  This routine runs a timer loop to calibrate the number of
@@ -140,5 +142,6 @@ gmx_cycles_calibrate(double sampletime)
 #else
     /* No timing function available */
     return -1;
+    GMX_UNUSED_VALUE(sampletime);
 #endif
 }