#
# 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.
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.
#
# 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.
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'
#
# 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.
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)")
#
# 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.
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()
#
# 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.
# GROMACS 2016 2
# GROMACS 2018 3
# GROMACS 2019 4
+# GROMACS 2020 5
# LIBRARY_SOVERSION_MINOR so minor version for the built libraries.
# Should be increased for each release that changes only the implementation.
# In GROMACS, the typical policy is to increase it for each patch version
# The GROMACS convention is that these are the version number of the next
# release that is going to be made from this branch.
-set(GMX_VERSION_MAJOR 2019)
-set(GMX_VERSION_PATCH 1)
+set(GMX_VERSION_MAJOR 2020)
+set(GMX_VERSION_PATCH 0)
# The suffix, on the other hand, is used mainly for betas and release
# candidates, where it signifies the most recent such release from
# this branch; it will be empty before the first such release, as well
# here. The important thing is to minimize the chance of third-party
# code being able to dynamically link with a version of libgromacs
# that might not work.
-set(LIBRARY_SOVERSION_MAJOR 4)
+set(LIBRARY_SOVERSION_MAJOR 5)
set(LIBRARY_SOVERSION_MINOR 0)
set(LIBRARY_VERSION ${LIBRARY_SOVERSION_MAJOR}.${LIBRARY_SOVERSION_MINOR}.0)
endif()
set(REGRESSIONTEST_VERSION "${GMX_VERSION_STRING}")
-set(REGRESSIONTEST_BRANCH "refs/heads/release-2019")
+set(REGRESSIONTEST_BRANCH "refs/heads/master")
# Run the regressiontests packaging job with the correct pakage
# version string, and the release box checked, in order to have it
# build the regressiontests tarball with all the right naming. The
# naming affects the md5sum that has to go here, and if it isn't right
# release workflow will report a failure.
-set(REGRESSIONTEST_MD5SUM "1271a74bfe91028b7f184866d5aee98e" CACHE INTERNAL "MD5 sum of the regressiontests tarball for this GROMACS version")
+set(REGRESSIONTEST_MD5SUM "3d06d41e07f523d70ae575b9ad75c670" CACHE INTERNAL "MD5 sum of the regressiontests tarball for this GROMACS version")
math(EXPR GMX_VERSION_NUMERIC
"${GMX_VERSION_MAJOR}*10000 + ${GMX_VERSION_PATCH}")
# 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
#
# 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.
how-to/visualize.rst
install-guide/index.rst
release-notes/index.rst
+ release-notes/highlights.rst
+ release-notes/features.rst
+ release-notes/performance.rst
+ release-notes/tools.rst
+ release-notes/bugs-fixed.rst
+ release-notes/removed-functionality.rst
+ 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
functionality supported, whereas patch releases contain only fixes for
issues identified in the corresponding major releases.
-Two versions of |Gromacs| are under active maintenance, the 2019
-series and the 2018 series. In the latter, only highly conservative
+Two versions of |Gromacs| are under active maintenance, the NEXT
+series and the 2019 series. In the latter, only highly conservative
fixes will be made, and only to address issues that affect scientific
correctness. Naturally, some of those releases will be made after the
-year 2018 ends, but we keep 2018 in the name so users understand how
+year 2019 ends, but we keep 2018 in the name so users understand how
up to date their version is. Such fixes will also be incorporated into
-the 2019 release series, as appropriate. Around the time the 2020
-release is made, the 2018 series will no longer be maintained.
+the NEXT release series, as appropriate. Around the time the NEXT+1
+release is made, the 2019 series will no longer be maintained.
Where issue numbers are reported in these release notes, more details
can be found at https://redmine.gromacs.org at that issue number.
+|Gromacs| NEXT series
+---------------------
+
+.. toctree::
+ :maxdepth: 1
+
+ highlights
+ features
+ performance
+ tools
+ bugs-fixed
+ deprecated-functionality
+ removed-functionality
+ portability
+ miscellaneous
+
+
|Gromacs| 2019 series
---------------------
.. toctree::
:maxdepth: 1
+ 2019/2019.1
+
Major release
^^^^^^^^^^^^^
#
# 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.
# 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})
${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)
#
# 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.
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})
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)
/*
* 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
/*
* 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.
#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
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);
+ }
/*
* 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.
{
}
- 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");
*
* 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;
}
}
- 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;
}
}
/* 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);
{
fprintf(stderr, "Initialized GPU ID #%d: %s\n", deviceInfo->id, deviceInfo->prop.name);
}
-
- checkCompiledTargetCompatibility(deviceInfo);
}
void free_gpu(const gmx_device_info_t *deviceInfo)
* \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
* 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)
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++;
}
*
* 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.
//! 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
/*
* 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.
* \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"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+
+ #include <cstdio>
#ifdef __APPLE__
# include <sys/sysctl.h>
#endif
#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"
#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 int is_gmx_supported_gpu_id(gmx_device_info_t *ocl_gpu_device)
+ static bool isDeviceSane(const gmx_device_info_t *devInfo,
+ std::string *errorMessage)
{
- if ((getenv("GMX_OCL_DISABLE_COMPATIBILITY_CHECK")) != nullptr)
+ 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 isDeviceSupported(const gmx_device_info_t *devInfo)
+ {
+ 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;
}
+
+ /*! \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.
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)
{
--- /dev/null
- * Copyright (c) 2018, by the GROMACS development team, led by
+ /*
+ * 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
*
* 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.
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))
{
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,
*
* 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.
* 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
*
*
* 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.
#include <algorithm>
+#include "gromacs/compat/make_unique.h"
#include "gromacs/domdec/domdec_struct.h"
#include "gromacs/fileio/confio.h"
#include "gromacs/gmxlib/network.h"
real V;
} gmx_sd_sigma_t;
-typedef struct {
+struct gmx_stochd_t
+{
/* BD stuff */
- real *bd_rf;
+ std::vector<real> bd_rf;
/* SD stuff */
- gmx_sd_const_t *sdc;
- gmx_sd_sigma_t *sdsig;
+ std::vector<gmx_sd_const_t> sdc;
+ std::vector<gmx_sd_sigma_t> sdsig;
/* andersen temperature control stuff */
- gmx_bool *randomize_group;
- real *boltzfac;
-} gmx_stochd_t;
+ std::vector<bool> randomize_group;
+ std::vector<real> boltzfac;
+
+ gmx_stochd_t(const t_inputrec *ir);
+};
struct gmx_update_t
{
- gmx_stochd_t *sd;
+ std::unique_ptr<gmx_stochd_t> sd;
/* xprime for constraint algorithms */
- PaddedVector<gmx::RVec> xp;
+ PaddedVector<gmx::RVec> xp;
/* Variables for the deform algorithm */
int64_t deformref_step;
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)
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);
}
} /* do_update_vv_pos */
-static gmx_stochd_t *init_stochd(const t_inputrec *ir)
+gmx_stochd_t::gmx_stochd_t(const t_inputrec *ir)
{
- gmx_stochd_t *sd;
-
- snew(sd, 1);
-
const t_grpopts *opts = &ir->opts;
- int ngtc = opts->ngtc;
+ const int ngtc = opts->ngtc;
if (ir->eI == eiBD)
{
- snew(sd->bd_rf, ngtc);
+ bd_rf.resize(ngtc);
}
else if (EI_SD(ir->eI))
{
- snew(sd->sdc, ngtc);
- snew(sd->sdsig, ngtc);
-
- gmx_sd_const_t *sdc = sd->sdc;
+ sdc.resize(ngtc);
+ sdsig.resize(ngtc);
for (int gt = 0; gt < ngtc; gt++)
{
}
else if (ETC_ANDERSEN(ir->etc))
{
- snew(sd->randomize_group, ngtc);
- snew(sd->boltzfac, ngtc);
+ randomize_group.resize(ngtc);
+ boltzfac.resize(ngtc);
/* for now, assume that all groups, if randomized, are randomized at the same rate, i.e. tau_t is the same. */
/* since constraint groups don't necessarily match up with temperature groups! This is checked in readir.c */
real reft = std::max<real>(0, opts->ref_t[gt]);
if ((opts->tau_t[gt] > 0) && (reft > 0)) /* tau_t or ref_t = 0 means that no randomization is done */
{
- sd->randomize_group[gt] = TRUE;
- sd->boltzfac[gt] = BOLTZ*opts->ref_t[gt];
+ randomize_group[gt] = true;
+ boltzfac[gt] = BOLTZ*opts->ref_t[gt];
}
else
{
- sd->randomize_group[gt] = FALSE;
+ randomize_group[gt] = false;
}
}
}
-
- return sd;
}
void update_temperature_constants(gmx_update_t *upd, const t_inputrec *ir)
{
gmx_update_t *upd = new(gmx_update_t);
- if (ir->eI == eiBD || EI_SD(ir->eI) || ir->etc == etcVRESCALE || ETC_ANDERSEN(ir->etc))
- {
- upd->sd = init_stochd(ir);
- }
+ upd->sd = gmx::compat::make_unique<gmx_stochd_t>(ir);
update_temperature_constants(upd, ir);
* two with only one contribution, and one with both contributions. */
template <SDUpdate updateType>
static void
-doSDUpdateGeneral(gmx_stochd_t *sd,
+doSDUpdateGeneral(const gmx_stochd_t &sd,
int start, int nrend, real dt,
const rvec accel[], const ivec nFreeze[],
const real invmass[], const unsigned short ptype[],
gmx::ThreeFry2x64<0> rng(seed, gmx::RandomDomain::UpdateCoordinates);
gmx::TabulatedNormalDistribution<real, 14> dist;
- gmx_sd_const_t *sdc = sd->sdc;
- gmx_sd_sigma_t *sig = sd->sdsig;
-
for (int n = start; n < nrend; n++)
{
int globalAtomIndex = gatindex ? gatindex[n] : n;
else if (updateType == SDUpdate::FrictionAndNoiseOnly)
{
real vn = v[n][d];
- v[n][d] = (vn*sdc[temperatureGroup].em +
- invsqrtMass*sig[temperatureGroup].V*dist(rng));
+ v[n][d] = (vn*sd.sdc[temperatureGroup].em +
+ invsqrtMass*sd.sdsig[temperatureGroup].V*dist(rng));
// The previous phase already updated the
// positions with a full v*dt term that must
// now be half removed.
else
{
real vn = v[n][d] + (inverseMass*f[n][d] + accel[accelerationGroup][d])*dt;
- v[n][d] = (vn*sdc[temperatureGroup].em +
- invsqrtMass*sig[temperatureGroup].V*dist(rng));
+ v[n][d] = (vn*sd.sdc[temperatureGroup].em +
+ invsqrtMass*sd.sdsig[temperatureGroup].V*dist(rng));
// Here we include half of the friction+noise
// update of v into the position update.
xprime[n][d] = x[n][d] + 0.5*(vn + v[n][d])*dt;
getThreadAtomRange(nth, th, homenr, &start_th, &end_th);
doSDUpdateGeneral<SDUpdate::FrictionAndNoiseOnly>
- (upd->sd,
+ (*upd->sd,
start_th, end_th, dt,
inputrec->opts.acc, inputrec->opts.nFreeze,
md->invmass, md->ptype,
{
// With constraints, the SD update is done in 2 parts
doSDUpdateGeneral<SDUpdate::ForcesOnly>
- (upd->sd,
+ (*upd->sd,
start_th, end_th, dt,
inputrec->opts.acc, inputrec->opts.nFreeze,
md->invmass, md->ptype,
else
{
doSDUpdateGeneral<SDUpdate::Combined>
- (upd->sd,
+ (*upd->sd,
start_th, end_th, dt,
inputrec->opts.acc, inputrec->opts.nFreeze,
md->invmass, md->ptype,
md->cFREEZE, md->cTC,
x_rvec, xp_rvec, v_rvec, f_rvec,
inputrec->bd_fric,
- upd->sd->bd_rf,
+ upd->sd->bd_rf.data(),
step, inputrec->ld_seed, DOMAINDECOMP(cr) ? cr->dd->globalAtomIndices.data() : nullptr);
break;
case (eiVV):
if ((ir->etc == etcANDERSEN) || do_per_step(step, roundToInt(1.0/rate)))
{
andersen_tcoupl(ir, step, cr, md, v, rate,
- upd->sd->randomize_group, upd->sd->boltzfac);
+ upd->sd->randomize_group,
+ upd->sd->boltzfac);
return TRUE;
}
return FALSE;
*
* 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.
real saved_conserved_quantity = 0;
real last_ekin = 0;
t_extmass MassQ;
- int **trotter_seq;
char sbuf[STEPSTRSIZE], sbuf2[STEPSTRSIZE];
/* PME load balancing data for GPU kernels */
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;
/* need to make an initiation call to get the Trotter variables set, as well as other constants for non-trotter
temperature control */
- trotter_seq = init_npt_vars(ir, state, &MassQ, bTrotter);
+ auto trotter_seq = init_npt_vars(ir, state, &MassQ, bTrotter);
if (MASTER(cr))
{
walltime_accounting_set_nsteps_done(walltime_accounting, step_rel);
destroy_enerdata(enerd);
+
sfree(enerd);
+
+ global_stat_destroy(gstat);
+
+ /* Clean up topology. top->atomtypes has an allocated pointer if no domain decomposition*/
+ if (!DOMAINDECOMP(cr))
+ {
+ done_atomtypes(&top->atomtypes);
+ }
sfree(top);
}
*
* 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.
// 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);
// 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);
pmedata,
EI_DYNAMICS(inputrec->eI) && !isMultiSim(ms));
+ // clean up cycle counter
+ wallcycle_destroy(wcycle);
+
// Free PME data
if (pmedata)
{
wait for that. */
if (PAR(cr) && MASTER(cr))
{
- done_commrec(cr);
tMPI_Finalize();
}
+ //TODO free commrec in MPI simulations
+ done_commrec(cr);
#endif
-
return rc;
}
/*
* 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.
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)
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;
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)
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?
/*
* 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.
* 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.
*
*
* \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.
* 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.
* 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, 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.
#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
#else
/* No timing function available */
return -1;
+ GMX_UNUSED_VALUE(sampletime);
#endif
}