message(FATAL_ERROR "HWLOC package support required, but not found.")
endif()
+ if (HWLOC_VERSION VERSION_LESS "2")
+ message(STATUS "Support for hwloc versions 1.x is deprecated")
+ endif()
+
set(HWLOC_FIND_QUIETLY_AFTER_FIRST_RUN TRUE CACHE INTERNAL "Be quiet during future attempts to find HWLOC")
endif()
if(${_gmx_gpu_uppercase} STREQUAL "CUDA")
include(gmxManageCuda)
elseif(${_gmx_gpu_uppercase} STREQUAL "OPENCL")
+ message(STATUS "GPU support with OpenCL is deprecated. It is still fully supported (and "
+ "recommended for AMD and Intel GPUs). It may be replaced by different approaches in "
+ "future releases of GROMACS.")
include(gmxManageOpenCL)
elseif(${_gmx_gpu_uppercase} STREQUAL "SYCL")
include(gmxManageSYCL)
# images needed, because the same one can test library,
# thread and no MPI configurations.
+args[${#args[@]}]="--gcc 10 --clfft --mpi openmpi --ubuntu 20.04"
+args[${#args[@]}]="--gcc 9 --clfft --mpi openmpi"
args[${#args[@]}]="--gcc 8 --cuda 11.0 --clfft --mpi openmpi"
-args[${#args[@]}]="--gcc 7 --clfft --mpi openmpi --ubuntu 18.04"
+args[${#args[@]}]="--gcc 7 --cuda 10.2 --clfft --mpi openmpi --ubuntu 18.04"
args[${#args[@]}]="--llvm 8 --tsan"
args[${#args[@]}]="--llvm 8 --cuda 10.0 --clfft --mpi openmpi"
args[${#args[@]}]="--llvm 8 --cuda 10.1 --clfft --mpi openmpi"
args[${#args[@]}]="--llvm 8 --cuda 11.0 --clfft --mpi openmpi"
args[${#args[@]}]="--llvm 9 --clfft --mpi openmpi --ubuntu 18.04"
-args[${#args[@]}]="--oneapi 2021.1-beta09"
+args[${#args[@]}]="--oneapi 2021.1.1"
args[${#args[@]}]="--llvm --doxygen"
echo "Building the following images."
apt_keys=['https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS-2023.PUB'],
apt_repositories=['deb https://apt.repos.intel.com/oneapi all main'],
# Add minimal packages (not the whole HPC toolkit!)
- ospackages=['intel-oneapi-dpcpp-cpp-compiler-pro-{}'.format(version),
+ ospackages=['intel-oneapi-dpcpp-cpp-{}'.format(version),
'intel-oneapi-openmp-{}'.format(version),
'intel-oneapi-mkl-{}'.format(version),
'intel-oneapi-mkl-devel-{}'.format(version)]
# oneAPI makes an official release. Also, the resulting container is a mix
# of packages with different betaXY version numbers, which hopefully works and
# is what Intel intends...
-compiler_group.add_argument('--oneapi', type=str, nargs='?', const="2021.1-beta09", default=None,
+compiler_group.add_argument('--oneapi', type=str, nargs='?', const="2021.1.1", default=None,
help='Select Intel oneAPI package version.')
linux_group = parser.add_mutually_exclusive_group()
- mkdir -p ccache
- export CCACHE_BASEDIR=${PWD}
- export CCACHE_DIR=${PWD}/ccache
+
+# Base definition for using the classic Intel compiler
+.use-icc-oneapi:base:
+ variables:
+ CMAKE_COMPILER_SCRIPT: -DCMAKE_C_COMPILER=icc -DCMAKE_CXX_COMPILER=icpc #-DCMAKE_PREFIX_PATH=/opt/intel/oneapi/compiler/latest/linux
+ CMAKE_EXTRA_OPTIONS: -DGMX_FFT_LIBRARY=mkl
+ before_script:
+ # Necessary to override gitlab default 'set -e' which breaks Intel's
+ # setvar.sh script
+ - set +e
+ - source /opt/intel/oneapi/setvars.sh
+ - set -e
+ - mkdir -p ccache
+# - export CCACHE_BASEDIR=${PWD}
+# - export CCACHE_DIR=${PWD}/ccache
# Templates for configuration stage
-gromacs:gcc-7:configure:
+gromacs:gcc-10:configure:
extends:
- .gromacs:base:configure
- .use-gcc:base
- .use-opencl
- .rules:merge-and-post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-20.04-gcc-10
variables:
CMAKE: /usr/local/cmake-3.13.0/bin/cmake
CMAKE_SIMD_OPTIONS: "-DGMX_SIMD=AVX2_256"
CMAKE_EXTRA_OPTIONS: "-DGMX_EXTERNAL_CLFFT=ON -DGMX_INSTALL_LEGACY_API=ON"
- COMPILER_MAJOR_VERSION: 7
+ COMPILER_MAJOR_VERSION: 10
gromacs:clang-8-cuda-10.0:configure:
extends:
CMAKE_BUILD_TYPE_OPTIONS: "-DCMAKE_BUILD_TYPE=RelWithDebInfo"
COMPILER_MAJOR_VERSION: 8
-gromacs:gcc-8-cuda-11.0:configure:
+gromacs:gcc-7-cuda-10.2:configure:
extends:
- .gromacs:base:configure
- .use-gcc:base
- .use-cuda
- .rules:merge-and-post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-8-cuda-11.0
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-cuda-10.2
variables:
CMAKE: /usr/local/cmake-3.15.7/bin/cmake
CMAKE_SIMD_OPTIONS: "-DGMX_SIMD=SSE4.1"
- COMPILER_MAJOR_VERSION: 8
+ COMPILER_MAJOR_VERSION: 7
gromacs:gcc-8-cuda-11.0:configureMPI:
extends:
COMPILER_MAJOR_VERSION: 8
CMAKE_BUILD_TYPE_OPTIONS: "-DCMAKE_BUILD_TYPE=TSAN"
+gromacs:icc-2021.1:configure:
+ extends:
+ - .gromacs:base:configure
+ - .use-icc-oneapi:base
+ - .rules:merge-and-post-merge-acceptance
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1.1
+ variables:
+ CMAKE: /usr/local/cmake-3.17.2/bin/cmake
+ COMPILER_MAJOR_VERSION: 2021
+
gromacs:clang-8:configure:
extends:
- .gromacs:base:configure
COMPILER_MAJOR_VERSION: 8
CMAKE_BUILD_TYPE_OPTIONS: "-DCMAKE_BUILD_TYPE=ASAN"
-gromacs:oneapi-2021.1-beta09-opencl:configure:
+gromacs:oneapi-2021.1.1-opencl:configure:
extends:
- .gromacs:base:configure
- .use-oneapi:base
- .use-opencl
- .rules:merge-requests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1-beta09
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1.1
variables:
CMAKE: /usr/local/cmake-3.17.2/bin/cmake
COMPILER_MAJOR_VERSION: 2021
-gromacs:oneapi-2021.1-beta09-sycl:configure:
+gromacs:oneapi-2021.1.1-sycl:configure:
extends:
- .gromacs:base:configure
- .use-oneapi:base
- .use-sycl
- .rules:merge-and-post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1-beta09
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1.1
variables:
CMAKE: /usr/local/cmake-3.17.2/bin/cmake
COMPILER_MAJOR_VERSION: 2021
- regressiontests:package
- prepare-release-version
-gromacs:gcc-7:release:configure:
+gromacs:gcc-9:release:configure:
extends:
- .gromacs:base:release:configure
- .use-gcc:base
- .use-opencl
- .rules:nightly-only-for-release
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-9
variables:
CMAKE: /usr/local/cmake-3.13.0/bin/cmake
- COMPILER_MAJOR_VERSION: 7
- CMAKE_EXTRA_OPTIONS: "-DGMX_EXTERNAL_CLFFT=ON"
+ COMPILER_MAJOR_VERSION: 9
RELEASE_BUILD_DIR: release-builds-gcc
CMAKE_BUILD_TYPE_OPTIONS: "-DCMAKE_BUILD_TYPE=RelWithAssert"
dependencies:
RELEASE_BUILD_DIR: release-builds-clang
CMAKE_BUILD_TYPE_OPTIONS: "-DCMAKE_BUILD_TYPE=RelWithAssert"
-gromacs:oneapi-2021.1-beta09-opencl:release:configure:
+gromacs:oneapi-2021.1.1-opencl:release:configure:
extends:
- .gromacs:base:release:configure
- .use-oneapi:base
- .use-opencl
- .rules:nightly-only-for-release
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1-beta09
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1.1
variables:
CMAKE: /usr/local/cmake-3.17.2/bin/cmake
COMPILER_MAJOR_VERSION: 2021
paths:
- $BUILD_DIR/scan_html
-gromacs:gcc-7:build:
+gromacs:gcc-10:build:
extends:
- .variables:default
- .gromacs:base:build
- .before_script:default
- .use-ccache
- .rules:merge-and-post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-20.04-gcc-10
variables:
CMAKE: /usr/local/cmake-3.13.0/bin/cmake
needs:
- - job: gromacs:gcc-7:configure
+ - job: gromacs:gcc-10:configure
gromacs:clang-8-cuda-10.0:build:
extends:
needs:
- job: gromacs:clang-8-cuda-10.0:configure
-gromacs:gcc-8-cuda-11.0:build:
+gromacs:gcc-7-cuda-10.2:build:
extends:
- .variables:default
- .gromacs:base:build
- .before_script:default
- .use-ccache
- .rules:merge-and-post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-8-cuda-11.0
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-cuda-10.2
variables:
CMAKE: /usr/local/cmake-3.15.7/bin/cmake
needs:
- - job: gromacs:gcc-8-cuda-11.0:configure
+ - job: gromacs:gcc-7-cuda-10.2:configure
gromacs:gcc-8-cuda-11.0:buildMPI:
extends:
needs:
- job: gromacs:clang-TSAN:configure
+gromacs:icc-2021.1:build:
+ extends:
+ - .variables:default
+ - .gromacs:base:build
+ - .use-icc-oneapi:base
+ - .rules:post-merge-acceptance
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1.1
+ variables:
+ CMAKE: /usr/local/cmake-3.17.2/bin/cmake
+ needs:
+ - job: gromacs:icc-2021.1:configure
+
gromacs:clang-ASAN:build:
extends:
- .variables:default
needs:
- job: gromacs:clang-8:configure
-gromacs:oneapi-2021.1-beta09-opencl:build:
+gromacs:oneapi-2021.1.1-opencl:build:
extends:
- .variables:default
- .gromacs:base:build
- .use-ccache
- .use-oneapi:base
- .rules:merge-requests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1-beta09
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1.1
variables:
CMAKE: /usr/local/cmake-3.17.2/bin/cmake
needs:
- - job: gromacs:oneapi-2021.1-beta09-opencl:configure
+ - job: gromacs:oneapi-2021.1.1-opencl:configure
-gromacs:oneapi-2021.1-beta09-sycl:build:
+gromacs:oneapi-2021.1.1-sycl:build:
extends:
- .variables:default
- .gromacs:base:build
- .use-ccache
- .use-oneapi:base
- .rules:merge-and-post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1-beta09
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1.1
variables:
CMAKE: /usr/local/cmake-3.17.2/bin/cmake
needs:
- - job: gromacs:oneapi-2021.1-beta09-sycl:configure
+ - job: gromacs:oneapi-2021.1.1-sycl:configure
gromacs:clang-9-mpi:build:
extends:
needs:
- job: gromacs:gcc-8-cuda-11.0:release:configure
-gromacs:gcc-7:release:build:
+gromacs:gcc-9:release:build:
extends:
- .variables:default
- .gromacs:base:build
variables:
CMAKE: /usr/local/cmake-3.13.0/bin/cmake
BUILD_DIR: release-builds-gcc
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-9
needs:
- - job: gromacs:gcc-7:release:configure
+ - job: gromacs:gcc-9:release:configure
gromacs:clang-9:release:build:
extends:
needs:
- job: gromacs:clang-8-cuda-10.1:release:configure
-gromacs:oneapi-2021.1-beta09-opencl:release:build:
+gromacs:oneapi-2021.1.1-opencl:release:build:
extends:
- .variables:default
- .gromacs:base:build
CMAKE: /usr/local/cmake-3.17.2/bin/cmake
BUILD_DIR: release-builds-oneapi
COMPILER_MAJOR_VERSION: 2021
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1-beta09
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1.1
needs:
- - job: gromacs:oneapi-2021.1-beta09-opencl:release:configure
+ - job: gromacs:oneapi-2021.1.1-opencl:release:configure
# Jobs running during test stage
when: always
expire_in: 1 week
-gromacs:gcc-7:test:
+gromacs:gcc-10:test:
extends:
- .gromacs:base:test
- .rules:merge-requests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-20.04-gcc-10
variables:
CMAKE: /usr/local/cmake-3.13.0/bin/cmake
KUBERNETES_EXTENDED_RESOURCE_NAME: "amd.com/gpu"
tags:
- k8s-scilifelab
needs:
- - job: gromacs:gcc-7:build
+ - job: gromacs:gcc-10:build
gromacs:clang-8-cuda-10.0:test:
extends:
needs:
- job: gromacs:clang-8-cuda-10.0:build
-gromacs:gcc-8-cuda-11.0:test:
+gromacs:gcc-7-cuda-10.2:test:
extends:
- .gromacs:base:test
- .rules:merge-requests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-8-cuda-11.0
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-cuda-10.2
variables:
CMAKE: /usr/local/cmake-3.15.7/bin/cmake
KUBERNETES_EXTENDED_RESOURCE_NAME: "nvidia.com/gpu"
tags:
- k8s-scilifelab
needs:
- - job: gromacs:gcc-8-cuda-11.0:build
+ - job: gromacs:gcc-7-cuda-10.2:build
-gromacs:gcc-8-cuda-11.0:test-gpucommupd:
+gromacs:gcc-8-cuda-10.2:test-gpucommupd:
extends:
- .gromacs:base:test
- .rules:post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-8-cuda-11.0
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-cuda-10.2
variables:
CMAKE: /usr/local/cmake-3.15.7/bin/cmake
KUBERNETES_EXTENDED_RESOURCE_NAME: "nvidia.com/gpu"
tags:
- k8s-scilifelab
needs:
- - job: gromacs:gcc-8-cuda-11.0:build
+ - job: gromacs:gcc-7-cuda-10.2:build
gromacs:clang-8:test:
extends:
needs:
- job: gromacs:clang-TSAN:build
+gromacs:icc-2021.1:test:
+ extends:
+ - .gromacs:base:test
+ - .use-icc-oneapi:base
+ - .rules:post-merge-acceptance
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1.1
+ variables:
+ CMAKE: /usr/local/cmake-3.17.2/bin/cmake
+ needs:
+ - job: gromacs:icc-2021.1:build
+
gromacs:clang-ASAN:test:
extends:
- .gromacs:base:test
needs:
- job: gromacs:clang-UBSAN:build
-gromacs:oneapi-2021.1-beta09-opencl:test:
+gromacs:oneapi-2021.1.1-opencl:test:
extends:
- .gromacs:base:test
- .use-oneapi:base
- .rules:merge-requests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1-beta09
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1.1
variables:
CMAKE: /usr/local/cmake-3.17.2/bin/cmake
needs:
- - job: gromacs:oneapi-2021.1-beta09-opencl:build
+ - job: gromacs:oneapi-2021.1.1-opencl:build
-gromacs:oneapi-2021.1-beta09-sycl:test:
+gromacs:oneapi-2021.1.1-sycl:test:
extends:
- .gromacs:base:test
- .use-oneapi:base
- .rules:post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1-beta09
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1.1
variables:
CMAKE: /usr/local/cmake-3.17.2/bin/cmake
needs:
- - job: gromacs:oneapi-2021.1-beta09-sycl:build
+ - job: gromacs:oneapi-2021.1.1-sycl:build
gromacs:clang-9-mpi:test:
extends:
needs:
- job: gromacs:clang-9-mpi:build
-gromacs:gcc-7:regressiontest:
+gromacs:gcc-10:regressiontest:
extends:
- .gromacs:base:regressiontest
- .rules:post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-20.04-gcc-10
variables:
CMAKE: /usr/local/cmake-3.13.0/bin/cmake
KUBERNETES_EXTENDED_RESOURCE_NAME: "amd.com/gpu"
tags:
- k8s-scilifelab
needs:
- - job: gromacs:gcc-7:build
+ - job: gromacs:gcc-10:build
- job: regressiontests:prepare
gromacs:clang-8-cuda-10.0:regressiontest:
- job: regressiontests:prepare
-gromacs:gcc-8-cuda-11.0:regressiontest:
+gromacs:gcc-7-cuda-10.2:regressiontest:
extends:
- .gromacs:base:regressiontest
- .rules:merge-requests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-8-cuda-11.0
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-cuda-10.2
variables:
CMAKE: /usr/local/cmake-3.15.7/bin/cmake
KUBERNETES_EXTENDED_RESOURCE_NAME: "nvidia.com/gpu"
tags:
- k8s-scilifelab
needs:
- - job: gromacs:gcc-8-cuda-11.0:build
+ - job: gromacs:gcc-7-cuda-10.2:build
- job: regressiontests:prepare
-gromacs:gcc-8-cuda-11.0:regressiontest-gpucommupd-tMPI:
+gromacs:gcc-7-cuda-10.2:regressiontest-gpucommupd-tMPI:
extends:
- .gromacs:base:regressiontest
- .rules:post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-8-cuda-11.0
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-cuda-10.2
variables:
CMAKE: /usr/local/cmake-3.15.7/bin/cmake
KUBERNETES_EXTENDED_RESOURCE_NAME: "nvidia.com/gpu"
tags:
- k8s-scilifelab
needs:
- - job: gromacs:gcc-8-cuda-11.0:build
+ - job: gromacs:gcc-7-cuda-10.2:build
- job: regressiontests:prepare
artifacts:
paths:
when: always
expire_in: 1 week
-gromacs:gcc-8-cuda-11.0:regressiontest-upd-tMPI:
+gromacs:gcc-7-cuda-10.2:regressiontest-upd-tMPI:
extends:
- .gromacs:base:regressiontest
- .rules:post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-8-cuda-11.0
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-cuda-10.2
variables:
KUBERNETES_EXTENDED_RESOURCE_NAME: "nvidia.com/gpu"
KUBERNETES_EXTENDED_RESOURCE_LIMIT: 2
tags:
- k8s-scilifelab
needs:
- - job: gromacs:gcc-8-cuda-11.0:build
+ - job: gromacs:gcc-7-cuda-10.2:build
- job: regressiontests:prepare
artifacts:
paths:
- job: gromacs:clang-TSAN:build
- job: regressiontests:prepare
+gromacs:icc-2021.1:regressiontest:
+ extends:
+ - .gromacs:base:regressiontest
+ - .use-icc-oneapi:base
+ - .rules:post-merge-acceptance
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1.1
+ variables:
+ CMAKE: /usr/local/cmake-3.17.2/bin/cmake
+ needs:
+ - job: gromacs:icc-2021.1:build
+ - job: regressiontests:prepare
+
gromacs:clang-ASAN:regressiontest:
extends:
- .gromacs:base:regressiontest
- job: gromacs:clang-9-mpi:build
- job: regressiontests:prepare
-gromacs:oneapi-2021.1-beta09-opencl:regressiontest:
+gromacs:oneapi-2021.1.1-opencl:regressiontest:
extends:
- .gromacs:base:regressiontest
- .use-oneapi:base
- .rules:merge-requests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1-beta09
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1.1
variables:
CMAKE: /usr/local/cmake-3.17.2/bin/cmake
needs:
- - job: gromacs:oneapi-2021.1-beta09-opencl:build
+ - job: gromacs:oneapi-2021.1.1-opencl:build
- job: regressiontests:prepare
-gromacs:oneapi-2021.1-beta09-sycl:regressiontest:
+gromacs:oneapi-2021.1.1-sycl:regressiontest:
extends:
- .gromacs:base:regressiontest
- .use-oneapi:base
- .rules:post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1-beta09
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1.1
variables:
CMAKE: /usr/local/cmake-3.17.2/bin/cmake
needs:
- - job: gromacs:oneapi-2021.1-beta09-sycl:build
+ - job: gromacs:oneapi-2021.1.1-sycl:build
- job: regressiontests:prepare
gromacs:gcc-8-cuda-11.0:release:test:
- job: gromacs:gcc-8-cuda-11.0:release:configure
- job: gromacs:gcc-8-cuda-11.0:release:build
-gromacs:gcc-7:release:test:
+gromacs:gcc-9:release:test:
extends:
- .gromacs:base:test
- .rules:nightly-only-for-release
stage: release-tests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-9
variables:
CMAKE: /usr/local/cmake-3.13.0/bin/cmake
BUILD_DIR: release-builds-gcc
tags:
- k8s-scilifelab
needs:
- - job: gromacs:gcc-7:release:configure
- - job: gromacs:gcc-7:release:build
+ - job: gromacs:gcc-9:release:configure
+ - job: gromacs:gcc-9:release:build
gromacs:clang-9:release:test:
extends:
- job: gromacs:clang-8-cuda-10.1:release:configure
- job: gromacs:clang-8-cuda-10.1:release:build
-gromacs:oneapi-2021.1-beta09-opencl:release:test:
+gromacs:oneapi-2021.1.1-opencl:release:test:
extends:
- .gromacs:base:test
- .use-oneapi:base
- .rules:nightly-only-for-release
stage: release-tests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1-beta09
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1.1
variables:
CMAKE: /usr/local/cmake-3.17.2/bin/cmake
BUILD_DIR: release-builds-oneapi
needs:
- - job: gromacs:oneapi-2021.1-beta09-opencl:release:configure
- - job: gromacs:oneapi-2021.1-beta09-opencl:release:build
+ - job: gromacs:oneapi-2021.1.1-opencl:release:configure
+ - job: gromacs:oneapi-2021.1.1-opencl:release:build
-gromacs:gcc-7:release:regressiontest:
+gromacs:gcc-9:release:regressiontest:
extends:
- .gromacs:base:regressiontest
- .rules:nightly-only-for-release
stage: release-tests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-9
variables:
CMAKE: /usr/local/cmake-3.13.0/bin/cmake
BUILD_DIR: release-builds-gcc
tags:
- k8s-scilifelab
needs:
- - job: gromacs:gcc-7:release:build
+ - job: gromacs:gcc-9:release:build
- job: regressiontests:package
gromacs:clang-9:release:regressiontest:
- job: gromacs:clang-8-cuda-10.1:release:build
- job: regressiontests:package
-gromacs:oneapi-2021.1-beta09-opencl:release:regressiontest:
+gromacs:oneapi-2021.1.1-opencl:release:regressiontest:
extends:
- .gromacs:base:regressiontest
- .use-oneapi:base
- .rules:nightly-only-for-release
stage: release-tests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1-beta09
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1.1
variables:
CMAKE: /usr/local/cmake-3.17.2/bin/cmake
BUILD_DIR: release-builds-oneapi
REGRESSIONTEST_TOTAL_RANK_NUMBER: 2
REGRESSIONTEST_OMP_RANK_NUMBER: 1
needs:
- - job: gromacs:oneapi-2021.1-beta09-opencl:release:build
+ - job: gromacs:oneapi-2021.1.1-opencl:release:build
- job: regressiontests:package
# Jobs to test gmxapi client (Python) packages
#
-.gmxapi-0.2:gcc-7:gmx2021:
+.gmxapi-0.2:gcc-10:gmx2021:
extends:
- .variables:default
- .use-clang:base
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-20.04-gcc-10
stage: test
variables:
KUBERNETES_CPU_LIMIT: 2
- k8s-scilifelab
# The dependency means we need to use the same tag restriction as upstream.
needs:
- - job: gromacs:gcc-7:build
+ - job: gromacs:gcc-10:build
artifacts: true
-gmxapi-0.2:gcc-7:gmx2021:py-3.6.10:
+gmxapi-0.2:gcc-10:gmx2021:py-3.6.10:
extends:
- - .gmxapi-0.2:gcc-7:gmx2021
+ - .gmxapi-0.2:gcc-10:gmx2021
- .rules:merge-requests:release-2021
variables:
VENVPATH: "/root/venv/py3.6"
PY_VER: "3.6.10"
-gmxapi-0.2:gcc-7:gmx2021:py-3.7.7:
+gmxapi-0.2:gcc-10:gmx2021:py-3.7.7:
extends:
- - .gmxapi-0.2:gcc-7:gmx2021
+ - .gmxapi-0.2:gcc-10:gmx2021
- .rules:merge-requests:release-2021
variables:
VENVPATH: "/root/venv/py3.7"
PY_VER: "3.7.7"
-gmxapi-0.2:gcc-7:gmx2021:py-3.8.2:
+gmxapi-0.2:gcc-10:gmx2021:py-3.8.2:
extends:
- - .gmxapi-0.2:gcc-7:gmx2021
+ - .gmxapi-0.2:gcc-10:gmx2021
- .rules:merge-requests:release-2021
variables:
VENVPATH: "/root/venv/py3.8"
# Jobs to test gmxapi client (Python) packages
#
-.gmxapi-0.3:gcc-7:gmx2022:
+.gmxapi-0.3:gcc-10:gmx2022:
extends:
- .variables:default
- .use-clang:base
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-20.04-gcc-10
stage: test
variables:
KUBERNETES_CPU_LIMIT: 2
- k8s-scilifelab
# The dependency means we need to use the same tag restriction as upstream.
needs:
- - job: gromacs:gcc-7:build
+ - job: gromacs:gcc-10:build
artifacts: true
-gmxapi-0.3:gcc-7:gmx2022:py-3.7.7:
+gmxapi-0.3:gcc-10:gmx2022:py-3.7.7:
extends:
- - .gmxapi-0.3:gcc-7:gmx2022
+ - .gmxapi-0.3:gcc-10:gmx2022
- .rules:merge-requests:master
variables:
VENVPATH: "/root/venv/py3.7"
PY_VER: "3.7.7"
-gmxapi-0.3:gcc-7:gmx2022:py-3.8.2:
+gmxapi-0.3:gcc-10:gmx2022:py-3.8.2:
extends:
- - .gmxapi-0.3:gcc-7:gmx2022
+ - .gmxapi-0.3:gcc-10:gmx2022
- .rules:merge-requests:master
variables:
VENVPATH: "/root/venv/py3.8"
# Base job definition for sample_restraint tests against GROMACS 2021.
-.sample_restraint:gcc-7:gmx2021:
+.sample_restraint:gcc-10:gmx2021:
extends:
- .variables:default
- .use-clang:base
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-20.04-gcc-10
stage: test
variables:
KUBERNETES_CPU_LIMIT: 2
- k8s-scilifelab
# The dependency means we need to use the same tag restriction as upstream.
needs:
- - job: gromacs:gcc-7:build
+ - job: gromacs:gcc-10:build
artifacts: true
-sample_restraint:gcc-7:gmx2021:py-3.6.10:
+sample_restraint:gcc-10:gmx2021:py-3.6.10:
extends:
- - .sample_restraint:gcc-7:gmx2021
- - .rules:merge-requests:master
+ - .sample_restraint:gcc-10:gmx2021
+ - .rules:merge-requests:release-2021
variables:
VENVPATH: "/root/venv/py3.6"
PY_VER: "3.6.10"
-sample_restraint:gcc-7:gmx2021:py-3.7.7:
+sample_restraint:gcc-10:gmx2021:py-3.7.7:
extends:
- - .sample_restraint:gcc-7:gmx2021
- - .rules:merge-requests:master
+ - .sample_restraint:gcc-10:gmx2021
+ - .rules:merge-requests:release-2021
variables:
VENVPATH: "/root/venv/py3.7"
PY_VER: "3.7.7"
-sample_restraint:gcc-7:gmx2021:py-3.8.2:
+sample_restraint:gcc-10:gmx2021:py-3.8.2:
extends:
- - .sample_restraint:gcc-7:gmx2021
- - .rules:merge-requests:master
+ - .sample_restraint:gcc-10:gmx2021
+ - .rules:merge-requests:release-2021
variables:
VENVPATH: "/root/venv/py3.8"
PY_VER: "3.8.2"
endif()
# Activate targets NBLIB
-if(GMX_NATIVE_WINDOWS OR GMX_BUILD_MDRUN_ONLY)
+if(GMX_NATIVE_WINDOWS OR GMX_BUILD_MDRUN_ONLY OR NOT BUILD_SHARED_LIBS OR CMAKE_CXX_COMPILER_ID MATCHES "Intel")
# NBLIB has not been tested in Microsoft environments.
# NBLIB relies on libgromacs and is incompatible with an `mdrun`-only build.
# NBLIB requires position-independent code
+ # NBLIB causes an ICE in icc 19.1.2.20200623
set(_NBLIB_DEFAULT OFF)
else()
set(_NBLIB_DEFAULT ON)
}
gmxForceCalculator_->interactionConst_->coulombEwaldTables =
std::make_unique<EwaldCorrectionTables>();
- init_interaction_const_tables(nullptr, gmxForceCalculator_->interactionConst_.get(), 0);
+ init_interaction_const_tables(nullptr, gmxForceCalculator_->interactionConst_.get(), 0, 0);
}
}
# 444: destructor for base class ".." is not virtual
# 869: was never referenced (false positives)
#2282: unrecognized GCC pragma
- GMX_TEST_CXXFLAG(CXXFLAGS_WARN "-w3;-wd177;-wd280;-wd304;-wd383;-wd411;-wd444;-wd869;-wd981;-wd1418;-wd1572;-wd1599;-wd2259;-wd2547;-wd3280;-wd11074;-wd11076;-wd2282" GMXC_CXXFLAGS)
+#2621: attribute "unused" does not apply here
+ GMX_TEST_CXXFLAG(CXXFLAGS_WARN "-w3;-wd177;-wd280;-wd304;-wd383;-wd411;-wd444;-wd869;-wd981;-wd1418;-wd1572;-wd1599;-wd2259;-wd2547;-wd2621;-wd3280;-wd11074;-wd11076;-wd2282" GMXC_CXXFLAGS)
endif()
GMX_TEST_CXXFLAG(CXXFLAGS_OPT "-ip;-funroll-all-loops;-alias-const;-ansi-alias;-no-prec-div;-fimf-domain-exclusion=14;-qoverride-limits" GMXC_CXXFLAGS_RELEASE)
GMX_TEST_CXXFLAG(CXXFLAGS_DEBUG "-O0" GMXC_CXXFLAGS_DEBUG)
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2013,2014,2016,2018,2019, by the GROMACS development team, led by
+# Copyright (c) 2013,2014,2016,2018,2019,2020, by the GROMACS development team, led by
# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
# and including many others, as listed in the AUTHORS file in the
# top-level source directory and at http://www.gromacs.org.
try_compile(GMX_TARGET_MIC ${CMAKE_BINARY_DIR}
"${CMAKE_SOURCE_DIR}/cmake/TestMIC.cpp")
endif()
+ if (GMX_TARGET_MIC)
+ message(STATUS "The Intel MIC KNC target is deprecated")
+ endif()
if (NOT DEFINED GMX_TARGET_FUJITSU_SPARC64)
try_compile(GMX_TARGET_FUJITSU_SPARC64 ${CMAKE_BINARY_DIR}
"${CMAKE_SOURCE_DIR}/cmake/TestFujitsuSparc64.cpp")
endif()
+ if (GMX_TARGET_FUJITSU_SPARC64)
+ message(STATUS "The Fujitsu Sparc64 target is deprecated")
+ endif()
endfunction()
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2012,2013,2014, by the GROMACS development team, led by
+# Copyright (c) 2012,2013,2014,2020, by the GROMACS development team, led by
# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
# and including many others, as listed in the AUTHORS file in the
# top-level source directory and at http://www.gromacs.org.
# Managing configuration for Fujitsu PrimeHPC Sparc64
# For now this is mainly used for K computer.
-message(STATUS "Configuring for Fujitsu Sparc64")
+message(STATUS "Configuring for Fujitsu Sparc64 (deprecated)")
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Use static linking by default on Fujitsu Sparc64" FORCE)
set(GMX_GPU OFF CACHE BOOL "Cannot do GPU acceleration on Fujitsu Sparc64" FORCE)
endif()
elseif(GMX_SIMD_ACTIVE STREQUAL "MIC")
-
# No flags needed. Not testing.
set(GMX_SIMD_X86_MIC 1)
- set(SIMD_STATUS_MESSAGE "Enabling MIC (Xeon Phi) SIMD instructions without special flags.")
+ set(SIMD_STATUS_MESSAGE "Enabling MIC (Xeon Phi) SIMD instructions without special flags. This SIMD support is deprecated.")
elseif(GMX_SIMD_ACTIVE STREQUAL "AVX_512")
string(REPLACE " " ";" SIMD_C_FLAGS ${SIMD_ARM_NEON_C_FLAGS})
string(REPLACE " " ";" SIMD_CXX_FLAGS ${SIMD_ARM_NEON_CXX_FLAGS})
set(GMX_SIMD_${GMX_SIMD_ACTIVE} 1)
- set(SIMD_STATUS_MESSAGE "Enabling 32-bit ARM NEON SIMD instructions using CXX flags: ${SIMD_ARM_NEON_CXX_FLAGS}")
+ set(SIMD_STATUS_MESSAGE "Enabling 32-bit ARM NEON SIMD instructions using CXX flags: ${SIMD_ARM_NEON_CXX_FLAGS}. This SIMD support is deprecated.")
elseif(GMX_SIMD_ACTIVE STREQUAL "ARM_NEON_ASIMD")
string(REPLACE " " ";" SIMD_C_FLAGS ${SIMD_IBM_VMX_C_FLAGS})
string(REPLACE " " ";" SIMD_CXX_FLAGS ${SIMD_IBM_VMX_CXX_FLAGS})
set(GMX_SIMD_${GMX_SIMD_ACTIVE} 1)
- set(SIMD_STATUS_MESSAGE "Enabling IBM VMX SIMD instructions using CXX flags: ${SIMD_IBM_VMX_CXX_FLAGS}")
+ set(SIMD_STATUS_MESSAGE "Enabling IBM VMX SIMD instructions using CXX flags: ${SIMD_IBM_VMX_CXX_FLAGS}. This SIMD support is deprecated.")
elseif(GMX_SIMD_ACTIVE STREQUAL "IBM_VSX")
# Note that GMX_RELAXED_DOUBLE_PRECISION is enabled by default in the top-level CMakeLists.txt
set(GMX_SIMD_${GMX_SIMD_ACTIVE} 1)
- set(SIMD_STATUS_MESSAGE "Enabling Sparc64 HPC-ACE SIMD instructions without special flags.")
+ set(SIMD_STATUS_MESSAGE "Enabling Sparc64 HPC-ACE SIMD instructions without special flags. This SIMD support is deprecated.")
elseif(GMX_SIMD_ACTIVE STREQUAL "REFERENCE")
# 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 "168992305e10b44c58cd22130558e5fc" CACHE INTERNAL "MD5 sum of the regressiontests tarball for this GROMACS version")
+set(REGRESSIONTEST_MD5SUM "ca12c40c20575df76b1b8b1a351cb7b0" CACHE INTERNAL "MD5 sum of the regressiontests tarball for this GROMACS version")
math(EXPR GMX_VERSION_NUMERIC
"${GMX_VERSION_MAJOR}*10000 + ${GMX_VERSION_PATCH}")
not be considered as *real*, or at the minimum it will be much harder to analyse to find the actual issue.
-If your inputs are sensitive, then it is possible to create private `issues <issue tracker>`_
+If your inputs are sensitive, then it is possible to create private
+`issues <https://gitlab.com/gromacs/gromacs/-/issues/>`_
so that the developer team can have access to solve the problem, while preventing widespread
visibility on the internet.
See :ref:`gmxapi_package_documentation`
-.. _testing_requirements:
+.. _testing requirements:
Testing requirements
--------------------
+Note that the test suite is only available in the GROMACS source tree.
+(It is not part of the installed package.)
+Acquire the GROMACS sources with :command:`git` or by downloading an archive, as documented elsewhere.
+
Testing is performed with `pytest <https://docs.pytest.org/en/latest/>`_.
-Tests also require numpy_.
-You can probably install both with pip_::
- pip install pytest numpy
+:file:`python_packaging/requirements-test.txt` lists additional requirements for testing.
+With pip_::
+
+ pip install -r python_packaging/requirements-test.txt
To test the full functionality also requires an MPI parallel environment.
You will need the mpi4py_ Python package and an MPI launcher
Document sample_restraint package. Reference issue
`3027 <https://gitlab.com/gromacs/gromacs/-/issues/3027>`_
+Testing
+=======
+
+Note `testing requirements`_ above.
+
+After installing the :py:mod:`gmxapi` Python package,
+you can run the Python test suite from the GROMACS source tree.
+Example::
+
+ # Assuming you are in the root directory of the repository:
+ pytest python_packaging/src/test/
+
+Refer to :file:`python_packaging/README.md` for more detailed information.
+
.. _gmxapi install troubleshooting:
Troubleshooting
Building only mdrun
~~~~~~~~~~~~~~~~~~~
-This is now supported with the ``cmake`` option
+This is now deprecated, but still supported with the ``cmake`` option
``-DGMX_BUILD_MDRUN_ONLY=ON``, which will build a different version of
-``libgromacs`` and the ``mdrun`` program.
-Naturally, now ``make install`` installs only those
-products. By default, mdrun-only builds will default to static linking
-against |Gromacs| libraries, because this is generally a good idea for
-the targets for which an mdrun-only build is desirable.
+``libgromacs`` and the ``mdrun`` program. Naturally, now ``make
+install`` installs only those products. By default, mdrun-only builds
+will default to static linking against |Gromacs| libraries, because
+this is generally a good idea for the targets for which an mdrun-only
+build is desirable.
Installing |Gromacs|
^^^^^^^^^^^^^^^^^^^^
For this testing, we use Ubuntu 18.04 or 20.04 operating system.
Other compiler, library, and OS versions are tested less frequently.
For details, you can have a look at the
-`continuous integration server used by GROMACS <gitlab>`_,
+`continuous integration server used by GROMACS <https://gitlab.com/gromacs/gromacs/>`_,
which uses GitLab runner on a local k8s x86 cluster with NVIDIA and
AMD GPU support.
an external force. This feature makes it possible to drive the
system into a non-equilibrium state and enables the performance of
non-equilibrium MD and hence to obtain transport properties.
+ (Deprecated)
energy-monitor group
The force derived from this potential is:
-.. math:: \mathbf{F}_i(\mathbf{r}_{ij}) = \left( 12~\frac{C_{ij}^{(12)}}{{r_{ij}}^{13}} -
+.. math:: \mathbf{F}_i(\mathbf{r}_{ij}) = -\left( 12~\frac{C_{ij}^{(12)}}{{r_{ij}}^{13}} -
6~\frac{C_{ij}^{(6)}}{{r_{ij}}^7} \right) {\frac{{\mathbf{r}_{ij}}}{{r_{ij}}}}
:label: eqnljforce
The force derived from this potential is:
-.. math:: \mathbf{F}_i(\mathbf{r}_{ij}) = f \frac{q_i q_j}{{\varepsilon_r}{r_{ij}}^2}{\frac{{\mathbf{r}_{ij}}}{{r_{ij}}}}
+.. math:: \mathbf{F}_i(\mathbf{r}_{ij}) = -f \frac{q_i q_j}{{\varepsilon_r}{r_{ij}}^2}{\frac{{\mathbf{r}_{ij}}}{{r_{ij}}}}
:label: eqnfcoul
A plain Coulomb interaction should only be used without cut-off or when
with respect to :math:`{r_{ij}}` (= -force) goes to zero at the cut-off
distance. The force derived from this potential reads:
-.. math:: \mathbf{F}_i(\mathbf{r}_{ij}) = f \frac{q_i q_j}{{\varepsilon_r}}\left[\frac{1}{{r_{ij}}^2} - 2 k_{rf}{r_{ij}}\right]{\frac{{\mathbf{r}_{ij}}}{{r_{ij}}}}
+.. math:: \mathbf{F}_i(\mathbf{r}_{ij}) = -f \frac{q_i q_j}{{\varepsilon_r}}\left[\frac{1}{{r_{ij}}^2} - 2 k_{rf}{r_{ij}}\right]{\frac{{\mathbf{r}_{ij}}}{{r_{ij}}}}
:label: eqnfcrf
The reaction-field correction should also be applied to all excluded
introduced into the release-2016 branch since it diverged from
release-5-1. These will not appear in the final release notes, because
no formal release is thought to have had the problem. Of course, the
-tracked `issues <issue tracker>`_ remain available should further discussion arise.
+tracked `issues <https://gitlab.com/gromacs/gromacs/-/issues/>`_
+remain available should further discussion arise.
Fixed bug in v-rescale thermostat & replica exchange
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Also, please use the syntax :issue:`number` to reference issues on GitLab, without the
a space between the colon and number!
+The core |Gromacs| team wants to let users and downstream developers
+know about impending changes so that disruption is minimized. Do get
+in touch if you feel something inappropriate is planned!
+
+Deprecated functionality often remains in |Gromacs| for a year or
+more, but this should not be relied upon.
+
Changes anticipated to |Gromacs| 2020 functionality
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+``gmx mdrun -membed``
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+The feature for embedding a protein in a membrane will be retained,
+but probably in a different form, such as ``gmx membed``.
+
+``gmx mdrun -rerun``
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+The feature for computing potential energy quantities from a
+trajectory will be retained, but probably in a different form, such as
+``gmx rerun`` and ``gmx test-particle-insertion``.
+
+Integrator .mdp options will only contain dynamical integrators
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+Energy minimization will be accessed in a differt form, perhaps with
+``gmx minimize`` and interpret an .mdp field for which minimizer to
+use. Normal-mode analysis may be accessed with e.g. ``gmx
+normal-modes``. The command-line help for these tools will then
+be better able to document which functionality is supported when.
+
+Much functionality in ``trjconv``, ``editconf``, ``eneconv`` and ``trjcat``
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+The functionality in such tools is being separated to make it
+available in composable modules, that we plan to make available as
+simpler tools, and eventually via the GROMACS API that is under
+development.
+
+``gmx do_dssp`` to be replaced
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+This tool is deprecated, because it is problematic for some users to
+obtain and install a separate DSSP binary, so we plan to replace the
+implementation at some point with a native implementation, likely
+based upon xssp, and make it available under a new gmx tool name.
+
Functionality deprecated in |Gromacs| 2020
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
:issue:`3469`
+Correct excluded perturbed interactions beyond the non-bonded cut-off distance
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+
+With free-energy calculations without coupling of intermolecular interactions,
+non-bonded pair interactions at distance longer than the cut-off distance can
+be excluded. These interactions would still have PME long-range contributions.
+The contributions are now removed. In addition, mdrun will stop with a fatal
+error when interactions beyond the pair-list cut-off are present.
+
+:issue:`3403`
+:issue:`3808`
+
Corrected AWH initial histogram size
""""""""""""""""""""""""""""""""""""
given in the reference manual.
:issue:`3751`
+
+Fixed LJ Ewald exclusions when used with cut-off electrostatics
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+
+The exclusion forces in CUDA and OpenCL kernels were computed incorrectly
+if LJ Ewald was used together with cut-off electrostatics.
+
+:issue:`3840`
Also, please use the syntax :issue:`number` to reference issues on GitLab, without the
a space between the colon and number!
+The core |Gromacs| team wants to let users and downstream developers
+know about impending changes so that disruption is minimized. Do get
+in touch if you feel something inappropriate is planned!
+
+Deprecated functionality often remains in |Gromacs| for a year or
+more, but this should not be relied upon.
+
+.. Note to maintainers!
+ The sections below should general copy the contents from the previous major release,
+ except where appropriate when code or planning changes have happened.
+
Changes anticipated to |Gromacs| 2021 functionality
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+``gmx mdrun -membed``
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+The feature for embedding a protein in a membrane will be retained,
+but probably in a different form, such as ``gmx membed``.
+
+``gmx mdrun -rerun``
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+The feature for computing potential energy quantities from a
+trajectory will be retained, but probably in a different form, such as
+``gmx rerun`` and ``gmx test-particle-insertion``.
+
+Integrator .mdp options will only contain dynamical integrators
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+Energy minimization will be accessed in a differt form, perhaps with
+``gmx minimize`` and interpret an .mdp field for which minimizer to
+use. Normal-mode analysis may be accessed with e.g. ``gmx
+normal-modes``. The command-line help for these tools will then
+be better able to document which functionality is supported when.
+
+Much functionality in ``trjconv``, ``editconf``, ``eneconv`` and ``trjcat``
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+The functionality in such tools is being separated to make it
+available in composable modules, that we plan to make available as
+simpler tools, and eventually via the GROMACS API that is under
+development.
+
+``gmx do_dssp`` to be replaced
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+This tool is deprecated, because it is problematic for some users to
+obtain and install a separate DSSP binary, so we plan to replace the
+implementation at some point with a native implementation, likely
+based upon xssp, and make it available under a new gmx tool name.
+
Functionality deprecated in |Gromacs| 2021
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+OpenCL to be removed as a GPU framework
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+:issue:`3818` Work is underway for ports to AMD and Intel GPUs, and it
+is likely that those ports will not be based on the current |Gromacs|
+OpenCL port. Nvidia GPUs are targeted by the CUDA port, and no changes
+are expectd there. The core team can't maintain, test, and extend up
+to 4 ports with current resource levels. Since there are no prospects
+of an emerging GPU vendor in HPC needing OpenCL support, we will
+remove the OpenCL port once AMD and Intel support is established in
+other ways.
+
+Intel KNC (MIC) support
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+:issue:`3818` This architecture is nearly extinct in HPC. Note that
+KNL support will continue and is not affected by this deprecation.
+
+Sparc64 HPC ACE
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+This architecture is nearly extinct in HPC.
+
+Legacy SIMD architecture support
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+:issue:`3818` We occasionally need to extend the |Gromacs| SIMD
+framework, and so should slowly remove older architectures that are
+difficult or impossible to test. The following implementations are
+deprecated and will not support new functionality in future.
+
+* Power 7
+* ARMv7 (this platform was deprecated in |Gromacs| 2020)
+* x86 MIC (this platform was deprecated in |Gromacs| 2021)
+* Sparc64 HPC ACE (this platform was deprecated in |Gromacs| 2021)
+
+The mdrun-only build of |Gromacs|
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+:issue:`3808` Before |Gromacs| had the ``gmx`` wrapper binary, the
+``mdrun`` binary could be built independently of the many other binary
+tools that were built by default. That was useful for installing on
+compute clusters because dependencies for ``mdrun`` were
+minimized. However, we now manage such dependencies better with CMake,
+and an mdrun-only build is no longer easier to build. The mdrun-only
+build is also harder to test, and introduces complexity into
+documenting |Gromacs| and teaching users to use it. So it is time to
+remove that build.
+
+Support for version 1 of the hardware locality library ``hwloc``
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+:issue:`3818` Version 2 has been supported in |Gromacs| for several
+years. The capabilities of newer hardware and hardware-support APIs
+are of most interest for |Gromacs| moving forward, so we should
+minimize our testing work and encourage clusters to upgrade older
+``hwloc`` installations.
+
+Legacy API
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+:issue:`3818` The legacy installed headers have been deprecated for a
+while, however we wish to state more broadly that all headers found
+within the ``src`` directory tree of |Gromacs| are intended for
+internal consumption only, and are thus subject to change without
+notice. Further, the form and contents of the ``libgromacs`` library
+and related CMake targets may change as we move towards building APIs
+and supporting machinery that can be stable and supported in the long
+term.
+
+Constant-acceleration MD
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+:issue:`1354` This has been broken for many years, and will be removed
+as nobody has been found with interest to fix it.
+
+Functionality deprecated in |Gromacs| 2020
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Support for 32bit architectures
+"""""""""""""""""""""""""""""""
+:issue:`3252` There are no current or planned large scale resources using 32bit architectures,
+and we have no ability to properly test and evaluate them.
+
+Free-energy soft-core power 48
+""""""""""""""""""""""""""""""
+:issue:`3253` Free-energy soft-core power 48 is almost never used and is therefore deprecated.
+
+Support for Armv7
+"""""""""""""""""
+:issue:`2990` There are several issues with current code for the architecture, and we don't
+have the resources for support and fix issues related to it. As the architecture has no
+large HPC impact it is thus deprecated.
+
+Functionality deprecated in |Gromacs| 2019
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Generation of virtual sites to replace aromatic rings in standard residues
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+:issue:`3254` These are thought to produce artefacts under some circumstances
+(unpublished results), were never well tested, are not widely used,
+and we need to simplify pdb2gmx.
+
+Benchmarking options only available with ``gmx benchmark``
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+:issue:`3255` Options such as ``-confout``, ``-resethway``, ``-resetstep`` are not
+intended for use by regular mdrun users, so making them only available
+with a dedicated tool is more clear. Also, this permits us to customize
+defaults for e.g. writing files at the end of a simulation part in ways
+that suit the respective mdrun and benchmark use cases, so ``-confout``
+will no longer be required.
+
+``gmx mdrun -nsteps``
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+:issue:`3256` The number of simulation steps described by the .tpr file can be
+changed with ``gmx convert-tpr``, or altered in .mdp file before the
+call to ``gmx grompp``. The convenience of this mdrun option was
+outweighted by the doubtful quality of its implementation, no clear
+record in the log file, and lack of maintenance.
+
groups for constant acceleration (*e.g.* ``Protein Sol``) all atoms
in groups Protein and Sol will experience constant acceleration as
- specified in the :mdp:`accelerate` line
+ specified in the :mdp:`accelerate` line. (Deprecated)
.. mdp:: accelerate
acceleration for :mdp:`acc-grps`; x, y and z for each group
(*e.g.* ``0.1 0.0 0.0 -0.1 0.0 0.0`` means that first group has
constant acceleration of 0.1 nm ps\ :sup:`-2` in X direction, second group
- the opposite).
+ the opposite). (Deprecated)
.. mdp:: freezegrps
Some dependencies (notably, a Python installation itself) may require some fiddling
with the XCode SDK.
https://developer.apple.com/documentation/xcode_release_notes/xcode_10_release_notes#3035624
+
+# Tests for gmxapi Python packages distributed with GROMACS
+
+## Requirements
+
+Python tests use the `unittest` standard library module and the `unittest.mock`
+submodule, included in Python 3.3+.
+
+The additional `pytest` package allows tests to be written more easily and
+concisely, with easier test fixtures (through decorators), log handling, and
+other output handling.
+
+## Files
+
+Python files beginning with `test_` are collected by the Python testing
+framework during automatic test discovery.
+
+`conftest.py` and `pytest.ini` provide configuration for `pytest`.
+
+## Usage
+
+For basic tests, install the Python package(s) (presumably into a virtualenv),
+then use the `pytest` executable to run these tests against the installed
+package(s).
+
+`pytest $LOCAL_REPO_DIR/python_packaging/src/test`
+
+where `$LOCAL_REPO_DIR` is the path to the local copy of the GROMACS source repository.
+
+For multi-process tests, run with an MPI execution wrapper and the `mpi4py` module.
+
+`mpiexec -n 2 python -m mpi4py -m pytest $LOCAL_REPO_DIR/python_packaging/test`
+
+## Controlling output
+
+Refer to pytest documentation for command line options to control the type and detail of output.
+Some high level overview and basic tasks are online at https://docs.pytest.org/en/3.9.3/usage.html
+but you should run `pytest -h` in a terminal to get the complete set of available options
+(in particular, note *log_cli* and *log_level*).
import os
+# Import setuptools early to avoid UserWarning from Distutils.
+# Ref: https://gitlab.com/gromacs/gromacs/-/issues/3715
+import setuptools
+
# Allow setup.py to be run when scikit-build is not installed, such as to
# produce source distribution archives with `python setup.py sdist`
try:
# Infer from GMXRC exports, if available.
gmxapi_DIR = os.getenv('GROMACS_DIR')
+
def _find_first_gromacs_suffix(directory):
dir_contents = os.listdir(directory)
for entry in dir_contents:
if entry.startswith('gromacs'):
return entry.strip('gromacs')
+
if gmx_toolchain_dir is None:
# Try to guess from standard GMXRC environment variables.
if gmxapi_DIR is not None:
[pytest]
-junit_family=xunit1
+junit_family=xunit2
+++ /dev/null
-# Tests for gmxapi Python packages distributed with GROMACS
-
-Potentially longer-running than the unit tests in the Python package directory
-and broader in scope. Intended to include more thorough and complete integration
-testing than in the `acceptance` subdirectory.
-
-## Requirements
-
-Python tests use the `unittest` standard library module and the `unittest.mock`
-submodule, included in Python 3.3+.
-
-The additional `pytest` package allows tests to be written more easily and
-concisely, with easier test fixtures (through decorators), log handling, and
-other output handling.
-
-## Files
-
-Python files beginning with `test_` are collected by the Python testing
-framework during automatic test discovery.
-
-`conftest.py` and `pytest.ini` provide configuration for `pytest`.
-
-Tests are organized according to the functional requirements
-documented in `roadmap.rst` in the `python_packaging` directory.
-
-## Usage
-
-For basic tests, install the Python package(s) (presumably into a virtualenv),
-then use the `pytest` executable to run these tests against the installed
-package(s).
-
-`pytest $LOCAL_REPO_DIR/python_packaging/test`
-
-where `$LOCAL_REPO_DIR` is the path to the local copy of the GROMACS source repository.
-
-For multi-process tests, run with an MPI execution wrapper and the `mpi4py` module.
-
-`mpiexec -n 2 python -m mpi4py -m pytest $LOCAL_REPO_DIR/python_packaging/test`
-
-## Controlling output
-
-Refer to pytest documentation for command line options to control the type and detail of output.
-Some high level overview and basic tasks are online at https://docs.pytest.org/en/3.9.3/usage.html
-but you should run `pytest -h` in a terminal to get the complete set of available options
-(in particular, note *log_cli* and *log_level*).
[pytest]
-junit_family=xunit1
+junit_family=xunit2
#ifndef BOOST_STL_INTERFACES_DOXYGEN
-#if defined(_MSC_VER) || defined(__GNUC__) && __GNUC__ < 8
+// It is not known whether intel has fixed this issue, but it was
+// observed to be present in icc 19.1.2.20200623. Update the version
+// check when it is fixed.
+#if defined(_MSC_VER) || defined(__GNUC__) && __GNUC__ < 8 || defined(__INTEL_COMPILER) && __INTEL_COMPILER < 1920
#define BOOST_STL_INTERFACES_NO_HIDDEN_FRIEND_CONSTEXPR
#define BOOST_STL_INTERFACES_HIDDEN_FRIEND_CONSTEXPR
#else
-cmake_minimum_required(VERSION 2.6.2)
+#cmake_minimum_required(VERSION 2.6.2)
project( googletest-distribution )
from consideration by wrapping with `#ifndef __clang_analyzer__`
or marking them with `/*NOLINT*/` comment.
... `#endif`.
+
+GoogleTest declares quite old minimum CMake versions, which newer
+CMake versions warn about. In practice, the CMake version requirement
+for GROMACS is greater than these minimums, and that version will be
+used for GoogleTest also. The warnings aren't useful for GROMACS
+developers, so those declarations by GoogleTest have been commented
+out.
# ${gmock_BINARY_DIR}.
# Language "C" is required for find_package(Threads).
project(gmock CXX C)
-cmake_minimum_required(VERSION 2.6.2)
+#cmake_minimum_required(VERSION 2.6.2)
if (COMMAND set_up_hermetic_build)
set_up_hermetic_build()
cmake_policy(SET CMP0048 NEW)
project(gtest VERSION 1.8.1 LANGUAGES CXX C)
endif()
-cmake_minimum_required(VERSION 2.6.4)
+#cmake_minimum_required(VERSION 2.6.4)
if (POLICY CMP0063) # Visibility
cmake_policy(SET CMP0063 NEW)
}
/* We always re-initialize the tables whether they are used or not */
- init_interaction_const_tables(nullptr, ic, ir.tabext);
+ init_interaction_const_tables(nullptr, ic, set->rlistOuter, ir.tabext);
Nbnxm::gpu_pme_loadbal_update_param(nbv, ic);
#include "gromacs/mdtypes/pullhistory.h"
#include "gromacs/mdtypes/state.h"
#include "gromacs/mdtypes/swaphistory.h"
+#include "gromacs/modularsimulator/modularsimulator.h"
#include "gromacs/trajectory/trajectoryframe.h"
#include "gromacs/utility/arrayref.h"
#include "gromacs/utility/baseversion.h"
#include "gromacs/utility/programcontext.h"
#include "gromacs/utility/smalloc.h"
#include "gromacs/utility/sysinfo.h"
+#include "gromacs/utility/textwriter.h"
#include "gromacs/utility/txtdump.h"
#define CPT_MAGIC1 171817
static void do_cpt_mdmodules(int fileVersion,
t_fileio* checkpointFileHandle,
- const gmx::MdModulesNotifier& mdModulesNotifier)
+ const gmx::MdModulesNotifier& mdModulesNotifier,
+ FILE* outputFile)
{
if (fileVersion >= cptv_MdModules)
{
gmx::FileIOXdrSerializer serializer(checkpointFileHandle);
gmx::KeyValueTreeObject mdModuleCheckpointParameterTree =
gmx::deserializeKeyValueTree(&serializer);
+ if (outputFile)
+ {
+ gmx::TextWriter textWriter(outputFile);
+ gmx::dumpKeyValueTree(&textWriter, mdModuleCheckpointParameterTree);
+ }
gmx::MdModulesCheckpointReadingDataOnMaster mdModuleCheckpointReadingDataOnMaster = {
mdModuleCheckpointParameterTree, fileVersion
};
fn);
}
- GMX_ASSERT(!(headerContents->isModularSimulatorCheckpoint && !useModularSimulator),
- "Checkpoint file was written by modular simulator, but the current simulation uses "
- "the legacy simulator.");
- GMX_ASSERT(!(!headerContents->isModularSimulatorCheckpoint && useModularSimulator),
- "Checkpoint file was written by legacy simulator, but the current simulation uses "
- "the modular simulator.");
+ GMX_RELEASE_ASSERT(!(headerContents->isModularSimulatorCheckpoint && !useModularSimulator),
+ "Checkpoint file was written by modular simulator, but the current "
+ "simulation uses the legacy simulator.\n\n"
+ "Try the following steps:\n"
+ "1. Make sure the GMX_DISABLE_MODULAR_SIMULATOR environment variable is not "
+ "set to return to the default behavior. Retry running the simulation.\n"
+ "2. If the problem persists, set the environment variable "
+ "GMX_USE_MODULAR_SIMULATOR=ON to overwrite the default behavior and use "
+ "modular simulator for all implemented use cases.");
+ GMX_RELEASE_ASSERT(!(!headerContents->isModularSimulatorCheckpoint && useModularSimulator),
+ "Checkpoint file was written by legacy simulator, but the current "
+ "simulation uses the modular simulator.\n\n"
+ "Try the following steps:\n"
+ "1. Make sure the GMX_USE_MODULAR_SIMULATOR environment variable is not set "
+ "to return to the default behavior. Retry running the simulation.\n"
+ "2. If the problem persists, set the environment variable "
+ "GMX_DISABLE_MODULAR_SIMULATOR=ON to overwrite the default behavior and use "
+ "legacy simulator for all implemented use cases.");
if (MASTER(cr))
{
{
cp_error();
}
- do_cpt_mdmodules(headerContents->file_version, fp, mdModulesNotifier);
+ do_cpt_mdmodules(headerContents->file_version, fp, mdModulesNotifier, nullptr);
if (headerContents->file_version >= cptv_ModularSimulator)
{
gmx::FileIOXdrSerializer serializer(fp);
static CheckpointHeaderContents read_checkpoint_data(t_fileio* fp,
t_state* state,
- std::vector<gmx_file_position_t>* outputfiles)
+ std::vector<gmx_file_position_t>* outputfiles,
+ gmx::ReadCheckpointDataHolder* modularSimulatorCheckpointData)
{
CheckpointHeaderContents headerContents;
do_cpt_header(gmx_fio_getxdr(fp), TRUE, nullptr, &headerContents);
cp_error();
}
gmx::MdModulesNotifier mdModuleNotifier;
- do_cpt_mdmodules(headerContents.file_version, fp, mdModuleNotifier);
+ do_cpt_mdmodules(headerContents.file_version, fp, mdModuleNotifier, nullptr);
if (headerContents.file_version >= cptv_ModularSimulator)
{
- // In the scope of the current function, we can just throw away the content
- // of the modular checkpoint, but we need to read it to move the file pointer
- gmx::FileIOXdrSerializer serializer(fp);
- gmx::ReadCheckpointDataHolder modularSimulatorCheckpointData;
- modularSimulatorCheckpointData.deserialize(&serializer);
+ // Store modular checkpoint data into modularSimulatorCheckpointData
+ gmx::FileIOXdrSerializer serializer(fp);
+ modularSimulatorCheckpointData->deserialize(&serializer);
}
ret = do_cpt_footer(gmx_fio_getxdr(fp), headerContents.file_version);
if (ret)
{
t_state state;
std::vector<gmx_file_position_t> outputfiles;
- CheckpointHeaderContents headerContents = read_checkpoint_data(fp, &state, &outputfiles);
+ gmx::ReadCheckpointDataHolder modularSimulatorCheckpointData;
+ CheckpointHeaderContents headerContents =
+ read_checkpoint_data(fp, &state, &outputfiles, &modularSimulatorCheckpointData);
+ if (headerContents.isModularSimulatorCheckpoint)
+ {
+ gmx::ModularSimulator::readCheckpointToTrxFrame(fr, &modularSimulatorCheckpointData, headerContents);
+ return;
+ }
fr->natoms = state.natoms;
fr->bStep = TRUE;
std::vector<gmx_file_position_t> outputfiles;
ret = do_cpt_files(gmx_fio_getxdr(fp), TRUE, &outputfiles, out, headerContents.file_version);
}
+ gmx::MdModulesNotifier mdModuleNotifier;
+ do_cpt_mdmodules(headerContents.file_version, fp, mdModuleNotifier, out);
+ if (headerContents.file_version >= cptv_ModularSimulator)
+ {
+ gmx::FileIOXdrSerializer serializer(fp);
+ gmx::ReadCheckpointDataHolder modularSimulatorCheckpointData;
+ modularSimulatorCheckpointData.deserialize(&serializer);
+ modularSimulatorCheckpointData.dump(out);
+ }
if (ret == 0)
{
CheckpointHeaderContents read_checkpoint_simulation_part_and_filenames(t_fileio* fp,
std::vector<gmx_file_position_t>* outputfiles)
{
- t_state state;
- CheckpointHeaderContents headerContents = read_checkpoint_data(fp, &state, outputfiles);
+ t_state state;
+ gmx::ReadCheckpointDataHolder modularSimulatorCheckpointData;
+ CheckpointHeaderContents headerContents =
+ read_checkpoint_data(fp, &state, outputfiles, &modularSimulatorCheckpointData);
if (gmx_fio_close(fp) != 0)
{
gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
endif()
gmx_add_unit_test(FileIOTests fileio-test
CPP_SOURCE_FILES
+ checkpoint.cpp
confio.cpp
filemd5.cpp
mrcserializer.cpp
#include "gromacs/utility/exceptions.h"
+#include "testutils/testasserts.h"
+
namespace gmx
{
namespace test
TEST(Checkpoint, ReadingThrowsWhenValueNotPresent)
{
KeyValueTreeObject kvtObject;
- std::int64_t readValue;
+ std::int64_t readValue = 0;
EXPECT_THROW_GMX(readKvtCheckpointValue(compat::make_not_null(&readValue), "non", "sense", kvtObject),
- InternalError);
+ gmx::InternalError);
}
TEST(Checkpoint, ReadingDoesNotThrowWhenValuePresent)
{
- int64_t value;
+ int64_t value = 37;
std::string name = "checkpointedInteger";
std::string identifier = "testingmodule";
KeyValueTreeBuilder kvtBuilder;
writeKvtCheckpointValue(value, name, identifier, kvtBuilder.rootObject());
const auto kvtObject = kvtBuilder.build();
int64_t readValue = 0;
- EXPECT_NO_THROW_GMX(readKvtCheckpointValue(compat::make_not_null(&readValue), "non", "sense", kvtObject),
- InternalError);
+ EXPECT_NO_THROW_GMX(
+ readKvtCheckpointValue(compat::make_not_null(&readValue), name, identifier, kvtObject));
}
TEST(Checkpoint, KvtRoundTripInt64)
{
- int64_t value;
+ int64_t value = INT64_MAX;
std::string name = "checkpointedInteger";
std::string identifier = "testingmodule";
KeyValueTreeBuilder kvtBuilder;
TEST(Checkpoint, KvtRoundTripReal)
{
- real value;
- std::string name = "checkpointedInteger";
+ real value = 926.7;
+ std::string name = "checkpointedReal";
std::string identifier = "testingmodule";
KeyValueTreeBuilder kvtBuilder;
writeKvtCheckpointValue(value, name, identifier, kvtBuilder.rootObject());
real* gmx_restrict f = &(forceWithShiftForces->force()[0][0]);
real* gmx_restrict fshift = &(forceWithShiftForces->shiftForces()[0][0]);
+ const real rlistSquared = gmx::square(fr->rlist);
+
+ int numExcludedPairsBeyondRlist = 0;
+
for (int n = 0; n < nri; n++)
{
int npair_within_cutoff = 0;
}
npair_within_cutoff++;
+ if (rSq > rlistSquared)
+ {
+ numExcludedPairsBeyondRlist++;
+ }
+
if (rSq > 0)
{
/* Note that unlike in the nbnxn kernels, we do not need
}
}
- if (vdwInteractionTypeIsEwald && r < rVdw)
+ if (vdwInteractionTypeIsEwald && (r < rVdw || !bPairIncluded))
{
/* See comment in the preamble. When using LJ-Ewald interactions
* (unless we use a switch modifier) we subtract the reciprocal-space
*/
#pragma omp atomic
inc_nrnb(nrnb, eNR_NBKERNEL_FREE_ENERGY, nlist->nri * 12 + nlist->jindex[nri] * 150);
+
+ if (numExcludedPairsBeyondRlist > 0)
+ {
+ gmx_fatal(FARGS,
+ "There are %d perturbed non-bonded pair interactions beyond the pair-list cutoff "
+ "of %g nm, which is not supported. This can happen because the system is "
+ "unstable or because intra-molecular interactions at long distances are "
+ "excluded. If the "
+ "latter is the case, you can try to increase nstlist or rlist to avoid this."
+ "The error is likely triggered by the use of couple-intramol=no "
+ "and the maximal distance in the decoupled molecule exceeding rlist.",
+ numExcludedPairsBeyondRlist,
+ fr->rlist);
+ }
}
typedef void (*KernelFunction)(const t_nblist* gmx_restrict nlist,
}
};
-TEST(NelderMeat, Optimizes2DFunctionCorrectly)
+TEST(NelderMead, Optimizes2DFunctionCorrectly)
{
std::vector<real> initalPoint = { 1, 1 };
auto result = nelderMead(mcCormick, initalPoint);
EXPECT_REAL_EQ_TOL(result.functionValue_, -1.91329, relativeToleranceAsFloatingPoint(1, 5e-5));
}
-TEST(NelderMeat, Optimizes3DFunctorCorrectly)
+TEST(NelderMead, Optimizes3DFunctorCorrectly)
{
std::vector<real> initalPoint = { 0, 0, 0 };
auto result = nelderMead(RosenBrock3d(), initalPoint);
EXPECT_REAL_EQ_TOL(result.coordinates_[0], 1.00, relativeToleranceAsFloatingPoint(1, 1e-6));
- EXPECT_REAL_EQ_TOL(result.coordinates_[1], 1.00, relativeToleranceAsFloatingPoint(1, 1e-6));
- EXPECT_REAL_EQ_TOL(result.coordinates_[2], 1.00, relativeToleranceAsFloatingPoint(1, 1e-6));
+ EXPECT_REAL_EQ_TOL(result.coordinates_[1], 1.00, relativeToleranceAsFloatingPoint(1, 2e-6));
+ EXPECT_REAL_EQ_TOL(result.coordinates_[2], 1.00, relativeToleranceAsFloatingPoint(1, 5e-6));
EXPECT_REAL_EQ_TOL(result.functionValue_, 0, relativeToleranceAsFloatingPoint(1, 1e-7));
}
* both accuracy requirements, when relevant.
*/
static void init_ewald_f_table(const interaction_const_t& ic,
- const real tableExtensionLength,
+ const real rlist,
+ const real tabext,
EwaldCorrectionTables* coulombTables,
EwaldCorrectionTables* vdwTables)
{
const bool havePerturbedNonbondeds = (ic.softCoreParameters != nullptr);
real tableLen = ic.rcoulomb;
- if (useCoulombTable && havePerturbedNonbondeds && tableExtensionLength > 0.0)
+ if ((useCoulombTable || useVdwTable) && havePerturbedNonbondeds && rlist + tabext > 0.0)
{
/* TODO: Ideally this should also check if couple-intramol == no, but that isn't
* stored in ir. Grompp puts that info into an opts structure that doesn't make it into the tpr.
* couple-intramol == no. Meanwhile, always having larger tables should only affect
* memory consumption, not speed (barring cache issues).
*/
- tableLen = ic.rcoulomb + tableExtensionLength;
+ tableLen = rlist + tabext;
}
const int tableSize = static_cast<int>(tableLen * tableScale) + 2;
}
}
-void init_interaction_const_tables(FILE* fp, interaction_const_t* ic, const real tableExtensionLength)
+void init_interaction_const_tables(FILE* fp, interaction_const_t* ic, const real rlist, const real tableExtensionLength)
{
if (EEL_PME_EWALD(ic->eeltype) || EVDW_PME(ic->vdwtype))
{
init_ewald_f_table(
- *ic, tableExtensionLength, ic->coulombEwaldTables.get(), ic->vdwEwaldTables.get());
+ *ic, rlist, tableExtensionLength, ic->coulombEwaldTables.get(), ic->vdwEwaldTables.get());
if (fp != nullptr)
{
fprintf(fp,
/* fr->ic is used both by verlet and group kernels (to some extent) now */
init_interaction_const(fp, &fr->ic, ir, mtop, systemHasNetCharge);
- init_interaction_const_tables(fp, fr->ic, ir->tabext);
+ init_interaction_const_tables(fp, fr->ic, fr->rlist, ir->tabext);
const interaction_const_t* ic = fr->ic;
* Initializes the tables in the interaction constant data structure.
* \param[in] fp File for debugging output
* \param[in] ic Structure holding the table constant
+ * \param[in] rlist Length of the neighbour list
* \param[in] tableExtensionLength Length by which to extend the tables. Taken from the input record.
*/
-void init_interaction_const_tables(FILE* fp, interaction_const_t* ic, real tableExtensionLength);
+void init_interaction_const_tables(FILE* fp, interaction_const_t* ic, real rlist, real tableExtensionLength);
/*! \brief Initialize forcerec structure.
*
Mdrunner::Mdrunner(Mdrunner&&) noexcept = default;
-Mdrunner& Mdrunner::operator=(Mdrunner&& /*handle*/) noexcept = default;
+//NOLINTNEXTLINE(performance-noexcept-move-constructor) working around GCC bug 58265 in CentOS 7
+Mdrunner& Mdrunner::operator=(Mdrunner&& /*handle*/) noexcept(BUGFREE_NOEXCEPT_STRING) = default;
class Mdrunner::BuilderImplementation
{
class SimulationContext;
class StopHandlerBuilder;
+//! Work-around for GCC bug 58265 still present in CentOS 7 devtoolset-7
+constexpr bool BUGFREE_NOEXCEPT_STRING = std::is_nothrow_move_assignable<std::string>::value;
+
/*! \libinternal \brief Runner object for supporting setup and execution of mdrun.
*
* This class has responsibility for the lifetime of data structures
* \{
*/
Mdrunner(Mdrunner&& handle) noexcept;
- Mdrunner& operator=(Mdrunner&& handle) noexcept;
+ //NOLINTNEXTLINE(performance-noexcept-move-constructor) working around GCC bug 58265 in CentOS 7
+ Mdrunner& operator=(Mdrunner&& handle) noexcept(BUGFREE_NOEXCEPT_STRING);
/* \} */
/*! \brief Driver routine, that calls the different simulation methods. */
#include "gromacs/utility/iserializer.h"
#include "gromacs/utility/keyvaluetreeserializer.h"
+#include "gromacs/utility/textwriter.h"
namespace gmx
{
return ReadCheckpointData(checkpointTree_[key].asObject());
}
+void ReadCheckpointDataHolder::dump(FILE* out) const
+{
+ if (out != nullptr)
+ {
+ TextWriter textWriter(out);
+ dumpKeyValueTree(&textWriter, checkpointTree_);
+ }
+}
+
WriteCheckpointData WriteCheckpointDataHolder::checkpointData(const std::string& key)
{
hasCheckpointDataBeenRequested_ = true;
return programVersion;
}
+inline ReadCheckpointData::CheckpointData(const KeyValueTreeObject& inputTree) :
+ inputTree_(&inputTree)
+{
+}
+inline WriteCheckpointData::CheckpointData(KeyValueTreeObjectBuilder&& outputTreeBuilder) :
+ outputTreeBuilder_(outputTreeBuilder)
+{
+}
/*! \libinternal
* \brief Holder for read checkpoint data
*
*/
[[nodiscard]] ReadCheckpointData checkpointData(const std::string& key) const;
+ //! Write the contents of the Checkpoint to file
+ void dump(FILE* out) const;
+
private:
//! KV-tree read from checkpoint
KeyValueTreeObject checkpointTree_;
return CheckpointData(outputTreeBuilder_->addObject(key));
}
-inline ReadCheckpointData::CheckpointData(const KeyValueTreeObject& inputTree) :
- inputTree_(&inputTree)
-{
-}
-
-inline WriteCheckpointData::CheckpointData(KeyValueTreeObjectBuilder&& outputTreeBuilder) :
- outputTreeBuilder_(outputTreeBuilder)
-{
-}
//! \endcond
} // namespace gmx
template<typename T>
static std::enable_if_t<std::is_same<T, tensor>::value, void> increment(const T** ptr);
- constexpr static bool testTrue = true;
- constexpr static bool testFalse = false;
- constexpr static tensor testTensor1 = { { 1.6234, 2.4632, 3.1112 },
+ static constexpr bool testTrue = true;
+ static constexpr bool testFalse = false;
+ static constexpr tensor testTensor1 = { { 1.6234, 2.4632, 3.1112 },
{ 4.66234, 5.9678, 6.088 },
{ 7.00001, 8.43535, 9.11233 } };
#if GMX_DOUBLE
- constexpr static tensor testTensor2 = { { 1, GMX_DOUBLE_EPS, 3 },
+ static constexpr tensor testTensor2 = { { 1, GMX_DOUBLE_EPS, 3 },
{ GMX_DOUBLE_MIN, 5, 6 },
{ 7, 8, GMX_DOUBLE_MAX } };
#else
- constexpr static tensor testTensor2 = { { 1, GMX_FLOAT_EPS, 3 },
+ static constexpr tensor testTensor2 = { { 1, GMX_FLOAT_EPS, 3 },
{ GMX_FLOAT_MIN, 5, 6 },
{ 7, 8, GMX_FLOAT_MAX } };
#endif
* every 15 minutes), and needs two NS steps to take effect - on the first
* NS step, the checkpoint helper on master rank signals to all other ranks
* that checkpointing is about to occur. At the next NS step, the checkpoint
- * is written. On the last step, checkpointing happens immediately after the
+ * is written. On the last step, checkpointing happens immediately before the
* step (no signalling). To be able to react to last step being signalled,
* the CheckpointHelper does also implement the `ISimulatorElement` interface,
* but does only register a function if the last step has been called. It
{
if (inputrec_->nstcalcenergy > 0 && isMasterRank_)
{
+ energyOutput_->printEnergyConservation(fplog_, inputrec_->simulation_part, EI_MD(inputrec_->eI));
energyOutput_->printAverages(fplog_, groups_);
}
}
#include "gromacs/mdtypes/inputrec.h"
#include "gromacs/mdtypes/mdatom.h"
#include "gromacs/mdtypes/state.h"
+#include "gromacs/trajectory/trajectoryframe.h"
#include "modularsimulator.h"
#include "simulatoralgorithm.h"
} // namespace
template<CheckpointDataOperation operation>
-void FreeEnergyPerturbationData::Element::doCheckpointData(CheckpointData<operation>* checkpointData)
+void FreeEnergyPerturbationData::doCheckpointData(CheckpointData<operation>* checkpointData)
{
checkpointVersion(checkpointData, "FreeEnergyPerturbationData version", c_currentVersion);
- checkpointData->scalar("current FEP state", &freeEnergyPerturbationData_->currentFEPState_);
- checkpointData->arrayRef("lambda vector",
- makeCheckpointArrayRef<operation>(freeEnergyPerturbationData_->lambda_));
+ checkpointData->scalar("current FEP state", ¤tFEPState_);
+ checkpointData->arrayRef("lambda vector", makeCheckpointArrayRef<operation>(lambda_));
}
void FreeEnergyPerturbationData::Element::saveCheckpointState(std::optional<WriteCheckpointData> checkpointData,
{
if (MASTER(cr))
{
- doCheckpointData<CheckpointDataOperation::Write>(&checkpointData.value());
+ freeEnergyPerturbationData_->doCheckpointData<CheckpointDataOperation::Write>(
+ &checkpointData.value());
}
}
{
if (MASTER(cr))
{
- doCheckpointData<CheckpointDataOperation::Read>(&checkpointData.value());
+ freeEnergyPerturbationData_->doCheckpointData<CheckpointDataOperation::Read>(
+ &checkpointData.value());
}
if (DOMAINDECOMP(cr))
{
const std::string& FreeEnergyPerturbationData::Element::clientID()
{
- return identifier_;
+ return FreeEnergyPerturbationData::checkpointID();
}
FreeEnergyPerturbationData::Element::Element(FreeEnergyPerturbationData* freeEnergyPerturbationElement,
return freeEnergyPerturbationData->element();
}
+void FreeEnergyPerturbationData::readCheckpointToTrxFrame(t_trxframe* trxFrame,
+ std::optional<ReadCheckpointData> readCheckpointData)
+{
+ if (readCheckpointData)
+ {
+ FreeEnergyPerturbationData freeEnergyPerturbationData;
+ freeEnergyPerturbationData.doCheckpointData(&readCheckpointData.value());
+ trxFrame->lambda = freeEnergyPerturbationData.lambda_[efptFEP];
+ trxFrame->fep_state = freeEnergyPerturbationData.currentFEPState_;
+ }
+ else
+ {
+ trxFrame->lambda = 0;
+ trxFrame->fep_state = 0;
+ }
+ trxFrame->bLambda = true;
+}
+
+const std::string& FreeEnergyPerturbationData::checkpointID()
+{
+ static const std::string identifier = "FreeEnergyPerturbationData";
+ return identifier;
+}
+
} // namespace gmx
#include "modularsimulatorinterfaces.h"
struct t_inputrec;
+struct t_trxframe;
namespace gmx
{
//! Get pointer to element (whose lifetime is managed by this)
Element* element();
+ //! Read everything that can be stored in t_trxframe from a checkpoint file
+ static void readCheckpointToTrxFrame(t_trxframe* trxFrame,
+ std::optional<ReadCheckpointData> readCheckpointData);
+ //! CheckpointHelper identifier
+ static const std::string& checkpointID();
+
private:
+ //! Default constructor - only used internally
+ FreeEnergyPerturbationData() = default;
//! Update the lambda values
void updateLambdas(Step step);
+ //! Helper function to read from / write to CheckpointData
+ template<CheckpointDataOperation operation>
+ void doCheckpointData(CheckpointData<operation>* checkpointData);
//! The element
std::unique_ptr<Element> element_;
FreeEnergyPerturbationData* freeEnergyPerturbationData_;
//! Whether lambda values are non-static
const bool lambdasChange_;
-
-
- //! CheckpointHelper identifier
- const std::string identifier_ = "FreeEnergyPerturbationElement";
- //! Helper function to read from / write to CheckpointData
- template<CheckpointDataOperation operation>
- void doCheckpointData(CheckpointData<operation>* checkpointData);
};
} // namespace gmx
#include "gromacs/ewald/pme.h"
#include "gromacs/ewald/pme_load_balancing.h"
#include "gromacs/ewald/pme_pp.h"
+#include "gromacs/fileio/checkpoint.h"
#include "gromacs/gmxlib/nrnb.h"
#include "gromacs/listed_forces/listed_forces.h"
#include "gromacs/mdlib/checkpointhandler.h"
#include "gromacs/nbnxm/nbnxm.h"
#include "gromacs/topology/mtop_util.h"
#include "gromacs/topology/topology.h"
+#include "gromacs/trajectory/trajectoryframe.h"
#include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/int64_to_int.h"
#include "computeglobalselement.h"
#include "constraintelement.h"
&& conditionalAssert(inputrec->eI != eiMD || modularSimulatorExplicitlyTurnedOn,
"Set GMX_USE_MODULAR_SIMULATOR=ON to use the modular "
"simulator with integrator md.");
+ isInputCompatible =
+ isInputCompatible
+ && conditionalAssert(
+ !inputrec->useMts,
+ "Multiple time stepping is not supported by the modular simulator.");
isInputCompatible =
isInputCompatible
&& conditionalAssert(!doRerun, "Rerun is not supported by the modular simulator.");
isInputCompatible = isInputCompatible
&& conditionalAssert(!GMX_FAHCORE,
"GMX_FAHCORE not supported by the modular simulator.");
+ GMX_RELEASE_ASSERT(
+ isInputCompatible || !(inputrec->eI == eiVV && inputrec->epc == epcPARRINELLORAHMAN),
+ "Requested Parrinello-Rahman barostat with md-vv, but other options are not compatible "
+ "with the modular simulator. The Parrinello-Rahman barostat is not implemented for "
+ "md-vv in the legacy simulator. Use a different pressure control algorithm.");
return isInputCompatible;
}
}
}
+void ModularSimulator::readCheckpointToTrxFrame(t_trxframe* fr,
+ ReadCheckpointDataHolder* readCheckpointDataHolder,
+ const CheckpointHeaderContents& checkpointHeaderContents)
+{
+ GMX_RELEASE_ASSERT(checkpointHeaderContents.isModularSimulatorCheckpoint,
+ "ModularSimulator::readCheckpointToTrxFrame can only read checkpoints "
+ "written by modular simulator.");
+ fr->bStep = true;
+ fr->step = int64_to_int(checkpointHeaderContents.step, "conversion of checkpoint to trajectory");
+ fr->bTime = true;
+ fr->time = checkpointHeaderContents.t;
+
+ fr->bAtoms = false;
+
+ StatePropagatorData::readCheckpointToTrxFrame(
+ fr, readCheckpointDataHolder->checkpointData(StatePropagatorData::checkpointID()));
+ if (readCheckpointDataHolder->keyExists(FreeEnergyPerturbationData::checkpointID()))
+ {
+ FreeEnergyPerturbationData::readCheckpointToTrxFrame(
+ fr, readCheckpointDataHolder->checkpointData(FreeEnergyPerturbationData::checkpointID()));
+ }
+ else
+ {
+ FreeEnergyPerturbationData::readCheckpointToTrxFrame(fr, std::nullopt);
+ }
+}
+
} // namespace gmx
#include "gromacs/mdrun/isimulator.h"
+struct CheckpointHeaderContents;
struct t_fcdata;
+struct t_trxframe;
namespace gmx
{
bool doEssentialDynamics,
bool doMembed);
+ //! Read everything that can be stored in t_trxframe from a checkpoint file
+ static void readCheckpointToTrxFrame(t_trxframe* fr,
+ ReadCheckpointDataHolder* readCheckpointDataHolder,
+ const CheckpointHeaderContents& checkpointHeaderContents);
+
// Only builder can construct
friend class SimulatorBuilder;
#include "gromacs/pbcutil/pbc.h"
#include "gromacs/topology/atoms.h"
#include "gromacs/topology/topology.h"
+#include "gromacs/trajectory/trajectoryframe.h"
#include "freeenergyperturbationdata.h"
#include "modularsimulator.h"
} // namespace
template<CheckpointDataOperation operation>
-void StatePropagatorData::Element::doCheckpointData(CheckpointData<operation>* checkpointData,
- const t_commrec* cr)
+void StatePropagatorData::doCheckpointData(CheckpointData<operation>* checkpointData)
+{
+ checkpointVersion(checkpointData, "StatePropagatorData version", c_currentVersion);
+ checkpointData->scalar("numAtoms", &totalNumAtoms_);
+
+ if (operation == CheckpointDataOperation::Read)
+ {
+ xGlobal_.resizeWithPadding(totalNumAtoms_);
+ vGlobal_.resizeWithPadding(totalNumAtoms_);
+ }
+
+ checkpointData->arrayRef("positions", makeCheckpointArrayRef<operation>(xGlobal_));
+ checkpointData->arrayRef("velocities", makeCheckpointArrayRef<operation>(vGlobal_));
+ checkpointData->tensor("box", box_);
+ checkpointData->scalar("ddpCount", &ddpCount_);
+ checkpointData->scalar("ddpCountCgGl", &ddpCountCgGl_);
+ checkpointData->arrayRef("cgGl", makeCheckpointArrayRef<operation>(cgGl_));
+}
+
+void StatePropagatorData::Element::saveCheckpointState(std::optional<WriteCheckpointData> checkpointData,
+ const t_commrec* cr)
{
- ArrayRef<RVec> xGlobalRef;
- ArrayRef<RVec> vGlobalRef;
if (DOMAINDECOMP(cr))
{
- if (MASTER(cr))
- {
- xGlobalRef = statePropagatorData_->xGlobal_;
- vGlobalRef = statePropagatorData_->vGlobal_;
- }
- if (operation == CheckpointDataOperation::Write)
- {
- dd_collect_vec(cr->dd,
- statePropagatorData_->ddpCount_,
- statePropagatorData_->ddpCountCgGl_,
- statePropagatorData_->cgGl_,
- statePropagatorData_->x_,
- xGlobalRef);
- dd_collect_vec(cr->dd,
- statePropagatorData_->ddpCount_,
- statePropagatorData_->ddpCountCgGl_,
- statePropagatorData_->cgGl_,
- statePropagatorData_->v_,
- vGlobalRef);
- }
+ // Collect state from all ranks into global vectors
+ dd_collect_vec(cr->dd,
+ statePropagatorData_->ddpCount_,
+ statePropagatorData_->ddpCountCgGl_,
+ statePropagatorData_->cgGl_,
+ statePropagatorData_->x_,
+ statePropagatorData_->xGlobal_);
+ dd_collect_vec(cr->dd,
+ statePropagatorData_->ddpCount_,
+ statePropagatorData_->ddpCountCgGl_,
+ statePropagatorData_->cgGl_,
+ statePropagatorData_->v_,
+ statePropagatorData_->vGlobal_);
}
else
{
- xGlobalRef = statePropagatorData_->x_;
- vGlobalRef = statePropagatorData_->v_;
+ // Everything is local - copy local vectors into global ones
+ statePropagatorData_->xGlobal_.resizeWithPadding(statePropagatorData_->totalNumAtoms());
+ statePropagatorData_->vGlobal_.resizeWithPadding(statePropagatorData_->totalNumAtoms());
+ std::copy(statePropagatorData_->x_.begin(),
+ statePropagatorData_->x_.end(),
+ statePropagatorData_->xGlobal_.begin());
+ std::copy(statePropagatorData_->v_.begin(),
+ statePropagatorData_->v_.end(),
+ statePropagatorData_->vGlobal_.begin());
}
if (MASTER(cr))
{
- GMX_ASSERT(checkpointData, "Master needs a valid pointer to a CheckpointData object");
- checkpointVersion(checkpointData, "StatePropagatorData version", c_currentVersion);
-
- checkpointData->arrayRef("positions", makeCheckpointArrayRef<operation>(xGlobalRef));
- checkpointData->arrayRef("velocities", makeCheckpointArrayRef<operation>(vGlobalRef));
- checkpointData->tensor("box", statePropagatorData_->box_);
- checkpointData->scalar("ddpCount", &statePropagatorData_->ddpCount_);
- checkpointData->scalar("ddpCountCgGl", &statePropagatorData_->ddpCountCgGl_);
- checkpointData->arrayRef("cgGl", makeCheckpointArrayRef<operation>(statePropagatorData_->cgGl_));
+ statePropagatorData_->doCheckpointData<CheckpointDataOperation::Write>(&checkpointData.value());
}
}
-void StatePropagatorData::Element::saveCheckpointState(std::optional<WriteCheckpointData> checkpointData,
- const t_commrec* cr)
-{
- doCheckpointData<CheckpointDataOperation::Write>(
- checkpointData ? &checkpointData.value() : nullptr, cr);
-}
-
/*!
* \brief Update the legacy global state
*
void StatePropagatorData::Element::restoreCheckpointState(std::optional<ReadCheckpointData> checkpointData,
const t_commrec* cr)
{
- doCheckpointData<CheckpointDataOperation::Read>(checkpointData ? &checkpointData.value() : nullptr, cr);
+ if (MASTER(cr))
+ {
+ statePropagatorData_->doCheckpointData<CheckpointDataOperation::Read>(&checkpointData.value());
+ }
// Copy data to global state to be distributed by DD at setup stage
if (DOMAINDECOMP(cr) && MASTER(cr))
statePropagatorData_->ddpCountCgGl_,
statePropagatorData_->cgGl_);
}
+ // Everything is local - copy global vectors to local ones
+ if (!DOMAINDECOMP(cr))
+ {
+ statePropagatorData_->x_.resizeWithPadding(statePropagatorData_->totalNumAtoms_);
+ statePropagatorData_->v_.resizeWithPadding(statePropagatorData_->totalNumAtoms_);
+ std::copy(statePropagatorData_->xGlobal_.begin(),
+ statePropagatorData_->xGlobal_.end(),
+ statePropagatorData_->x_.begin());
+ std::copy(statePropagatorData_->vGlobal_.begin(),
+ statePropagatorData_->vGlobal_.end(),
+ statePropagatorData_->v_.begin());
+ }
}
const std::string& StatePropagatorData::Element::clientID()
{
- return identifier_;
+ return StatePropagatorData::checkpointID();
}
void StatePropagatorData::Element::trajectoryWriterTeardown(gmx_mdoutf* gmx_unused outf)
return statePropagatorData->element();
}
+void StatePropagatorData::readCheckpointToTrxFrame(t_trxframe* trxFrame, ReadCheckpointData readCheckpointData)
+{
+ StatePropagatorData statePropagatorData;
+ statePropagatorData.doCheckpointData(&readCheckpointData);
+
+ trxFrame->natoms = statePropagatorData.totalNumAtoms_;
+ trxFrame->bX = true;
+ trxFrame->x = makeRvecArray(statePropagatorData.xGlobal_, statePropagatorData.totalNumAtoms_);
+ trxFrame->bV = true;
+ trxFrame->v = makeRvecArray(statePropagatorData.vGlobal_, statePropagatorData.totalNumAtoms_);
+ trxFrame->bF = false;
+ trxFrame->bBox = true;
+ copy_mat(statePropagatorData.box_, trxFrame->box);
+}
+
+const std::string& StatePropagatorData::checkpointID()
+{
+ static const std::string identifier = "StatePropagatorData";
+ return identifier;
+}
+
} // namespace gmx
struct t_inputrec;
class t_state;
struct t_mdatoms;
+struct t_trxframe;
namespace gmx
{
//! Initial set up for the associated element
void setup();
+ //! Read everything that can be stored in t_trxframe from a checkpoint file
+ static void readCheckpointToTrxFrame(t_trxframe* trxFrame, ReadCheckpointData readCheckpointData);
+ //! CheckpointHelper identifier
+ static const std::string& checkpointID();
+
//! \cond
// (doxygen doesn't like these)
// Classes which need access to legacy state
//! \endcond
private:
+ //! Default constructor - only used internally
+ StatePropagatorData() = default;
//! The total number of atoms in the system
int totalNumAtoms_;
//! The local number of atoms
//! OMP helper to move x_ to previousX_
void copyPosition(int start, int end);
+ //! Helper function to read from / write to CheckpointData
+ template<CheckpointDataOperation operation>
+ void doCheckpointData(CheckpointData<operation>* checkpointData);
+
// Access to legacy state
//! Get a deep copy of the current state in legacy format
std::unique_ptr<t_state> localState();
//! ITrajectoryWriterClient implementation
std::optional<ITrajectoryWriterCallback> registerTrajectoryWriterCallback(TrajectoryEvent event) override;
- //! CheckpointHelper identifier
- const std::string identifier_ = "StatePropagatorData";
- //! Helper function to read from / write to CheckpointData
- template<CheckpointDataOperation operation>
- void doCheckpointData(CheckpointData<operation>* checkpointData, const t_commrec* cr);
-
//! ILastStepSignallerClient implementation (used for final output only)
std::optional<SignallerCallback> registerLastStepCallback() override;
GMX_RELEASE_ASSERT(options.ewaldcoeff_q > 0, "Ewald coefficient should be > 0");
ic.ewaldcoeff_q = options.ewaldcoeff_q;
ic.coulombEwaldTables = std::make_unique<EwaldCorrectionTables>();
- init_interaction_const_tables(nullptr, &ic, 0);
+ init_interaction_const_tables(nullptr, &ic, 0, 0);
}
return ic;
# define EL_EWALD_ANY
#endif
+#if defined LJ_EWALD_COMB_GEOM || defined LJ_EWALD_COMB_LB
+/* Note: convenience macro, needs to be undef-ed at the end of the file. */
+# define LJ_EWALD
+#endif
+
#if defined EL_EWALD_ANY || defined EL_RF || defined LJ_EWALD \
|| (defined EL_CUTOFF && defined CALC_ENERGIES)
/* Macro to control the calculation of exclusion forces in the kernel
# define EXCLUSION_FORCES
#endif
-#if defined LJ_EWALD_COMB_GEOM || defined LJ_EWALD_COMB_LB
-/* Note: convenience macro, needs to be undef-ed at the end of the file. */
-# define LJ_EWALD
-#endif
-
#if defined LJ_COMB_GEOM || defined LJ_COMB_LB
# define LJ_COMB
#endif
# define EL_EWALD_ANY
#endif
+#if defined LJ_EWALD_COMB_GEOM || defined LJ_EWALD_COMB_LB
+/* Note: convenience macro, needs to be undef-ed at the end of the file. */
+# define LJ_EWALD
+#endif
+
#if defined EL_EWALD_ANY || defined EL_RF || defined LJ_EWALD \
|| (defined EL_CUTOFF && defined CALC_ENERGIES)
/* Macro to control the calculation of exclusion forces in the kernel
# define EXCLUSION_FORCES
#endif
-#if defined LJ_EWALD_COMB_GEOM || defined LJ_EWALD_COMB_LB
-/* Note: convenience macro, needs to be undef-ed at the end of the file. */
-# define LJ_EWALD
-#endif
-
#if defined LJ_COMB_GEOM || defined LJ_COMB_LB
/* Note: convenience macro, needs to be undef-ed at the end of the file. */
# define LJ_COMB
const float32x4_t half = vdupq_n_f32(0.5F);
int32x4_t iExponent;
- iExponent = vandq_s32(vreinterpretq_s32_f32(value.simdInternal_), exponentMask);
- iExponent = vsubq_s32(vshrq_n_s32(iExponent, 23), exponentBias);
- exponent->simdInternal_ = iExponent;
+ iExponent = vandq_s32(vreinterpretq_s32_f32(value.simdInternal_), exponentMask);
+ iExponent = vsubq_s32(vshrq_n_s32(iExponent, 23), exponentBias);
+
+ float32x4_t result = vreinterpretq_f32_s32(
+ vorrq_s32(vandq_s32(vreinterpretq_s32_f32(value.simdInternal_), mantissaMask),
+ vreinterpretq_s32_f32(half)));
- return { vreinterpretq_f32_s32(vorrq_s32(vandq_s32(vreinterpretq_s32_f32(value.simdInternal_), mantissaMask),
- vreinterpretq_s32_f32(half))) };
+ if (opt == MathOptimization::Safe)
+ {
+ uint32x4_t valueIsZero = vceqq_f32(value.simdInternal_, vdupq_n_f32(0.0F));
+ iExponent = vbicq_s32(iExponent, vreinterpretq_s32_u32(valueIsZero));
+ result = vbslq_f32(valueIsZero, value.simdInternal_, result);
+ }
+
+ exponent->simdInternal_ = iExponent;
+ return { result };
}
template<MathOptimization opt = MathOptimization::Safe>
const float64x2_t half = vdupq_n_f64(0.5);
int64x2_t iExponent;
- iExponent = vandq_s64(int64x2_t(value.simdInternal_), int64x2_t(exponentMask));
- iExponent = vsubq_s64(vshrq_n_s64(iExponent, 52), exponentBias);
+ iExponent = vandq_s64(int64x2_t(value.simdInternal_), int64x2_t(exponentMask));
+ iExponent = vsubq_s64(vshrq_n_s64(iExponent, 52), exponentBias);
+
+ float64x2_t result = float64x2_t(vorrq_s64(
+ vandq_s64(int64x2_t(value.simdInternal_), int64x2_t(mantissaMask)), int64x2_t(half)));
+
+ if (opt == MathOptimization::Safe)
+ {
+ uint64x2_t valueIsZero = vceqq_f64(value.simdInternal_, vdupq_n_f64(0.0));
+ iExponent = vbicq_s64(iExponent, int64x2_t(valueIsZero));
+ result = vbslq_f64(valueIsZero, value.simdInternal_, result);
+ }
+
exponent->simdInternal_ = vmovn_s64(iExponent);
- return { float64x2_t(vorrq_s64(
- vandq_s64(int64x2_t(value.simdInternal_), int64x2_t(mantissaMask)), int64x2_t(half))) };
+ return { result };
}
template<MathOptimization opt = MathOptimization::Safe>
svint64_t iExponent;
iExponent = svand_s64_x(pg, svreinterpret_s64_f64(value.simdInternal_), exponentMask);
- // iExponent = svsub_s64_x(pg, svlsr_n_s64_x(pg, iExponent, 52), exponentBias);
iExponent = svsub_s64_x(
pg, svreinterpret_s64_u64(svlsr_n_u64_x(pg, svreinterpret_u64_s64(iExponent), 52)), exponentBias);
- exponent->simdInternal_ = iExponent;
- return { svreinterpret_f64_s64(
+ svfloat64_t result = svreinterpret_f64_s64(
svorr_s64_x(pg,
svand_s64_x(pg, svreinterpret_s64_f64(value.simdInternal_), mantissaMask),
- svreinterpret_s64_f64(half))) };
+ svreinterpret_s64_f64(half)));
+
+ if (opt == MathOptimization::Safe)
+ {
+ svbool_t valueIsZero = svcmpeq_n_f64(pg, value.simdInternal_, 0.0);
+ iExponent = svsel_s64(valueIsZero, svdup_s64(0), iExponent);
+ result = svsel_f64(valueIsZero, value.simdInternal_, result);
+ }
+
+ exponent->simdInternal_ = iExponent;
+ return { result };
}
template<MathOptimization opt = MathOptimization::Safe>
iExponent = svand_s32_x(pg, svreinterpret_s32_f32(value.simdInternal_), exponentMask);
iExponent = svsub_s32_x(
pg, svreinterpret_s32_u32(svlsr_n_u32_x(pg, svreinterpret_u32_s32(iExponent), 23)), exponentBias);
- exponent->simdInternal_ = iExponent;
- return { svreinterpret_f32_s32(
+ svfloat32_t result = svreinterpret_f32_s32(
svorr_s32_x(pg,
svand_s32_x(pg, svreinterpret_s32_f32(value.simdInternal_), mantissaMask),
- svreinterpret_s32_f32(half))) };
+ svreinterpret_s32_f32(half)));
+
+ if (opt == MathOptimization::Safe)
+ {
+ svbool_t valueIsZero = svcmpeq_n_f32(pg, value.simdInternal_, 0.0F);
+ iExponent = svsel_s32(valueIsZero, svdup_s32(0), iExponent);
+ result = svsel_f32(valueIsZero, value.simdInternal_, result);
+ }
+
+ exponent->simdInternal_ = iExponent;
+ return { result };
}
template<MathOptimization opt = MathOptimization::Safe>
GMX_UNUSED_VALUE(sampletime);
#else
# if ((defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__PATHSCALE__) || defined(__PGIC__)) \
- && defined(__x86_64__) && !defined(_CRAYC))
+ && defined(__x86_64__) && !defined(__ILP32__) && !defined(_CRAYC))
long gmx_unused tmp;
int cpuid1;
int gmx_unused cpuid2;
*
* \throws std::bad_alloc if out of memory.
*/
- template<typename T, typename = std::enable_if_t<!std::is_same_v<T, Any>>>
- explicit Any(T&& value) : content_(new Content<std::decay_t<T>>(std::forward<T>(value)))
+ template<typename T, typename = std::enable_if_t<!std::is_same<T, Any>::value>>
+ explicit Any(T&& value) :
+ content_(new Content<typename std::decay<T>::type>(std::forward<T>(value)))
{
}
/*! \brief
else
{
GMX_RELEASE_ASSERT(false, "Unknown GPU configuration");
+ return "impossible";
}
}
else
dumpKeyValueTree(writer, value.asObject());
writer->wrapperSettings().setIndent(oldIndent);
}
+ else if (value.isArray()
+ && std::all_of(value.asArray().values().begin(),
+ value.asArray().values().end(),
+ [](const auto& elem) { return elem.isObject(); }))
+ {
+ // Array containing only objects
+ writer->writeString(prop.key());
+ writer->writeLine(":");
+ int oldIndent = writer->wrapperSettings().indent();
+ writer->wrapperSettings().setIndent(oldIndent + 2);
+ for (const auto& elem : value.asArray().values())
+ {
+ dumpKeyValueTree(writer, elem.asObject());
+ }
+ writer->wrapperSettings().setIndent(oldIndent);
+ }
else
{
int indent = writer->wrapperSettings().indent();
writer->writeString("[");
for (const auto& elem : value.asArray().values())
{
- GMX_RELEASE_ASSERT(!elem.isObject() && !elem.isArray(),
- "Arrays of objects not currently implemented");
+ GMX_RELEASE_ASSERT(
+ !elem.isObject() && !elem.isArray(),
+ "Only arrays of simple types and array of objects are implemented. "
+ "Arrays of arrays and mixed arrays are not supported.");
writer->writeString(" ");
writer->writeString(simpleValueToString(elem));
}
add_library(fahcore $<TARGET_OBJECTS:mdrun_objlib>)
target_link_libraries(fahcore PRIVATE ${GMX_COMMON_LIBRARIES} legacy_api)
elseif(GMX_BUILD_MDRUN_ONLY)
+ message(STATUS "The mdrun-only build is deprecated")
add_executable(mdrun-only $<TARGET_OBJECTS:mdrun_objlib> mdrun_main.cpp)
gmx_target_compile_options(mdrun-only)
target_include_directories(mdrun-only SYSTEM BEFORE PRIVATE ${PROJECT_SOURCE_DIR}/src/external/thread_mpi/include)
gmx_add_gtest_executable(${exename}
CPP_SOURCE_FILES
+ checkpoint.cpp
exactcontinuation.cpp
grompp.cpp
initialconstraints.cpp
ewaldsurfaceterm.cpp
multiple_time_stepping.cpp
orires.cpp
- simulator.cpp
swapcoords.cpp
tabulated_bonded_interactions.cpp
# pseudo-library for code for mdrun
# TODO: Link specific modules: topology
target_link_libraries(${exename} PRIVATE legacy_modules)
gmx_register_gtest_test(${testname} ${exename} OPENMP_THREADS 2 INTEGRATION_TEST IGNORE_LEAKS)
+
+# End-to-end tests comparing different simulator code paths
+set(testname "MdrunSimulatorComparison")
+set(exename "mdrun-simulator-comparison-test")
+
+gmx_add_gtest_executable(${exename}
+ CPP_SOURCE_FILES
+ # files with code for tests
+ simulator.cpp
+ # pseudo-library for code for mdrun
+ $<TARGET_OBJECTS:mdrun_objlib>
+ )
+target_link_libraries(${exename} PRIVATE mdrun_test_infrastructure)
+gmx_register_gtest_test(${testname} ${exename} OPENMP_THREADS 2 INTEGRATION_TEST IGNORE_LEAKS)
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2020, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * 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.
+ */
+
+/*! \internal \file
+ * \brief Tests for checkpoint writing sanity checks
+ *
+ * Checks that final checkpoint is equal to final trajectory output.
+ *
+ * \author Pascal Merz <pascal.merz@me.com>
+ * \ingroup module_mdrun_integration_tests
+ */
+#include "gmxpre.h"
+
+#include "config.h"
+
+#include "gromacs/utility/strconvert.h"
+#include "gromacs/utility/stringutil.h"
+
+#include "testutils/simulationdatabase.h"
+
+#include "moduletest.h"
+#include "simulatorcomparison.h"
+#include "trajectoryreader.h"
+
+namespace gmx::test
+{
+namespace
+{
+
+class CheckpointCoordinatesSanityChecks :
+ public MdrunTestFixture,
+ public ::testing::WithParamInterface<std::tuple<std::string, std::string, std::string, std::string>>
+{
+public:
+ void runSimulation(MdpFieldValues mdpFieldValues,
+ int numSteps,
+ const std::string& trrFileName,
+ const std::string& cptFileName)
+ {
+ mdpFieldValues["nsteps"] = toString(numSteps);
+ // Trajectories have the initial and the last frame
+ mdpFieldValues["nstxout"] = toString(numSteps);
+ mdpFieldValues["nstvout"] = toString(numSteps);
+ mdpFieldValues["nstfout"] = toString(0);
+
+ // Run grompp
+ runner_.useStringAsMdpFile(prepareMdpFileContents(mdpFieldValues));
+ runGrompp(&runner_);
+
+ // Do first mdrun
+ runner_.fullPrecisionTrajectoryFileName_ = trrFileName;
+ runMdrun(&runner_, { { "-cpo", cptFileName } });
+ }
+
+ static void compareCptAndTrr(const std::string& trrFileName,
+ const std::string& cptFileName,
+ const TrajectoryComparison& trajectoryComparison)
+ {
+ TrajectoryFrameReader trrReader(trrFileName);
+ TrajectoryFrameReader cptReader(cptFileName);
+ // Checkpoint has at least one frame
+ EXPECT_TRUE(cptReader.readNextFrame());
+ // Trajectory has at least two frames
+ EXPECT_TRUE(trrReader.readNextFrame());
+ EXPECT_NO_THROW(trrReader.frame());
+ EXPECT_TRUE(trrReader.readNextFrame());
+
+ // Now compare frames
+ trajectoryComparison(cptReader.frame(), trrReader.frame());
+
+ // Files had exactly 1 / 2 frames
+ EXPECT_FALSE(cptReader.readNextFrame());
+ EXPECT_FALSE(trrReader.readNextFrame());
+ }
+};
+
+TEST_P(CheckpointCoordinatesSanityChecks, WithinTolerances)
+{
+ const auto& params = GetParam();
+ const auto& simulationName = std::get<0>(params);
+ const auto& integrator = std::get<1>(params);
+ const auto& temperatureCoupling = std::get<2>(params);
+ const auto& pressureCoupling = std::get<3>(params);
+
+ // Specify how trajectory frame matching must work.
+ TrajectoryFrameMatchSettings trajectoryMatchSettings{ true,
+ true,
+ true,
+ ComparisonConditions::MustCompare,
+ ComparisonConditions::MustCompare,
+ ComparisonConditions::NoComparison,
+ MaxNumFrames::compareAllFrames() };
+ if (integrator == "md-vv")
+ {
+ // When using md-vv and modular simulator, the velocities are expected to be off by
+ // 1/2 dt between checkpoint (top of the loop) and trajectory (full time step state)
+ trajectoryMatchSettings.velocitiesComparison = ComparisonConditions::NoComparison;
+ }
+ const TrajectoryTolerances trajectoryTolerances{
+ defaultRealTolerance(), defaultRealTolerance(), defaultRealTolerance(), defaultRealTolerance()
+ };
+
+ const auto mdpFieldValues =
+ prepareMdpFieldValues(simulationName, integrator, temperatureCoupling, pressureCoupling);
+ runner_.useTopGroAndNdxFromDatabase(simulationName);
+ // Set file names
+ const auto cptFileName = fileManager_.getTemporaryFilePath(".cpt");
+ const auto trrFileName = fileManager_.getTemporaryFilePath(".trr");
+
+ SCOPED_TRACE(formatString(
+ "Checking the sanity of the checkpointed coordinates using system '%s' "
+ "with integrator '%s', '%s' temperature coupling, and '%s' pressure coupling ",
+ simulationName.c_str(),
+ integrator.c_str(),
+ temperatureCoupling.c_str(),
+ pressureCoupling.c_str()));
+
+ SCOPED_TRACE("End of trajectory sanity");
+ // Running a few steps - we expect the checkpoint to be equal
+ // to the final configuration
+ runSimulation(mdpFieldValues, 16, trrFileName, cptFileName);
+ compareCptAndTrr(trrFileName, cptFileName, { trajectoryMatchSettings, trajectoryTolerances });
+}
+
+#if !GMX_GPU_OPENCL
+INSTANTIATE_TEST_CASE_P(CheckpointCoordinatesAreSane,
+ CheckpointCoordinatesSanityChecks,
+ ::testing::Combine(::testing::Values("spc2"),
+ ::testing::Values("md", "md-vv"),
+ ::testing::Values("no"),
+ ::testing::Values("no")));
+#else
+INSTANTIATE_TEST_CASE_P(DISABLED_CheckpointCoordinatesAreSane,
+ CheckpointCoordinatesSanityChecks,
+ ::testing::Combine(::testing::Values("spc2"),
+ ::testing::Values("md", "md-vv"),
+ ::testing::Values("no"),
+ ::testing::Values("no")));
+#endif
+
+} // namespace
+} // namespace gmx::test
const bool isTCouplingCompatibleWithModularSimulator =
(temperatureCoupling == "no" || temperatureCoupling == "v-rescale"
|| temperatureCoupling == "berendsen");
+ // GPU update is not compatible with modular simulator
+ const bool isGpuUpdateRequested = (getenv("GMX_FORCE_UPDATE_DEFAULT_GPU") != nullptr);
if (integrator == "md-vv" && pressureCoupling == "parrinello-rahman"
- && (isModularSimulatorExplicitlyDisabled || !isTCouplingCompatibleWithModularSimulator))
+ && (isModularSimulatorExplicitlyDisabled || !isTCouplingCompatibleWithModularSimulator
+ || isGpuUpdateRequested))
{
// Under md-vv, Parrinello-Rahman is only implemented for the modular simulator
return;
const auto maxNumWarnings = std::get<1>(GetParam());
const auto& interactionsList = std::get<2>(GetParam());
- // TODO In similar tests, we are checking if the tests
- // can be run with the number of MPI ranks available
+ // As these tests check reproducibility, we restrict the maximum number
+ // of ranks to allow us to keep the tolerances tight. See also #3741.
+ const int numRanksAvailable = getNumberOfTestMpiRanks();
+ constexpr int maxNumRanks = 8;
+ if (numRanksAvailable > maxNumRanks)
+ {
+ fprintf(stdout,
+ "The FEP tests cannot run with %d ranks.\n"
+ "The maximum number of ranks supported is %d.",
+ numRanksAvailable,
+ maxNumRanks);
+ return;
+ }
SCOPED_TRACE(formatString("Comparing FEP simulation '%s' to reference", simulationName.c_str()));
- // Tolerance set to pass with identical code version and a range of different test setups
+ // Tolerance set to pass with identical code version and a range of different test setups for most tests
const auto defaultEnergyTolerance = relativeToleranceAsFloatingPoint(50.0, GMX_DOUBLE ? 1e-5 : 1e-4);
+ // Some simulations are significantly longer, so they need a larger tolerance
+ const auto longEnergyTolerance = relativeToleranceAsFloatingPoint(50.0, GMX_DOUBLE ? 1e-4 : 1e-3);
+ const bool isLongSimulation = (simulationName == "expanded");
+ const auto energyTolerance = isLongSimulation ? longEnergyTolerance : defaultEnergyTolerance;
- EnergyTermsToCompare energyTermsToCompare{ { interaction_function[F_EPOT].longname,
- defaultEnergyTolerance } };
+ EnergyTermsToCompare energyTermsToCompare{ { interaction_function[F_EPOT].longname, energyTolerance } };
for (const auto& interaction : interactionsList)
{
energyTermsToCompare.emplace(interaction_function[interaction].longname, defaultEnergyTolerance);
ComparisonConditions::NoComparison,
ComparisonConditions::MustCompare };
TrajectoryTolerances trajectoryTolerances = TrajectoryComparison::s_defaultTrajectoryTolerances;
+ trajectoryTolerances.forces = relativeToleranceAsFloatingPoint(100.0, GMX_DOUBLE ? 5.0e-5 : 5.0e-4);
// Build the functor that will compare reference and test
// trajectory frames in the chosen way.
runner_.dhdlFileName_ = simulationDhdlFileName;
runMdrun(&runner_);
- // Currently used tests write trajectory (x/v/f) frames every 20 steps.
- // Testing more than the first force frame is only feasible in double precision
- // using a single rank.
- // Note that this only concerns trajectory frames, energy frames are checked
- // in all cases.
- const bool testAllTrajectoryFrames = (GMX_DOUBLE && (getNumberOfTestMpiRanks() == 1));
+ /* Currently used tests write trajectory (x/v/f) frames every 20 steps.
+ * Except for the expanded ensemble test, all tests run for 20 steps total.
+ * As the tolerances are relatively strict, we need to restrict the number of
+ * force frames we can expect to match.
+ * Testing more than the first force frame is only feasible in double precision
+ * using a single rank.
+ * Testing one force frame is only feasible in double precision.
+ * Note that this only concerns trajectory frames, energy frames are checked
+ * in all cases. */
+ const bool testTwoTrajectoryFrames = (GMX_DOUBLE && (getNumberOfTestMpiRanks() == 1));
+ const bool testOneTrajectoryFrame = GMX_DOUBLE;
// Compare simulation results
TestReferenceData refData;
// Check that the energies agree with the refdata within tolerance.
checkEnergiesAgainstReferenceData(simulationEdrFileName, energyTermsToCompare, &rootChecker);
// Check that the trajectories agree with the refdata within tolerance.
- if (testAllTrajectoryFrames)
+ if (testTwoTrajectoryFrames)
{
- checkTrajectoryAgainstReferenceData(simulationTrajectoryFileName, trajectoryComparison, &rootChecker);
+ checkTrajectoryAgainstReferenceData(
+ simulationTrajectoryFileName, trajectoryComparison, &rootChecker, MaxNumFrames(2));
}
- else
+ else if (testOneTrajectoryFrame)
{
checkTrajectoryAgainstReferenceData(
simulationTrajectoryFileName, trajectoryComparison, &rootChecker, MaxNumFrames(1));
}
+ else
+ {
+ checkTrajectoryAgainstReferenceData(
+ simulationTrajectoryFileName, trajectoryComparison, &rootChecker, MaxNumFrames(0));
+ }
if (File::exists(simulationDhdlFileName, File::returnFalseOnError))
{
TextInputFile dhdlFile(simulationDhdlFileName);
return;
}
+ const std::string envVariableModSimOn = "GMX_USE_MODULAR_SIMULATOR";
+ const std::string envVariableModSimOff = "GMX_DISABLE_MODULAR_SIMULATOR";
+
+ GMX_RELEASE_ASSERT(
+ environmentVariable == envVariableModSimOn || environmentVariable == envVariableModSimOff,
+ ("Expected tested environment variable to be " + envVariableModSimOn + " or " + envVariableModSimOff)
+ .c_str());
+
const auto hasConservedField = !(tcoupling == "no" && pcoupling == "no");
SCOPED_TRACE(formatString(
simulationName.c_str(), integrator.c_str(), tcoupling.c_str(), pcoupling.c_str());
EnergyTermsToCompare energyTermsToCompare{ {
- { interaction_function[F_EPOT].longname, relativeToleranceAsPrecisionDependentUlp(10.0, 100, 80) },
- { interaction_function[F_EKIN].longname, relativeToleranceAsPrecisionDependentUlp(60.0, 100, 80) },
+ { interaction_function[F_EPOT].longname, relativeToleranceAsPrecisionDependentUlp(60.0, 200, 160) },
+ { interaction_function[F_EKIN].longname, relativeToleranceAsPrecisionDependentUlp(60.0, 200, 160) },
{ interaction_function[F_PRES].longname,
relativeToleranceAsPrecisionDependentFloatingPoint(10.0, 0.01, 0.001) },
} };
runner_.useStringAsMdpFile(prepareMdpFileContents(mdpFieldValues));
runGrompp(&runner_);
- // Backup current state of environment variable and unset it
- const char* environmentVariableBackup = getenv(environmentVariable.c_str());
- gmxUnsetenv(environmentVariable.c_str());
+ // Backup current state of both environment variables and unset them
+ const char* environmentVariableBackupOn = getenv(envVariableModSimOn.c_str());
+ const char* environmentVariableBackupOff = getenv(envVariableModSimOff.c_str());
+ gmxUnsetenv(envVariableModSimOn.c_str());
+ gmxUnsetenv(envVariableModSimOff.c_str());
// Do first mdrun
runner_.fullPrecisionTrajectoryFileName_ = simulator1TrajectoryFileName;
runner_.edrFileName_ = simulator1EdrFileName;
runMdrun(&runner_);
- // Set environment variable
+ // Set tested environment variable
const int overWriteEnvironmentVariable = 1;
gmxSetenv(environmentVariable.c_str(), "ON", overWriteEnvironmentVariable);
runner_.edrFileName_ = simulator2EdrFileName;
runMdrun(&runner_);
- // Reset or unset environment variable to leave further tests undisturbed
- if (environmentVariableBackup != nullptr)
+ // Unset tested environment variable
+ gmxUnsetenv(environmentVariable.c_str());
+ // Reset both environment variables to leave further tests undisturbed
+ if (environmentVariableBackupOn != nullptr)
{
- // set environment variable
- gmxSetenv(environmentVariable.c_str(), environmentVariableBackup, overWriteEnvironmentVariable);
+ gmxSetenv(environmentVariable.c_str(), environmentVariableBackupOn, overWriteEnvironmentVariable);
}
- else
+ if (environmentVariableBackupOff != nullptr)
{
- // unset environment variable
- gmxUnsetenv(environmentVariable.c_str());
+ gmxSetenv(environmentVariable.c_str(), environmentVariableBackupOff, overWriteEnvironmentVariable);
}
// Compare simulation results