AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: true
-BinPackArguments: true
+BinPackArguments: false
BinPackParameters: false
BraceWrapping:
AfterClass: true
- local: '/admin/gitlab-ci/global.gitlab-ci.yml'
- local: '/admin/gitlab-ci/rules.gitlab-ci.yml'
# gmxapi Python package.
- - local: '/admin/gitlab-ci/python-gmxapi.gitlab-ci.yml'
+ - local: '/admin/gitlab-ci/python-gmxapi01.gitlab-ci.yml'
+ - local: '/admin/gitlab-ci/python-gmxapi02.gitlab-ci.yml'
+ - local: '/admin/gitlab-ci/python-gmxapi03.gitlab-ci.yml'
# Further API validation and usability of sample gmxapi extension package.
- local: '/admin/gitlab-ci/sample_restraint.gitlab-ci.yml'
# API regression testing using sample gmxapi extension package.
set(CMAKE_PREFIX_PATH "" CACHE STRING "Extra locations to search for external libraries and tools (give directory without lib, bin, or include)")
-# Fujitsu only has SIMD in double precision, so this will be faster
-gmx_set_boolean(GMX_DOUBLE_DEFAULT GMX_TARGET_FUJITSU_SPARC64)
-option(GMX_DOUBLE "Use double precision (much slower, use only if you really need it)" ${GMX_DOUBLE_DEFAULT})
-option(GMX_RELAXED_DOUBLE_PRECISION "Accept single precision 1/sqrt(x) when using Fujitsu HPC-ACE SIMD" OFF)
-mark_as_advanced(GMX_RELAXED_DOUBLE_PRECISION)
+option(GMX_DOUBLE "Use double precision (much slower, use only if you really need it)" OFF)
option(GMX_MPI "Build a parallel (message-passing) version of GROMACS" OFF)
option(GMX_THREAD_MPI "Build a thread-MPI-based multithreaded version of GROMACS (not compatible with MPI)" ON)
-gmx_dependent_option(
- GMX_MPI_IN_PLACE
- "Enable MPI_IN_PLACE for MPIs that have it defined"
- ON
- GMX_MPI)
-mark_as_advanced(GMX_MPI_IN_PLACE)
option(GMX_MIMIC "Enable MiMiC QM/MM interface (CPMD is required)" OFF)
GMX_SIMD
"SIMD instruction set for CPU kernels and compiler optimization"
"AUTO"
- AUTO None SSE2 SSE4.1 AVX_128_FMA AVX_256 AVX2_256 AVX2_128 AVX_512 AVX_512_KNL MIC ARM_NEON ARM_NEON_ASIMD ARM_SVE IBM_VMX IBM_VSX Sparc64_HPC_ACE Reference)
+ AUTO None SSE2 SSE4.1 AVX_128_FMA AVX_256 AVX2_256 AVX2_128 AVX_512 AVX_512_KNL ARM_NEON_ASIMD ARM_SVE IBM_VSX Reference)
-if(GMX_TARGET_MIC)
- set(GMX_FFT_LIBRARY_DEFAULT "mkl")
-else()
- set(GMX_FFT_LIBRARY_DEFAULT "fftw3")
-endif()
+set(GMX_FFT_LIBRARY_DEFAULT "fftw3")
gmx_option_multichoice(
GMX_FFT_LIBRARY
option(GMX_USE_TNG "Use the TNG library for trajectory I/O" ON)
-option(GMX_BUILD_MDRUN_ONLY "Build and install only the mdrun binary" OFF)
-
option(GMX_CYCLE_SUBCOUNTERS "Enable cycle subcounters to get a more detailed cycle timings" OFF)
mark_as_advanced(GMX_CYCLE_SUBCOUNTERS)
# want such variables to always have a definition, because #if is more
# robust than #ifdef. So, we put this value on the compiler command
# line in all cases.
-#
-# GMX_RELAXED_DOUBLE_PRECISION does not need to be handled here,
-# because no installed header needs it
if(GMX_DOUBLE)
set(GMX_DOUBLE_VALUE 1)
else()
gmx_set_boolean(GMX_USE_NICE "HAVE_UNISTD_H AND HAVE_NICE")
-# Management of GROMACS options for specific toolchains should go
-# here. Because the initial settings for some of the main options have
-# already happened, but things like library detection and MPI compiler
-# feature detection have not, the docstrings for any over-rides of
-# GROMACS defaults or user settings will make sense. Also, any
-# toolchain-related reasons for choosing whether to detect various
-# things can be sorted out now, before the detection takes place.
-if(GMX_TARGET_FUJITSU_SPARC64)
- include(gmxManageFujitsuSparc64)
-endif()
-
########################################################################
#Process MPI settings
########################################################################
if(GMX_THREAD_MPI)
# enable MPI functions
tmpi_enable()
- set(MPI_IN_PLACE_EXISTS 1)
endif()
# If atomics are manually disabled a define is needed because atomics.h doesn't depend on config.h
if (TMPI_ATOMICS_DISABLED)
# Our own GROMACS tests
########################################################################
-include_directories(BEFORE ${CMAKE_SOURCE_DIR}/src)
include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/src/external)
-# Required for config.h, maybe should only be set in src/CMakeLists.txt
-include_directories(BEFORE ${CMAKE_BINARY_DIR}/src)
include(gmxTestInlineASM)
gmx_test_inline_asm_gcc_x86(GMX_X86_GCC_INLINE_ASM)
option(GMX_PYTHON_PACKAGE "Configure gmxapi Python package" OFF)
mark_as_advanced(GMX_PYTHON_PACKAGE)
-if (NOT GMX_BUILD_MDRUN_ONLY)
- find_package(ImageMagick QUIET COMPONENTS convert)
- include(gmxTestImageMagick)
- GMX_TEST_IMAGEMAGICK(IMAGE_CONVERT_POSSIBLE)
- # TODO: Resolve circular dependency between docs, gromacs, and python_packaging
- add_subdirectory(docs)
- add_subdirectory(share)
- add_subdirectory(scripts)
-endif()
+find_package(ImageMagick QUIET COMPONENTS convert)
+include(gmxTestImageMagick)
+GMX_TEST_IMAGEMAGICK(IMAGE_CONVERT_POSSIBLE)
+# TODO: Resolve circular dependency between docs, gromacs, and python_packaging
+add_subdirectory(docs)
+add_subdirectory(share)
+add_subdirectory(scripts)
add_subdirectory(api)
add_subdirectory(src)
add_subdirectory(tests)
endif()
-if(GMX_PYTHON_PACKAGE AND NOT GMX_BUILD_MDRUN_ONLY)
+if(GMX_PYTHON_PACKAGE)
add_subdirectory(python_packaging)
endif()
--- /dev/null
+#!/usr/bin/env bash
+#
+# Build, install, and test the gmxapi 0.2 Python package developed with
+# GROMACS 2021.
+#
+# This script assumes an activated Python venv with the
+# gmxapi dependencies already installed, with `python` resolvable by the shell
+# to the appropriate Python interpreter.
+#
+# This script is intended to support automated GROMACS testing infrastructure,
+# and may be removed without notice.
+#
+# WARNING: This script assumes OpenMPI mpiexec. Syntax for launch wrappers from
+# other implementations will need different syntax, and we should get a
+# MPIRUNNER from the environment, or something.
+
+# Make sure the script errors if any commands error.
+set -e
+
+# Create "sdist" source distribution archive.
+pushd python_packaging/src
+ # TODO: Remove extraneous environment variable with resolution of #3273
+ # Ref: https://redmine.gromacs.org/issues/3273
+ GMXTOOLCHAINDIR=$INSTALL_DIR/share/cmake/gromacs \
+ python setup.py sdist
+ # TODO: Identify SDIST
+
+ # Build and install from sdist.
+ # Note that tool chain may be provided differently in GROMACS 2020 and 2021.
+ GMXTOOLCHAINDIR=$INSTALL_DIR/share/cmake/gromacs \
+ python -m pip install \
+ --no-cache-dir \
+ --no-deps \
+ --no-index \
+ --no-build-isolation \
+ dist/gmxapi*
+ # TODO: Build and install from $SDIST instead of wildcard.
+
+popd
+
+# Run Python unit tests.
+python -m pytest python_packaging/src/test --junitxml=$PY_UNIT_TEST_XML --threads=2
+
+# Note: Multiple pytest processes getting --junitxml output file argument
+# may cause problems, so we set the option on only one of the launched processes.
+# See also Multiple Instruction Multiple Data Model for OpenMPI mpirun:
+# https://www.open-mpi.org/doc/v3.0/man1/mpiexec.1.php
+PROGRAM=(`which python` -m mpi4py -m pytest \
+ -p no:cacheprovider \
+ $PWD/python_packaging/src/test \
+ --threads=1)
+# shellcheck disable=SC2068
+if [ -x `which mpiexec` ]; then
+ PYTHONDONTWRITEBYTECODE=1 \
+ mpiexec --allow-run-as-root \
+ -x OMP_NUM_THREADS=1 \
+ --mca opal_warn_on_missing_libcuda 0 \
+ --mca orte_base_help_aggregate 0 \
+ -n 1 ${PROGRAM[@]} --junitxml=$PLUGIN_MPI_TEST_XML : \
+ -n 1 ${PROGRAM[@]}
+fi
+
+# Run Python acceptance tests.
+python -m pytest python_packaging/test --junitxml=$PY_ACCEPTANCE_TEST_XML --threads=2
+
+# Note: Multiple pytest processes getting --junitxml output file argument
+# may cause problems, so we set the option on only one of the launched processes.
+# See also Multiple Instruction Multiple Data Model for OpenMPI mpirun:
+# https://www.open-mpi.org/doc/v3.0/man1/mpiexec.1.php
+PROGRAM=(`which python` -m mpi4py -m pytest \
+ -p no:cacheprovider \
+ $PWD/python_packaging/test \
+ --threads=1)
+# shellcheck disable=SC2068
+if [ -x `which mpiexec` ]; then
+ PYTHONDONTWRITEBYTECODE=1 \
+ mpiexec --allow-run-as-root \
+ -x OMP_NUM_THREADS=1 \
+ --mca opal_warn_on_missing_libcuda 0 \
+ --mca orte_base_help_aggregate 0 \
+ -n 1 ${PROGRAM[@]} --junitxml=$PLUGIN_MPI_TEST_XML : \
+ -n 1 ${PROGRAM[@]}
+fi
args[${#args[@]}]="--gcc 8 --cuda 11.0 --clfft --mpi openmpi"
args[${#args[@]}]="--gcc 7 --cuda 10.2 --clfft --mpi openmpi --ubuntu 18.04"
args[${#args[@]}]="--llvm 8 --tsan"
+args[${#args[@]}]="--llvm 11 --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.1"
-args[${#args[@]}]="--llvm --doxygen"
+args[${#args[@]}]="--llvm --doxygen --mpi openmpi --venvs 3.7.7"
echo "Building the following images."
for arg_string in "${args[@]}"; do
for arg_string in "${args[@]}"; do
# shellcheck disable=SC2086
- tag=$(python3 -m utility $arg_string):release-2021
+ tag=$(python3 -m utility $arg_string)
tags[${#tags[@]}]=$tag
# shellcheck disable=SC2086
python3 $SCRIPT $arg_string | docker build -t $tag -
def get_compiler(args, compiler_build_stage: hpccm.Stage = None) -> bb_base:
# Compiler
- if args.icc is not None:
- raise RuntimeError('Intel compiler toolchain recipe not implemented yet')
-
if args.llvm is not None:
# Build our own version instead to get TSAN + OMP
if args.tsan is not None:
compiler = compiler_build_stage.runtime(_from='oneapi')
# Prepare the toolchain (needed only for builds done within the Dockerfile, e.g.
# OpenMPI builds, which don't currently work for other reasons)
- oneapi_toolchain = hpccm.toolchain(CC='/opt/intel/oneapi/compiler/latest/linux/bin/intel64/icc',
- CXX='/opt/intel/oneapi/compiler/latest/linux/bin/intel64/icpc')
+ oneapi_toolchain = hpccm.toolchain(CC=f'/opt/intel/oneapi/compiler/{args.oneapi}/linux/bin/intel64/icx',
+ CXX=f'/opt/intel/oneapi/compiler/{args.oneapi}/linux/bin/intel64/icpx')
setattr(compiler, 'toolchain', oneapi_toolchain)
else:
This stage is isolated so that its installed components are minimized in the
final image (chiefly /opt/intel) and its environment setup script can be
sourced. This also helps with rebuild time and final image size.
-
- Note that the ICC compiler inside oneAPI on linux also needs
- gcc to build other components and provide libstdc++.
"""
if not isinstance(output_stages, collections.abc.MutableMapping):
raise RuntimeError('Need output_stages container.')
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-{}'.format(version),
- 'intel-oneapi-openmp-{}'.format(version),
- 'intel-oneapi-mkl-{}'.format(version),
- 'intel-oneapi-mkl-devel-{}'.format(version)]
+ ospackages=[f'intel-oneapi-dpcpp-cpp-{version}',
+ f'intel-oneapi-openmp-{version}',
+ f'intel-oneapi-mkl-{version}',
+ f'intel-oneapi-mkl-devel-{version}']
)
# Ensure that all bash shells on the final container will have access to oneAPI
oneapi_stage += hpccm.primitives.shell(
- commands=['echo "source /opt/intel/oneapi/setvars.sh" >> /etc/bash.bashrc']
+ commands=['echo "source /opt/intel/oneapi/setvars.sh" >> /etc/bash.bashrc',
+ 'unlink /opt/intel/oneapi/compiler/latest',
+ f'ln -sf /opt/intel/oneapi/compiler/{version} /opt/intel/oneapi/compiler/latest']
)
setattr(oneapi_stage, 'runtime', oneapi_runtime)
pyenv = '$HOME/.pyenv/bin/pyenv'
- py_ver = '{}.{}'.format(major, minor)
- venv_path = '$HOME/venv/py{}'.format(py_ver)
- commands = ['$({pyenv} prefix `{pyenv} whence python{py_ver}`)/bin/python -m venv {path}'.format(
- pyenv=pyenv,
- py_ver=py_ver,
- path=venv_path
- )]
-
- commands.append('{path}/bin/python -m pip install --upgrade pip setuptools'.format(
- path=venv_path
- ))
+ py_ver = f'{major}.{minor}'
+ venv_path = f'$HOME/venv/py{py_ver}'
+ commands = [f'$({pyenv} prefix `{pyenv} whence python{py_ver}`)/bin/python -m venv {venv_path}']
+
+ commands.append(f'{venv_path}/bin/python -m pip install --upgrade pip setuptools')
# Install dependencies for building and testing gmxapi Python package.
# WARNING: Please keep this list synchronized with python_packaging/requirements-test.txt
# TODO: Get requirements.txt from an input argument.
- commands.append("""{path}/bin/python -m pip install --upgrade \
+ commands.append(f"""{venv_path}/bin/python -m pip install --upgrade \
'cmake>=3.13' \
'flake8>=3.7.7' \
+ 'gcovr>=4.2' \
'mpi4py>=3.0.3' \
'networkx>=2.0' \
'numpy>=1' \
'pip>=10.1' \
+ 'Pygments>=2.2.0' \
'pytest>=3.9' \
'setuptools>=42' \
- 'scikit-build>=0.10'""".format(path=venv_path))
+ 'scikit-build>=0.10' \
+ 'Sphinx>=1.6.3' \
+ 'sphinxcontrib-plantuml>=0.14'""")
# TODO: Remove 'importlib_resources' dependency when Python >=3.7 is required.
if minor == 6:
- commands.append("""{path}/bin/python -m pip install --upgrade \
- 'importlib_resources'""".format(path=venv_path))
+ commands.append(f"""{venv_path}/bin/python -m pip install --upgrade \
+ 'importlib_resources'""")
return commands
"""echo 'eval "$(pyenv init -)"' >> $HOME/.bashrc""",
"""echo 'eval "$(pyenv virtualenv-init -)"' >> $HOME/.bashrc"""])
pyenv = '$HOME/.pyenv/bin/pyenv'
- commands = ['PYTHON_CONFIGURE_OPTS="--enable-shared" {pyenv} install -s {version}'.format(
- pyenv=pyenv,
- version=str(version))]
+ commands = [f'PYTHON_CONFIGURE_OPTS="--enable-shared" {pyenv} install -s {version}']
stage += hpccm.primitives.shell(commands=commands)
commands = prepare_venv(version)
return
output_stages['main'] += hpccm.primitives.shell(
commands=['sed -i \'/\"XPS\"/d;/\"PDF\"/d;/\"PS\"/d;/\"EPS\"/d;/disable ghostscript format types/d\' /etc/ImageMagick-6/policy.xml'])
- output_stages['main'] += hpccm.building_blocks.pip(pip='pip3', packages=['sphinx==1.6.1', 'gcovr'])
if input_args.doxygen == '1.8.5':
doxygen_commit = 'ed4ed873ab0e7f15116e2052119a6729d4589f7a'
output_stages['main'] += hpccm.building_blocks.generic_autotools(
'--static'])
else:
version = input_args.doxygen
- archive_name = 'doxygen-{}.linux.bin.tar.gz'.format(version)
- archive_url = 'https://sourceforge.net/projects/doxygen/files/rel-{}/{}'.format(
- version,
- archive_name
- )
- binary_path = 'doxygen-{}/bin/doxygen'.format(version)
+ archive_name = f'doxygen-{version}.linux.bin.tar.gz'
+ archive_url = f'https://sourceforge.net/projects/doxygen/files/rel-{version}/{archive_name}'
+ binary_path = f'doxygen-{version}/bin/doxygen'
commands = [
'mkdir doxygen && cd doxygen',
- 'wget {}'.format(archive_url),
- 'tar xf {} {}'.format(archive_name, binary_path),
- 'cp {} /usr/local/bin/'.format(binary_path),
+ f'wget {archive_url}',
+ f'tar xf {archive_name} {binary_path}',
+ f'cp {binary_path} /usr/local/bin/',
'cd .. && rm -rf doxygen'
]
output_stages['main'] += hpccm.primitives.shell(commands=commands)
for i, cmake in enumerate(args.cmake):
building_blocks['cmake' + str(i)] = hpccm.building_blocks.cmake(
eula=True,
- prefix='/usr/local/cmake-{}'.format(cmake),
+ prefix=f'/usr/local/cmake-{cmake}',
version=cmake)
# Install additional packages early in the build to optimize Docker build layer cache.
stages['main'] += bb
# We always add Python3 and Pip
- stages['main'] += hpccm.building_blocks.python(python3=True, python2=False, devel=True)
- stages['main'] += hpccm.building_blocks.pip(upgrade=True, pip='pip3',
- packages=['pytest', 'networkx', 'numpy'])
+ stages['main'] += hpccm.building_blocks.python(python3=True, python2=False)
# Add documentation requirements (doxygen and sphinx + misc).
if args.doxygen is not None:
compiler_group.add_argument('--llvm', type=str, nargs='?', const='7', default=None,
help='Select LLVM compiler tool chain. '
'Some checking is implemented to avoid incompatible combinations')
-compiler_group.add_argument('--icc', type=int, nargs='?', const=19, default=None,
- help='Select Intel compiler tool chain. '
- 'Some checking is implemented to avoid incompatible combinations')
# TODO currently the installation merely gets the latest beta version of oneAPI,
# not a specific version. GROMACS probably doesn't need to address that until
# oneAPI makes an official release. Also, the resulting container is a mix
if version is not None:
elements.append(distro + '-' + version)
break
- for compiler in ('icc', 'llvm', 'gcc'):
+ for compiler in ('llvm', 'gcc'):
version = getattr(configuration, compiler, None)
if version is not None:
elements.append(compiler + '-' + str(version).split('.')[0])
- .variables:default
- .rules:nightly-only-for-release
cache: {}
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-7-docs:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-7-docs
stage: configure-build
variables:
KUBERNETES_CPU_LIMIT: 1
- .variables:default
- .rules:merge-and-post-merge-acceptance
cache: {}
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-7-docs:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-7-docs
stage: configure-build
variables:
KUBERNETES_CPU_LIMIT: 1
KUBERNETES_CPU_REQUEST: 1
KUBERNETES_MEMORY_REQUEST: 2Gi
- # Always clone the default version for this branch, 2021 in this case
+ # Always clone the default version for this branch, master in this case
script:
- - export REGTESTBRANCH=release-2021
+ - export REGTESTBRANCH=master
- if [[ ! -z $REGRESSIONTESTBRANCH ]] ; then
export REGTESTBRANCH=$REGRESSIONTESTBRANCH ;
echo "Using $REGTESTBRANCH instead of default" ;
cache: {}
# Docker image uploaded to dockerhub by user eriklindahl
# TODO: Get DockerFile for admin/dockerfiles
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-7-docs:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-7-docs
stage: release-package
variables:
KUBERNETES_CPU_LIMIT: 1
- if [[ $GROMACS_RELEASE != "true" ]] ; then
REGTESTNAME=$REGTESTNAME-dev ;
fi
- - export REGTESTBRANCH=release-2021
+ - export REGTESTBRANCH=master
- if [[ $CI_COMMIT_REF_NAME == "master" || $CI_COMMIT_REF_NAME == "release-20"[1-2][0-9] ]] ; then
export REGTESTBRANCH=$CI_COMMIT_REF_NAME ;
fi
- .use-ccache
- .before_script:default
- .docs:build
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-7-docs:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-7-docs
variables:
KUBERNETES_CPU_LIMIT: 4
KUBERNETES_CPU_REQUEST: 2
BUILD_DIR: build-package
release-verify:
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-7-docs:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-7-docs
stage: release-verify
extends:
- .variables:default
- job: webpage:build
variables:
BUILD_DIR: build-docs
+ before_script:
+ - eval $(ssh-agent -s)
+ - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
+ - mkdir -p ~/.ssh
+ - chmod 700 ~/.ssh
+ - ssh-keyscan manual.gromacs.org > ~/.ssh/known_hosts # Force overwrite the known hosts so we only have that one key in it.
+ - chmod 644 ~/.ssh/known_hosts
script:
- tar czf webpage.tar.gz $BUILD_DIR/docs/html/
+ - rsync --chmod=u+rwX,g+rwX,o+rX -av $BUILD_DIR/docs/html/* $BUILD_DIR/docs/html/.[a-z]* pbauer@manual.gromacs.org:/var/www/manual/nightly/
artifacts:
when: always
- .gromacs:base:configure
- .before_script:default
# TODO (#3480) this should be organized more like the current documentation.py script
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-7-docs:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-7-docs
stage: configure-build
cache: {}
variables:
mkdir $BUILD_DIR ;
fi
- cd $BUILD_DIR
+ # Running CMake with the venv activated should not be strictly necessary,
+ # but helps to find and cache self-consistent Python and Sphinx details
+ # without additional hinting. Once CMakeCache.txt exists, the later stages
+ # should work fine without reactivating the venv.
+ - source /root/venv/py3.7/bin/activate
- cmake ..
-DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
$CMAKE_COMPILER_SCRIPT
- .before_script:default
- .rules:nightly-only-for-release
# TODO (#3480) this should be organized more like the current documentation.py script
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-7-docs:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-7-docs
stage: release-configure
cache: {}
variables:
.docs:build:
# TODO (#3480) this should be organized more like the current documentation.py script
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-7-docs:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-7-docs
script:
- cd $BUILD_DIR
- cmake --build . --target gmx -- -j8
- .gromacs:base:build
- .before_script:default
# TODO (#3480) this should be organized more like the current documentation.py script
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-7-docs:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-7-docs
cache: {}
variables:
KUBERNETES_CPU_LIMIT: 4
KUBERNETES_MEMORY_LIMIT: 8Gi
KUBERNETES_EXTENDED_RESOURCE_NAME: ""
KUBERNETES_EXTENDED_RESOURCE_LIMIT: 0
- CACHE_FALLBACK_KEY: "$CI_JOB_NAME-$CI_JOB_STAGE-release-2021"
+ CACHE_FALLBACK_KEY: "$CI_JOB_NAME-$CI_JOB_STAGE-master"
BUILD_DIR: build
INSTALL_DIR: install
CMAKE_GMXAPI_OPTIONS: ""
# Base definition for using oneAPI.
.use-oneapi:base:
variables:
- # Use the HPC variants of icc and icpc so that OpenMP is active
+ # Use the HPC clang-based compiler variants so that OpenMP is active
CMAKE_COMPILER_SCRIPT: -DCMAKE_C_COMPILER=icx -DCMAKE_CXX_COMPILER=icpx -DCMAKE_INCLUDE_PATH=/opt/intel/oneapi/compiler/latest/linux/include/sycl -DCMAKE_PREFIX_PATH=/opt/intel/oneapi/compiler/latest/linux
CMAKE_EXTRA_OPTIONS: -DGMX_FFT_LIBRARY=mkl
before_script:
- 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
- .use-clang:base
- .rules:basic-push
stage: pre-build
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-9:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-9
variables:
CMAKE: /usr/local/cmake-3.15.7/bin/cmake
KUBERNETES_CPU_LIMIT: 8
- local: '/admin/gitlab-ci/gromacs.matrix/gromacs.gcc-8-cuda-11.0.gitlab-ci.yml'
- local: '/admin/gitlab-ci/gromacs.matrix/gromacs.gcc-8-cuda-11.0-release.gitlab-ci.yml'
- local: '/admin/gitlab-ci/gromacs.matrix/gromacs.gcc-9-release.gitlab-ci.yml'
- - local: '/admin/gitlab-ci/gromacs.matrix/gromacs.icc-2021.1.gitlab-ci.yml'
- local: '/admin/gitlab-ci/gromacs.matrix/gromacs.oneapi-2021.1.1-opencl.gitlab-ci.yml'
- local: '/admin/gitlab-ci/gromacs.matrix/gromacs.oneapi-2021.1.1-opencl-release.gitlab-ci.yml'
- local: '/admin/gitlab-ci/gromacs.matrix/gromacs.oneapi-2021.1.1-sycl.gitlab-ci.yml'
- .use-clang:base
- .use-cuda
- .rules:merge-and-post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-cuda-10.0:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-cuda-10.0
variables:
CMAKE: /usr/local/cmake-3.13.0/bin/cmake
CMAKE_SIMD_OPTIONS: "-DGMX_USE_SIMD_KERNELS=off"
- .use-clang:base
- .use-ccache
- .rules:merge-and-post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-cuda-10.0:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-cuda-10.0
variables:
CMAKE: /usr/local/cmake-3.13.0/bin/cmake
needs:
extends:
- .gromacs:base:test
- .rules:post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-cuda-10.0:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-cuda-10.0
variables:
CMAKE: /usr/local/cmake-3.13.0/bin/cmake
KUBERNETES_EXTENDED_RESOURCE_NAME: "nvidia.com/gpu"
extends:
- .gromacs:base:regressiontest
- .rules:post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-cuda-10.0:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-cuda-10.0
variables:
CMAKE: /usr/local/cmake-3.13.0/bin/cmake
KUBERNETES_EXTENDED_RESOURCE_NAME: "nvidia.com/gpu"
- .use-clang:base
- .use-cuda
- .rules:nightly-only-for-release
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-cuda-10.1:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-cuda-10.1
variables:
COMPILER_MAJOR_VERSION: 8
RELEASE_BUILD_DIR: release-builds-clang
stage: release-build
variables:
BUILD_DIR: release-builds-clang
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-cuda-10.1:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-cuda-10.1
needs:
- job: gromacs:clang-8-cuda-10.1:release:configure
- .gromacs:base:test
- .rules:nightly-only-for-release
stage: release-tests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-cuda-10.1:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-cuda-10.1
variables:
KUBERNETES_EXTENDED_RESOURCE_NAME: "nvidia.com/gpu"
KUBERNETES_EXTENDED_RESOURCE_LIMIT: 1
- .gromacs:base:regressiontest
- .rules:nightly-only-for-release
stage: release-tests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-cuda-10.1:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-cuda-10.1
variables:
BUILD_DIR: release-builds-clang
KUBERNETES_EXTENDED_RESOURCE_NAME: "nvidia.com/gpu"
- .gromacs:base:configure
- .use-clang:base
- .rules:merge-requests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-cuda-10.0:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-cuda-10.0
variables:
COMPILER_MAJOR_VERSION: 8
- .before_script:default
- .use-ccache
- .rules:merge-requests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-cuda-10.0:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-cuda-10.0
needs:
- job: gromacs:clang-8:configure
extends:
- .gromacs:base:test
- .rules:merge-requests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-cuda-10.0:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-cuda-10.0
needs:
- job: gromacs:clang-8:build
extends:
- .gromacs:base:regressiontest
- .rules:merge-requests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-cuda-10.0:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-cuda-10.0
tags:
- k8s-scilifelab
needs:
- .use-clang:base
- .use-mpi
- .rules:merge-requests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-9:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-9
variables:
CMAKE: /usr/local/cmake-3.15.7/bin/cmake
COMPILER_MAJOR_VERSION: 9
- .before_script:default
- .use-ccache
- .rules:merge-requests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-9:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-9
variables:
CMAKE: /usr/local/cmake-3.15.7/bin/cmake
needs:
extends:
- .gromacs:base:test
- .rules:merge-requests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-9:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-9
variables:
CMAKE: /usr/local/cmake-3.15.7/bin/cmake
tags:
extends:
- .gromacs:base:regressiontest
- .rules:merge-requests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-9:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-9
variables:
CMAKE: /usr/local/cmake-3.15.7/bin/cmake
REGRESSIONTEST_DOUBLE: "-double"
- .use-clang:base
- .use-mpi
- .rules:nightly-only-for-release
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-9:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-9
variables:
CMAKE: /usr/local/cmake-3.15.7/bin/cmake
COMPILER_MAJOR_VERSION: 9
variables:
CMAKE: /usr/local/cmake-3.15.7/bin/cmake
BUILD_DIR: release-builds-clang
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-9:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-9
needs:
- job: gromacs:clang-9:release:configure
- .gromacs:base:test
- .rules:nightly-only-for-release
stage: release-tests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-9:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-9
variables:
CMAKE: /usr/local/cmake-3.15.7/bin/cmake
BUILD_DIR: release-builds-clang
- .gromacs:base:regressiontest
- .rules:nightly-only-for-release
stage: release-tests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-9:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-9
variables:
CMAKE: /usr/local/cmake-3.15.7/bin/cmake
BUILD_DIR: release-builds-clang
- .gromacs:base:configure
- .use-clang:base
- .rules:merge-requests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-tsan:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-tsan
variables:
CMAKE: /usr/local/cmake-3.13.0/bin/cmake
COMPILER_MAJOR_VERSION: 8
- .use-clang:base
- .use-ccache
- .rules:merge-requests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-tsan:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-tsan
variables:
CMAKE: /usr/local/cmake-3.13.0/bin/cmake
tags:
- .gromacs:base:test
- .use-clang:base
- .rules:merge-requests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-tsan:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-tsan
variables:
CMAKE: /usr/local/cmake-3.13.0/bin/cmake
CTEST_RUN_MODE: "ExperimentalMemCheck"
- .gromacs:base:regressiontest
- .use-clang:base
- .rules:merge-requests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-tsan:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-tsan
variables:
CMAKE: /usr/local/cmake-3.13.0/bin/cmake
tags:
- .gromacs:base:configure
- .use-clang:base
- .rules:merge-and-post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-tsan:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-tsan
variables:
CMAKE: /usr/local/cmake-3.13.0/bin/cmake
COMPILER_MAJOR_VERSION: 8
- .use-clang:base
- .use-ccache
- .rules:merge-and-post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-tsan:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-tsan
variables:
CMAKE: /usr/local/cmake-3.13.0/bin/cmake
needs:
extends:
- .gromacs:base:test
- .rules:post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-tsan:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-tsan
variables:
CMAKE: /usr/local/cmake-3.13.0/bin/cmake
needs:
extends:
- .gromacs:base:regressiontest
- .rules:post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-tsan:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-tsan
variables:
CMAKE: /usr/local/cmake-3.13.0/bin/cmake
tags:
- .gromacs:base:configure
- .use-clang:base
- .rules:merge-and-post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-tsan:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-tsan
variables:
CMAKE: /usr/local/cmake-3.13.0/bin/cmake
COMPILER_MAJOR_VERSION: 8
- .use-clang:base
- .use-ccache
- .rules:merge-and-post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-tsan:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-tsan
variables:
CMAKE: /usr/local/cmake-3.13.0/bin/cmake
tags:
- .gromacs:base:test
- .use-clang:base
- .rules:post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-tsan:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-tsan
variables:
CMAKE: /usr/local/cmake-3.13.0/bin/cmake
tags:
- .gromacs:base:configure
- .use-clang:base
- .rules:merge-requests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-tsan:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-tsan
variables:
CMAKE: /usr/local/cmake-3.13.0/bin/cmake
CMAKE_COMPILER_SCRIPT: "-DCMAKE_CXX_COMPILER=/usr/local/libexec/c++-analyzer -DCMAKE_C_COMPILER=gcc"
- .use-clang:base
- .use-ccache
- .rules:merge-requests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-tsan:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-8-tsan
variables:
CMAKE: /usr/local/cmake-3.13.0/bin/cmake
tags:
- .use-gcc:base
- .use-opencl
- .rules:merge-and-post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-20.04-gcc-10:release-2021
+ 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"
- .before_script:default
- .use-ccache
- .rules:merge-and-post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-20.04-gcc-10:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-20.04-gcc-10
variables:
CMAKE: /usr/local/cmake-3.13.0/bin/cmake
needs:
extends:
- .gromacs:base:test
- .rules:merge-requests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-20.04-gcc-10:release-2021
+ 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"
extends:
- .gromacs:base:regressiontest
- .rules:post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-20.04-gcc-10:release-2021
+ 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"
- .use-gcc:base
- .use-cuda
- .rules:merge-and-post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-cuda-10.2:release-2021
+ 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"
- .before_script:default
- .use-ccache
- .rules:merge-and-post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-cuda-10.2:release-2021
+ 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:
extends:
- .gromacs:base:test
- .rules:merge-requests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-cuda-10.2:release-2021
+ 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"
extends:
- .gromacs:base:test
- .rules:post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-cuda-10.2:release-2021
+ 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"
extends:
- .gromacs:base:regressiontest
- .rules:merge-requests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-cuda-10.2:release-2021
+ 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"
extends:
- .gromacs:base:regressiontest
- .rules:post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-cuda-10.2:release-2021
+ 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"
extends:
- .gromacs:base:regressiontest
- .rules:post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-cuda-10.2:release-2021
+ 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
-# Test goal: GCC with newest CUDA; Mdrun-only build
+# Test goal: GCC with newest CUDA
# Test intents (should change rarely and conservatively):
# OS: Ubuntu oldest supported
# GPU: CUDA newest supported
# HW: NVIDIA GPU
-# Features: Mdrun-only build
# Scope: configure, build, unit tests
# Test implementation choices (free to change as needed):
# OS: Ubuntu 18.04
- .use-mpi
- .use-cuda
- .rules:nightly-only-for-release
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-8-cuda-11.0:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-8-cuda-11.0
variables:
CMAKE: /usr/local/cmake-3.15.7/bin/cmake
COMPILER_MAJOR_VERSION: 8
RELEASE_BUILD_DIR: release-builds-gcc
- CMAKE_EXTRA_OPTIONS: "-DGMX_BUILD_MDRUN_ONLY=ON"
CMAKE_BUILD_TYPE_OPTIONS : "-DCMAKE_BUILD_TYPE=RelWithAssert"
CMAKE_REGRESSIONTEST_OPTIONS: ""
dependencies:
variables:
CMAKE: /usr/local/cmake-3.15.7/bin/cmake
BUILD_DIR: release-builds-gcc
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-8-cuda-11.0:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-8-cuda-11.0
needs:
- job: gromacs:gcc-8-cuda-11.0:release:configure
- .gromacs:base:test
- .rules:nightly-only-for-release
stage: release-tests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-8-cuda-11.0:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-8-cuda-11.0
variables:
CMAKE: /usr/local/cmake-3.15.7/bin/cmake
KUBERNETES_EXTENDED_RESOURCE_NAME: "nvidia.com/gpu"
- .use-cuda
- .use-mpi
- .rules:merge-and-post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-8-cuda-11.0:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-8-cuda-11.0
variables:
CMAKE: /usr/local/cmake-3.15.7/bin/cmake
CMAKE_SIMD_OPTIONS: "-DGMX_SIMD=SSE4.1"
- .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:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-8-cuda-11.0
variables:
CMAKE: /usr/local/cmake-3.15.7/bin/cmake
needs:
extends:
- .gromacs:base:regressiontest
- .rules:post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-8-cuda-11.0:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-8-cuda-11.0
variables:
CMAKE: /usr/local/cmake-3.15.7/bin/cmake
KUBERNETES_EXTENDED_RESOURCE_NAME: "nvidia.com/gpu"
- .use-gcc:base
- .use-opencl
- .rules:nightly-only-for-release
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-9:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-9
variables:
CMAKE: /usr/local/cmake-3.13.0/bin/cmake
COMPILER_MAJOR_VERSION: 9
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-9:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-9
needs:
- job: gromacs:gcc-9:release:configure
- .gromacs:base:test
- .rules:nightly-only-for-release
stage: release-tests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-9:release-2021
+ 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
- .gromacs:base:regressiontest
- .rules:nightly-only-for-release
stage: release-tests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-9:release-2021
+ 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
+++ /dev/null
-# Test goal: Newest ICC CPU-only build
-# Test intents (should change rarely and conservatively):
-# OS: Ubuntu oldest supported
-# Compiler: ICC newest supported
-# FFT: MKL
-# GPU: no
-# Scope: configure, build, unit tests, regression tests
-# Test implementation choices (free to change as needed):
-# OS: Ubuntu 18.04
-# Build type: Debug
-# Compiler: ICC 2021.1
-# MPI: thread_MPI
-# SIMD: AVX2_256
-# Parallelism nt/ntomp: 4/2
-
-gromacs:icc-2021.1:configure:
- # Test SIMD: AVX2_256
- # Test FFT: MKL
- # Test scope: 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:release-2021
- variables:
- CMAKE: /usr/local/cmake-3.17.2/bin/cmake
- COMPILER_MAJOR_VERSION: 2021
-
-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:release-2021
- variables:
- CMAKE: /usr/local/cmake-3.17.2/bin/cmake
- needs:
- - job: gromacs:icc-2021.1:configure
-
-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:release-2021
- variables:
- CMAKE: /usr/local/cmake-3.17.2/bin/cmake
- needs:
- - job: gromacs:icc-2021.1:build
-
-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:release-2021
- variables:
- CMAKE: /usr/local/cmake-3.17.2/bin/cmake
- needs:
- - job: gromacs:icc-2021.1:build
- - job: regressiontests:prepare
-
- .use-oneapi:base
- .use-opencl
- .rules:nightly-only-for-release
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1.1:release-2021
+ 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
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.1:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1.1
needs:
- job: gromacs:oneapi-2021.1.1-opencl:release:configure
- .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.1:release-2021
+ 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
- .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.1:release-2021
+ 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
- .use-oneapi:base
- .use-opencl
- .rules:merge-requests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1.1:release-2021
+ 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
- .use-ccache
- .use-oneapi:base
- .rules:merge-requests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1.1:release-2021
+ 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:
- .gromacs:base:test
- .use-oneapi:base
- .rules:merge-requests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1.1:release-2021
+ 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:
- .gromacs:base:regressiontest
- .use-oneapi:base
- .rules:merge-requests
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1.1:release-2021
+ 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:
- .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.1:release-2021
+ 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
- .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.1:release-2021
+ 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:
- .gromacs:base:test
- .use-oneapi:base
- .rules:post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1.1:release-2021
+ 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:
- .gromacs:base:regressiontest
- .use-oneapi:base
- .rules:post-merge-acceptance
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-gcc-7-oneapi-2021.1.1:release-2021
+ 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:
- .gromacs:base:configure
- .use-clang:base
- .rules:basic-push
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-9:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-9
variables:
CMAKE: /usr/local/cmake-3.15.7/bin/cmake
COMPILER_MAJOR_VERSION: 9
- .gromacs:base:configure
- .use-clang:base
- .rules:nightly-not-for-release
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-9:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-9
variables:
CMAKE: /usr/local/cmake-3.15.7/bin/cmake
COMPILER_MAJOR_VERSION: 9
- .variables:default
- .rules:nightly-not-for-release
stage: source-check
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-9:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-9
needs:
- job: clang-tidy:configure-schedule
variables:
- .variables:default
- .rules:basic-push
stage: source-check
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-9:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-9
needs:
- job: clang-tidy:configure-push
variables:
# Make sure that a Python interpreter can be found for `/bin/env python`
- test -x /usr/bin/python || update-alternatives --install /usr/bin/python python /usr/bin/python3 1
# TODO (issue #3272) `master` is not appropriate for use on release-xxxx branches, how should we handle that?
- - REV=$(git fetch -q https://gitlab.com/gromacs/gromacs.git release-2021 && git show -s --pretty=format:"%h" `git merge-base FETCH_HEAD HEAD`)
+ - REV=$(git fetch -q https://gitlab.com/gromacs/gromacs.git master && git show -s --pretty=format:"%h" `git merge-base FETCH_HEAD HEAD`)
- HEAD_REV=$(git show -s --pretty=format:"%h" HEAD)
- if [[ "$REV" == "$HEAD_REV" ]] ; then
REV="HEAD~1" ;
- .rules:basic-push
cache: {}
stage: pre-build
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-7-docs:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-7-docs
variables:
COMPILER_MAJOR_VERSION: 7
KUBERNETES_CPU_LIMIT: 1
KUBERNETES_MEMORY_REQUEST: 2Gi
EXTRA_INSTALLS: clang-format-$COMPILER_MAJOR_VERSION
script:
- - REV=$(git fetch -q https://gitlab.com/gromacs/gromacs.git release-2021 && git show -s --pretty=format:"%h" `git merge-base FETCH_HEAD HEAD`)
+ # TODO (issue #3272) `master` is not appropriate for use on release-xxxx branches, how should we handle that?
+ - REV=$(git fetch -q https://gitlab.com/gromacs/gromacs.git master && git show -s --pretty=format:"%h" `git merge-base FETCH_HEAD HEAD`)
- HEAD_REV=$(git show -s --pretty=format:"%h" HEAD)
- if [[ "$REV" == "$HEAD_REV" ]] ; then
REV="HEAD~1" ;
- .rules:basic-push
cache: {}
stage: pre-build
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-7-docs:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-18.04-llvm-7-docs
variables:
KUBERNETES_CPU_LIMIT: 1
KUBERNETES_CPU_REQUEST: 1
- .variables:default
- .use-clang:base
stage: test
- image: ${CI_REGISTRY}/gromacs/gromacs/cmake-3.15.7-llvm-8-intelopencl-openmpi:2020:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/cmake-3.15.7-llvm-8-intelopencl-openmpi:2020
variables:
KUBERNETES_CPU_LIMIT: 2
KUBERNETES_CPU_REQUEST: 2
extends:
- .variables:default
- .use-clang:base
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-20.04-gcc-10:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-20.04-gcc-10
stage: test
variables:
KUBERNETES_CPU_LIMIT: 2
--- /dev/null
+#
+# Jobs to test gmxapi client (Python) packages
+#
+
+.gmxapi-0.2:gcc-10:gmx2021:
+ extends:
+ - .variables:default
+ - .use-clang:base
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-20.04-gcc-10
+ stage: test
+ variables:
+ KUBERNETES_CPU_LIMIT: 2
+ KUBERNETES_CPU_REQUEST: 2
+ KUBERNETES_MEMORY_LIMIT: 2Gi
+ KUBERNETES_MEMORY_REQUEST: 2Gi
+ PY_UNIT_TEST_XML: $CI_PROJECT_DIR/py-JUnitTestResults.xml
+ PY_MPI_UNIT_TEST_XML: $CI_PROJECT_DIR/py-mpi-JUnitTestResults.xml
+ PY_ACCEPTANCE_TEST_XML: $CI_PROJECT_DIR/gmxapi-acceptance-JUnitTestResults.xml
+ PY_MPI_ACCEPTANCE_TEST_XML: $CI_PROJECT_DIR/gmxapi-acceptance-mpi-JUnitTestResults.xml
+ script:
+ - source $INSTALL_DIR/bin/GMXRC
+ - source $VENVPATH/bin/activate && INSTALL_DIR=$PWD/$INSTALL_DIR OMP_NUM_THREADS=1 bash admin/ci-scripts/build-and-test-py-gmxapi-0.2.sh
+ artifacts:
+ reports:
+ junit:
+ - $PY_UNIT_TEST_XML
+ - $PY_MPI_UNIT_TEST_XML
+ - $PY_ACCEPTANCE_TEST_XML
+ - $PY_MPI_ACCEPTANCE_TEST_XML
+ when: always
+ expire_in: 1 week
+ tags:
+ - k8s-scilifelab
+ # The dependency means we need to use the same tag restriction as upstream.
+ needs:
+ - job: gromacs:gcc-10:build
+ artifacts: true
+
+gmxapi-0.2:gcc-10:gmx2021:py-3.6.10:
+ extends:
+ - .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-10:gmx2021:py-3.7.7:
+ extends:
+ - .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-10:gmx2021:py-3.8.2:
+ extends:
+ - .gmxapi-0.2:gcc-10:gmx2021
+ - .rules:merge-requests:release-2021
+ variables:
+ VENVPATH: "/root/venv/py3.8"
+ PY_VER: "3.8.2"
--- /dev/null
+#
+# Jobs to test gmxapi client (Python) packages
+#
+
+.gmxapi-0.3:gcc-10:gmx2022:
+ extends:
+ - .variables:default
+ - .use-clang:base
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-20.04-gcc-10
+ stage: test
+ variables:
+ KUBERNETES_CPU_LIMIT: 2
+ KUBERNETES_CPU_REQUEST: 2
+ KUBERNETES_MEMORY_LIMIT: 2Gi
+ KUBERNETES_MEMORY_REQUEST: 2Gi
+ PY_UNIT_TEST_XML: $CI_PROJECT_DIR/py-JUnitTestResults.xml
+ PY_MPI_UNIT_TEST_XML: $CI_PROJECT_DIR/py-mpi-JUnitTestResults.xml
+ PY_ACCEPTANCE_TEST_XML: $CI_PROJECT_DIR/gmxapi-acceptance-JUnitTestResults.xml
+ PY_MPI_ACCEPTANCE_TEST_XML: $CI_PROJECT_DIR/gmxapi-acceptance-mpi-JUnitTestResults.xml
+ script:
+ - source $INSTALL_DIR/bin/GMXRC
+ - source $VENVPATH/bin/activate && INSTALL_DIR=$PWD/$INSTALL_DIR OMP_NUM_THREADS=1 bash admin/ci-scripts/build-and-test-py-gmxapi-0.3.sh
+ artifacts:
+ reports:
+ junit:
+ - $PY_UNIT_TEST_XML
+ - $PY_MPI_UNIT_TEST_XML
+ - $PY_ACCEPTANCE_TEST_XML
+ - $PY_MPI_ACCEPTANCE_TEST_XML
+ when: always
+ expire_in: 1 week
+ tags:
+ - k8s-scilifelab
+ # The dependency means we need to use the same tag restriction as upstream.
+ needs:
+ - job: gromacs:gcc-10:build
+ artifacts: true
+
+gmxapi-0.3:gcc-10:gmx2022:py-3.7.7:
+ extends:
+ - .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-10:gmx2022:py-3.8.2:
+ extends:
+ - .gmxapi-0.3:gcc-10:gmx2022
+ - .rules:merge-requests:master
+ variables:
+ VENVPATH: "/root/venv/py3.8"
+ PY_VER: "3.8.2"
.rules-element:if-post-merge-acceptance-or-mr-then-always: &if-post-merge-acceptance-or-mr-then-always
if: '$CI_PIPELINE_SOURCE == "merge_request_event" ||
($CI_PIPELINE_SOURCE == "push" &&
- $CI_COMMIT_REF_NAME == "release-2021")'
+ $CI_COMMIT_REF_NAME == "master")'
when: always
# Include job only for post submit push
.rules-element:if-post-merge-acceptance-then-always: &if-post-merge-acceptance-then-always
if: '$CI_PIPELINE_SOURCE == "push" &&
- $CI_COMMIT_REF_NAME == "release-2021"'
+ $CI_COMMIT_REF_NAME == "master"'
when: always
# When composing a rule set, note that the first matching rule is applied.
- *if-schedule-then-always
- *if-mr-then-always
-# Jobs that run for merge requests and schedules for branch `release-2020`,
+# Jobs that run for merge requests and schedules for branch `release-2021`,
# but not when GROMACS_RELEASE is set.
# Excludes non-gromacs projects.
-.rules:merge-requests:release-2020:
+.rules:merge-requests:release-2021:
rules:
- *if-not-gromacs-then-never
- *if-release-then-never
- *if-post-merge-acceptance-then-never
- # This next rule catches "push" and other events in branches other than `release-2020`
- # but allows merge_request_events for merge requests targeting `release-2020`.
+ # This next rule catches "push" and other events in branches other than `release-2021`
+ # but allows merge_request_events for merge requests targeting `release-2021`.
# This rule is before "web" so the web interface won't include jobs that can't succeed
# (and would not ordinarily be run). Such jobs are hard to identify in a way that is
# sufficiently general for a global rules definition.
# If extra coverage is needed through a web-triggered job in merge request branches,
# we could provide an additional short-circuiting rule based on an environment variable
# to be provided through the web interface.
- - if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME != "release-2020" && $CI_COMMIT_REF_NAME != "release-2020"'
+ - if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME != "release-2021" && $CI_COMMIT_REF_NAME != "release-2021"'
when: never
- *if-web-then-always
- *if-schedule-then-always
- *if-mr-then-always
-# Jobs that run for merge requests and schedules for branch `release-2021`,
+# Jobs that run for merge requests and schedules for branch `release-2020`,
# but not when GROMACS_RELEASE is set.
# Excludes non-gromacs projects.
-.rules:merge-requests:release-2021:
+.rules:merge-requests:release-2020:
rules:
- *if-not-gromacs-then-never
- *if-release-then-never
- *if-post-merge-acceptance-then-never
- # This next rule catches "push" and other events in branches other than `release-2021`
- # but allows merge_request_events for merge requests targeting `release-2021`.
+ # This next rule catches "push" and other events in branches other than `release-2020`
+ # but allows merge_request_events for merge requests targeting `release-2020`.
# This rule is before "web" so the web interface won't include jobs that can't succeed
# (and would not ordinarily be run). Such jobs are hard to identify in a way that is
# sufficiently general for a global rules definition.
# If extra coverage is needed through a web-triggered job in merge request branches,
# we could provide an additional short-circuiting rule based on an environment variable
# to be provided through the web interface.
- - if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME != "release-2021" && $CI_COMMIT_REF_NAME != "release-2021"'
+ - if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME != "release-2020" && $CI_COMMIT_REF_NAME != "release-2020"'
when: never
- *if-web-then-always
- *if-schedule-then-always
extends:
- .variables:default
- .use-clang:base
- image: ${CI_REGISTRY}/gromacs/gromacs/cmake-3.15.7-llvm-8-intelopencl-openmpi:2020:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/cmake-3.15.7-llvm-8-intelopencl-openmpi:2020
stage: test
variables:
KUBERNETES_CPU_LIMIT: 2
extends:
- .variables:default
- .use-clang:base
- image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-20.04-gcc-10:release-2021
+ image: ${CI_REGISTRY}/gromacs/gromacs/ci-ubuntu-20.04-gcc-10
stage: test
variables:
KUBERNETES_CPU_LIMIT: 2
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+# Copyright (c) 2018,2019,2020,2021, 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.
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+# The legacy public API headers may still be installed,
+# but may be removed or changed without warning.
+add_subdirectory(legacy)
# Activate targets for new C++ API components and docs.
-if(GMX_NATIVE_WINDOWS OR GMX_BUILD_MDRUN_ONLY)
+if(GMX_NATIVE_WINDOWS)
# GMXAPI has not been tested in Microsoft environments.
- # GMXAPI relies on libgromacs and is incompatible with an `mdrun`-only build.
# GMXAPI requires position-independent code
set(_GMXAPI_DEFAULT OFF)
else()
endif()
# Activate targets NBLIB
-if(GMX_NATIVE_WINDOWS OR GMX_BUILD_MDRUN_ONLY OR NOT BUILD_SHARED_LIBS OR CMAKE_CXX_COMPILER_ID MATCHES "Intel")
+if(GMX_NATIVE_WINDOWS OR NOT BUILD_SHARED_LIBS)
# 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)
# be tagged. Official GROMACS releases should be mappable to a distinct gmxapi
# release string. For roadmap details, see https://gitlab.com/gromacs/gromacs/-/issues/2585
set(GMXAPI_MAJOR 0)
-set(GMXAPI_MINOR 2)
+set(GMXAPI_MINOR 3)
set(GMXAPI_PATCH 0)
set(GMXAPI_RELEASE ${GMXAPI_MAJOR}.${GMXAPI_MINOR}.${GMXAPI_PATCH})
# Do not target_link_options(gmxapi PRIVATE ${MPI_LINKER_FLAGS})
# because the root CMakeLists.txt sets CMAKE_SHARED_LINKER_FLAGS.
target_compile_options(gmxapi PUBLIC ${MPI_COMPILE_FLAGS})
- target_link_libraries(gmxapi PUBLIC ${MPI_C_LIBRARIES})
+ target_link_libraries(gmxapi PUBLIC ${MPI_CXX_LIBRARIES})
elseif(GMX_THREAD_MPI)
# GROMACS is built with its internal thread-MPI implementation.
set(_gmx_mpi_type "tmpi")
)
target_link_libraries(gmxapi PRIVATE libgromacs)
+target_link_libraries(gmxapi PRIVATE common)
+# TODO: Explicitly link specific modules: mdlib, mdtypes, utility, commandline
+target_link_libraries(gmxapi PRIVATE legacy_modules)
################################################
@PACKAGE_INIT@
# Refer to CMake docs for information on more elaborate use of this stub file:
# https://cmake.org/cmake/help/v3.4/module/CMakePackageConfigHelpers.html#command:configure_package_config_file
+include(CMakeFindDependencyMacro)
+@_gmxapi_find_dependencies@
include("${CMAKE_CURRENT_LIST_DIR}/gmxapi.cmake")
check_required_components(gmxapi)
set_property(TARGET Gromacs::gmxapi PROPERTY MPI "@_mpi@")
SimulationContext simulationContext(communicator, multiSimDirectoryNames);
- StartingBehavior startingBehavior = StartingBehavior::NewSimulation;
- LogFilePtr logFileGuard = nullptr;
- gmx_multisim_t* ms = simulationContext.multiSimulation_.get();
- std::tie(startingBehavior, logFileGuard) = handleRestart(
- findIsSimulationMasterRank(ms, simulationContext.simulationCommunicator_),
- simulationContext.simulationCommunicator_, ms, options.mdrunOptions.appendingBehavior,
- ssize(options.filenames), options.filenames.data());
+ StartingBehavior startingBehavior = StartingBehavior::NewSimulation;
+ LogFilePtr logFileGuard = nullptr;
+ gmx_multisim_t* ms = simulationContext.multiSimulation_.get();
+ std::tie(startingBehavior, logFileGuard) =
+ handleRestart(findIsSimulationMasterRank(ms, simulationContext.simulationCommunicator_),
+ simulationContext.simulationCommunicator_,
+ ms,
+ options.mdrunOptions.appendingBehavior,
+ ssize(options.filenames),
+ options.filenames.data());
auto builder = MdrunnerBuilder(std::move(mdModules),
compat::not_null<SimulationContext*>(&simulationContext));
builder.addLogFile(logFileGuard.get());
// Note, creation is not mature enough to be exposed in the external API yet.
- launchedSession = createSession(shared_from_this(), std::move(builder),
- std::move(simulationContext), std::move(logFileGuard));
+ launchedSession = createSession(
+ shared_from_this(), std::move(builder), std::move(simulationContext), std::move(logFileGuard));
// Clean up argv once builder is no longer in use
// TODO: Remove long-lived references to argv so this is no longer necessary.
auto& callCounter = manager_->called_.at(name_);
callCounter.store(true);
using pairType = typename decltype(manager_->called_)::value_type;
- if (std::all_of(manager_->called_.cbegin(), manager_->called_.cend(),
- [](const pairType& p) { return p.second.load(); }))
+ if (std::all_of(manager_->called_.cbegin(), manager_->called_.cend(), [](const pairType& p) {
+ return p.second.load();
+ }))
{
*manager_->state_ = gmx::StopSignal::stopAtNextNSStep;
}
{
// We should be able to get a communicator (or subcommunicator) through the
// Context.
- return std::make_unique<SessionImpl>(std::move(context), std::move(runnerBuilder),
- std::move(simulationContext), std::move(logFilehandle));
+ return std::make_unique<SessionImpl>(std::move(context),
+ std::move(runnerBuilder),
+ std::move(simulationContext),
+ std::move(logFilehandle));
}
SessionImpl::SessionImpl(std::shared_ptr<ContextImpl> context,
gmx::SimulationContext&& simulationContext,
gmx::LogFilePtr logFilehandle)
{
- auto newSession = SessionImpl::create(std::move(context), std::move(runnerBuilder),
- std::move(simulationContext), std::move(logFilehandle));
+ auto newSession = SessionImpl::create(std::move(context),
+ std::move(runnerBuilder),
+ std::move(simulationContext),
+ std::move(logFilehandle));
auto launchedSession = std::make_shared<Session>(std::move(newSession));
return launchedSession;
}
{
return false;
}
- gmxapicompat::writeTprFile(
- outFile, *gmxapicompat::getMdParams(input), *gmxapicompat::getStructureSource(input),
- *gmxapicompat::getSimulationState(input), *gmxapicompat::getTopologySource(input));
+ gmxapicompat::writeTprFile(outFile,
+ *gmxapicompat::getMdParams(input),
+ *gmxapicompat::getStructureSource(input),
+ *gmxapicompat::getSimulationState(input),
+ *gmxapicompat::getTopologySource(input));
return true;
}
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2014,2015, by the GROMACS development team, led by
+# 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.
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
-set(CMAKE_SYSTEM_NAME Linux)
-set(CMAKE_SYSTEM_PROCESSOR XeonPhi)
-if(NOT GMX_MPI)
- set(CMAKE_C_COMPILER "icc")
- set(CMAKE_CXX_COMPILER "icpc")
-else()
- set(CMAKE_C_COMPILER "mpiicc") #FindMPI doesn't work (#14991)
- set(CMAKE_CXX_COMPILER "mpiicpc")
+# The legacy installed API consists of headers that are not considered
+# to be maintainable in terms of a stable API specification. These headers
+# will no longer be available to install in a future release.
+
+# Note: Any usage requirements that should be transitive should be added to
+# this INTERFACE target. Compiler and linker options (that do not need to
+# be propagated when linking to the `common` target) can be added directly
+# to the `common` target.
+add_library(legacy_api INTERFACE)
+target_include_directories(legacy_api INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>
+ $<INSTALL_INTERFACE:include>)
+
+configure_file(version.h.cmakein include/gromacs/version.h)
+
+# Allow an export target for legacy_api since it is a dependency of the
+# installable libgromacs target.
+install(TARGETS legacy_api
+ EXPORT libgromacs
+ INCLUDES DESTINATION include)
+
+if(GMX_INSTALL_LEGACY_API)
+ # Install public header directories.
+ install(DIRECTORY include/gromacs
+ DESTINATION include)
+
+ # Install "configured" files from the build tree.
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/gromacs/version.h
+ DESTINATION include/gromacs)
endif()
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2016,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2015,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.
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2012,2014,2015,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2012,2014,2015,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.
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
*/
int gmx_fedisableexcept();
+/*! \brief Return true if the current build should enable floating-point exceptions by default.
+ *
+ * Currently, it returns true unless any of the following conditions are met:
+ * - release build,
+ * - SYCL build (Intel IGC, at least 1.0.5964, raises FP exceptions in JIT compilation),
+ * - - See https://github.com/intel/intel-graphics-compiler/issues/164
+ * - compilers with known buggy FP exception support (clang with any optimization)
+ * or suspected buggy FP exception support (gcc 7.* with optimization).
+ *
+ * Note that this function does not check whether the build/OS supports FP exceptions.
+ *
+ * \returns true if we should enable FP exceptions by default.
+ */
+bool gmxShouldEnableFPExceptions();
+
#endif
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
*/
#ifndef gmx_unused
# ifdef __GNUC__
-/* GCC, clang, and some ICC pretending to be GCC */
-# define gmx_unused __attribute__((unused))
-# elif (defined(__INTEL_COMPILER) || defined(__ECC)) && !defined(_MSC_VER)
-/* ICC on *nix */
+/* GCC, clang, and any pretending to be or based on them */
# define gmx_unused __attribute__((unused))
# elif defined(__PGI)
/* Portland group compilers */
*/
#define GMX_UNUSED_VALUE(value) (void)value
+#if defined(__GNUC__) && !defined(__clang__)
+# define DO_PRAGMA(x) _Pragma(# x)
+# define GCC_DIAGNOSTIC_IGNORE(warning) \
+ _Pragma("GCC diagnostic push") DO_PRAGMA(GCC diagnostic ignored #warning)
+# define GCC_DIAGNOSTIC_RESET _Pragma("GCC diagnostic pop")
+#else
+//! Ignore specified clang warning until GCC_DIAGNOSTIC_RESET
+# define GCC_DIAGNOSTIC_IGNORE(warning)
+//! Reset all diagnostics to default
+# define GCC_DIAGNOSTIC_RESET
+#endif
+
#ifdef __clang__
# define DO_PRAGMA(x) _Pragma(# x)
# define CLANG_DIAGNOSTIC_IGNORE(warning) \
# define MSVC_DIAGNOSTIC_RESET
#endif
-#ifdef __INTEL_COMPILER
-//! Ignore unused loop variable warning - it was used until the compiler removes the use!
-# define DO_PRAGMA(x) _Pragma(# x)
-# define INTEL_DIAGNOSTIC_IGNORE(id) DO_PRAGMA(warning push) DO_PRAGMA(warning(disable : id))
-# define INTEL_DIAGNOSTIC_RESET DO_PRAGMA(warning pop)
-#else
-//! Ignore specified diagnostic message from Intel compiler.
-# define INTEL_DIAGNOSTIC_IGNORE(id)
-//! Reset the diagnostic message setting.
-# define INTEL_DIAGNOSTIC_RESET
-#endif
-
namespace gmx
{
namespace internal
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2019, by the GROMACS development team, led by
+ * Copyright (c) 2015,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
# define GMX_CURRENT_FUNCTION __FUNCSIG__
-#elif (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)) \
- || (defined(__IBMCPP__) && (__IBMCPP__ >= 500))
+#elif (defined(__IBMCPP__) && (__IBMCPP__ >= 500))
# define GMX_CURRENT_FUNCTION __FUNCTION__
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2011-2018, The GROMACS development team.
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
# define GMX_RELEASE_ASSERT(condition, msg)
#else
# ifdef _MSC_VER
-# define GMX_RELEASE_ASSERT(condition, msg) \
- ((void)((condition) ? (void)0 \
- : ::gmx::internal::assertHandler(#condition, msg, GMX_CURRENT_FUNCTION, \
- __FILE__, __LINE__)))
+# define GMX_RELEASE_ASSERT(condition, msg) \
+ ((void)((condition) ? (void)0 \
+ : ::gmx::internal::assertHandler( \
+ #condition, msg, GMX_CURRENT_FUNCTION, __FILE__, __LINE__)))
# else
// Use an "immediately invoked function expression" to allow being
// used in constexpr context with older GCC versions
//! Appends a ListOfLists at the end and increments the appended elements by \p offset
void appendListOfLists(const ListOfLists& listOfLists, const T offset = 0)
{
- listRanges_.insert(listRanges_.end(), listOfLists.listRanges_.begin() + 1,
- listOfLists.listRanges_.end());
+ listRanges_.insert(
+ listRanges_.end(), listOfLists.listRanges_.begin() + 1, listOfLists.listRanges_.end());
const int oldNumElements = elements_.size();
for (std::size_t i = listRanges_.size() - listOfLists.size(); i < listRanges_.size(); i++)
{
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2012,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.
+ *
+ * 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.
+ */
+/*! \file
+ * \brief
+ * Version information for software that links to \Gromacs.
+ *
+ * \if libapi
+ * This include file will be configured by CMake and contains version
+ * information. It is not used by \Gromacs, but intended for software that
+ * links to \Gromacs.
+ * The values come from the main CMakeLists.txt.
+ * \endif
+ *
+ * This file exists from 4.6 onward, and can be included as
+ * `<gromacs/version.h>`. In 4.6, it is also included by
+ * `<gromacs/typedefs.h>, but that header has already moved in 5.0.
+ *
+ * This header defines two values, the \Gromacs version, and the API version.
+ * The versions are in numerical form, where, for example, version
+ * 4.6.1 would be 40601.
+ *
+ * The API version is defined in ::GMX_API_VERSION, and denotes the
+ * version of the programmer interface, i.e. the installed header files
+ * and compatible library.
+ *
+ * Programs written against the \Gromacs library can use this file
+ * to provide some backward compatibility even though parts of the API
+ * change. For example:
+ * \code
+ #include <gromacs/version.h>
+ #if (GMX_API_VERSION < 50000)
+ .... <do pre-5.0 stuff>
+ #else
+ .... <do post-5.0 stuff>
+ #endif
+ \endcode
+ * where version.h is included directly. For code that must be compatible
+ * between 4.5 and 4.6, an interim solution is to include typedefs.h, which
+ * includes this file:
+ * \code
+ #include <gromacs/typedefs.h>
+ #if !defined(GMX_API_VERSION) || (GMX_API_VERSION < 40600)
+ .... <do 4.5 specific stuff>
+ #elif (GMX_API_VERSION < 40700)
+ .... <do 4.6 specific stuff>
+ #endif
+ \endcode
+ *
+ * \inpublicapi
+ */
+#ifndef GMX_VERSION_H
+#define GMX_VERSION_H
+
+/*! \brief
+ * API version of this set of \Gromacs headers.
+ *
+ * If there are multiple versions of \Gromacs that work with the same set of
+ * headers, then this version is not updated between the versions, even though
+ * ::GMX_VERSION is.
+ * For 4.6 and 5.0 (and likely for some time in the future as well), this
+ * tracks the exact \Gromacs version.
+ */
+#define GMX_API_VERSION @GMX_API_VERSION@
+
+/*! \brief
+ * Exact \Gromacs version of this set of headers.
+ *
+ * This specifies the version number of the actual \Gromacs library that
+ * installed these headers.
+ */
+#define GMX_VERSION @GMX_VERSION_NUMERIC@
+
+#endif
target_link_libraries(nblib PRIVATE libgromacs)
target_include_directories(nblib PRIVATE ${PROJECT_SOURCE_DIR}/api)
include_directories(BEFORE ${CMAKE_SOURCE_DIR}/api)
+target_link_libraries(nblib PRIVATE common)
+# There are transitive dependencies on the legacy GROMACS headers.
+target_link_libraries(nblib PUBLIC legacy_api)
+# TODO: Explicitly link specific modules.
+target_link_libraries(nblib PRIVATE legacy_modules)
install(TARGETS nblib
EXPORT nblib
// update the coordinates in the backend
nbv_->convertCoordinates(gmx::AtomLocality::Local, false, coordinateInput);
- nbv_->dispatchNonbondedKernel(gmx::InteractionLocality::Local, *interactionConst_, *stepWork_,
- enbvClearFYes, *forcerec_, enerd_.get(), nrnb_.get());
+ nbv_->dispatchNonbondedKernel(gmx::InteractionLocality::Local,
+ *interactionConst_,
+ *stepWork_,
+ enbvClearFYes,
+ *forcerec_,
+ enerd_.get(),
+ nrnb_.get());
nbv_->atomdata_add_nbat_f_to_f(gmx::AtomLocality::All, forceOutput);
}
const real particleDensity = coordinates.size() / det(legacyBox);
- nbnxn_put_on_grid(nbv_.get(), legacyBox, 0, lowerCorner, upperCorner, nullptr,
- { 0, int(coordinates.size()) }, particleDensity, particleInfoAllVdw,
- coordinates, 0, nullptr);
+ nbnxn_put_on_grid(nbv_.get(),
+ legacyBox,
+ 0,
+ lowerCorner,
+ upperCorner,
+ nullptr,
+ { 0, int(coordinates.size()) },
+ particleDensity,
+ particleInfoAllVdw,
+ coordinates,
+ 0,
+ nullptr);
}
} // namespace nblib
Nbnxm::KernelSetup kernelSetup = getKernelSetup(options);
PairlistParams pairlistParams(kernelSetup.kernelType, false, options.pairlistCutoff, false);
- Nbnxm::GridSet gridSet(PbcType::Xyz, false, nullptr, nullptr, pairlistParams.pairlistType,
- false, numThreads, pinPolicy);
- auto pairlistSets = std::make_unique<PairlistSets>(pairlistParams, false, 0);
- auto pairSearch =
- std::make_unique<PairSearch>(PbcType::Xyz, false, nullptr, nullptr,
- pairlistParams.pairlistType, false, numThreads, pinPolicy);
+ Nbnxm::GridSet gridSet(
+ PbcType::Xyz, false, nullptr, nullptr, pairlistParams.pairlistType, false, numThreads, pinPolicy);
+ auto pairlistSets = std::make_unique<PairlistSets>(pairlistParams, false, 0);
+ auto pairSearch = std::make_unique<PairSearch>(
+ PbcType::Xyz, false, nullptr, nullptr, pairlistParams.pairlistType, false, numThreads, pinPolicy);
auto atomData = std::make_unique<nbnxn_atomdata_t>(pinPolicy);
// Needs to be called with the number of unique ParticleTypes
- nbnxn_atomdata_init(gmx::MDLogger(), atomData.get(), kernelSetup.kernelType, combinationRule,
- numParticleTypes, nonbondedParameters_, 1, numThreads);
+ nbnxn_atomdata_init(gmx::MDLogger(),
+ atomData.get(),
+ kernelSetup.kernelType,
+ combinationRule,
+ numParticleTypes,
+ nonbondedParameters_,
+ 1,
+ numThreads);
// Put everything together
- auto nbv = std::make_unique<nonbonded_verlet_t>(std::move(pairlistSets), std::move(pairSearch),
- std::move(atomData), kernelSetup, nullptr,
- nullWallcycle);
+ auto nbv = std::make_unique<nonbonded_verlet_t>(
+ std::move(pairlistSets), std::move(pairSearch), std::move(atomData), kernelSetup, nullptr, nullWallcycle);
gmxForceCalculator_->nbv_ = std::move(nbv);
}
gmxForceCalculator_->interactionConst_->epsfac = 0;
}
- calc_rffac(nullptr, gmxForceCalculator_->interactionConst_->epsilon_r,
+ calc_rffac(nullptr,
+ gmxForceCalculator_->interactionConst_->epsilon_r,
gmxForceCalculator_->interactionConst_->epsilon_rf,
gmxForceCalculator_->interactionConst_->rcoulomb,
&gmxForceCalculator_->interactionConst_->k_rf,
{
gmx::ListOfLists<int> exclusions(std::move(exclusionLists.ListRanges),
std::move(exclusionLists.ListElements));
- gmxForceCalculator_->nbv_->constructPairlist(gmx::InteractionLocality::Local, exclusions, 0,
- gmxForceCalculator_->nrnb_.get());
+ gmxForceCalculator_->nbv_->constructPairlist(
+ gmx::InteractionLocality::Local, exclusions, 0, gmxForceCalculator_->nrnb_.get());
}
std::string message = formatString(
"Attempting to add nonbonded interaction parameters between the particle types "
"{} {} twice",
- particleTypeName1.value(), particleTypeName2.value());
+ particleTypeName1.value(),
+ particleTypeName2.value());
throw InputException(message);
}
}
C6 c6_combo{ combineNonbondedParameters(c6_1, c6_2, combinationRule_) };
C12 c12_combo{ combineNonbondedParameters(c12_1, c12_2, combinationRule_) };
- nonbondedParameters_.setInteractions(particleType1.first, particleType2.first, c6_combo,
- c12_combo);
+ nonbondedParameters_.setInteractions(
+ particleType1.first, particleType2.first, c6_combo, c12_combo);
}
}
if (nonbondedParameters_.count(interactionKey) == 0)
{
std::string message = formatString("Missing interaction between {} {}",
- particleTypeName1.value(), particleTypeName2.value());
+ particleTypeName1.value(),
+ particleTypeName2.value());
throw InputException(message);
}
}
for (const auto& keyval : other.twoParticlesInteractionsMap_)
{
- add(std::get<0>(keyval.first), std::get<1>(keyval.first), std::get<0>(keyval.second),
+ add(std::get<0>(keyval.first),
+ std::get<1>(keyval.first),
+ std::get<0>(keyval.second),
std::get<1>(keyval.second));
}
}
TEST(NBlibTest, BondTypesOperatorEqualWorks)
{
- auto bondList3 = std::make_tuple(HarmonicBondType(), G96BondType(), FENEBondType(),
- HalfAttractiveQuarticBondType());
+ auto bondList3 = std::make_tuple(
+ HarmonicBondType(), G96BondType(), FENEBondType(), HalfAttractiveQuarticBondType());
for_each_tuple([](const auto& b) { test_detail::testTwoParameterBondEquality(b); }, bondList3);
auto bondList4 = std::make_tuple(CubicBondType(), MorseBondType());
TEST(NBlibTest, BondTypesLessThanWorks)
{
- auto bondList3 = std::make_tuple(HarmonicBondType(), G96BondType(), FENEBondType(),
- HalfAttractiveQuarticBondType());
+ auto bondList3 = std::make_tuple(
+ HarmonicBondType(), G96BondType(), FENEBondType(), HalfAttractiveQuarticBondType());
for_each_tuple([](const auto& b) { test_detail::testTwoParameterBondLessThan(b); }, bondList3);
auto bondList4 = std::make_tuple(CubicBondType(), MorseBondType());
for (int m = 0; m < dimSize; ++m)
{
EXPECT_FLOAT_DOUBLE_EQ_TOL(
- forces[i][m], refForcesFloat[i][m], refForcesDouble[i][m],
+ forces[i][m],
+ refForcesFloat[i][m],
+ refForcesDouble[i][m],
// Todo: why does the tolerance need to be so low?
gmx::test::relativeToleranceAsFloatingPoint(refForcesDouble[i][m], 5e-5));
}
{
for (size_t i = 0; i < energies.size(); ++i)
{
- EXPECT_REAL_EQ_TOL(energies[i], refEnergies[i],
+ EXPECT_REAL_EQ_TOL(energies[i],
+ refEnergies[i],
gmx::test::relativeToleranceAsFloatingPoint(refEnergies[i], 1e-5));
}
}
{
for (size_t m = 0; m < dimSize; ++m)
{
- EXPECT_REAL_EQ_TOL(refMasterBuffer[i][m], masterBuffer[i][m],
- gmx::test::defaultRealTolerance());
+ EXPECT_REAL_EQ_TOL(
+ refMasterBuffer[i][m], masterBuffer[i][m], gmx::test::defaultRealTolerance());
}
}
using InteractionContainerType = std::decay_t<decltype(interactionElement)>;
using InteractionType = typename InteractionContainerType::type;
- std::sort(begin(interactionElement.indices), end(interactionElement.indices),
+ std::sort(begin(interactionElement.indices),
+ end(interactionElement.indices),
interactionSortKey<InteractionType>);
};
+ name_.value());
}
- addInteractionImpl(interaction, particleI.particleName(), residueName(particleI),
- particleJ.particleName(), residueName(particleJ));
+ addInteractionImpl(interaction,
+ particleI.particleName(),
+ residueName(particleI),
+ particleJ.particleName(),
+ residueName(particleJ));
}
void Molecule::addInteraction(const ParticleIdentifier& particleI,
+ name_.value());
}
- addInteractionImpl(interaction, particleI.particleName(), residueName(particleI),
- particleJ.particleName(), residueName(particleJ), particleK.particleName(),
+ addInteractionImpl(interaction,
+ particleI.particleName(),
+ residueName(particleI),
+ particleJ.particleName(),
+ residueName(particleJ),
+ particleK.particleName(),
residueName(particleK));
}
+ name_.value());
}
- addInteractionImpl(interaction, particleI.particleName(), residueName(particleI),
- particleJ.particleName(), residueName(particleJ), particleK.particleName(),
- residueName(particleK), particleL.particleName(), residueName(particleL));
+ addInteractionImpl(interaction,
+ particleI.particleName(),
+ residueName(particleI),
+ particleJ.particleName(),
+ residueName(particleJ),
+ particleK.particleName(),
+ residueName(particleK),
+ particleL.particleName(),
+ residueName(particleL));
}
void Molecule::addInteraction(const ParticleIdentifier& particleI,
+ name_.value());
}
- addInteractionImpl(interaction, particleI.particleName(), residueName(particleI),
- particleJ.particleName(), residueName(particleJ), particleK.particleName(),
- residueName(particleK), particleL.particleName(), residueName(particleL),
- particleM.particleName(), residueName(particleM));
+ addInteractionImpl(interaction,
+ particleI.particleName(),
+ residueName(particleI),
+ particleJ.particleName(),
+ residueName(particleJ),
+ particleK.particleName(),
+ residueName(particleK),
+ particleL.particleName(),
+ residueName(particleL),
+ particleM.particleName(),
+ residueName(particleM));
}
}
// duplication for the swapped pair happens in getExclusions()
- exclusionsByName_.emplace_back(std::make_tuple(particle.particleName(), residueName(particle),
+ exclusionsByName_.emplace_back(std::make_tuple(particle.particleName(),
+ residueName(particle),
particleToExclude.particleName(),
residueName(particleToExclude)));
}
const std::string& residueName2 = std::get<3>(tup);
// look up first index (binary search)
- auto it1 = std::lower_bound(std::begin(indexKey), std::end(indexKey),
- std::make_tuple(particleName1, residueName2, 0), sortKey);
+ auto it1 = std::lower_bound(std::begin(indexKey),
+ std::end(indexKey),
+ std::make_tuple(particleName1, residueName2, 0),
+ sortKey);
// make sure we have the (particleName,residueName) combo
if (it1 == std::end(indexKey) or std::get<0>(*it1) != particleName1 or std::get<1>(*it1) != residueName1)
int firstIndex = std::get<2>(*it1);
// look up second index (binary search)
- auto it2 = std::lower_bound(std::begin(indexKey), std::end(indexKey),
- std::make_tuple(particleName2, residueName2, 0), sortKey);
+ auto it2 = std::lower_bound(std::begin(indexKey),
+ std::end(indexKey),
+ std::make_tuple(particleName2, residueName2, 0),
+ sortKey);
// make sure we have the (particleName,residueName) combo
if (it2 == std::end(indexKey) or std::get<0>(*it2) != particleName2 or std::get<1>(*it2) != residueName2)
// TODO: use string format function once we have it
if (moleculeName.value() == residueName.value())
{
- printf("No particle %s in residue %s in molecule %s found\n", particleName.value().c_str(),
- residueName.value().c_str(), moleculeName.value().c_str());
+ printf("No particle %s in residue %s in molecule %s found\n",
+ particleName.value().c_str(),
+ residueName.value().c_str(),
+ moleculeName.value().c_str());
}
else
{
- printf("No particle %s in molecule %s found\n", particleName.value().c_str(),
+ printf("No particle %s in molecule %s found\n",
+ particleName.value().c_str(),
moleculeName.value().c_str());
}
gmx::ArrayRef<nblib::Vec3> userForces(simState.forces());
forceCalculator.compute(simState.coordinates(), userForces);
// Print some diagnostic info
- printf(" final forces on particle 0: x %4f y %4f z %4f\n", userForces[0][0], userForces[0][1],
+ printf(" final forces on particle 0: x %4f y %4f z %4f\n",
+ userForces[0][0],
+ userForces[0][1],
userForces[0][2]);
// User may modify forces stored in simState.forces() if needed
// Print some diagnostic info
- printf("initial position of particle 0: x %4f y %4f z %4f\n", simState.coordinates()[0][0],
- simState.coordinates()[0][1], simState.coordinates()[0][2]);
+ printf("initial position of particle 0: x %4f y %4f z %4f\n",
+ simState.coordinates()[0][0],
+ simState.coordinates()[0][1],
+ simState.coordinates()[0][2]);
// Integrate with a time step of 1 fs
integrator.integrate(1.0, simState.coordinates(), simState.velocities(), simState.forces());
// Print some diagnostic info
- printf(" final position of particle 0: x %4f y %4f z %4f\n", simState.coordinates()[0][0],
- simState.coordinates()[0][1], simState.coordinates()[0][2]);
+ printf(" final position of particle 0: x %4f y %4f z %4f\n",
+ simState.coordinates()[0][0],
+ simState.coordinates()[0][1],
+ simState.coordinates()[0][2]);
return 0;
}
ForceCalculator forceCalculator(simulationState, options);
// The listed force calculator is also initialized with the required arguments
- ListedForceCalculator listedForceCalculator(topology.getInteractionData(),
- topology.numParticles(), 4, box);
+ ListedForceCalculator listedForceCalculator(
+ topology.getInteractionData(), topology.numParticles(), 4, box);
// Integrator is initialized with an array of inverse masses (constructed from topology) and
// the bounding box
LeapFrog integrator(topology, box);
// Print some diagnostic info
- printf("initial position of particle 0: x %4f y %4f z %4f\n", simulationState.coordinates()[0][0],
- simulationState.coordinates()[0][1], simulationState.coordinates()[0][2]);
+ printf("initial position of particle 0: x %4f y %4f z %4f\n",
+ simulationState.coordinates()[0][0],
+ simulationState.coordinates()[0][1],
+ simulationState.coordinates()[0][2]);
// MD Loop
int numSteps = 2;
listedForceCalculator.compute(simulationState.coordinates(), simulationState.forces());
// Integrate with a time step of 1 fs, positions, velocities and forces
- integrator.integrate(1.0, simulationState.coordinates(), simulationState.velocities(),
- simulationState.forces());
+ integrator.integrate(
+ 1.0, simulationState.coordinates(), simulationState.velocities(), simulationState.forces());
}
- printf(" final position of particle 9: x %4f y %4f z %4f\n", simulationState.coordinates()[9][0],
- simulationState.coordinates()[9][1], simulationState.coordinates()[9][2]);
+ printf(" final position of particle 9: x %4f y %4f z %4f\n",
+ simulationState.coordinates()[9][0],
+ simulationState.coordinates()[9][1],
+ simulationState.coordinates()[9][2]);
return 0;
} // main
)
target_include_directories(nblib_test_infrastructure PRIVATE ${PROJECT_SOURCE_DIR}/api)
target_include_directories(nblib_test_infrastructure SYSTEM PRIVATE ${PROJECT_SOURCE_DIR}/src/external)
+target_link_libraries(nblib_test_infrastructure PRIVATE legacy_api)
+# TODO: Explicitly link specific modules: math,
+target_link_libraries(nblib_test_infrastructure PRIVATE legacy_modules)
set(testname "NbLibSetupTests")
set(exename "nblib-setup-test")
<< formatString(
"Coordinate {} of atom {} is different from analytical solution "
"at step {}.",
- d, i, step);
+ d,
+ i,
+ step);
EXPECT_REAL_EQ_TOL(vAnalytical[d], simulationState.velocities()[i][d], tolerance)
<< formatString(
"Velocity component {} of atom {} is different from analytical "
"solution at step {}.",
- d, i, step);
+ d,
+ i,
+ step);
}
- integrator.integrate(dt, simulationState.coordinates(), simulationState.velocities(),
+ integrator.integrate(dt,
+ simulationState.coordinates(),
+ simulationState.velocities(),
simulationState.forces());
}
}
EXPECT_REAL_EQ_TOL(c12_1, nbfp.getC12(atom1.name(), atom1.name()), gmx::test::defaultRealTolerance());
//! geometric comb rule for c6
- EXPECT_REAL_EQ_TOL(std::sqrt(c6_1 * c6_2), nbfp.getC6(atom1.name(), atom2.name()),
+ EXPECT_REAL_EQ_TOL(std::sqrt(c6_1 * c6_2),
+ nbfp.getC6(atom1.name(), atom2.name()),
gmx::test::defaultRealTolerance());
//! + symmetric pair
- EXPECT_REAL_EQ_TOL(std::sqrt(c6_1 * c6_2), nbfp.getC6(atom2.name(), atom1.name()),
+ EXPECT_REAL_EQ_TOL(std::sqrt(c6_1 * c6_2),
+ nbfp.getC6(atom2.name(), atom1.name()),
gmx::test::defaultRealTolerance());
//! geometric comb rule for c12
- EXPECT_REAL_EQ_TOL(std::sqrt(c12_1 * c12_2), nbfp.getC12(atom1.name(), atom2.name()),
+ EXPECT_REAL_EQ_TOL(std::sqrt(c12_1 * c12_2),
+ nbfp.getC12(atom1.name(), atom2.name()),
gmx::test::defaultRealTolerance());
//! + symmetric par
- EXPECT_REAL_EQ_TOL(std::sqrt(c12_1 * c12_2), nbfp.getC12(atom2.name(), atom1.name()),
+ EXPECT_REAL_EQ_TOL(std::sqrt(c12_1 * c12_2),
+ nbfp.getC12(atom2.name(), atom1.name()),
gmx::test::defaultRealTolerance());
//! explicit pairwise interaction c6
EXPECT_REAL_EQ_TOL(c6comb, nbfp.getC6(atom3.name(), atom2.name()), gmx::test::defaultRealTolerance());
//! explicit pairwise interaction c12
- EXPECT_REAL_EQ_TOL(c12comb, nbfp.getC12(atom2.name(), atom3.name()),
- gmx::test::defaultRealTolerance());
- EXPECT_REAL_EQ_TOL(c12comb, nbfp.getC12(atom3.name(), atom2.name()),
- gmx::test::defaultRealTolerance());
+ EXPECT_REAL_EQ_TOL(
+ c12comb, nbfp.getC12(atom2.name(), atom3.name()), gmx::test::defaultRealTolerance());
+ EXPECT_REAL_EQ_TOL(
+ c12comb, nbfp.getC12(atom3.name(), atom2.name()), gmx::test::defaultRealTolerance());
ParticleType atom4(ParticleTypeName("a4"), Mass(1));
interactions.add(atom3.name(), atom4.name(), C6(1), C12(2));
auto nbfp = interactions.generateTable();
- EXPECT_REAL_EQ_TOL(std::sqrt(c6_3 * c6_4), nbfp.getC6(atom3.name(), atom4.name()),
- gmx::test::defaultRealTolerance());
- EXPECT_REAL_EQ_TOL(std::sqrt(c12_3 * c12_4), nbfp.getC12(atom3.name(), atom4.name()),
- gmx::test::defaultRealTolerance());
- EXPECT_REAL_EQ_TOL(c6_override, nbfp.getC6(atom4.name(), atom5.name()),
+ EXPECT_REAL_EQ_TOL(std::sqrt(c6_3 * c6_4),
+ nbfp.getC6(atom3.name(), atom4.name()),
gmx::test::defaultRealTolerance());
- EXPECT_REAL_EQ_TOL(c12_override, nbfp.getC12(atom4.name(), atom5.name()),
+ EXPECT_REAL_EQ_TOL(std::sqrt(c12_3 * c12_4),
+ nbfp.getC12(atom3.name(), atom4.name()),
gmx::test::defaultRealTolerance());
+ EXPECT_REAL_EQ_TOL(
+ c6_override, nbfp.getC6(atom4.name(), atom5.name()), gmx::test::defaultRealTolerance());
+ EXPECT_REAL_EQ_TOL(
+ c12_override, nbfp.getC12(atom4.name(), atom5.name()), gmx::test::defaultRealTolerance());
}
} // namespace
{
gmx::ArrayRef<Vec3> forces(simState.forces());
forceCalculator.compute(simState.coordinates(), simState.forces());
- EXPECT_NO_THROW(integrator.integrate(1.0, simState.coordinates(), simState.velocities(),
- simState.forces()));
+ EXPECT_NO_THROW(integrator.integrate(
+ 1.0, simState.coordinates(), simState.velocities(), simState.forces()));
}
}
std::vector<std::string> typeNames = { "Ow", "H" };
for (const auto& name : typeNames)
{
- interactions.add(ParticleTypeName(name), library.c6(ParticleName(name)),
- library.c12(ParticleName(name)));
+ interactions.add(
+ ParticleTypeName(name), library.c6(ParticleName(name)), library.c12(ParticleName(name)));
}
// Add some molecules to the topology
std::vector<std::string> typeNames = { "Ow", "H", "OMet", "CMet" };
for (const auto& name : typeNames)
{
- interactions.add(ParticleTypeName(name), library.c6(ParticleName(name)),
- library.c12(ParticleName(name)));
+ interactions.add(
+ ParticleTypeName(name), library.c6(ParticleName(name)), library.c12(ParticleName(name)));
}
// Add some molecules to the topology
ParticleLibrary library;
ParticleTypesInteractions nbinteractions;
- nbinteractions.add(ParticleTypeName("Ar"), library.c6(ParticleName("Ar")),
- library.c12(ParticleName("Ar")));
+ nbinteractions.add(
+ ParticleTypeName("Ar"), library.c6(ParticleName("Ar")), library.c12(ParticleName("Ar")));
Molecule argonMolecule(MoleculeName("AR"));
argonMolecule.addParticle(ParticleName("AR"), library.type("Ar"));
WaterTopologyBuilder waters;
Topology watersTopology = waters.buildTopology(2);
- EXPECT_EQ(0, watersTopology.sequenceID(MoleculeName("SOL"), 0, ResidueName("SOL"),
- ParticleName("Oxygen")));
+ EXPECT_EQ(0, watersTopology.sequenceID(MoleculeName("SOL"), 0, ResidueName("SOL"), ParticleName("Oxygen")));
EXPECT_EQ(1, watersTopology.sequenceID(MoleculeName("SOL"), 0, ResidueName("SOL"), ParticleName("H1")));
EXPECT_EQ(2, watersTopology.sequenceID(MoleculeName("SOL"), 0, ResidueName("SOL"), ParticleName("H2")));
- EXPECT_EQ(3, watersTopology.sequenceID(MoleculeName("SOL"), 1, ResidueName("SOL"),
- ParticleName("Oxygen")));
+ EXPECT_EQ(3, watersTopology.sequenceID(MoleculeName("SOL"), 1, ResidueName("SOL"), ParticleName("Oxygen")));
EXPECT_EQ(4, watersTopology.sequenceID(MoleculeName("SOL"), 1, ResidueName("SOL"), ParticleName("H1")));
EXPECT_EQ(5, watersTopology.sequenceID(MoleculeName("SOL"), 1, ResidueName("SOL"), ParticleName("H2")));
}
std::vector<HarmonicBondType> bondsTest;
// use the expansionArray (bondsExpansion) to expand to the full list if bonds
- std::transform(begin(bondsExpansion), end(bondsExpansion), std::back_inserter(bondsTest),
+ std::transform(begin(bondsExpansion),
+ end(bondsExpansion),
+ std::back_inserter(bondsTest),
[&bonds](size_t i) { return bonds[i]; });
std::vector<HarmonicBondType> waterBonds =
#undef SORT
/// \endcond
- EXPECT_TRUE(std::equal(begin(interactions_reference), end(interactions_reference),
- begin(interactions_test)));
+ EXPECT_TRUE(std::equal(
+ begin(interactions_reference), end(interactions_reference), begin(interactions_test)));
}
TEST(NBlibTest, TopologyListedInteractionsMultipleTypes)
int MeH1 = topology.sequenceID(MoleculeName("MeOH"), 0, ResidueName("MeOH"), ParticleName("H3"));
std::vector<CubicBondType> cubicBondsReference{ testBond };
- std::vector<InteractionIndex<CubicBondType>> cubicIndicesReference{ { std::min(H1, H2),
- std::max(H1, H2), 0 } };
+ std::vector<InteractionIndex<CubicBondType>> cubicIndicesReference{
+ { std::min(H1, H2), std::max(H1, H2), 0 }
+ };
EXPECT_EQ(cubicBondsReference, cubicBonds.parameters);
EXPECT_EQ(cubicIndicesReference, cubicBonds.indices);
{
auto offsetExclusions = offsetGmxBlock(exclusionBlockPerMolecule, particleNumberOffset);
- std::copy(std::begin(offsetExclusions), std::end(offsetExclusions),
+ std::copy(std::begin(offsetExclusions),
+ std::end(offsetExclusions),
std::back_inserter(exclusionBlockGlobal));
particleNumberOffset += molecule.numParticlesInMolecule();
// combine stage 1 + 2 expansion arrays
std::vector<size_t> expansionArray(expansionArrayStage1.size());
- std::transform(begin(expansionArrayStage1), end(expansionArrayStage1), begin(expansionArray),
+ std::transform(begin(expansionArrayStage1),
+ end(expansionArrayStage1),
+ begin(expansionArray),
[& S2 = expansionArrayStage2](size_t S1Element) { return S2[S1Element]; });
// add data about InteractionType instances
// coordinateIndices contains the particle sequence IDs of all interaction coordinates of type <BondType>
auto coordinateIndices = detail::sequenceIDs<InteractionType>(this->molecules_, particleSequencer);
// zip coordinateIndices(i,j,...) + expansionArray(k) -> interactionDataElement.indices(i,j,...,k)
- std::transform(begin(coordinateIndices), end(coordinateIndices), begin(expansionArray),
+ std::transform(begin(coordinateIndices),
+ end(coordinateIndices),
+ begin(expansionArray),
begin(interactionDataElement.indices),
[](auto coordinateIndex, auto interactionIndex) {
std::array<int, coordinateIndex.size() + 1> ret{ 0 };
{
std::string message =
formatString("Missing nonbonded interaction parameters for pair {} {}",
- particleType1.first, particleType2.first);
+ particleType1.first,
+ particleType2.first);
throw InputException(message);
}
}
// shift particle numbers by offset
for (auto& localBlock : inBlock)
{
- std::transform(std::begin(localBlock.atomNumber), std::end(localBlock.atomNumber),
- std::begin(localBlock.atomNumber), [offset](auto i) { return i + offset; });
+ std::transform(std::begin(localBlock.atomNumber),
+ std::end(localBlock.atomNumber),
+ std::begin(localBlock.atomNumber),
+ [offset](auto i) { return i + offset; });
}
return inBlock;
fprintf(debug,
"Velocities were taken from a Maxwell distribution\n"
"Initial generated temperature: %12.5e (scaled to: %12.5e)\n",
- temp, tempi);
+ temp,
+ tempi);
}
return velocities;
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2019,2020, by the GROMACS development team, led by
+# Copyright (c) 2019,2020,2021, 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.
message(FATAL_ERROR "${GMX_GPLUSPLUS_PATH}/include/c++ doesn't exist even though it should. "
"Please report to developers.")
endif()
- else() #Intel
- if (${GMX_GPLUSPLUS_VERSION} VERSION_GREATER_EQUAL 7 AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19)
- message(FATAL_ERROR "ICC versions below 19 don't support GCC versions above 6.")
- endif ()
endif()
# Set up to use the libstdc++ from that g++. Note that we checked
# we will not override any user settings here.
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --gcc-toolchain=${GMX_GPLUSPLUS_PATH}")
- else() #Intel
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -gcc-name=${GMX_GPLUSPLUS_PATH}")
endif()
endif()
+++ /dev/null
-#
-# This file is part of the GROMACS molecular simulation package.
-#
-# Copyright (c) 2012,2013,2014, 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.
-
-# the name of the target operating system
-set(CMAKE_SYSTEM_NAME Linux CACHE STRING "Cross-compiling for Fujitsu Sparc64, with MPI")
-set(CMAKE_SYSTEM_PROCESSOR "s64fx")
-
-set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE)
-
-# set the compiler
-set(CMAKE_C_COMPILER mpifccpx)
-set(CMAKE_CXX_COMPILER mpiFCCpx)
-
-# Prevent CMake from adding GNU-specific linker flags (-rdynamic)
-set(CMAKE_C_COMPILER_ID "Fujitsu" CACHE STRING "Fujitsu C cross-compiler" FORCE)
-set(CMAKE_CXX_COMPILER_ID "Fujitsu" CACHE STRING "Fujitsu C++ cross-compiler" FORCE)
-
-# FindOpenMP.cmake does not try -Kopenmp,but the package will try specific
-# flags based on the compier ID.
-set(OMP_FLAG_Fujitsu "-Kopenmp")
+++ /dev/null
-#
-# This file is part of the GROMACS molecular simulation package.
-#
-# Copyright (c) 2012,2013,2014, 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.
-
-# the name of the target operating system
-set(CMAKE_SYSTEM_NAME Linux CACHE STRING "Cross-compiling for Fujitsu Sparc64")
-# Set the identification to the same value we would get on the nodes (uname -m)
-set(CMAKE_SYSTEM_PROCESSOR "s64fx")
-
-set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE)
-
-# set the compiler
-set(CMAKE_C_COMPILER fccpx)
-set(CMAKE_CXX_COMPILER FCCpx)
-
-# Prevent CMake from adding GNU-specific linker flags (-rdynamic)
-# A patch has been submitted to make CMake itself handle this in the future
-set(CMAKE_C_COMPILER_ID "Fujitsu" CACHE STRING "Fujitsu C cross-compiler" FORCE)
-set(CMAKE_CXX_COMPILER_ID "Fujitsu" CACHE STRING "Fujitsu C++ cross-compiler" FORCE)
-
-# FindOpenMP.cmake does not try -Kopenmp,but the package will try specific
-# flags based on the compier ID.
-set(OMP_FLAG_Fujitsu "-Kopenmp")
+++ /dev/null
-int main()
-{
-#if defined (__FUJITSU) && ( defined(__sparc) || defined(__sparcv9) ) && ( defined(__LP64__) || defined(__arch64) )
- return 0;
-#else
-#error This compiler is not targetting Fujitsu Sparc64
-#endif
-}
+++ /dev/null
-int main()
-{
-#ifdef __MIC__
- return 0;
-#else
-#error This compiler is not targetting MIC
-#endif
-}
list(APPEND ${SRC_VARIABLE} ${SRC_ROOT}/winthreads.cpp)
endif ()
- if (TMPI_CXX_LIB)
- list(APPEND ${SRC_VARIABLE} ${SRC_ROOT}/system_error.cpp)
- endif ()
-
if (TMPI_ENABLED)
list(APPEND ${SRC_VARIABLE}
${SRC_ROOT}/alltoall.cpp ${SRC_ROOT}/p2p_protocol.cpp
#
# Copyright (c) 2009,2010,2011,2012,2013 by the GROMACS development team.
# Copyright (c) 2014,2015,2016,2017,2018 by the GROMACS development team.
-# Copyright (c) 2019,2020, by the GROMACS development team, led by
+# Copyright (c) 2019,2020,2021, 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.
GMX_TEST_CXXFLAG(CXXFLAGS_NOINLINE "-fno-inline" GMXC_CXXFLAGS_DEBUG)
endif()
- # icc
- if (CMAKE_C_COMPILER_ID MATCHES "Intel")
- if (NOT WIN32)
- if(NOT GMX_OPENMP)
-# 3180: unrecognized OpenMP #pragma
- GMX_TEST_CFLAG(CFLAGS_PRAGMA "-wd3180" GMXC_CFLAGS)
- endif()
- if (GMX_COMPILER_WARNINGS)
-# -w3 enables a lot of useful diagnostics but we don't care about all. -wd disables some selectively.
-# 177: function/variable ".." was declared but never referenced
-# 280: selector expression is constant
-# 411: class defines no constructor to initialize the following (incorrect for struct, initializer list works)
-# 593: variable ".." was set but never used
-# 981: operands are evaluated in unspecified order
-#1418: external function definition with no prior declaration
-#1419: external declaration in primary source file
-#1572: floating-point equality and inequality comparisons are unreliable
-#1599: declaration hides variable ".."
-#2259: non-pointer conversion from ".." to ".." may lose significant bits
-#2415: variable ".." of static storage duration was declared but never referenced
-#2547: ".." was specified as both a system and non-system include directory
-#2557: comparison between signed and unsigned operands
-#3280: declaration hides member ".."
-#11074: Inlining inhibited by limit max-size(/max-total-size)
-#11076: To get full report use -opt-report=3 -opt-report-phase ipo (shown for previous remark)
- GMX_TEST_CFLAG(CFLAGS_WARN "-w3;-wd177;-wd280;-wd411;-wd593;-wd981;-wd1418;-wd1419;-wd1572;-wd1599;-wd2259;-wd2415;-wd2547;-wd2557;-wd3280;-wd11074;-wd11076" GMXC_CFLAGS)
- endif()
- GMX_TEST_CFLAG(CFLAGS_STDGNU "-std=gnu99" GMXC_CFLAGS)
- GMX_TEST_CFLAG(CFLAGS_OPT "-ip;-funroll-all-loops;-alias-const;-ansi-alias;-no-prec-div;-fimf-domain-exclusion=14;-qoverride-limits" GMXC_CFLAGS_RELEASE)
- GMX_TEST_CFLAG(CFLAGS_DEBUG "-O0" GMXC_CFLAGS_DEBUG) #icc defaults to -O2 even with -g
- # The "except" fp-model requires something other than the
- # default "fast" model, so we test and use it with
- # "precise".
- GMX_TEST_CFLAG(CFLAGS_FP_MODEL_RELASSERT "-fp-model=except;-fp-model=precise" GMXC_CFLAGS_RELWITHASSERT)
- else()
- if(NOT GMX_OPENMP)
- GMX_TEST_CFLAG(CFLAGS_PRAGMA "/wd3180" GMXC_CFLAGS)
- endif()
- if (GMX_COMPILER_WARNINGS)
-#only on Windows
-#161: unrecognized pragma
-#1786 function was declared deprecated (is issued for stdlib function such as strncpy which have a _s version)
-GMX_TEST_CFLAG(CFLAGS_WARN "/W3;/wd161;/wd177;/wd411;/wd593;/wd981;/wd1418;/wd1419;/wd1572;/wd1599;/wd1786;/wd2259;/wd2415;/wd2547;/wd2557;/wd3280" GMXC_CFLAGS)
- endif()
- GMX_TEST_CFLAG(CFLAGS_OPT "/Qip" GMXC_CFLAGS_RELEASE)
- endif()
- endif()
-
- if (CMAKE_CXX_COMPILER_ID MATCHES "Intel")
- if (NOT WIN32)
- if(NOT GMX_OPENMP)
- GMX_TEST_CXXFLAG(CXXFLAGS_PRAGMA "-wd3180" GMXC_CXXFLAGS)
- endif()
- if (GMX_COMPILER_WARNINGS)
-#All but the following warnings are identical for the C-compiler (see above)
-# 304: access control not specified
-# 383: value copied to temporary, reference to temporary used
-# 444: destructor for base class ".." is not virtual
-# 869: was never referenced (false positives)
-#2282: unrecognized GCC pragma
-#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)
- # The "except" fp-model requires something other than the
- # default "fast" model, so we test and use it with
- # "precise".
- GMX_TEST_CXXFLAG(CXXFLAGS_FP_MODEL_RELASSERT "-fp-model=except;-fp-model=precise" GMXC_CXXFLAGS_RELWITHASSERT)
- else()
- if(NOT GMX_OPENMP)
- GMX_TEST_CXXFLAG(CXXFLAGS_PRAGMA "/wd3180" GMXC_CFLAGS)
- endif()
- if (GMX_COMPILER_WARNINGS)
-#161: unrecognized pragma
-#809: exception specification for virtual function X is incompatible with that of overridden function
- GMX_TEST_CXXFLAG(CXXFLAGS_WARN "/W3;/wd161;/wd177;/wd280;/wd304;/wd383;/wd411;/wd444;/wd809;/wd869;/wd981;/wd1418;/wd1572;/wd1599;/wd1786;/wd2259;/wd2547;/wd3280;/wd11074;/wd11076;/wd2282" GMXC_CXXFLAGS)
- endif()
- GMX_TEST_CXXFLAG(CXXFLAGS_OPT "/Qip" GMXC_CXXFLAGS_RELEASE)
- endif()
- endif()
-
# PGI
# Inter-procedural analysis causes pgcc/pgc++ to crash when linking the library with PGI release 15.7.
if (CMAKE_C_COMPILER_ID MATCHES "PGI")
endif()
endif()
- # Fujitsu compilers on PrimeHPC/Sparc64
- if(${CMAKE_C_COMPILER_ID} MATCHES Fujitsu OR
- (${CMAKE_C_COMPILER_ID} MATCHES unknown AND ${CMAKE_C_COMPILER} MATCHES ^fcc))
- GMX_TEST_CFLAG(CFLAG_GNUCOMPAT "-Xg;-w" GMXC_CFLAGS)
- GMX_TEST_CFLAG(CFLAG_OPT "-Kfast,reduction,swp,simd=2,uxsimd,fsimple;-x100" GMXC_CFLAGS)
- endif()
-
- if(${CMAKE_CXX_COMPILER_ID} MATCHES Fujitsu OR
- (${CMAKE_CXX_COMPILER_ID} MATCHES unknown AND ${CMAKE_CXX_COMPILER} MATCHES ^FCC))
- GMX_TEST_CXXFLAG(CXXFLAG_GNUCOMPAT "-Xg;-w" GMXC_CXXFLAGS)
- GMX_TEST_CXXFLAG(CXXFLAG_OPT "-Kfast,reduction,swp,simd=2,uxsimd,fsimple;-x100" GMXC_CXXFLAGS)
- endif()
-
endmacro()
# This file is part of the GROMACS molecular simulation package.
#
# Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team.
-# Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
+# Copyright (c) 2017,2018,2019,2020,2021, 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.
else()
if(CPU_DETECTION_FEATURES MATCHES " vsx ")
set(OUTPUT_SIMD "IBM_VSX")
- elseif(CPU_DETECTION_FEATURES MATCHES " vmx ")
- set(OUTPUT_SIMD "IBM_VMX")
elseif(CPU_DETECTION_FEATURES MATCHES " sve ")
set(OUTPUT_SIMD "ARM_SVE")
elseif(CPU_DETECTION_FEATURES MATCHES " neon_asimd ")
set(OUTPUT_SIMD "ARM_NEON_ASIMD")
- elseif(CPU_DETECTION_FEATURES MATCHES " neon " AND NOT GMX_DOUBLE)
- set(OUTPUT_SIMD "ARM_NEON")
endif()
endif()
if (NOT SUGGEST_SIMD_QUIETLY)
function(gmx_detect_simd _suggested_simd)
if(GMX_SIMD STREQUAL "AUTO")
- if(GMX_TARGET_FUJITSU_SPARC64)
- # HPC-ACE is always present. In the future we
- # should add detection for HPC-ACE2 here.
- set(${_suggested_simd} "Sparc64_HPC_ACE")
- elseif(GMX_TARGET_MIC)
- set(${_suggested_simd} "MIC")
- else()
- gmx_suggest_simd(${_suggested_simd})
- endif()
+ gmx_suggest_simd(${_suggested_simd})
string(TOUPPER "${${_suggested_simd}}" ${_suggested_simd})
set(${_suggested_simd} ${${_suggested_simd}} PARENT_SCOPE)
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2013,2014,2016,2018,2019,2020, by the GROMACS development team, led by
+# Copyright (c) 2013,2014,2016,2018,2019,2020, by the GROMACS development team.
+# Copyright (c) 2021, 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_X86 ${CMAKE_BINARY_DIR}
"${CMAKE_SOURCE_DIR}/cmake/TestX86.cpp")
endif()
- if (NOT DEFINED GMX_TARGET_MIC)
- 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,2015,2016 by the GROMACS development team.
-# Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
+# Copyright (c) 2017,2018,2019,2020,2021, 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.
# all their stuff. It's not easy if you only want some of their
# stuff...
set(MKL_MANUALLY FALSE)
-if (GMX_FFT_LIBRARY STREQUAL "MKL" AND
- NOT ((CMAKE_C_COMPILER_ID MATCHES "Intel" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER "11")
- OR GMX_ICC_NEXTGEN))
+if (GMX_FFT_LIBRARY STREQUAL "MKL" AND NOT GMX_ICC_NEXTGEN)
# The user will have to provide the set of magic libraries in
# MKL_LIBRARIES (see below), which we cache (non-advanced), so that they
# don't have to keep specifying it, and can easily see that
set(FFT_LIBRARIES ${${FFTW}_LIBRARIES})
elseif(${GMX_FFT_LIBRARY} STREQUAL "MKL")
- # Intel 11 and up makes life somewhat easy if you just want to use
+ # Intel compilers make life somewhat easy if you just want to use
# all their stuff. It's not easy if you only want some of their
# stuff...
if (NOT MKL_MANUALLY)
+++ /dev/null
-#
-# This file is part of the GROMACS molecular simulation package.
-#
-# 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.
-#
-# 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.
-
-# Managing configuration for Fujitsu PrimeHPC Sparc64
-# For now this is mainly used for K computer.
-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)
-
-set(GMX_SOFTWARE_INVSQRT OFF CACHE BOOL "Use native 1.0/sqrt(x) on Fujitsu Sparc64" FORCE)
-set(GMX_X11 OFF CACHE BOOL "X11 not compatible with Fujitsu Sparc64 cross-compile, disabled." FORCE)
-
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2013,2014,2016,2020, by the GROMACS development team, led by
+# Copyright (c) 2013,2014,2016,2020,2021, 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.
# these. If the libraries are not in a standard location, the user can
# indicate a search path with CMAKE_PREFIX_PATH.
#
-# However, if we are using icc+mkl (so a build command that includes
+# However, if we are using icpx+mkl (so a build command that includes
# -mkl), then it is probably painful to try to link some other BLAS or
# LAPACK. In that case, we use the BLAS & LAPACK provided by MKL. In
# principle, we could offer a more configurable behaviour if/when
# This file is part of the GROMACS molecular simulation package.
#
# Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team.
-# Copyright (c) 2019,2020, by the GROMACS development team, led by
+# Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
# and including many others, as listed in the AUTHORS file in the
# top-level source directory and at http://www.gromacs.org.
# If CMAKE_C_COMPILER is not a MPI wrapper. Try to find MPI using cmake module as fall-back.
if(NOT MPI_FOUND)
find_package(MPI)
- if(MPI_C_FOUND)
- set(MPI_COMPILE_FLAGS ${MPI_C_COMPILE_FLAGS})
+ if (MPI_CXX_VERSION VERSION_LESS 2.0)
+ message(FATAL_ERROR "MPI version 2.0 or higher is required. Please update your MPI library.")
+ endif()
+ if(MPI_CXX_FOUND)
+ set(MPI_COMPILE_FLAGS ${MPI_CXX_COMPILE_FLAGS})
separate_arguments(MPI_COMPILE_FLAGS)
- set(MPI_LINKER_FLAGS ${MPI_C_LINK_FLAGS})
- separate_arguments(MPI_C_LINK_FLAGS)
- include_directories(SYSTEM ${MPI_C_INCLUDE_PATH})
- list(APPEND GMX_COMMON_LIBRARIES ${MPI_C_LIBRARIES})
+ set(MPI_LINKER_FLAGS ${MPI_CXX_LINK_FLAGS})
+ separate_arguments(MPI_CXX_LINK_FLAGS)
+ include_directories(SYSTEM ${MPI_CXX_INCLUDE_PATH})
+ list(APPEND GMX_COMMON_LIBRARIES ${MPI_CXX_LIBRARIES})
endif()
- set(MPI_FOUND ${MPI_C_FOUND})
+ set(MPI_FOUND ${MPI_CXX_FOUND})
else()
# The following defaults are based on FindMPI.cmake in cmake
# 3.1.2. (That package does not actually do any detection of the
endif()
if(MPI_FOUND)
- include(gmxTestMPI_IN_PLACE)
- if (GMX_MPI_IN_PLACE)
- gmx_test_mpi_in_place(MPI_IN_PLACE_EXISTS)
- endif()
-
# Find path of the mpi compilers
- if (${MPI_C_FOUND})
- get_filename_component(_mpi_c_compiler_path "${MPI_C_COMPILER}" PATH)
+ if (${MPI_CXX_FOUND})
+ get_filename_component(_mpi_c_compiler_path "${MPI_CXX_COMPILER}" PATH)
get_filename_component(_mpiexec_path "${MPIEXEC}" PATH)
else()
get_filename_component(_cmake_c_compiler_path "${CMAKE_C_COMPILER}" PATH)
message(FATAL_ERROR
"MPI support requested, but no MPI compiler found. Either set the "
"C-compiler (CMAKE_C_COMPILER) to the MPI compiler (often called mpicc), "
- "or set the variables reported missing for MPI_C above.")
+ "or set the variables reported missing for MPI_CXX above.")
endif()
set(GMX_LIB_MPI 1)
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2020, by the GROMACS development team, led by
+# Copyright (c) 2020,2021, by the GROMACS development team, led by
# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
# and including many others, as listed in the AUTHORS file in the
# top-level source directory and at http://www.gromacs.org.
"#include <CL/sycl.hpp>
namespace sycl = cl::sycl;
int main(){
- constexpr int length = 1000;
sycl::queue q(sycl::default_selector{});
- // Check USM extension
- sycl::usm_allocator<int, sycl::usm::alloc::shared> q_alloc{q};
- std::vector<int, sycl::usm_allocator<int, sycl::usm::alloc::shared>> v(q_alloc);
- v.reserve(length);
- for(int i = 0; i < length ; i++) { v.push_back(i); }
- q.parallel_for<class whatever>(sycl::range<1>{length}, [=, ptr = v.data()] (sycl::id<1> i){ ptr[i] *= 2; }).wait();
return 0;
}
- " "CXX" DISABLE_SYCL_CXX_FLAGS SYCL_CXX_FLAGS "-fsycl")
+ " "CXX" DISABLE_SYCL_CXX_FLAGS SYCL_CXX_FLAGS "-fsycl -fsycl-device-code-split=per_kernel")
if(NOT CHECK_SYCL_CXX_FLAGS_QUIETLY)
if(SYCL_CXX_FLAGS_RESULT)
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2012,2013,2014,2015,2018,2020, by the GROMACS development team, led by
+# Copyright (c) 2012,2013,2014,2015,2018,2020,2021, 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.
########################################################################
# Determine the defaults (this block has no effect if the variables have
# already been set)
-if((APPLE OR CYGWIN OR ${CMAKE_SYSTEM_NAME} MATCHES "Linux|.*BSD|GNU") AND NOT GMX_BUILD_MDRUN_ONLY)
+if((APPLE OR CYGWIN OR ${CMAKE_SYSTEM_NAME} MATCHES "Linux|.*BSD|GNU"))
# Maybe Solaris should be here? Patch this if you know!
SET(SHARED_LIBS_DEFAULT ON)
elseif(WIN32)
set(GMX_PREFER_STATIC_LIBS_DEFAULT ON)
endif()
-if(BUILD_SHARED_LIBS AND GMX_BUILD_MDRUN_ONLY)
- message(WARNING "Both BUILD_SHARED_LIBS and GMX_BUILD_MDRUN_ONLY are set. Generally, an mdrun-only build should prefer to use static libraries, which is the default if you make a fresh build tree. You may be re-using an old build tree, and so may wish to set BUILD_SHARED_LIBS=off yourself.")
-endif()
-
if (UNIX)
set(GMX_PREFER_STATIC_LIBS_DESCRIPTION
"When finding libraries prefer static archives (it will only work if static versions of external dependencies are available and found)")
# This file is part of the GROMACS molecular simulation package.
#
# Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team.
-# Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
+# Copyright (c) 2017,2018,2019,2020,2021, by the GROMACS development team, led by
# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
# and including many others, as listed in the AUTHORS file in the
# top-level source directory and at http://www.gromacs.org.
set(SIMD_STATUS_MESSAGE "Enabling 256-bit AVX2 SIMD instructions using CXX flags: ${SIMD_AVX2_CXX_FLAGS}")
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. This SIMD support is deprecated.")
-
elseif(GMX_SIMD_ACTIVE STREQUAL "AVX_512")
gmx_find_simd_avx_512_flags(SIMD_AVX_512_C_SUPPORTED SIMD_AVX_512_CXX_SUPPORTED
set(GMX_SIMD_X86_${GMX_SIMD_ACTIVE} 1)
set(SIMD_STATUS_MESSAGE "Enabling 512-bit AVX-512-KNL SIMD instructions using CXX flags: ${SIMD_AVX_512_KNL_CXX_FLAGS}")
-elseif(GMX_SIMD_ACTIVE STREQUAL "ARM_NEON")
-
- if (GMX_DOUBLE)
- message(FATAL_ERROR "ARM_NEON SIMD support is not available for a double precision build because the architecture lacks double-precision support")
- endif()
-
- gmx_find_simd_arm_neon_flags(SIMD_ARM_NEON_C_SUPPORTED SIMD_ARM_NEON_CXX_SUPPORTED
- SIMD_ARM_NEON_C_FLAGS SIMD_ARM_NEON_CXX_FLAGS)
-
- if(NOT SIMD_ARM_NEON_C_SUPPORTED OR NOT SIMD_ARM_NEON_CXX_SUPPORTED)
- gmx_give_fatal_error_when_simd_support_not_found("ARM NEON" "disable SIMD support (slower)" "${SUGGEST_BINUTILS_UPDATE}")
- endif()
-
- # If multiple flags are neeed, make them into a list
- 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}. This SIMD support is deprecated.")
-
elseif(GMX_SIMD_ACTIVE STREQUAL "ARM_NEON_ASIMD")
gmx_find_simd_arm_neon_asimd_flags(SIMD_ARM_NEON_ASIMD_C_SUPPORTED SIMD_ARM_NEON_ASIMD_CXX_SUPPORTED
elseif(GMX_SIMD_ACTIVE STREQUAL "ARM_SVE")
- # Note that GMX_RELAXED_DOUBLE_PRECISION is enabled by default in the top-level CMakeLists.txt
gmx_option_multichoice(
GMX_SIMD_ARM_SVE_LENGTH
"SVE vector length in bits"
set(GMX_SIMD_${GMX_SIMD_ACTIVE} 1)
set(SIMD_STATUS_MESSAGE "Enabling ARM (AArch64) SVE Advanced SIMD instructions using CXX flags: ${SIMD_ARM_SVE_CXX_FLAGS}")
-elseif(GMX_SIMD_ACTIVE STREQUAL "IBM_VMX")
-
- gmx_find_simd_ibm_vmx_flags(SIMD_IBM_VMX_C_SUPPORTED SIMD_IBM_VMX_CXX_SUPPORTED
- SIMD_IBM_VMX_C_FLAGS SIMD_IBM_VMX_CXX_FLAGS)
-
- if(NOT SIMD_IBM_VMX_C_SUPPORTED OR NOT SIMD_IBM_VMX_CXX_SUPPORTED)
- gmx_give_fatal_error_when_simd_support_not_found("IBM VMX" "disable SIMD support (slower)" "${SUGGEST_BINUTILS_UPDATE}")
- endif()
-
- # If multiple flags are neeed, make them into a list
- 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}. This SIMD support is deprecated.")
-
elseif(GMX_SIMD_ACTIVE STREQUAL "IBM_VSX")
# IBM_VSX and gcc > 9 do not work together, so we need to prevent people from
set(GMX_SIMD_${GMX_SIMD_ACTIVE} 1)
set(SIMD_STATUS_MESSAGE "Enabling IBM VSX SIMD instructions using CXX flags: ${SIMD_IBM_VSX_CXX_FLAGS}")
-elseif(GMX_SIMD_ACTIVE STREQUAL "SPARC64_HPC_ACE")
-
- # 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. This SIMD support is deprecated.")
-
elseif(GMX_SIMD_ACTIVE STREQUAL "REFERENCE")
# NB: This file handles settings for the SIMD module, so in the interest
# By default, 32-bit windows cannot pass SIMD (SSE/AVX) arguments in registers,
# and even on 64-bit (all platforms) it is only used for a handful of arguments.
-# The __vectorcall (MSVC, from MSVC2013) or __regcall (ICC) calling conventions
-# enable this, which is critical to enable 32-bit SIMD and improves performance
+# The __vectorcall (MSVC, from MSVC2013) calling convention
+# enables this, which is critical to enable 32-bit SIMD and improves performance
# for 64-bit SIMD.
# Check if the compiler supports one of these, and in that case set gmx_simdcall
# to that string. If we do not have any such calling convention modifier, set it
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2013,2014, by the GROMACS development team, led by
+# Copyright (c) 2013,2014,2021, 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.
endif()
endif()
unset(SUFFIXES_CHANGED)
-
-if (GMX_BUILD_MDRUN_ONLY)
- set(GMX_LIBS_SUFFIX "_mdrun${GMX_LIBS_SUFFIX}")
-endif()
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
+# Copyright (c) 2017,2018,2019,2020,2021, 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.
# AVX2
function(gmx_find_simd_avx2_flags C_FLAGS_RESULT CXX_FLAGS_RESULT C_FLAGS_VARIABLE CXX_FLAGS_VARIABLE)
find_x86_toolchain_flags(TOOLCHAIN_C_FLAGS TOOLCHAIN_CXX_FLAGS)
- # For our "AVX2_256" support we would ideally want to enable the instructions
- # we want to use, '-mavx2 -mfma'. icc (v16-18) does not allow doing that and
- # instead, it requires the '-march=core-avx2' flag to be used. Annoyingly, it does
- # however accept the former flags but it is not silent about it issuing warnings
- # that can't be disabled.
- # At the same time Intel's -march=core-avx2 flag is not rejected by gcc/clang either
- # (though they're at least silent). However, -march=core-avx2 is an undocumented
- # flag with unclear behavior in gcc/clang (and might enable some arch-specific optimizations).
- # For this reason, and because we can't distinguish compilers just based on checking flag
- # compatibility, we need to treat the Intel and gcc/clang separately.
- if (CMAKE_C_COMPILER_ID MATCHES "Intel")
- set(TOOLCHAIN_FLAG_FOR_AVX2 "-march=core-avx2")
- else()
- set(TOOLCHAIN_FLAG_FOR_AVX2 "-mavx2 -mfma")
- endif()
gmx_find_flags(SIMD_AVX2_C_FLAGS_RESULT SIMD_AVX2_CXX_FLAGS_RESULT
"#include<immintrin.h>
int main(){__m256i x=_mm256_set1_epi32(5);x=_mm256_add_epi32(x,x);return _mm256_movemask_epi8(x);}"
TOOLCHAIN_C_FLAGS TOOLCHAIN_CXX_FLAGS
SIMD_AVX2_C_FLAGS SIMD_AVX2_CXX_FLAGS
- "${TOOLCHAIN_FLAG_FOR_AVX2}" "-mavx2" "/arch:AVX2" "-hgnu")
+ "-mavx2 -mfma" "-mavx2" "/arch:AVX2" "-hgnu")
if(${SIMD_AVX2_C_FLAGS_RESULT})
set(${C_FLAGS_VARIABLE} "${TOOLCHAIN_C_FLAGS} ${SIMD_AVX2_C_FLAGS}" CACHE INTERNAL "C flags required for AVX2 instructions")
return idata[0]*(int)(_mm512_cmp_ps_mask(x,y,_CMP_LT_OS));}"
TOOLCHAIN_C_FLAGS TOOLCHAIN_CXX_FLAGS
SIMD_AVX_512_C_FLAGS SIMD_AVX_512_CXX_FLAGS
- "-xCORE-AVX512 -qopt-zmm-usage=high" "-xCORE-AVX512" "-mavx512f -mfma" "-mavx512f" "/arch:AVX512" "-hgnu") #ICC should use ZMM if code anyhow uses ZMM
+ "-xCORE-AVX512 -qopt-zmm-usage=high" "-xCORE-AVX512" "-mavx512f -mfma" "-mavx512f" "/arch:AVX512" "-hgnu")
if(${SIMD_AVX_512_C_FLAGS_RESULT})
set(${C_FLAGS_VARIABLE} "${TOOLCHAIN_C_FLAGS} ${SIMD_AVX_512_C_FLAGS}" CACHE INTERNAL "C flags required for AVX-512 instructions")
endfunction()
-# Arm Neon (32-bit ARM)
-function(gmx_find_simd_arm_neon_flags C_FLAGS_RESULT CXX_FLAGS_RESULT C_FLAGS_VARIABLE CXX_FLAGS_VARIABLE)
-
- gmx_find_flags(SIMD_ARM_NEON_C_FLAGS_RESULT SIMD_ARM_NEON_CXX_FLAGS_RESULT
- "#include<arm_neon.h>
- int main(){float32x4_t x=vdupq_n_f32(0.5);x=vmlaq_f32(x,x,x);return vgetq_lane_f32(x,0)>0;}"
- TOOLCHAIN_C_FLAGS TOOLCHAIN_CXX_FLAGS
- SIMD_ARM_NEON_C_FLAGS SIMD_ARM_NEON_CXX_FLAGS
- "-mfpu=neon-vfpv4" "-mfpu=neon" "")
-
- if(${SIMD_ARM_NEON_C_FLAGS_RESULT})
- set(${C_FLAGS_VARIABLE} "${TOOLCHAIN_C_FLAGS} ${SIMD_ARM_NEON_C_FLAGS}" CACHE INTERNAL "C flags required for Arm Neon instructions")
- endif()
- if(${SIMD_ARM_NEON_CXX_FLAGS_RESULT})
- set(${CXX_FLAGS_VARIABLE} "${TOOLCHAIN_CXX_FLAGS} ${SIMD_ARM_NEON_CXX_FLAGS}" CACHE INTERNAL "C++ flags required for Arm Neon instructions")
- endif()
- set(${C_FLAGS_RESULT} ${SIMD_ARM_NEON_C_FLAGS_RESULT} CACHE INTERNAL "Result of test for Arm Neon C flags" FORCE)
- set(${CXX_FLAGS_RESULT} ${SIMD_ARM_NEON_CXX_FLAGS_RESULT} CACHE INTERNAL "Result of test for Arm Neon C++ flags" FORCE)
-endfunction()
-
# Arm Neon Asimd (64-bit ARM)
function(gmx_find_simd_arm_neon_asimd_flags C_FLAGS_RESULT CXX_FLAGS_RESULT C_FLAGS_VARIABLE CXX_FLAGS_VARIABLE)
set(${CXX_FLAGS_RESULT} ${SIMD_ARM_SVE_CXX_FLAGS_RESULT} CACHE INTERNAL "Result of test for Arm SVE C++ flags" FORCE)
endfunction()
-# IBM VMX (power6)
-function(gmx_find_simd_ibm_vmx_flags C_FLAGS_RESULT CXX_FLAGS_RESULT C_FLAGS_VARIABLE CXX_FLAGS_VARIABLE)
-
- gmx_find_flags(SIMD_IBM_VMX_C_FLAGS_RESULT SIMD_IBM_VMX_CXX_FLAGS_RESULT
- "#include<altivec.h>
- int main(){vector float x,y=vec_ctf(vec_splat_s32(1),0);x=vec_madd(y,y,y);return vec_all_ge(y,x);}"
- TOOLCHAIN_C_FLAGS TOOLCHAIN_CXX_FLAGS
- SIMD_IBM_VMX_C_FLAGS SIMD_IBM_VMX_CXX_FLAGS
- "-maltivec -mabi=altivec" "-qarch=auto -qaltivec")
-
- if(${SIMD_IBM_VMX_C_FLAGS_RESULT})
- set(${C_FLAGS_VARIABLE} "${TOOLCHAIN_C_FLAGS} ${SIMD_IBM_VMX_C_FLAGS}" CACHE INTERNAL "C flags required for IBM VMX instructions")
- endif()
- if(${SIMD_IBM_VMX_CXX_FLAGS_RESULT})
- set(${CXX_FLAGS_VARIABLE} "${TOOLCHAIN_CXX_FLAGS} ${SIMD_IBM_VMX_CXX_FLAGS}" CACHE INTERNAL "C++ flags required for IBM VMX instructions")
- endif()
- set(${C_FLAGS_RESULT} ${SIMD_IBM_VMX_C_FLAGS_RESULT} CACHE INTERNAL "Result of test for IBM VMX C flags" FORCE)
- set(${CXX_FLAGS_RESULT} ${SIMD_IBM_VMX_CXX_FLAGS_RESULT} CACHE INTERNAL "Result of test for IBM VMX C++ flags" FORCE)
-endfunction()
-
# IBM VSX (power7 and later)
function(gmx_find_simd_ibm_vsx_flags C_FLAGS_RESULT CXX_FLAGS_RESULT C_FLAGS_VARIABLE CXX_FLAGS_VARIABLE)
find_power_vsx_toolchain_flags(TOOLCHAIN_C_FLAGS TOOLCHAIN_CXX_FLAGS)
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5)
set(cxx_required_version "Clang 5")
endif()
- elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
- if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.1)
- set(cxx_required_version "Intel Compiler 2017")
- endif()
else()
message(WARNING "You are using an unsupported compiler. Please make sure it fully supports C++17.")
endif()
"Earlier versions don't have full C++17 support.")
endif()
+ if (CMAKE_CXX_COMPILER_ID MATCHES "Intel")
+ message(WARNING "The Intel classic compiler is no longer supported. It may pass the tests, but is not tested by the GROMACS developers. Use the clang-based compiler from oneAPI, or gcc")
+ endif()
+
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "XL")
check_cxx_source_compiles(
"// Test in-class array initalizers used with constructor initializer lists
endif()
endif()
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "PGI")
- message(WARNING "Currently tested PGI compiler versions (up to 15.7) generate binaries that do not pass all regression test, and the generated binaries are significantly slower than with GCC, ICC or Clang. For now we do not recommend PGI beyond development testing - make sure to run the regressiontests.")
+ message(WARNING "Currently tested PGI compiler versions (up to 15.7) generate binaries that do not pass all regression test, and the generated binaries are significantly slower than with GCC or Clang. For now we do not recommend PGI beyond development testing - make sure to run the regressiontests.")
endif()
endmacro(gmx_test_compiler_problems)
+++ /dev/null
-#
-# This file is part of the GROMACS molecular simulation package.
-#
-# Copyright (c) 2009,2011,2012,2014,2015 by the GROMACS development team.
-# Copyright (c) 2016,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.
-
-# - Define macro to check if MPI_IN_PLACE exists
-#
-# GMX_TEST_MPI_IN_PLACE(VARIABLE)
-#
-# VARIABLE will be set to true if MPI_IN_PLACE exists
-#
-
-include(CheckCSourceCompiles)
-MACRO(GMX_TEST_MPI_IN_PLACE VARIABLE)
- if(NOT DEFINED MPI_IN_PLACE_COMPILE_OK)
- MESSAGE(STATUS "Checking for MPI_IN_PLACE")
-
- if(CMAKE_VERSION VERSION_LESS 3.12)
- foreach(_FLAG ${MPI_COMPILE_FLAGS})
- set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${_FLAG}")
- endforeach()
- else()
- list(JOIN MPI_COMPILE_FLAGS " " CMAKE_REQUIRED_FLAGS)
- endif()
- set(CMAKE_REQUIRED_INCLUDES ${MPI_INCLUDE_PATH})
- set(CMAKE_REQUIRED_LIBRARIES ${MPI_LIBRARIES})
- check_cxx_source_compiles(
- "#include <mpi.h>
-int main(void) {
- void* buf;
- MPI_Allreduce(MPI_IN_PLACE, buf, 10, MPI_FLOAT, MPI_SUM, MPI_COMM_WORLD);
-}" MPI_IN_PLACE_COMPILE_OK)
-
- if(MPI_IN_PLACE_COMPILE_OK)
- MESSAGE(STATUS "Checking for MPI_IN_PLACE - yes")
- else()
- MESSAGE(STATUS "Checking for MPI_IN_PLACE - no")
- endif()
- set(MPI_IN_PLACE_COMPILE_OK "${MPI_IN_PLACE_COMPILE_OK}" CACHE INTERNAL "Result of mpi_in_place check")
- set(CMAKE_REQUIRED_FLAGS)
- set(CMAKE_REQUIRED_INCLUDES)
- set(CMAKE_REQUIRED_LIBRARIES)
- endif()
- if (MPI_IN_PLACE_COMPILE_OK)
- set(${VARIABLE} ${MPI_IN_PLACE_COMPILE_OK}
- "Result of test for MPI_IN_PLACE")
- endif()
-ENDMACRO(GMX_TEST_MPI_IN_PLACE VARIABLE)
-
-
-
# GROMACS 2019 4
# GROMACS 2020 5
# GROMACS 2021 6
+# GROMACS 2022 7
# LIBRARY_SOVERSION_MINOR so minor version for the built libraries.
# Should be increased for each release that changes only the implementation.
# In GROMACS, the typical policy is to increase it for each patch version
# The GROMACS convention is that these are the version number of the next
# release that is going to be made from this branch.
-set(GMX_VERSION_MAJOR 2021)
-set(GMX_VERSION_PATCH 1)
+set(GMX_VERSION_MAJOR 2022)
+set(GMX_VERSION_PATCH 0)
# The suffix, on the other hand, is used mainly for betas and release
# candidates, where it signifies the most recent such release from
# this branch; it will be empty before the first such release, as well
# here. The important thing is to minimize the chance of third-party
# code being able to dynamically link with a version of libgromacs
# that might not work.
-set(LIBRARY_SOVERSION_MAJOR 6)
+set(LIBRARY_SOVERSION_MAJOR 7)
set(LIBRARY_SOVERSION_MINOR 0)
set(LIBRARY_VERSION ${LIBRARY_SOVERSION_MAJOR}.${LIBRARY_SOVERSION_MINOR}.0)
endif()
set(REGRESSIONTEST_VERSION "${GMX_VERSION_STRING}")
-set(REGRESSIONTEST_BRANCH "release-2021")
+set(REGRESSIONTEST_BRANCH "master")
# Run the regressiontests packaging job with the correct pakage
# version string, and the release box checked, in order to have it
# build the regressiontests tarball with all the right naming. The
how-to/visualize.rst
install-guide/index.rst
release-notes/index.rst
+ release-notes/2022/major/highlights.rst
+ release-notes/2022/major/features.rst
+ release-notes/2022/major/performance.rst
+ release-notes/2022/major/tools.rst
+ release-notes/2022/major/bugs-fixed.rst
+ release-notes/2022/major/removed-functionality.rst
+ release-notes/2022/major/deprecated-functionality.rst
+ release-notes/2022/major/portability.rst
+ release-notes/2022/major/miscellaneous.rst
release-notes/2021/2021.1.rst
release-notes/2021/major/highlights.rst
release-notes/2021/major/features.rst
.. todo:: This could likely be replaced by a (yet another) build type.
-.. cmake:: GMX_BUILD_MDRUN_ONLY
-
- If set ``ON``, the build system is configured to only build and install a
- single :file:`mdrun` executable. To be fully functional, the installed
- :file:`mdrun` requires a standard |Gromacs| installation (with
- ``GMX_BUILD_MDRUN_ONLY=OFF``) in the same installation prefix, as the
- mdrun-only build does not install any data files or scripts, only the
- binary. This is intended for cases where one wants to/needs to compile one
- or more instances of :file:`mdrun` with different build options (e.g., MPI
- or SIMD) than the full installation with the other utilities.
- Defaults to ``OFF``, in which case a single :file:`gmx` executable is built
- and installed, together with all the supporting files. :command:`mdrun` can
- be executed as :command:`gmx mdrun`.
-
.. cmake:: GMX_BUILD_OWN_FFTW
.. cmake:: GMX_BUILD_SHARED_EXE
unaffected by this setting. See reference manual for further
information.
-.. cmake:: GMX_RELAXED_DOUBLE_PRECISION
-
- Permit a double-precision configuration to compute some quantities
- to single-precision accuracy. Particularly on architectures where
- only double-precision SIMD is available (e.g. Sparc machines such
- as the K computer), it is faster to default to ``GMX_DOUBLE=ON``
- and use SIMD than to use ``GMX_DOUBLE=OFF`` and use no
- SIMD. However, if the user does not need full double precision,
- then some optimizations can achieve the equivalent of
- single-precision results (e.g. fewer Newton-Raphson iterations for
- a reciprocal square root computation).
-
.. cmake:: GMX_EXTRAE
.. cmake:: GMX_EXTERNAL_BLAS
headers fall in this category. See Doxygen documentation for
:file:`gmxpre.h`.
- All the above files get generated in :file:`src/`.
+ The above files are available through the INTERFACE_INCLUDE_DIR of
+ the ``common`` CMake target. I.e. to ``#include "config.h"``, be sure to
+ ``target_link_libraries(mymodule PRIVATE common)``
Additionally, the following file is generated by the build system:
Steps:
-1. Create a `personal access token <https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html>`__
- with ``write_registry`` scope. Save the hash!
-2. Authenticate from the command line with ``docker login registry.gitlab.com -u <token name> -p <hash>``
+1. Create a `personal access token <https://gitlab.com/-/profile/personal_access_tokens>`__ (`docs <https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html>`__)
+ with ``write_registry`` and ``read_registry`` scopes. Save the hash!
+2. Authenticate from the command line with ``docker login registry.gitlab.com -u <user name> -p <hash>``
3. ``docker push registry.gitlab.com/gromacs/gromacs/<imagename>``
Refer to :file:`buildall.sh` in the ``master`` branch for the set of images
to build the ``man`` target manually before installing). See
:cmake:`GMX_BUILD_HELP`.
-Some documentation cannot be built if the CMake option
-``GMX_BUILD_MDRUN_ONLY`` is enabled, or when cross-compiling, as it
+Some documentation cannot be built when cross-compiling, as it
requires executing the ``gmx`` binary.
The following make targets are the most useful:
Avoid using *before-script* directly, and be cautious
about nested *extends* overriding multiple *before_script* definitions.
- cache
+ job cache
There is no global default, but jobs that build software will likely
set *cache*. To explicitly unset *cache* directives, specify a job
parameter of ``cache: {}``.
1. Each *source* file should include ``gmxpre.h`` first.
2. If a *source* file has a corresponding header, it should be included next.
If the header is in the same directory as the source, then it is included
- without any path (i.e., relative to the source), otherwise relative to
- ``src/`` (the latter case should be rare).
+ without any path (i.e., relative to the source). Otherwise, the canonical
+ include path of ``libraryname/modulename/header.h`` is used.
3. If the file depends on defines from ``config.h``, that comes next.
4. This is followed by standard C/C++ headers, grouped as follows:
``<gtest/gtest.h>``.
6. |Gromacs|-specific libraries from ``src/external/``, such as
``"thread_mpi/threads.h"``.
-7. |Gromacs|-specific headers that are not internal to the including module,
- included with a path relative to ``src/``.
-8. In *test* files, headers not internal to the module, but specific to
- testing code, are in a separate block at this point, paths relative to
- ``src/``.
-9. Finally, |Gromacs| headers that are internal to the including module are
- included using a relative path (but never with a path starting with ``../``;
- such headers go into group 7 instead). For test files, this group contains
- headers that are internal to tests for that module.
+7. |Gromacs| headers that are not part of the including module.
+8. Public |Gromacs| headers that are part of the including module.
+9. Finally, |Gromacs| headers that are internal to the including module,
+ executable, or test target
+ (typically at the same path as the source file).
All |Gromacs| headers are included with quotes (``"gromacs/utility/path.h"``),
other headers with angle brackets (``<stdio.h>``). Headers under ``src/external/``
cases. Trailing comments on the same line as #include statements are
preserved and do not affect the checker/sorter.
-The includestyle used to differentiate between header files that were declared
-to be part of the module and not used outside the module, and those that were
-either not part of a module, used in other modules, or installed.
-As the possibility of installation has been removed (for now), changes to the
-previous organization might occur where such installed files were implicitly
-marked as being used outside of a module even though they were not used within
-|Gromacs| outside their module.
-
As part of the effort to build a proper API, a new scheme of separating between
public, library and module functionality in header files is planned.
-
-The guidelines are enforced by an automatic checker script that can also
-sort/reformat include statements to follow the guidelines.
-See :doc:`gmxtree` for details.
+See also :doc:`gmxtree` and
+`API restructuring issues <https://gitlab.com/gromacs/gromacs/-/issues?label_name%5B%5D=API+restructuring>`__
+for details.
Enforcing a consistent order and style has a few advantages:
first. With this order, the person working on the header is most likely to
see these problems instead of someone else seeing them later when
refactoring unrelated code.
-* Consistent usage of paths in #include directives makes it easy to use
+* Consistent usage of paths in ``#include`` directives makes it easy to use
``grep`` to find all uses of a header, as well as all include dependencies
between two modules.
* An automatic script can be used to re-establish clean code after
* Member variables are named with a trailing underscore.
* Accessors for a variable ``foo_`` are named ``foo()`` and ``setFoo()``.
* Global variables are named with a ``g_`` prefix.
-* Static class variables are named with a ``s_`` prefix.
-* Static ``constexpr`` class members are named with a ``sc_`` prefix.
+* Global and file-static variables are named with a ``g_`` prefix.
+* Static class and function variables are named with an ``s_`` prefix.
+* Static ``constexpr`` file, class, or function members are named with a ``sc_`` prefix.
* Global constants are often named with a ``c_`` prefix.
* If the main responsibility of a file is to implement a particular class,
then the name of the file should match that class, except for possible
The following figure shows a high-level view of components of what gets built
from the source code under :file:`src/` and how the code is organized.
+Arrows indicate the direction of dependencies.
The build system is described in detail in :doc:`build-system`.
With default options, the green and white components are built as part of the
-default target. If ``GMX_BUILD_MDRUN_ONLY`` is ``ON``, then the blue and white
-components are built instead; :file:`libgromacs_mdrun` is built from a subset
-of the code used for :file:`libgromacs`.
+default target.
The gray parts are for testing, and are by default only built as part of the
``tests`` target, but if ``GMX_DEVELOPER_BUILD`` is ``ON``, then these are
included in the default build target.
label="externals\nsrc/external/", group=common, style=rounded
]
gtest [
- label="Google Test & Mock\nsrc/external/gmock-1.7.0/", group=test
+ label="Google Test & Mock\nsrc/external/googletest/", group=test
style="rounded,filled", fillcolor="0 0 0.9"
]
}
libgromacs [
label="libgromacs\nsrc/gromacs/", group=gmx, fillcolor="0.33 0.3 1"
]
- libgromacs_mdrun [
- label="libgromacs_mdrun\nsrc/gromacs/", group=mdrun, fillcolor="0.66 0.3 1"
- ]
}
testutils [
label="testutils\nsrc/testutils/", group=test
style="rounded,filled", fillcolor="0 0 0.9"
]
- mdrun_objlib [
- label="mdrun object lib.\nsrc/programs/mdrun/", group=common, style=rouded
- ]
subgraph {
rank = same
gmx [
label="gmx\nsrc/programs/", group=gmx, fillcolor="0.33 0.3 1"
]
- mdrun [
- label="mdrun\nsrc/programs/", group=mdrun, fillcolor="0.66 0.3 1"
- ]
tests [
label="test binaries\nsrc/.../tests/", group=test
style="rounded,filled", fillcolor="0 0 0.9"
]
gmx -> template [ style=invis, constraint=no ]
- template -> mdrun [ style=invis, constraint=no ]
}
libgromacs -> externals
- libgromacs_mdrun -> externals
- mdrun_objlib -> libgromacs
gmx -> libgromacs
- gmx -> mdrun_objlib
- mdrun -> libgromacs_mdrun
- mdrun -> mdrun_objlib
testutils -> externals
testutils -> gtest
testutils -> libgromacs
tests -> gtest
tests -> libgromacs
- tests -> mdrun_objlib
tests -> testutils
template -> libgromacs
- template -> mdrun_objlib [ style=invis ]
- mdrun_objlib -> externals [ style=invis ]
-
All the source code (except for the analysis template) is under the
:file:`src/` directory. Only a few files related to the build system are
included at the root level. All actual code is in subdirectories:
This is the main part of the code, and is organized into further subdirectories
as *modules*. See below for details.
:file:`src/programs/`
- |Gromacs| executables are built from code under this directory.
- Although some build options can change this, there is typically only a single
- binary, :file:`gmx`, built.
+ The |Gromacs| executable ``gmx`` is built from code under this directory.
+ Also found here is some of the driver code for the ``mdrun`` module called
+ by ``gmx``, the whole of the ``gmx view`` visualization module, and numerous
+ end-to-end tests of ``gmx mdrun``.
:file:`src/{...}/tests/`
Various subdirectories under :file:`src/` contain a subdirectory named
necessary for that file. You can use the public API header if you
really require everything declared in it.
-intra-module/intra-file.
-
See :doc:`naming` for some common naming patterns for files that can help
locating declarations.
regression tests
+floating-point exceptions
+ In debug builds, floating-point exceptions (FPEs) are generated whenever one of the
+ following operations is encountered: division by zero, floating-point overflow,
+ invalid operation (e.g., taking sqrt of a negative number).
+ Such checks are *not* performed in the following configurations:
+
+ - release build,
+ - any build by GCC 7.x or Clang with optimizations,
+ - build with SYCL support.
+
+ In these configurations, FPEs can be enabled by adding ``-fpexcept`` flag to ``gmx``
+ invocation. However, FPEs are not supported on Windows and non-x86 Apple hardware.
+ See ``api/legacy/include/gromacs/math/utilities.h`` for more details.
+
.. _dev-formatting-tools:
Code formatting and style
LAYOUT_FILE = @CMAKE_CURRENT_SOURCE_DIR@/DoxygenLayout.xml
INPUT = @CMAKE_CURRENT_SOURCE_DIR@ \
@CMAKE_SOURCE_DIR@/src \
+ @CMAKE_SOURCE_DIR@/api/legacy/include \
@CMAKE_SOURCE_DIR@/share/template
FILE_PATTERNS = *.c *.cpp *.h *.md
# CUDA files could be included like this, but currently produce a lot of
EXCLUDE_SYMBOLS += MOCK_METHOD* MOCK_CONST_METHOD*
FULL_PATH_NAMES = YES
STRIP_FROM_PATH = @CMAKE_SOURCE_DIR@
-STRIP_FROM_INC_PATH = @CMAKE_SOURCE_DIR@/src
+STRIP_FROM_INC_PATH = @CMAKE_SOURCE_DIR@/src \
+ @CMAKE_SOURCE_DIR@/src/include \
+ @CMAKE_SOURCE_DIR@/src/gromacs/*/include \
+ @CMAKE_SOURCE_DIR@/api/legacy/include
INCLUDE_PATH = @CMAKE_SOURCE_DIR@/src
HAVE_DOT = @DOXYGEN_DOT_FOUND@
DOT_PATH = @DOXYGEN_DOT_PATH@
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2014,2015,2018,2019, by the GROMACS development team, led by
+# Copyright (c) 2014,2015,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.
def check_all(tree, reporter, check_ignored):
"""Do all checks for the GROMACS tree."""
- includesorter = IncludeSorter()
- for fileobj in tree.get_files():
- if isinstance(fileobj, gmxtree.GeneratorSourceFile):
- continue
- check_file(fileobj, tree, reporter)
- for includedfile in fileobj.get_includes():
- check_include(fileobj, includedfile, reporter)
- if fileobj.should_includes_be_sorted():
- is_sorted, details = includesorter.check_sorted(fileobj)
- if not is_sorted:
- details.append("You can use includesorter.py to do the sorting automatically; see docs/dev-manual/gmxtree.rst")
- reporter.code_issue(fileobj,
- "include style/order is not consistent; see docs/dev-manual/includestyle.rst", details)
+ # Include sorting is disabled pending resolution of
+ # https://gitlab.com/gromacs/gromacs/-/issues/3288 and
+ # https://gitlab.com/gromacs/gromacs/-/issues/3659
+ # includesorter = IncludeSorter()
+ # for fileobj in tree.get_files():
+ # if isinstance(fileobj, gmxtree.GeneratorSourceFile):
+ # continue
+ # check_file(fileobj, tree, reporter)
+ # for includedfile in fileobj.get_includes():
+ # check_include(fileobj, includedfile, reporter)
+ # if fileobj.should_includes_be_sorted():
+ # is_sorted, details = includesorter.check_sorted(fileobj)
+ # if not is_sorted:
+ # details.append("You can use includesorter.py to do the sorting automatically; see docs/dev-manual/gmxtree.rst")
+ # reporter.code_issue(fileobj,
+ # "include style/order is not consistent; see docs/dev-manual/includestyle.rst", details)
for classobj in tree.get_classes():
check_class(classobj, reporter)
simd -> hardware
gpu_utils -> hardware
listed_forces -> mdlib
-utility -> math
# modular simulator uses shellfc from mdrun, but is later included in mdrun by simulator builder
modularsimulator -> mdrun
builder->add<ForceElement>();
// We have a full state here (positions(t), velocities(t-dt/2), forces(t)
builder->add<StatePropagatorData::Element>();
- if (legacySimulatorData_->inputrec->etc == etcVRESCALE)
+ if (legacySimulatorData_->inputrec->etc == TemperatureCoupling::VRescale)
{
builder->add<VRescaleThermostat>(-1, VRescaleThermostatUseFullStepKE::No);
}
builder->add<ComputeGlobalsElement<ComputeGlobalsAlgorithm::LeapFrog>>();
// We have the energies at time t here
builder->add<EnergyData::Element>();
- if (legacySimulatorData_->inputrec->epc == epcPARRINELLORAHMAN)
+ if (legacySimulatorData_->inputrec->epc == PressureCoupling::ParrinelloRahman)
{
builder->add<ParrinelloRahmanBarostat>(-1);
}
Finally, for some architectures with large or very large SIMD width (e.g. AVX
with 8 elements in single precision, or AVX-512 with 16), the nonbonded
kernels can become inefficient. Since all such architectures presently known
-(AVX, AVX2, MIC, AVX512) also provide extensive support for accessing
+(AVX, AVX2, AVX512) also provide extensive support for accessing
parts of the register, we optionally define a handful of routines to
perform load, store, and reduce operations based on half-SIMD-width data,
which can improve performance. It is only useful for wide implementations,
-# The script is currently a bit too eager
-share/template/template.cpp: error: source file documentation appears outside full documentation
-# The parser in the script is not clever enough
-src/gromacs/version.h: warning: includes local file as <gromacs/version.h>
-
-# These are OK
-src/gromacs/linearalgebra/eigensolver.cpp: warning: should include "config.h"
-src/gromacs/linearalgebra/gmx_arpack.cpp: warning: should include "config.h"
-src/gromacs/linearalgebra/gmx_blas/*: warning: does not include "gmxpre.h" first
-src/gromacs/linearalgebra/gmx_blas/*: warning: should include "config.h"
-src/gromacs/linearalgebra/gmx_lapack/*: warning: does not include "gmxpre.h" first
-src/gromacs/linearalgebra/gmx_lapack/*: warning: should include "config.h"
-src/gromacs/utility/baseversion-gen.cpp: warning: does not include "gmxpre.h" first
-
-# Exclude header files that are used for inlining code; the responsibility for
-# making the right #includes should be on the source file that uses these.
-# TODO: # Stop using the preprocessor for meta-programming!
-src/gromacs/ewald/pme_simd4.h: warning: should include "pme_simd.h"
-src/gromacs/ewald/pme_spline_work.cpp: warning: includes "simd.h" unnecessarily
-src/gromacs/ewald/pme_spline_work.h: warning: includes "simd.h" unnecessarily
-src/gromacs/ewald/pme_spread.cpp: warning: includes "simd.h" unnecessarily
-src/gromacs/nbnxm/boundingboxes.h: warning: includes "simd.h" unnecessarily
-src/gromacs/nbnxm/kernels_simd_2xmm/kernel_inner.h: warning: should include "simd.h"
-src/gromacs/nbnxm/kernels_simd_2xmm/kernel_outer.h: warning: should include "simd.h"
-src/gromacs/nbnxm/kernels_simd_4xm/kernel_inner.h: warning: should include "simd.h"
-src/gromacs/nbnxm/kernels_simd_4xm/kernel_outer.h: warning: should include "simd.h"
-src/gromacs/nbnxm/pairlist_simd_2xmm.h: warning: should include "simd.h"
-src/gromacs/nbnxm/pairlist_simd_4xm.h: warning: should include "simd.h"
-
-# This module name doesn't really fall into any currently used pattern; needs some thought
-: error: no matching directory for module: module_mdrun_integration_tests
-
-# These would be nice to fix, but can wait for later / deletion / rewrites
-src/gromacs/nbnxm/kernels_simd_2xmm/kernel_common.h: warning: should include "nbnxm_simd.h"
-src/gromacs/nbnxm/kernels_simd_4xm/kernel_common.h: warning: should include "nbnxm_simd.h"
-
# This seems to be a false positive
src/gromacs/nbnxm/cuda/nbnxm_cuda_types.h: error: NbnxmGpu: is in internal file(s), but appears in public documentation
+# doxygen has problems with the template construct in this file
+src/gromacs/modularsimulator/signallers.h: error: build: is documented, but does not have brief description
+
# False positive caused by forward-declaration of BasicVector in src/testutils/refdata.h
-src/gromacs/math/vectypes.h: error: gmx::BasicVector: is in library file(s), but appears in public documentation
+src/testutils/refdata.h: error: gmx::BasicVector: is in library file(s), but appears in public documentation
-# Temporary while we change the SIMD implementation
-src/gromacs/simd/impl_sparc64_hpc_ace/impl_sparc64_hpc_ace_common.h: warning: should include "simd.h"
+#
+# All following suppressions are disabled while the include checker
+# is temporarily disabled pending resolution of
+# https://gitlab.com/gromacs/gromacs/-/issues/3288 and
+# https://gitlab.com/gromacs/gromacs/-/issues/3659
+#
-src/gromacs/simd/tests/scalar.cpp: warning: includes "simd.h" unnecessarily
-src/gromacs/simd/tests/scalar_math.cpp: warning: includes "simd.h" unnecessarily
-src/gromacs/simd/tests/scalar_util.cpp: warning: includes "simd.h" unnecessarily
-src/gromacs/tables/cubicsplinetable.h: warning: includes "simd.h" unnecessarily
-src/gromacs/tables/quadraticsplinetable.h: warning: includes "simd.h" unnecessarily
+# # The script is currently a bit too eager
+# share/template/template.cpp: error: source file documentation appears outside full documentation
+# # The parser in the script is not clever enough
+# src/gromacs/version.h: warning: includes local file as <gromacs/version.h>
-# These are specific to Folding@Home, and easiest to suppress here
-src/gmxpre.h: warning: includes non-local file as "swindirect.h"
+# # These are OK
+# src/gromacs/linearalgebra/eigensolver.cpp: warning: should include "config.h"
+# src/gromacs/linearalgebra/gmx_arpack.cpp: warning: should include "config.h"
+# src/gromacs/linearalgebra/gmx_blas/*: warning: does not include "gmxpre.h" first
+# src/gromacs/linearalgebra/gmx_blas/*: warning: should include "config.h"
+# src/gromacs/linearalgebra/gmx_lapack/*: warning: does not include "gmxpre.h" first
+# src/gromacs/linearalgebra/gmx_lapack/*: warning: should include "config.h"
+# src/gromacs/utility/baseversion-gen.cpp: warning: does not include "gmxpre.h" first
-# New external API (see https://gitlab.com/gromacs/gromacs/-/issues/2586) has some unresolved
-# conflicts with previous definitions of public API, installed API, and other things
-# described or implemented in check-source.py, gmxtree.py, gmxtree.rst, and others
-# TODO: resolve definitions, update testing heuristics, and activate policy checks
-# for src/api/cpp files.
-src/api/cpp/*: *
+# # Exclude header files that are used for inlining code; the responsibility for
+# # making the right #includes should be on the source file that uses these.
+# # TODO: # Stop using the preprocessor for meta-programming!
+# src/gromacs/ewald/pme_simd4.h: warning: should include "pme_simd.h"
+# src/gromacs/ewald/pme_spline_work.cpp: warning: includes "simd.h" unnecessarily
+# src/gromacs/ewald/pme_spline_work.h: warning: includes "simd.h" unnecessarily
+# src/gromacs/ewald/pme_spread.cpp: warning: includes "simd.h" unnecessarily
+# src/gromacs/nbnxm/boundingboxes.h: warning: includes "simd.h" unnecessarily
+# src/gromacs/nbnxm/kernels_simd_2xmm/kernel_inner.h: warning: should include "simd.h"
+# src/gromacs/nbnxm/kernels_simd_2xmm/kernel_outer.h: warning: should include "simd.h"
+# src/gromacs/nbnxm/kernels_simd_4xm/kernel_inner.h: warning: should include "simd.h"
+# src/gromacs/nbnxm/kernels_simd_4xm/kernel_outer.h: warning: should include "simd.h"
+# src/gromacs/nbnxm/pairlist_simd_2xmm.h: warning: should include "simd.h"
+# src/gromacs/nbnxm/pairlist_simd_4xm.h: warning: should include "simd.h"
-# doxygen has problems with the template construct in this file
-src/gromacs/modularsimulator/signallers.h: error: build: is documented, but does not have brief description
+# # This module name doesn't really fall into any currently used pattern; needs some thought
+# : error: no matching directory for module: module_mdrun_integration_tests
+
+# # These would be nice to fix, but can wait for later / deletion / rewrites
+# src/gromacs/nbnxm/kernels_simd_2xmm/kernel_common.h: warning: should include "nbnxm_simd.h"
+# src/gromacs/nbnxm/kernels_simd_4xm/kernel_common.h: warning: should include "nbnxm_simd.h"
+
+
+# # Temporary while we change the SIMD implementation
+# src/gromacs/simd/impl_sparc64_hpc_ace/impl_sparc64_hpc_ace_common.h: warning: should include "simd.h"
+
+# src/gromacs/simd/tests/scalar.cpp: warning: includes "simd.h" unnecessarily
+# src/gromacs/simd/tests/scalar_math.cpp: warning: includes "simd.h" unnecessarily
+# src/gromacs/simd/tests/scalar_util.cpp: warning: includes "simd.h" unnecessarily
+# src/gromacs/tables/cubicsplinetable.h: warning: includes "simd.h" unnecessarily
+# src/gromacs/tables/quadraticsplinetable.h: warning: includes "simd.h" unnecessarily
+
+# # These are specific to Folding@Home, and easiest to suppress here
+# src/gmxpre.h: warning: includes non-local file as "swindirect.h"
+
+# # New external API (see https://gitlab.com/gromacs/gromacs/-/issues/2586) has some unresolved
+# # conflicts with previous definitions of public API, installed API, and other things
+# # described or implemented in check-source.py, gmxtree.py, gmxtree.rst, and others
+# # TODO: resolve definitions, update testing heuristics, and activate policy checks
+# # for src/api/cpp files.
+# src/api/cpp/*: *
}
To check the status or error output of a command line operation, refer to the
-``returncode`` and ``erroroutput`` outputs.
+``returncode`` and ``stderr`` outputs.
To access the results from the output file arguments, use the command line flags
as keys in the ``file`` dictionary output.
On a cluster where users are expected to be running across multiple
nodes using MPI, make one installation similar to the above, and
-another using ``-DGMX_MPI=on`` and which is `building only
-mdrun`_, because that is the only component of |Gromacs| that uses
-MPI. The latter will install a single simulation engine binary,
-i.e. ``mdrun_mpi`` when the default suffix is used. Hence it is safe
+another using ``-DGMX_MPI=on``.
+The latter will install binaries and libraries named using
+a default suffix of ``_mpi`` ie ``gmx_mpi``. Hence it is safe
and common practice to install this into the same location where
the non-MPI build is installed.
* ``-DCMAKE_C_COMPILER=xxx`` equal to the name of the C99 `Compiler`_ you wish to use (or the environment variable ``CC``)
* ``-DCMAKE_CXX_COMPILER=xxx`` equal to the name of the C++17 `compiler`_ you wish to use (or the environment variable ``CXX``)
-* ``-DGMX_MPI=on`` to build using `MPI support`_ (generally good to combine with `building only mdrun`_)
+* ``-DGMX_MPI=on`` to build using `MPI support`_
* ``-DGMX_GPU=CUDA`` to build with NVIDIA CUDA support enabled.
* ``-DGMX_GPU=OpenCL`` to build with OpenCL_ support enabled.
* ``-DGMX_SIMD=xxx`` to specify the level of `SIMD support`_ of the node on which |Gromacs| will run
-* ``-DGMX_BUILD_MDRUN_ONLY=on`` for `building only mdrun`_, e.g. for compute cluster back-end nodes
* ``-DGMX_DOUBLE=on`` to build |Gromacs| in double precision (slower, and not normally useful)
* ``-DCMAKE_PREFIX_PATH=xxx`` to add a non-standard location for CMake to `search for libraries, headers or programs`_
* ``-DCMAKE_INSTALL_PREFIX=xxx`` to install |Gromacs| to a `non-standard location`_ (default ``/usr/local/gromacs``)
compiler versions are
* GNU (gcc/libstdc++) 7
-* Intel (icc) 19.1
* LLVM (clang/libc++) 5
* Microsoft (MSVC) 2017 15.7
not offer competitive performance. We recommend against PGI because
the performance with C++ is very bad.
+The Intel classic compiler (icc/icpc) is no longer supported in
+|Gromacs|. Use Intel's newer clang-based compiler from oneAPI, or
+gcc.
+
The xlc compiler is not supported and version 16.1 does not compile on
POWER architectures for |Gromacs|\ -\ |version|. We recommend to use
the gcc compiler instead, as it is being extensively tested.
compiler also manages the standard library library via compiler flags,
these will be honored. For configuration of other compilers, read on.
-On Linux, both the Intel and clang compiler use the libstdc++ which
+On Linux, the clang compilers use the libstdc++ which
comes with gcc as the default C++ library. For |Gromacs|, we require
the compiler to support libstc++ version 7.1 or higher. To select a
particular libstdc++ library, provide the path to g++ with
``-DGMX_GPLUSPLUS_PATH=/path/to/g++``.
-On Windows with the Intel compiler, the MSVC standard library is used,
-and at least MSVC 2017 15.7 is required. Load the environment variables with
-vcvarsall.bat.
-
To build with clang and llvm's libcxx standard library, use
``-DCMAKE_CXX_FLAGS=-stdlib=libc++``.
-If you are running on Mac OS X, the best option is the Intel
-compiler. Both clang and gcc will work, but they produce lower
-performance and each have some shortcomings. clang 3.8 now offers
-support for OpenMP, and so may provide decent performance.
+If you are running on Mac OS X, the best option is gcc. The Apple
+clang compiler provided by MacPorts will work, but does not support
+OpenMP, so will probably not provide best performance.
For all non-x86 platforms, your best option is typically to use gcc or
the vendor's default or recommended compiler, and check for
in order to enable this.
If you wish to run in parallel on multiple machines across a network,
-you will need to have
-
-* an MPI library installed that supports the MPI 1.3
- standard, and
-* wrapper compilers that will compile code using that library.
+you will need to have an MPI library installed that supports the MPI
+2.0 standard. That's true for any MPI library version released since
+about 2009, but the |Gromacs| team recommends the latest version (for
+best performance) of either your vendor's library, OpenMPI_ or MPICH_.
To compile with MPI set your compiler to the normal (non-MPI) compiler
and add ``-DGMX_MPI=on`` to the cmake options. It is possible to set
the compiler to the MPI compiler wrapper but it is neither necessary
nor recommended.
-The |Gromacs| team recommends OpenMPI_ version
-1.6 (or higher), MPICH_ version 1.4.1 (or
-higher), or your hardware vendor's MPI installation. The most recent
-version of either of these is likely to be the best. More specialized
-networks might depend on accelerations only available in the vendor's
-library. LAM-MPI_ might work, but since it has
-been deprecated for years, it is not supported.
-
-For example, depending on your actual MPI library, use ``cmake
--DMPI_C_COMPILER=mpicc -DGMX_MPI=on``.
-
-
CMake
^^^^^
Additionally, with GPU accelerated runs ``AVX2_256`` can also be
faster on high-end Skylake CPUs with both 512-bit FMA units enabled.
9. ``AVX_512_KNL`` Knights Landing Xeon Phi processors
-10. ``Sparc64_HPC_ACE`` Fujitsu machines like the K computer have this.
-11. ``IBM_VMX`` Power6 and similar Altivec processors have this.
-12. ``IBM_VSX`` Power7, Power8, Power9 and later have this.
-13. ``ARM_NEON`` 32-bit ARMv7 with NEON support.
-14. ``ARM_NEON_ASIMD`` 64-bit ARMv8 and later.
-15. ``ARM_SVE`` 64-bit ARMv8 and later with the Scalable Vector Extensions (SVE).
+10. ``IBM_VSX`` Power7, Power8, Power9 and later have this.
+11. ``ARM_NEON_ASIMD`` 64-bit ARMv8 and later.
+12. ``ARM_SVE`` 64-bit ARMv8 and later with the Scalable Vector Extensions (SVE).
The SVE vector length is fixed at CMake configure time. The default vector
length is automatically detected, and this can be changed via the
``GMX_SIMD_ARM_SVE_LENGTH`` CMake variable.
mdrun) that run slowly on the new hardware. Building two full
installations and locally managing how to call the correct one
(e.g. using a module system) is the recommended
-approach. Alternatively, as at the moment the |Gromacs| tools do not
-make strong use of SIMD acceleration, it can be convenient to create
-an installation with tools portable across different x86 machines, but
-with separate mdrun binaries for each architecture. To achieve this,
+approach. Alternatively, one can use different suffixes to install
+several versions of |Gromacs| in the same location. To achieve this,
one can first build a full installation with the
least-common-denominator SIMD instruction set, e.g. ``-DGMX_SIMD=SSE2``,
-then build separate mdrun binaries for each architecture present in
+in order for simple commands like ``gmx grompp`` to work on all machines,
+then build specialized ``gmx`` binaries for each architecture present in
the heterogeneous environment. By using custom binary and library
-suffixes for the mdrun-only builds, these can be installed to the
-same location as the "generic" tools installation.
-`Building just the mdrun binary`_ is possible by setting the
-``-DGMX_BUILD_MDRUN_ONLY=ON`` option.
+suffixes (with CMake variables ``-DGMX_BINARY_SUFFIX=xxx`` and
+``-DGMX_LIBS_SUFFIX=xxx``), these can be installed to the same
+location.
Linear algebra libraries
~~~~~~~~~~~~~~~~~~~~~~~~
.. _building just the mdrun binary:
-Building only mdrun
-~~~~~~~~~~~~~~~~~~~
-
-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.
-
Installing |Gromacs|
^^^^^^^^^^^^^^^^^^^^
your hardware, and the output of ``gmx mdrun -version`` (which contains
valuable diagnostic information in the header).
-Testing for MDRUN_ONLY executables
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A build with ``-DGMX_BUILD_MDRUN_ONLY`` cannot be tested with
-``make check`` from the build tree, because most of the tests
-require a full build to run things like ``grompp``. To test such an
-mdrun fully requires installing it to the same location as a normal
-build of |Gromacs|, downloading the regression tests tarball manually
-as described above, sourcing the correct ``GMXRC`` and running the
-perl script manually. For example, from your |Gromacs| source
-directory:
-
-::
-
- mkdir build-normal
- cd build-normal
- # First, build and install normally to allow full testing of the standalone simulator.
- cmake .. -DGMX_MPI=ON -DCMAKE_INSTALL_PREFIX=/your/installation/prefix/here
- make -j 4
- make install
- cd ..
- mkdir build-mdrun-only
- cd build-mdrun-only
- # Next, build and install the GMX_BUILD_MDRUN_ONLY version (optional).
- cmake .. -DGMX_MPI=ON -DGMX_BUILD_MDRUN_ONLY=ON -DCMAKE_INSTALL_PREFIX=/your/installation/prefix/here
- make -j 4
- make install
- cd /to/your/unpacked/regressiontests
- source /your/installation/prefix/here/bin/GMXRC
- ./gmxtest.pl all -np 2
-
Non-standard suffix
~~~~~~~~~~~~~~~~~~~
-If your mdrun program has been suffixed in a non-standard way, then
-the ``./gmxtest.pl -mdrun`` option will let you specify that name to the
+If your ``gmx`` program has been suffixed in a non-standard way, then
+the ``./gmxtest.pl -suffix`` option will let you specify that suffix to the
test machinery. You can use ``./gmxtest.pl -double`` to test the
double-precision version. You can use ``./gmxtest.pl -crosscompiling``
to stop the test harness attempting to check that the programs can
does not currently compile |Gromacs| correctly, perhaps because the
thread-MPI atomics are incorrectly implemented in |Gromacs|).
-Fujitsu PRIMEHPC
-^^^^^^^^^^^^^^^^
-
-This is the architecture of the K computer, which uses Fujitsu
-Sparc64VIIIfx chips. On this platform, |Gromacs| has
-accelerated group kernels using the HPC-ACE instructions, no
-accelerated Verlet kernels, and a custom build toolchain. Since this
-particular chip only does double precision SIMD, the default setup
-is to build |Gromacs| in double. Since most users only need single, we have added
-an option GMX_RELAXED_DOUBLE_PRECISION to accept single precision square root
-accuracy in the group kernels; unless you know that you really need 15 digits
-of accuracy in each individual force, we strongly recommend you use this. Note
-that all summation and other operations are still done in double.
-
-The recommended configuration is to use
-
-::
-
- cmake .. -DCMAKE_TOOLCHAIN_FILE=Toolchain-Fujitsu-Sparc64-mpi.cmake \
- -DCMAKE_PREFIX_PATH=/your/fftw/installation/prefix \
- -DCMAKE_INSTALL_PREFIX=/where/gromacs/should/be/installed \
- -DGMX_MPI=ON \
- -DGMX_BUILD_MDRUN_ONLY=ON \
- -DGMX_RELAXED_DOUBLE_PRECISION=ON
- make
- make install
-
Intel Xeon Phi
^^^^^^^^^^^^^^
Xeon Phi processors, hosted or self-hosted, are supported.
-Only symmetric (aka native) mode is supported on Knights Corner. The
-performance depends among other factors on the system size, and for
-now the performance might not be faster than CPUs. When building for it,
-the recommended configuration is
-
-::
-
- cmake .. -DCMAKE_TOOLCHAIN_FILE=Platform/XeonPhi
- make
- make install
-
-
The Knights Landing-based Xeon Phi processors behave like standard x86 nodes,
but support a special SIMD instruction set. When cross-compiling for such nodes,
use the ``AVX_512_KNL`` SIMD flavor.
gcc versions 7 and 8,
clang versions 8 and 9,
and
-a beta version of oneAPI containing Intel's compiler.
+a version of oneAPI containing Intel's clang-based compiler.
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
simulation, and afterward use position restraints in conjunction
with constant pressure.
-accelerate group
-
- On each atom in an “accelerate group” an acceleration
- :math:`\mathbf{a}^g` is imposed. This is equivalent to
- 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
Mutual interactions between all energy-monitor groups are compiled
-.. _anticipated-changes:
-
.. Note to developers!
Please use """"""" to underline the individual entries for fixed issues in the subfolders,
otherwise the formatting on the webpage is messed up.
--- /dev/null
+Bugs fixed
+^^^^^^^^^^
+
+Fixed slight inaccuracies when using virtual sites with pressure coupling
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+
+Virtual sites were reconstructed after the system was propagated, but before
+scaling due to pressure coupling. For virtual site types which are not a linear
+combination of other atoms, this is not completely correct. Since the scaling
+due to pressure coupling is very small in healthy simulations, the resulting
+inaccuracies are expected to have been extremely minor, and in most cases
+undetectable.
+
+:issue:`3866`
+
+.. Note to developers!
+ Please use """"""" to underline the individual entries for fixed issues in the subfolders,
+ otherwise the formatting on the webpage is messed up.
+ Also, please use the syntax :issue:`number` to reference issues on GitLab, without the
+ a space between the colon and number!
+
--- /dev/null
+.. _anticipated-changes:
+
+.. Note to developers!
+ Please use """"""" to underline the individual entries for fixed issues in the subfolders,
+ otherwise the formatting on the webpage is messed up.
+ Also, please use the syntax :issue:`number` to reference issues on GitLab, without the
+ a space between the colon and number!
+
+Changes anticipated to |Gromacs| 2022 functionality
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Functionality deprecated in |Gromacs| 2022
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
--- /dev/null
+New and improved features
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. Note to developers!
+ Please use """"""" to underline the individual entries for fixed issues in the subfolders,
+ otherwise the formatting on the webpage is messed up.
+ Also, please use the syntax :issue:`number` to reference issues on GitLab, without the
+ a space between the colon and number!
+
--- /dev/null
+Highlights
+^^^^^^^^^^
+
+|Gromacs| 2022 was released on INSERT DATE HERE. Patch releases may
+have been made since then, please use the updated versions! Here are
+some highlights of what you can expect, along with more detail in the
+links below!
+
+As always, we've got several useful performance improvements, with or
+without GPUs, all enabled and automated by default. In addition,
+several new features are available for running simulations. We are extremely
+interested in your feedback on how well the new release works on your
+simulations and hardware. The new features are:
+
+* Cool quotes music play list
+
+
+.. Note to developers!
+ Please use """"""" to underline the individual entries for fixed issues in the subfolders,
+ otherwise the formatting on the webpage is messed up.
+ Also, please use the syntax :issue:`number` to reference issues on GitLab, without the
+ a space between the colon and number!
--- /dev/null
+Miscellaneous
+^^^^^^^^^^^^^
+
+.. Note to developers!
+ Please use """"""" to underline the individual entries for fixed issues in the subfolders,
+ otherwise the formatting on the webpage is messed up.
+ Also, please use the syntax :issue:`number` to reference issues on GitLab, without the
+ a space between the colon and number!
+
--- /dev/null
+Performance improvements
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. Note to developers!
+ Please use """"""" to underline the individual entries for fixed issues in the subfolders,
+ otherwise the formatting on the webpage is messed up.
+ Also, please use the syntax :issue:`number` to reference issues on GitLab, without the
+ a space between the colon and number!
+
--- /dev/null
+Portability
+^^^^^^^^^^^
+
+Intel classic compiler (icc/icpc) no longer supported
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+
+We now support the Intel clang-based compiler from oneAPI (icx/icpx)
+instead. Please use it, or gcc.
+
+:issue:`3893`
--- /dev/null
+Removed functionality
+^^^^^^^^^^^^^^^^^^^^^
+
+Removed constant-acceleration groups support
+""""""""""""""""""""""""""""""""""""""""""""
+This code has been broken since before GROMACS 4.6, so it has been
+removed.
+
+:issue:`1354`
+
+.. Note to developers!
+ Please use """"""" to underline the individual entries for fixed issues in the subfolders,
+ otherwise the formatting on the webpage is messed up.
+ Also, please use the syntax :issue:`number` to reference issues on GitLab, without the
+ a space between the colon and number!
+
+Removed mdrun-only build configuration
+""""""""""""""""""""""""""""""""""""""
+
+The need for the mdrun-only build of |Gromacs| has expired, as it has
+the same set of dependencies as regular |Gromacs|. It was deprecated
+in GROMACS 2021. Removing it will simplify maintenance, testing,
+documentation, installation, and teaching new users.
+
+:issue:`3808`
+
+Removed support for x86 MIC, ARMv7, Sparc64 HPC-ACE, and IBM VMX SIMD
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+
+These platforms are dead in HPC and so are no longer supported. The
+KNL platform is unaffected by this change.
+
+:issue:`3891`
+
+Removed deprecated environment variables
+""""""""""""""""""""""""""""""""""""""""
+
+The following environment variables were removed after being deprecated
+in favor of better-named alternatives:
+
+* ``GMX_CUDA_NB_ANA_EWALD`` and ``GMX_OCL_NB_ANA_EWALD`` (use ``GMX_GPU_NB_ANA_EWALD``)
+* ``GMX_CUDA_NB_TAB_EWALD`` and ``GMX_OCL_NB_TAB_EWALD`` (use ``GMX_GPU_NB_TAB_EWALD``)
+* ``GMX_CUDA_NB_EWALD_TWINCUT`` and ``GMX_OCL_NB_EWALD_TWINCUT`` (use ``GMX_GPU_NB_EWALD_TWINCUT``)
+
+:issue:`3803`
--- /dev/null
+Improvements to |Gromacs| tools
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. Note to developers!
+ Please use """"""" to underline the individual entries for fixed issues in the subfolders,
+ otherwise the formatting on the webpage is messed up.
+ Also, please use the syntax :issue:`number` to reference issues on GitLab, without the
+ a space between the colon and number!
+
functionality supported, whereas patch releases contain only fixes for
issues identified in the corresponding major releases.
-Two versions of |Gromacs| are under active maintenance, the 2021
-series and the 2020 series. In the latter, only highly conservative
+Two versions of |Gromacs| are under active maintenance, the 2022
+series and the 2021 series. In the latter, only highly conservative
fixes will be made, and only to address issues that affect scientific
correctness. Naturally, some of those releases will be made after the
-year 2020 ends, but we keep 2019 in the name so users understand how
+year 2021 ends, but we keep 2021 in the name so users understand how
up to date their version is. Such fixes will also be incorporated into
-the 2021 release series, as appropriate. Around the time the 2022
-release is made, the 2020 series will no longer be maintained.
+the 2022 release series, as appropriate. Around the time the 2023
+release is made, the 2021 series will no longer be maintained.
Where issue numbers are reported in these release notes, more details
can be found on the `issue tracker`_ at that issue number.
-|Gromacs| 2021 series
+|Gromacs| 2022 series
---------------------
.. todolist::
2021/2021.1
+Major release
+^^^^^^^^^^^^^
+
+.. toctree::
+ :maxdepth: 1
+
+ 2022/major/highlights
+ 2022/major/features
+ 2022/major/performance
+ 2022/major/tools
+ 2022/major/bugs-fixed
+ 2022/major/deprecated-functionality
+ 2022/major/removed-functionality
+ 2022/major/portability
+ 2022/major/miscellaneous
+
+
+|Gromacs| 2021 series
+---------------------
+
Major release
^^^^^^^^^^^^^
2021/major/portability
2021/major/miscellaneous
+
+Older (unmaintained) |Gromacs| series
+-------------------------------------------------------
+
|Gromacs| 2020 series
---------------------
2019/major/portability
2019/major/miscellaneous
-Older (unmaintained) |Gromacs| series
--------------------------------------------------------
-
|Gromacs| 2018 series
---------------------
|Gromacs| includes many tools for preparing, running and analyzing
molecular dynamics simulations. These are all structured as part of a single
:command:`gmx` wrapper binary, and invoked with commands like :command:`gmx grompp`.
-:ref:`mdrun <gmx mdrun>` is the only other binary that
-:ref:`can be built <building just the mdrun binary>`; in the normal
-build it can be run with :command:`gmx mdrun`. Documentation for these can
+or :command:`gmx mdrun`. Documentation for these can
be found at the respective sections below, as well as on man pages (e.g.,
:manpage:`gmx-grompp(1)`) and with :samp:`gmx help {command}` or
:samp:`gmx {command} -h`.
by mdrun. Values should be between the pruning frequency value
(1 for CPU and 2 for GPU) and :mdp:`nstlist` ``- 1``.
-``GMX_USE_TREEREDUCE``
- use tree reduction for nbnxn force reduction. Potentially faster for large number of
- OpenMP threads (if memory locality is important).
-
.. _opencl-management:
OpenCL management
#. Do I need to compile all utilities with MPI?
- With one rarely-used exception (:ref:`pme_error <gmx pme_error>`), only the
- :ref:`mdrun <gmx mdrun>` binary is able to use the :ref:`MPI <mpi-support>`
+ With one rarely-used exception (:ref:`pme_error <gmx pme_error>`), only
+ :ref:`mdrun <gmx mdrun>` is able to use the :ref:`MPI <mpi-support>`
parallelism. So you only need to use the ``-DGMX_MPI=on`` flag
when :ref:`configuring <configure-cmake>` for a build intended to run
- the main simulation engine :ref:`mdrun <gmx mdrun>`.
+ the main simulation engine :ref:`mdrun <gmx mdrun>`. Generally that
+ is desirable when running on a multi-node cluster, and necessary
+ when using multi-simulation algorithms. Usually also installing a
+ build of GROMACS configured without MPI is convenient for users.
#. Should my version be compiled using double precision?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Once the run input file is available, we can start the simulation. The
-program which starts the simulation is called :ref:`gmx mdrun` (or
-sometimes just mdrun, or mdrun_mpi). The only input file of :ref:`gmx mdrun`
+program which starts the simulation is called :ref:`gmx mdrun`.
+The only input file of :ref:`gmx mdrun`
that you usually need in order to start a run is the run input
file (:ref:`tpr` file). The typical output files of :ref:`gmx mdrun` are the
trajectory file (:ref:`trr` file), a logfile (:ref:`log` file), and perhaps a
Non-equilibrium MD
^^^^^^^^^^^^^^^^^^
-.. mdp:: acc-grps
-
- 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. (Deprecated)
-
-.. mdp:: accelerate
-
- (0) [nm ps\ :sup:`-2`]
- 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). (Deprecated)
-
.. mdp:: freezegrps
Groups that are to be frozen (*i.e.* their X, Y, and/or Z position
:ref:`configuring |Gromacs| with an external MPI library <mpi-support>`
so that the set of
simulations can communicate. The ``n`` simulations within the set can
-use internal MPI parallelism also, so that ``mpirun -np x mdrun_mpi``
+use internal MPI parallelism also, so that ``mpirun -np x gmx_mpi mdrun``
for ``x`` a multiple of ``n`` will use ``x/n`` ranks per simulation.
There are two ways of organizing files when running such
This requires configuring |Gromacs| to build with an external MPI
library. By default, this :ref:`mdrun <gmx mdrun>` executable is run with
-:ref:`mdrun_mpi`. All of the considerations for running single-node
+``gmx_mpi mdrun``. All of the considerations for running single-node
:ref:`mdrun <gmx mdrun>` still apply, except that ``-ntmpi`` and ``-nt`` cause a fatal
error, and instead the number of ranks is controlled by the
MPI environment.
mpirun -np 16 gmx_mpi mdrun
-Starts :ref:`mdrun_mpi` with 16 ranks, which are mapped to
+Starts :ref:`gmx mdrun` with 16 ranks, which are mapped to
the hardware by the MPI library, e.g. as specified
in an MPI hostfile. The available cores will be
automatically split among ranks using OpenMP threads,
mpirun -np 16 gmx_mpi mdrun -npme 5
-Starts :ref:`mdrun_mpi` with 16 ranks, as above, and
+Starts :ref:`gmx mdrun` with 16 ranks, as above, and
require that 5 of them are dedicated to the PME
component.
mpirun -np 11 gmx_mpi mdrun -ntomp 2 -npme 6 -ntomp_pme 1
-Starts :ref:`mdrun_mpi` with 11 ranks, as above, and
+Starts :ref:`gmx mdrun` with 11 ranks, as above, and
require that six of them are dedicated to the PME
component with one OpenMP thread each. The remaining
five do the PP component, with two OpenMP threads
mpirun -np 4 gmx_mpi mdrun -ntomp 6 -nb gpu -gputasks 00
-Starts :ref:`mdrun_mpi` on a machine with two nodes, using
+Starts :ref:`gmx mdrun` on a machine with two nodes, using
four total ranks, each rank with six OpenMP threads,
and both ranks on a node sharing GPU with ID 0.
mpirun -np 8 gmx_mpi mdrun -ntomp 3 -gputasks 0000
Using a same/similar hardware as above,
-starts :ref:`mdrun_mpi` on a machine with two nodes, using
+starts :ref:`gmx mdrun` on a machine with two nodes, using
eight total ranks, each rank with three OpenMP threads,
and all four ranks on a node sharing GPU with ID 0.
This may or may not be faster than the previous setup
mpirun -np 20 gmx_mpi mdrun -ntomp 4 -gputasks 00
-Starts :ref:`mdrun_mpi` with 20 ranks, and assigns the CPU cores evenly
+Starts :ref:`gmx mdrun` with 20 ranks, and assigns the CPU cores evenly
across ranks each to one OpenMP thread. This setup is likely to be
suitable when there are ten nodes, each with one GPU, and each node
has two sockets each of four cores.
mpirun -np 10 gmx_mpi mdrun -gpu_id 1
-Starts :ref:`mdrun_mpi` with 20 ranks, and assigns the CPU cores evenly
+Starts :ref:`gmx mdrun` with 20 ranks, and assigns the CPU cores evenly
across ranks each to one OpenMP thread. This setup is likely to be
suitable when there are ten nodes, each with two GPUs, but another
job on each node is using GPU 0. The job scheduler should set the
mpirun -np 20 gmx_mpi mdrun -gpu_id 01
-Starts :ref:`mdrun_mpi` with 20 ranks. This setup is likely
+Starts :ref:`gmx mdrun` with 20 ranks. This setup is likely
to be suitable when there are ten nodes, each with two
GPUs, but there is no need to specify ``-gpu_id`` for the
normal case where all the GPUs on the node are available
* Don't use double precision unless you're absolute sure you need it.
* Compile the FFTW library (yourself) with the correct flags on x86 (in most
cases, the correct flags are automatically configured).
-* On x86, use gcc or icc as the compiler (not pgi or the Cray compiler).
+* On x86, use gcc as the compiler (not icc, pgi or the Cray compiler).
* On POWER, use gcc instead of IBM's xlc.
* Use a new compiler version, especially for gcc (e.g. from version 5 to 6
the performance of the compiled code improved a lot).
# If building with setuptools, CMake will not be performing the install
set_target_properties(gmxapi_extension_ensemblepotential PROPERTIES BUILD_WITH_INSTALL_RPATH TRUE)
-target_link_libraries(gmxapi_extension_ensemblepotential PRIVATE Gromacs::gmxapi)
+target_link_libraries(gmxapi_extension_ensemblepotential PUBLIC Gromacs::libgromacs Gromacs::gmxapi)
add_executable(gmxapi_extension_library-test test_binding.cpp)
add_dependencies(gmxapi_extension_library-test gmxapi_extension_spc2_water_box)
target_include_directories(gmxapi_extension_library-test PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
-target_link_libraries(gmxapi_extension_library-test Gromacs::gmxapi GTest::Main)
+target_link_libraries(gmxapi_extension_library-test Gromacs::libgromacs Gromacs::gmxapi GTest::Main)
gtest_add_tests(TARGET gmxapi_extension_library-test
TEST_LIST BasicPlugin)
assert os.path.exists(topfile)
if solvate.output.returncode.result() != 0:
- logging.debug(solvate.output.erroroutput.result())
+ logging.debug(solvate.output.stderr.result())
raise RuntimeError('solvate failed in spc_water_box testing fixture.')
# Choose an exactly representable dt of 2^-9 ps (approximately 0.002)
output_files={'-o': tprfile})
tprfilename = grompp.output.file['-o'].result()
if grompp.output.returncode.result() != 0:
- logging.debug(grompp.output.erroroutput.result())
+ logging.debug(grompp.output.stderr.result())
raise RuntimeError('grompp failed in spc_water_box testing fixture.')
# TODO: more inspection of grompp errors...
# Note that this is the gmxapi._gmxapi Python bindings package version,
# not the C++ API version. It is not essential that it match the pure Python
# package version, but is likely to do so.
-project(gmxapi VERSION 0.2.0)
+project(gmxapi VERSION 0.3.0)
# Check if Python package is being built directly or via add_subdirectory
set(GMXAPI_MASTER_PROJECT OFF)
# * provides `output` publishing proxy to the inner function and
# * produce a result with attributes for
# * file: mapping of output flags to output filenames
-# * erroroutput: text results in case of error
+# * stdout: process STDOUT
+# * stderr: porcess STDERR
# * returncode: integer return code of wrapped command
#
# Note that the existence of the 'file' output map is expressed here, but
#
# TODO: Operation returns the output object when called with the shorter signature.
#
-@gmx.function_wrapper(output={'erroroutput': str, 'returncode': int})
+@gmx.function_wrapper(output={'stdout': str,
+ 'stderr': str,
+ 'returncode': int})
def cli(command: NDArray, shell: bool, output: OutputCollectionDescription, stdin: str = ''):
"""Execute a command line program in a subprocess.
>>> my_filename = "somefilename"
>>> result = cli(('exe', '--origin', 1.0, 2.0, 3.0, '-f', my_filename), shell=False)
>>> assert hasattr(result, 'file')
- >>> assert hasattr(result, 'erroroutput')
+ >>> assert hasattr(result, 'stdout')
+ >>> assert hasattr(result, 'stderr')
>>> assert hasattr(result, 'returncode')
Returns:
- A data structure with attributes for each of the results `file`, `erroroutput`, and `returncode`
+ A data structure with attributes for each of the results `file`, `stdout`, `stderr`, and `returncode`
Result object attributes:
* `file`: the mapping of CLI flags to filename strings resulting from the `output` kwarg
- * `erroroutput`: A string of error output (if any) if the process failed.
+ * `stdout`: A string mapping from process STDOUT.
+ * `stderr`: A string mapping from process STDERR; it will be the
+ error output (if any) if the process failed.
* `returncode`: return code of the subprocess.
"""
- # Note: we could make provisions for stdio filehandles in a future version. E.g.
- # * STDOUT is available if a consuming operation is bound to `output.stdout`.
- # * STDERR is available if a consuming operation is bound to `output.stderr`.
- # * Otherwise, STDOUT and/or STDERR is(are) closed when command is called.
-
# In the operation implementation, we expect the `shell` parameter to be intercepted by the
# wrapper and set to False.
if shell:
# TODO: (FR9) Can OS input/output filehandles be a responsibility of
# the code providing 'resources'?
- erroroutput = ''
+ stdout = ''
+ stderr = ''
logger.debug('executing subprocess')
try:
completed_process = subprocess.run(command,
input=stdin,
check=True,
stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT,
+ stderr=subprocess.PIPE,
encoding='utf-8',
universal_newlines=True
)
returncode = completed_process.returncode
# TODO: Resource management code should manage a safe data object for `output`.
- for line in completed_process.stdout.split('\n'):
- logger.debug(line)
+ logger.debug('STDOUT:')
+ if completed_process.stderr is not None:
+ for line in completed_process.stdout.split('\n'):
+ logger.debug(line)
+ else:
+ logger.debug('STDOUT is empty')
+ logger.debug('STDERR:')
+ if completed_process.stderr is not None:
+ for line in completed_process.stderr.split('\n'):
+ logger.debug(line)
+ else:
+ logger.debug('STDERR is empty')
+
+ stdout = completed_process.stdout
+ stderr = completed_process.stderr
+
except subprocess.CalledProcessError as e:
- logger.info("commandline operation had non-zero return status when calling {}".format(e.cmd))
- erroroutput = e.output
+ logger.info("commandline operation had non-zero return status"
+ "when calling {}".format(e.cmd))
+ stdout = e.stdout
+ stderr = e.stderr
returncode = e.returncode
+
# Publish outputs.
- output.erroroutput = erroroutput
+ output.stdout = stdout
+ output.stderr = stderr
output.returncode = returncode
The output node of the resulting operation handle contains
* ``file``: the mapping of CLI flags to filename strings resulting from the ``output_files`` kwarg
- * ``erroroutput``: A string of error output (if any) if the process failed.
+ * ``stdout``: A string mapping from process STDOUT.
+ * ``stderr``: A string mapping from process STDERR; it will be the
+ error output (if any) if the process failed.
* ``returncode``: return code of the subprocess.
"""
#
# TODO: (FR4+) Characterize the `file` dictionary key type:
# explicitly sequences rather than maybe-string/maybe-sequence-of-strings
- @gmx.function_wrapper(output={'erroroutput': str, 'returncode': int, 'file': dict})
- def merged_ops(erroroutput: str = None, returncode: int = None, file: dict = None,
+ @gmx.function_wrapper(output={'stdout': str,
+ 'stderr': str,
+ 'returncode': int,
+ 'file': dict})
+ def merged_ops(stdout: str = None,
+ stderr: str = None,
+ returncode: int = None,
+ file: dict = None,
output: OutputCollectionDescription = None):
- assert erroroutput is not None
+ assert stdout is not None
+ assert stderr is not None
assert returncode is not None
assert file is not None
assert output is not None
output.returncode = returncode
- output.erroroutput = erroroutput
+ output.stdout = stdout
+ output.stderr = stderr
if returncode == 0:
output.file = file
else:
# TODO: ``label`` kwarg
# TODO: input fingerprinting
cli_result = cli(**cli_args)
- merged_result = merged_ops(erroroutput=cli_result.output.erroroutput,
+ merged_result = merged_ops(stdout=cli_result.output.stdout,
+ stderr=cli_result.output.stderr,
returncode=cli_result.output.returncode,
file=output_files,
**kwargs)
// Add argument type before it is used for more sensible automatic bindings behavior.
py::class_<MDArgs, std::unique_ptr<MDArgs>> mdargs(m, "MDArgs");
mdargs.def(py::init(), "Create an empty MDArgs object.");
- mdargs.def("set", [](MDArgs* self, const py::dict& params) { setMDArgs(self, params); },
+ mdargs.def("set",
+ [](MDArgs* self, const py::dict& params) { setMDArgs(self, params); },
"Assign parameters in MDArgs from Python dict.");
// Export execution context class
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
struct UnknownExceptionPlaceHolder
{
};
- static py::exception<UnknownExceptionPlaceHolder> unknownException(m, "UnknownException",
- baseException.ptr());
+ static py::exception<UnknownExceptionPlaceHolder> unknownException(
+ m, "UnknownException", baseException.ptr());
unknownException.doc() =
"GROMACS library produced an exception that is "
"not mapped in gmxapi or which should have been "
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
// required to maintain and to pass to the API.
py::class_<::gmxapi::Session, std::shared_ptr<::gmxapi::Session>> session(m, "MDSession");
session.def("run", &::gmxapi::Session::run, "Run the simulation workflow");
- session.def("close", &::gmxapi::Session::close,
+ session.def("close",
+ &::gmxapi::Session::close,
"Shut down the execution environment and close the session.");
// Export system container class
"Launch the configured workflow in the provided context.");
// Module-level function
- m.def("from_tpr", &gmxpy::from_tpr,
+ m.def("from_tpr",
+ &gmxpy::from_tpr,
"Return a system container initialized from the given input record.");
}
[](GmxMdParams* self, const std::string& key, int64_t value) {
gmxapicompat::setParam(self, key, value);
},
- py::arg("key").none(false), py::arg("value").none(false),
+ py::arg("key").none(false),
+ py::arg("value").none(false),
"Use a dictionary to update simulation parameters.");
mdparams.def("set",
[](GmxMdParams* self, const std::string& key, double value) {
gmxapicompat::setParam(self, key, value);
},
- py::arg("key").none(false), py::arg("value").none(false),
+ py::arg("key").none(false),
+ py::arg("value").none(false),
"Use a dictionary to update simulation parameters.");
mdparams.def("set",
[](GmxMdParams* self, const std::string& key, py::none) {
// unsetParam(self, key);
},
- py::arg("key").none(false), py::arg("value"),
+ py::arg("key").none(false),
+ py::arg("value"),
"Use a dictionary to update simulation parameters.");
return params;
});
- module.def("read_tprfile", &readTprFile, py::arg("filename"),
+ module.def("read_tprfile",
+ &readTprFile,
+ py::arg("filename"),
"Get a handle to a TPR file resource for a given file name.");
module.def("write_tprfile",
auto topology = gmxapicompat::getTopologySource(tprReadHandle);
gmxapicompat::writeTprFile(filename, *params, *structure, *state, *topology);
},
- py::arg("filename").none(false), py::arg("parameters"),
+ py::arg("filename").none(false),
+ py::arg("parameters"),
"Write a new TPR file with the provided data.");
module.def("copy_tprfile",
[](const gmxapicompat::TprReadHandle& input, std::string outFile) {
return gmxapicompat::copy_tprfile(input, outFile);
},
- py::arg("source"), py::arg("destination"),
+ py::arg("source"),
+ py::arg("destination"),
"Copy a TPR file from ``source`` to ``destination``.");
module.def("rewrite_tprfile",
[](std::string input, std::string output, double end_time) {
return gmxapicompat::rewrite_tprfile(input, output, end_time);
},
- py::arg("source"), py::arg("destination"), py::arg("end_time"),
+ py::arg("source"),
+ py::arg("destination"),
+ py::arg("end_time"),
"Copy a TPR file from ``source`` to ``destination``, replacing `nsteps` with "
"``end_time``.");
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
export_exceptions(m);
// Export core bindings
- m.def("has_feature", &gmxapi::Version::hasFeature,
+ m.def("has_feature",
+ &gmxapi::Version::hasFeature,
"Check the gmxapi library for a named feature.");
py::class_<::gmxapi::Status> gmx_status(m, "Status", "Holds status for API operations.");
# TODO: Version management policy and procedures.
_major = 0
-_minor = 2
+_minor = 3
_micro = 0
_suffix = ''
name='gmxapi',
# TODO: single-source version information (currently repeated in gmxapi/version.py and CMakeLists.txt)
- version='0.2.0',
+ version='0.3.0a1',
python_requires='>=3.6',
install_requires=['networkx>=2.0',
'numpy>=1'],
assert os.path.exists(topfile)
if solvate.output.returncode.result() != 0:
- logging.debug(solvate.output.erroroutput.result())
+ logging.debug(solvate.output.stderr.result())
raise RuntimeError('solvate failed in spc_water_box testing fixture.')
# Choose an exactly representable dt of 2^-9 ps (approximately 0.002)
output_files={'-o': tprfile})
tprfilename = grompp.output.file['-o'].result()
if grompp.output.returncode.result() != 0:
- logging.debug(grompp.output.erroroutput.result())
+ logging.debug(grompp.output.stderr.result())
raise RuntimeError('grompp failed in spc_water_box testing fixture.')
# TODO: more inspection of grompp errors...
command = shutil.which('true')
operation = commandline.cli(command=[command], shell=False)
- # Note: 'stdout' and 'stderr' not mapped.
# Note: getitem not implemented.
- # assert not 'stdout' in operation.output
- # assert not 'stderr' in operation.output
- assert not hasattr(operation.output, 'stdout')
- assert not hasattr(operation.output, 'stderr')
-
- # Check for the attributes that we _do_ expect.
- assert hasattr(operation.output, 'erroroutput')
+ # assert 'stdout' in operation.output
+ # assert 'stderr' in operation.output
+ assert hasattr(operation.output, 'stdout')
+ assert hasattr(operation.output, 'stderr')
+ assert not hasattr(operation.output, 'erroroutput')
assert hasattr(operation.output, 'returncode')
operation.run()
def test_true(self):
operation = commandline.commandline_operation(executable='true')
- # Note: 'stdout' and 'stderr' not mapped.
# Note: getitem not implemented.
- # assert not 'stdout' in operation.output
- # assert not 'stderr' in operation.output
- assert not hasattr(operation.output, 'stdout')
- assert not hasattr(operation.output, 'stderr')
+ # assert 'stdout' in operation.output
+ # assert 'stderr' in operation.output
+ assert not hasattr(operation.output, 'erroroutput')
assert hasattr(operation.output, 'file')
- assert hasattr(operation.output, 'erroroutput')
+ assert hasattr(operation.output, 'stdout')
+ assert hasattr(operation.output, 'stderr')
assert hasattr(operation.output, 'returncode')
assert operation.output.returncode.result() == 0
assert operation.output.returncode.result() == 1
def test_echo(self):
- # TODO: (FR5+) do we want to pipeline or checkpoint stdout somehow?
+ # TODO: (#3549) Check stdout, stderr.
operation = commandline.commandline_operation(executable='echo',
arguments=['hi there'])
assert operation.output.returncode.result() == 0
# This should be removable once object libraries can directly use target_link_libraries
# with CMake 3.12, #3290
target_include_directories(template SYSTEM PRIVATE ${PROJECT_SOURCE_DIR}/src/external)
-target_link_libraries(template libgromacs ${GMX_EXE_LINKER_FLAGS})
+target_link_libraries(template libgromacs legacy_modules ${GMX_EXE_LINKER_FLAGS})
set(DOCUMENTATION_HTTP_URL_BASE
http://jenkins.gromacs.org/job/Documentation_Nightly_master/javadoc)
# CMAKE_BUILD_TYPE is #included into buildinfo.h and populates the
# fields e.g. printed to the log file.
file(GENERATE
- OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/compilerflaginfo-$<CONFIG>-$<COMPILE_LANGUAGE>.h
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/include/compilerflaginfo-$<CONFIG>-$<COMPILE_LANGUAGE>.h
INPUT ${CMAKE_CURRENT_SOURCE_DIR}/compilerflaginfo.h.cmakein
CONDITION $<CONFIG:${CMAKE_BUILD_TYPE}>
)
mark_as_advanced(CLANG_TIDY_EXE)
endif()
+# Create a basic target for the `src` section of the build tree to capture
+# the library-level shared details through CMake infrastructure. It is not
+# installed or exported, so it must only be used as a PRIVATE dependency by
+# installed targets.
+# Initially, this is just an INTERFACE target to provide include directory.
+# It should also absorb global variables and compiler/linker details to be
+# provided as transitive usage requirements.
+# It could expand to aggregate the module targets in the future.
+add_library(common INTERFACE)
+target_include_directories(common INTERFACE
+ ${CMAKE_CURRENT_SOURCE_DIR}/include
+ ${CMAKE_CURRENT_BINARY_DIR}/include)
+
add_subdirectory(external)
if (BUILD_TESTING)
# header file in both of the make stages. That's slow, and is useless
# busy work for ccache, too.
string(TOUPPER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_UPPER)
-configure_file(config.h.cmakein config.h)
-configure_file(gmxpre-config.h.cmakein gmxpre-config.h)
+configure_file(config.h.cmakein include/config.h)
+configure_file(gmxpre-config.h.cmakein include/gmxpre-config.h)
set(CMAKE_BUILD_CONFIGURATION_C_FLAGS ${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE_UPPER}})
set(CMAKE_BUILD_CONFIGURATION_CXX_FLAGS ${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE_UPPER}})
-configure_file(buildinfo.h.cmakein buildinfo.h ESCAPE_QUOTES)
+configure_file(buildinfo.h.cmakein include/buildinfo.h ESCAPE_QUOTES)
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+# Copyright (c) 2018,2019,2020,2021, 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.
# Activate targets for new C++ API components and docs.
if (GMXAPI)
- if (GMX_BUILD_MDRUN_ONLY)
- message(FATAL_ERROR "GMXAPI relies on libgromacs and is incompatible with GMX_BUILD_MDRUN_ONLY.")
- endif()
if(NOT ${BUILD_SHARED_LIBS})
# Note: this conditional should check for the existence of a libgromacs target supporting PIC
# using the POSITION_INDEPENDENT_CODE property, but for now the only facility we have is the global
#include "gromacs/math/vectypes.h"
#include "gromacs/restraint/restraintpotential.h"
#include "gromacs/utility/arrayref.h"
-#include "gromacs/utility/classhelpers.h"
namespace gmxapi
{
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018, by the GROMACS development team, led by
+ * Copyright (c) 2018,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 to simulate an interrupt signal to catch.
gmx_set_stop_condition(gmx_stop_cond_next_ns);
- session->run();
+ auto status = session->run();
+ EXPECT_FALSE(status.success());
// If this assertion fails, it is not an error, but it indicates expected behavior has
// changed and we need to consider the impact of whatever changes caused this.
// Launching a session should clear the stop condition.
EXPECT_EQ(gmx_get_stop_condition(), gmx_stop_cond_none);
- session->run();
+ auto status = session->run();
+ EXPECT_TRUE(status.success());
// Stop condition should still be clear.
EXPECT_EQ(gmx_get_stop_condition(), gmx_stop_cond_none);
"tau-t = 1\n"
"ref-t = 298\n"
"compressed-x-grps = Sol\n",
- steps, getTestStepSize()));
+ steps,
+ getTestStepSize()));
EXPECT_EQ(0, runner_.callGromppOnThisRank());
}
*
* Copyright (c) 2009,2010,2011,2012,2013 by the GROMACS development team.
* Copyright (c) 2014,2015,2016,2017,2018 by the GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
/* AVX2 128-bit SIMD instruction set level was selected */
#cmakedefine01 GMX_SIMD_X86_AVX2_128
-/* MIC (Xeon Phi) SIMD instruction set level was selected */
-#cmakedefine01 GMX_SIMD_X86_MIC
-
/* AVX-512F foundation level instruction SIMD */
#cmakedefine01 GMX_SIMD_X86_AVX_512
/* AVX-512ER foundation level instruction SIMD */
#cmakedefine01 GMX_SIMD_X86_AVX_512_KNL
-/* 32-bit ARM NEON SIMD instruction set level was selected */
-#cmakedefine01 GMX_SIMD_ARM_NEON
-
/* ARM (AArch64) NEON Advanced SIMD instruction set level was selected */
#cmakedefine01 GMX_SIMD_ARM_NEON_ASIMD
/* SVE vector length */
#define GMX_SIMD_ARM_SVE_LENGTH_VALUE @GMX_SIMD_ARM_SVE_LENGTH_VALUE@
-/* IBM VMX was selected as SIMD instructions (Power 6 and later) */
-#cmakedefine01 GMX_SIMD_IBM_VMX
-
/* IBM VSX was selected as SIMD instructions (Power 7 and later) */
#cmakedefine01 GMX_SIMD_IBM_VSX
-/* Fujitsu Sparc64 HPC-ACE SIMD acceleration */
-#cmakedefine01 GMX_SIMD_SPARC64_HPC_ACE
-
/* Reference SIMD implementation for testing */
#cmakedefine01 GMX_SIMD_REFERENCE
/* Whether NBNXM and other SIMD kernels should be compiled */
#cmakedefine01 GMX_USE_SIMD_KERNELS
-/* Whether a double-precision configuration may target accuracy equivalent to single precision */
-#cmakedefine01 GMX_RELAXED_DOUBLE_PRECISION
-
/* Integer byte order is big endian. */
#cmakedefine01 GMX_INTEGER_BIG_ENDIAN
(MPI or thread_mpi) */
#define GMX_MPI (GMX_LIB_MPI || GMX_THREAD_MPI)
-/* MPI_IN_PLACE exists for collective operations */
-#cmakedefine01 MPI_IN_PLACE_EXISTS
-
/* Use OpenMP multithreading */
#cmakedefine01 GMX_OPENMP
#cmakedefine01 HAVE_FSEEKO
/* Define to 1 if _fseeki64 (and presumably _fseeki64) exists and is declared. */
+//NOLINTNEXTLINE(bugprone-reserved-identifier)
#cmakedefine01 HAVE__FSEEKI64
/* Have io.h (windows)*/
#cmakedefine01 HAVE_MEMALIGN
/* Define to 1 if you have the MSVC _aligned_malloc() function. */
+//NOLINTNEXTLINE(bugprone-reserved-identifier)
#cmakedefine01 HAVE__ALIGNED_MALLOC
/* Define to 1 if you have the clock_gettime() function. */
#cmakedefine01 HAVE_FSYNC
/* Define to 1 if you have the Windows _commit() function. */
+//NOLINTNEXTLINE(bugprone-reserved-identifier)
#cmakedefine01 HAVE__COMMIT
/* Define to 1 if you have the fileno() function. */
#cmakedefine01 HAVE_FILENO
/* Define to 1 if you have the _fileno() function. */
+//NOLINTNEXTLINE(bugprone-reserved-identifier)
#cmakedefine01 HAVE__FILENO
/* Define to 1 if you have the sigaction() function. */
* malloc.h or xmmintrin.h, and 0 otherwise. Note that you need to
* conditionally include the three headers too before using _mm_malloc().
*/
+//NOLINTNEXTLINE(bugprone-reserved-identifier)
#cmakedefine01 HAVE__MM_MALLOC
/* Define if SIGUSR1 is present */
#else
/* older versions of gcc don't support atomic intrinsics */
-#ifndef __MIC__
#define tMPI_Atomic_memory_barrier() __asm__ __volatile__("sfence;" : : : "memory")
-#else
-/* MIC is in-order and does not need nor support sfense */
-#define tMPI_Atomic_memory_barrier() __asm__ __volatile__("" ::: "memory")
-#endif
#define TMPI_ATOMIC_HAVE_NATIVE_FETCH_ADD
static inline int tMPI_Atomic_fetch_add(tMPI_Atomic_t *a, int i)
+++ /dev/null
-/*
- This source code file is part of thread_mpi.
- Written by Sander Pronk, Erik Lindahl, and possibly others.
-
- Copyright (c) 2009, Sander Pronk, Erik Lindahl.
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- 1) Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2) Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- 3) Neither the name of the copyright holders nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY US ''AS IS'' AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL WE BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- If you want to redistribute modifications, 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 should not
- be called official thread_mpi. Details are found in the README & COPYING
- files.
- */
-
-/** \file
- *
- * \brief mutex objects with C++11 API compatibility.
- *
- * This header contains classes mutex and lock_guard, used in C++ mutex
- * implementations safe for exceptions.
- */
-
-#ifndef TMPI_MUTEX_H_
-#define TMPI_MUTEX_H_
-
-#include "visibility.h"
-#include "system_error.h"
-#include "threads.h"
-
-namespace tMPI
-{
-/*! \brief A lock guard class that allows for the simple management of
- mutexes. C++11 compatible.
-
- In C++, mutexes would normally have to be unlocked with explicit
- exception handlers and unlock statements. This class automates that
- by handling the mutex unlock in a destructor. The constructor locks
- the mutex.
-
- Usage example:
- tMPI::mutex mtx;
- void do_count()
- {
- tMPI::lock_guard<tMPI::mutex> lock(mtx);
- count += 1;
- }
- */
-template <class Mutex> class TMPI_EXPORT lock_guard
-{
- public:
- //! Lockable type that this lock operates on.
- typedef Mutex mutex_type;
- /*! \brief The constructor, which locks the mutex.
-
- \param m The exisiting (globally accessible) mutex to lock. */
- explicit lock_guard(mutex_type &m) : m_(m)
- {
- m_.lock();
- }
- //lock_guard(mutex_type &m, adopt_lock_t t);
-
- /*! \brief The destructor, which unlocks the mutex */
- ~lock_guard()
- {
- m_.unlock();
- }
- private:
- // forbid copy constructor & assignment
- lock_guard(const lock_guard &l);
- lock_guard &operator=(const lock_guard &l);
-
- mutex_type &m_;
-};
-
-/*! \brief A basic mutex class with C++11 compatibility. */
-class TMPI_EXPORT mutex
-{
- public:
- //! Type of the native mutex handle.
- typedef tMPI_Thread_mutex_t* native_handle_type;
-
- /*! \brief The constructor.
-
- Throws a tMPI::system_error exception upon failure. */
- mutex()
- {
- int ret = tMPI_Thread_mutex_init(&handle_);
- if (ret)
- {
- throw system_error(ret);
- }
- }
-
- /*! \brief The destructor.*/
- ~mutex()
- {
- tMPI_Thread_mutex_destroy(&handle_);
- }
-
- /*! \brief The lock function.
-
- Throws a tMPI::system_error exception upon failure. */
- void lock()
- {
- int ret = tMPI_Thread_mutex_lock(&handle_);
- if (ret)
- {
- throw system_error(ret);
- }
- }
-
- /*! \brief The try_lock function.
-
- \return true if the lock was locked successfully, false if
- another thread owned it, and implementation-specific if
- already held by this thread. Do not rely on the return code
- if the calling thread could already hold this lock. */
- bool try_lock()
- {
- if (tMPI_Thread_mutex_trylock(&handle_))
- {
- return false;
- }
- return true;
- }
-
- /*! \brief The unlock function.
-
- Throws a tMPI::system_error exception upon failure. */
- void unlock()
- {
- int ret = tMPI_Thread_mutex_unlock(&handle_);
- if (ret)
- {
- throw system_error(ret);
- }
- }
-
- //! Returns the native handle for this mutex.
- native_handle_type native_handle() { return &handle_; }
- private:
- // forbid copy constructor & assignment
- mutex(const mutex &m);
- mutex &operator=(const mutex &m);
-
- tMPI_Thread_mutex_t handle_;
-};
-}
-
-#endif /* TMPI_MUTEX_H_ */
+++ /dev/null
-/*
- This source code file is part of thread_mpi.
- Written by Sander Pronk, Erik Lindahl, and possibly others.
-
- Copyright (c) 2009, Sander Pronk, Erik Lindahl.
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- 1) Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2) Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- 3) Neither the name of the copyright holders nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY US ''AS IS'' AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL WE BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- If you want to redistribute modifications, 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 should not
- be called official thread_mpi. Details are found in the README & COPYING
- files.
- */
-
-/** \file
- * \brief A C++11 compatible system_error class for reporting exceptions
- *
- * This header contains class definitions for system_error.
- */
-
-#ifndef TMPI_SYSTEM_ERROR_H_
-#define TMPI_SYSTEM_ERROR_H_
-
-#include <stdexcept>
-
-#include "visibility.h"
-
-namespace tMPI
-{
-/*! \brief Subset of the C++11 system_error class
-
- Only contains the errno-based constructor. */
-class system_error : public std::runtime_error
-{
- public:
- //! Type to represent error codes within this class.
- typedef int error_code;
-
- //system_error(error_code ec, const std::string& what_arg);
- //system_error(error_code ec, const char* what_arg);
- /*! \brief Constuctor that takes an system error number */
- explicit system_error(error_code ec);
-
- /*! \brief Returns the error code */
- const error_code &code() const
- {
- return ec_;
- }
- private:
- error_code ec_;
-};
-}
-
-#endif /* TMPI_SYSTEM_ERROR_H_ */
+++ /dev/null
-/*
- This source code file is part of thread_mpi.
- Written by Sander Pronk, Erik Lindahl, and possibly others.
-
- Copyright (c) 2009, Sander Pronk, Erik Lindahl.
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- 1) Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2) Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- 3) Neither the name of the copyright holders nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY US ''AS IS'' AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL WE BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- If you want to redistribute modifications, 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 should not
- be called official thread_mpi. Details are found in the README & COPYING
- files.
- */
-
-#include <cerrno>
-#include <cstring>
-#include <cstdlib>
-#include <stdexcept>
-#include <string>
-#include "thread_mpi/system_error.h"
-
-tMPI::system_error::system_error(error_code ec)
- : runtime_error(std::string(std::strerror(ec))), ec_(ec)
-{
-}
# This file is part of the GROMACS molecular simulation package.
#
# Copyright (c) 2010,2011,2012,2013,2014 by the GROMACS development team.
-# Copyright (c) 2015,2016,2017,2018,2019,2020, by the GROMACS development team, led by
+# Copyright (c) 2015,2016,2017,2018,2019,2020,2021, 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.
add_subdirectory(compat)
add_subdirectory(mimic)
add_subdirectory(modularsimulator)
-if (NOT GMX_BUILD_MDRUN_ONLY)
- add_subdirectory(gmxana)
- add_subdirectory(gmxpreprocess)
- add_subdirectory(correlationfunctions)
- add_subdirectory(statistics)
- add_subdirectory(analysisdata)
- add_subdirectory(coordinateio)
- add_subdirectory(trajectoryanalysis)
- add_subdirectory(energyanalysis)
- add_subdirectory(tools)
-endif()
+add_subdirectory(gmxana)
+add_subdirectory(gmxpreprocess)
+add_subdirectory(correlationfunctions)
+add_subdirectory(statistics)
+add_subdirectory(analysisdata)
+add_subdirectory(coordinateio)
+add_subdirectory(trajectoryanalysis)
+add_subdirectory(energyanalysis)
+add_subdirectory(tools)
get_property(PROPERTY_SOURCES GLOBAL PROPERTY GMX_LIBGROMACS_SOURCES)
list(APPEND LIBGROMACS_SOURCES ${GMXLIB_SOURCES} ${MDLIB_SOURCES} ${PROPERTY_SOURCES})
endif()
list(APPEND libgromacs_object_library_dependencies thread_mpi)
-configure_file(version.h.cmakein version.h)
if(GMX_INSTALL_LEGACY_API)
install(FILES
- ${CMAKE_CURRENT_BINARY_DIR}/version.h
analysisdata.h
options.h
selection.h
else()
add_library(libgromacs ${LIBGROMACS_SOURCES})
endif()
+target_link_libraries(libgromacs PRIVATE $<BUILD_INTERFACE:common>)
+# As long as the libgromacs target has source files that reference headers from
+# modules that don't provide CMake targets, libgromacs needs to use `src/`
+# amongst its include directories (to support `#include "gromacs/module/header.h"`).
+add_library(legacy_modules INTERFACE)
+target_include_directories(legacy_modules INTERFACE $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/src>)
+target_link_libraries(libgromacs PRIVATE $<BUILD_INTERFACE:legacy_modules>)
# Add these contents first because linking their tests can take a lot
# of time, so we want lots of parallel work still available after
set_target_properties(${object_library} PROPERTIES POSITION_INDEPENDENT_CODE true)
endif()
target_include_directories(${object_library} SYSTEM BEFORE PRIVATE ${PROJECT_SOURCE_DIR}/src/external/thread_mpi/include)
+ target_link_libraries(${object_library} PRIVATE common)
# Add the sources from the object libraries to the main library.
target_sources(libgromacs PRIVATE $<TARGET_OBJECTS:${object_library}>)
PUBLIC
${GMX_PUBLIC_LIBRARIES}
)
+target_link_libraries(libgromacs PUBLIC legacy_api)
+# Dependencies from libgromacs to the modules are set up here, but
+# once the add_subdirectory() commands are re-ordered then
+# responsibility for setting this up will move to the respective
+# modules.
+target_link_libraries(libgromacs PRIVATE
+ $<BUILD_INTERFACE:analysisdata>
+ $<BUILD_INTERFACE:applied_forces>
+ $<BUILD_INTERFACE:commandline>
+ $<BUILD_INTERFACE:compat>
+ $<BUILD_INTERFACE:coordinateio>
+ $<BUILD_INTERFACE:correlationfunctions>
+ $<BUILD_INTERFACE:domdec>
+# $<BUILD_INTERFACE:energyanalysis>
+ $<BUILD_INTERFACE:essentialdynamics>
+ $<BUILD_INTERFACE:ewald>
+ $<BUILD_INTERFACE:fft>
+ $<BUILD_INTERFACE:fileio>
+ $<BUILD_INTERFACE:gmxana>
+ $<BUILD_INTERFACE:gmxlib>
+ $<BUILD_INTERFACE:gmxpreprocess>
+ $<BUILD_INTERFACE:gpu_utils>
+ $<BUILD_INTERFACE:hardware>
+ $<BUILD_INTERFACE:imd>
+ $<BUILD_INTERFACE:linearalgebra>
+ $<BUILD_INTERFACE:listed_forces>
+ $<BUILD_INTERFACE:math>
+ $<BUILD_INTERFACE:mdlib>
+ $<BUILD_INTERFACE:mdrun>
+ $<BUILD_INTERFACE:mdrunutility>
+ $<BUILD_INTERFACE:mdspan>
+ $<BUILD_INTERFACE:mdtypes>
+ $<BUILD_INTERFACE:mimic>
+ $<BUILD_INTERFACE:modularsimulator>
+ $<BUILD_INTERFACE:nbnxm>
+ $<BUILD_INTERFACE:onlinehelp>
+ $<BUILD_INTERFACE:options>
+ $<BUILD_INTERFACE:pbcutil>
+ $<BUILD_INTERFACE:pulling>
+ $<BUILD_INTERFACE:random>
+ $<BUILD_INTERFACE:restraint>
+ $<BUILD_INTERFACE:selection>
+ $<BUILD_INTERFACE:simd>
+ $<BUILD_INTERFACE:statistics>
+ $<BUILD_INTERFACE:swap>
+ $<BUILD_INTERFACE:tables>
+ $<BUILD_INTERFACE:taskassignment>
+ $<BUILD_INTERFACE:timing>
+ $<BUILD_INTERFACE:tools>
+ $<BUILD_INTERFACE:topology>
+ $<BUILD_INTERFACE:trajectory>
+ $<BUILD_INTERFACE:trajectoryanalysis>
+ $<BUILD_INTERFACE:utility>
+ )
if (GMX_OPENMP)
target_link_libraries(libgromacs PUBLIC OpenMP::OpenMP_CXX)
endif()
target_compile_options(libgromacs PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-w>)
endif()
-# Only install the library in mdrun-only mode if it is actually necessary
-# for the binary
-if (NOT GMX_BUILD_MDRUN_ONLY OR BUILD_SHARED_LIBS)
+# TODO: Stop installing libgromacs. Possibly allow installation during deprecation period with GMX_INSTALL_LEGACY_API.
+if (BUILD_SHARED_LIBS)
install(TARGETS libgromacs
EXPORT libgromacs
LIBRARY
if(GMX_INSTALL_LEGACY_API)
target_compile_features(libgromacs INTERFACE cxx_std_${CMAKE_CXX_STANDARD})
endif()
- add_library(Gromacs::libgromacs ALIAS libgromacs)
endif()
+add_library(Gromacs::libgromacs ALIAS libgromacs)
-if (NOT GMX_BUILD_MDRUN_ONLY)
- include(InstallLibInfo.cmake)
-endif()
+include(InstallLibInfo.cmake)
# Technically, the user could want to do this for an OpenCL build
# using the CUDA runtime, but currently there's no reason to want to
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+add_library(analysisdata INTERFACE)
file(GLOB ANALYSISDATA_SOURCES *.cpp modules/*.cpp)
set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${ANALYSISDATA_SOURCES} PARENT_SCOPE)
DESTINATION include/gromacs/analysisdata)
endif()
+# Source files have the following private module dependencies.
+target_link_libraries(analysisdata PRIVATE
+# gmxlib
+# math
+# mdtypes
+# tng_io
+ )
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(analysisdata PUBLIC
+target_include_directories(analysisdata INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(analysisdata PUBLIC
+target_link_libraries(analysisdata INTERFACE
+ legacy_api
+ )
+
+# TODO: when analysisdata is an OBJECT target
+#target_link_libraries(analysisdata PUBLIC legacy_api)
+#target_link_libraries(analysisdata PRIVATE common)
+
+# Module dependencies
+# analysisdata interfaces convey transitive dependence on these modules.
+#target_link_libraries(analysisdata PUBLIC
+target_link_libraries(analysisdata INTERFACE
+ utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(analysisdata PRIVATE tng_io)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(analysisdata PRIVATE legacy_modules)
add_subdirectory(modules)
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2010,2011,2012,2013,2014 by the GROMACS development team.
- * Copyright (c) 2015,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2015,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <memory>
-#include "gromacs/utility/classhelpers.h"
-
namespace gmx
{
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2010-2018, The GROMACS development team.
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 2019,2021, 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.
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
friend class AnalysisDataHandle;
};
AnalysisDataFrameHeader header(i, xvalue(i), 0);
modules.notifyFrameStart(header);
modules.notifyPointsAdd(AnalysisDataPointSetRef(
- header, pointSetInfo_,
- makeConstArrayRef(value_).subArray(i * columnCount(), columnCount())));
+ header, pointSetInfo_, makeConstArrayRef(value_).subArray(i * columnCount(), columnCount())));
modules.notifyFrameFinish(header);
}
modules.notifyDataFinish();
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2010,2011,2012,2013,2014 by the GROMACS development team.
- * Copyright (c) 2015,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2015,2019,2020,2021, 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.
#ifndef GMX_ANALYSISDATA_DATAMODULEMANAGER_H
#define GMX_ANALYSISDATA_DATAMODULEMANAGER_H
+#include <memory>
+
#include "gromacs/analysisdata/abstractdata.h"
-#include "gromacs/utility/classhelpers.h"
namespace gmx
{
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team.
- * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/analysisdata/dataframe.h"
#include "gromacs/analysisdata/datamodulemanager.h"
#include "gromacs/analysisdata/paralleloptions.h"
+#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/gmxassert.h"
{
GMX_RELEASE_ASSERT(data_ != nullptr, "Invalid frame accessed");
const AbstractAnalysisData& baseData = data_->baseData();
- GMX_RELEASE_ASSERT(index >= 0 && index < baseData.dataSetCount(),
- "Out of range data set index");
+ GMX_RELEASE_ASSERT(index >= 0 && index < baseData.dataSetCount(), "Out of range data set index");
GMX_RELEASE_ASSERT(!baseData.isMultipoint() || !bPointSetInProgress_,
"Point sets in multipoint data cannot span data sets");
currentDataSet_ = index;
{
firstColumn = 0;
}
- data_->addPointSet(currentDataSet_, firstColumn,
- makeConstArrayRef(values_).subArray(begin, end - begin));
+ data_->addPointSet(
+ currentDataSet_, firstColumn, makeConstArrayRef(values_).subArray(begin, end - begin));
}
clearValues();
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2013,2014,2019, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2019,2021, 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.
#ifndef GMX_ANALYSISDATA_DATASTORAGE_H
#define GMX_ANALYSISDATA_DATASTORAGE_H
+#include <memory>
#include <vector>
#include "gromacs/analysisdata/dataframe.h"
private:
typedef internal::AnalysisDataStorageImpl Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2010,2011,2012,2013,2014 by the GROMACS development team.
- * Copyright (c) 2015,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2015,2018,2019,2020,2021, 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.
#ifndef GMX_ANALYSISDATA_MODULES_AVERAGE_H
#define GMX_ANALYSISDATA_MODULES_AVERAGE_H
+#include <memory>
#include <vector>
#include "gromacs/analysisdata/abstractdata.h"
#include "gromacs/analysisdata/arraydata.h"
#include "gromacs/analysisdata/datamodule.h"
-#include "gromacs/utility/classhelpers.h"
namespace gmx
{
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
//! Smart pointer to manage an AnalysisDataAverageModule object.
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
//! Smart pointer to manage an AnalysisDataFrameAverageModule object.
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2010,2011,2012,2013,2014 by the GROMACS development team.
- * Copyright (c) 2015,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2015,2018,2019,2020,2021, 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.
class Impl;
- PrivateImplPointer<Impl> _impl;
+ std::unique_ptr<Impl> _impl;
};
//! Smart pointer to manage an AnalysisDataDisplacementModule object.
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2010,2011,2012,2013,2014 by the GROMACS development team.
- * Copyright (c) 2015,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2015,2018,2019,2020,2021, 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.
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
// Copy and assign disallowed by base.
};
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
// Copy and assign disallowed by base.
};
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
// Copy and assign disallowed by base.
};
// if explicitly requested.
std::vector<Impl::LifetimeHistogram>::iterator histogram;
for (histogram = impl_->lifetimeHistograms_.begin();
- histogram != impl_->lifetimeHistograms_.end(); ++histogram)
+ histogram != impl_->lifetimeHistograms_.end();
+ ++histogram)
{
Impl::LifetimeHistogram::iterator shorter, longer;
for (shorter = histogram->begin(); shorter != histogram->end(); ++shorter)
setColumnCount(impl_->lifetimeHistograms_.size());
std::vector<Impl::LifetimeHistogram>::const_iterator histogram;
size_t maxLifetime = 1;
- for (histogram = impl_->lifetimeHistograms_.begin();
- histogram != impl_->lifetimeHistograms_.end(); ++histogram)
+ for (histogram = impl_->lifetimeHistograms_.begin(); histogram != impl_->lifetimeHistograms_.end();
+ ++histogram)
{
maxLifetime = std::max(maxLifetime, histogram->size());
}
// Fill up the output data from the histograms.
allocateValues();
int column = 0;
- for (histogram = impl_->lifetimeHistograms_.begin();
- histogram != impl_->lifetimeHistograms_.end(); ++histogram, ++column)
+ for (histogram = impl_->lifetimeHistograms_.begin(); histogram != impl_->lifetimeHistograms_.end();
+ ++histogram, ++column)
{
int row = 0;
Impl::LifetimeHistogram::const_iterator i;
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2013,2014,2015,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2018,2019,2021, 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.
#ifndef GMX_ANALYSISDATA_MODULES_LIFETIME_H
#define GMX_ANALYSISDATA_MODULES_LIFETIME_H
+#include <memory>
+
#include "gromacs/analysisdata/arraydata.h"
#include "gromacs/analysisdata/datamodule.h"
-#include "gromacs/utility/classhelpers.h"
namespace gmx
{
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
//! Smart pointer to manage an AnalysisDataLifetimeModule object.
* Technically this duplicates a definition in pargs.cpp for legacy
* support code, but as the latter will go away and the alternatives
* are ugly, the duplication is acceptable. */
-const gmx::EnumerationArray<XvgFormat, const char*> c_xvgFormatNames = { { "xmgrace", "xmgr",
- "none" } };
+const gmx::EnumerationArray<XvgFormat, const char*> c_xvgFormatNames = {
+ { "xmgrace", "xmgr", "none" }
+};
void AnalysisDataPlotSettings::initOptions(IOptionsContainer* options)
{
gmx_output_env_t* oenv;
output_env_init(&oenv, getProgramContext(), timeUnit, FALSE, xvgFormat, 0);
const unique_cptr<gmx_output_env_t, output_env_done> oenvGuard(oenv);
- impl_->fp_ = xvgropen(impl_->filename_.c_str(), impl_->title_.c_str(), impl_->xlabel_,
- impl_->ylabel_, oenv);
+ impl_->fp_ = xvgropen(
+ impl_->filename_.c_str(), impl_->title_.c_str(), impl_->xlabel_, impl_->ylabel_, oenv);
const SelectionCollection* selections = impl_->settings_.selectionCollection();
if (selections != nullptr && output_env_get_xvg_format(oenv) != XvgFormat::None)
{
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2010,2011,2012,2013,2014 by the GROMACS development team.
- * Copyright (c) 2015,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2015,2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/analysisdata/datamodule.h"
#include "gromacs/options/timeunitmanager.h"
-#include "gromacs/utility/classhelpers.h"
enum class XvgFormat : int;
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
gmx_add_unit_test_library(analysisdata-test-shared
datatest.cpp
mock_datamodule.cpp)
+target_link_libraries(analysisdata-test-shared PRIVATE legacy_api)
gmx_add_unit_test(AnalysisDataUnitTests analysisdata-test
CPP_SOURCE_FILES
{
if (points.hasError(j))
{
- handle.setPoint(j + points.firstColumn(), points.y(j), points.error(j),
+ handle.setPoint(j + points.firstColumn(),
+ points.y(j),
+ points.error(j),
AnalysisDataTestInputPointSet::present(j));
}
else
{
- handle.setPoint(j + points.firstColumn(), points.y(j),
+ handle.setPoint(j + points.firstColumn(),
+ points.y(j),
AnalysisDataTestInputPointSet::present(j));
}
}
for (int ps = 0; ps < frame.pointSetCount(); ++ps)
{
const AnalysisDataTestInputPointSet& points = frame.pointSet(ps);
- StaticDataPointsChecker checker(&frame, &points, 0,
- data.columnCount(points.dataSetIndex()));
+ StaticDataPointsChecker checker(
+ &frame, &points, 0, data.columnCount(points.dataSetIndex()));
EXPECT_CALL(*this, pointsAdded(Property(&AnalysisDataPointSetRef::frameIndex, row)))
.WillOnce(Invoke(checker));
}
for (int ps = 0; ps < frame.pointSetCount(); ++ps)
{
const AnalysisDataTestInputPointSet& points = frame.pointSet(ps);
- StaticDataPointsChecker checker(&frame, &points, 0,
- data.columnCount(points.dataSetIndex()));
+ StaticDataPointsChecker checker(
+ &frame, &points, 0, data.columnCount(points.dataSetIndex()));
EXPECT_CALL(*this, pointsAdded(_)).WillOnce(Invoke(checker));
}
EXPECT_CALL(*this, frameFinished(_)).WillOnce(Invoke(StaticDataFrameHeaderChecker(&frame)));
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2011,2012,2013,2014,2015 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/analysisdata/dataframe.h"
#include "gromacs/analysisdata/datamodule.h"
#include "gromacs/analysisdata/paralleloptions.h"
-#include "gromacs/utility/classhelpers.h"
namespace gmx
{
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
//! Smart pointer to manage an MockAnalysisDataModule object.
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+# Set up the module library
+add_library(applied_forces INTERFACE)
+
+# Source files have the following private module dependencies.
+target_link_libraries(applied_forces PRIVATE
+ # gmxlib
+ # math
+ # mdtypes
+ # tng_io
+ )
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(applied_forces PUBLIC
+target_include_directories(applied_forces INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(applied_forces PUBLIC
+target_link_libraries(applied_forces INTERFACE
+ legacy_api
+ )
+
+# TODO: when fileio is an OBJECT target
+#target_link_libraries(applied_forces PUBLIC legacy_api)
+#target_link_libraries(applied_forces PRIVATE common)
+
+# Module dependencies
+# This module convey transitive dependence on these modules.
+#target_link_libraries(applied_forces PUBLIC
+target_link_libraries(applied_forces INTERFACE
+ # utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(applied_forces PRIVATE tng_io)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(applied_forces PRIVATE legacy_modules)
+
gmx_add_libgromacs_sources(
electricfield.cpp
)
}
double conversionFactor = pull_coordinate_is_angletype(&pullCoord) ? DEG2RAD : 1;
pullCoordIndex.push_back(awhDimParams.coordIndex);
- dimParams.push_back(DimParams::pullDimParams(conversionFactor,
- awhDimParams.forceConstant, beta));
+ dimParams.push_back(DimParams::pullDimParams(
+ conversionFactor, awhDimParams.forceConstant, beta));
}
else
{
/* Construct the bias and couple it to the system. */
Bias::ThisRankWillDoIO thisRankWillDoIO =
(MASTER(commRecord_) ? Bias::ThisRankWillDoIO::Yes : Bias::ThisRankWillDoIO::No);
- biasCoupledToSystem_.emplace_back(
- Bias(k, awhParams, awhParams.awhBiasParams[k], dimParams, beta, inputRecord.delta_t,
- numSharingSimulations, biasInitFilename, thisRankWillDoIO),
- pullCoordIndex);
+ biasCoupledToSystem_.emplace_back(Bias(k,
+ awhParams,
+ awhParams.awhBiasParams[k],
+ dimParams,
+ beta,
+ inputRecord.delta_t,
+ numSharingSimulations,
+ biasInitFilename,
+ thisRankWillDoIO),
+ pullCoordIndex);
biasCoupledToSystem_.back().bias_.printInitializationToLog(fplog);
}
/* Note: In the near future this call will be split in calls
* to supports bias sharing within a single simulation.
*/
- gmx::ArrayRef<const double> biasForce = biasCts.bias_.calcForceAndUpdateBias(
- coordValue, neighborLambdaEnergies, neighborLambdaDhdl, &biasPotential,
- &biasPotentialJump, commRecord_, multiSimRecord_, t, step, seed_, fplog);
+ gmx::ArrayRef<const double> biasForce =
+ biasCts.bias_.calcForceAndUpdateBias(coordValue,
+ neighborLambdaEnergies,
+ neighborLambdaDhdl,
+ &biasPotential,
+ &biasPotentialJump,
+ commRecord_,
+ multiSimRecord_,
+ t,
+ step,
+ seed_,
+ fplog);
awhPotential += biasPotential;
{
if (biasCts.bias_.dimParams()[d].isPullDimension())
{
- apply_external_pull_coord_force(pull_, biasCts.pullCoordIndex_[d - numLambdaDimsCounted],
- biasForce[d], masses, forceWithVirial);
+ apply_external_pull_coord_force(pull_,
+ biasCts.pullCoordIndex_[d - numLambdaDimsCounted],
+ biasForce[d],
+ masses,
+ forceWithVirial);
}
else
{
{
if (biasParams.dimParams[d].eCoordProvider == eawhcoordproviderPULL)
{
- register_external_pull_potential(pull_work, biasParams.dimParams[d].coordIndex,
- Awh::externalPotentialString());
+ register_external_pull_potential(
+ pull_work, biasParams.dimParams[d].coordIndex, Awh::externalPotentialString());
}
}
}
bool Awh::hasFepLambdaDimension() const
{
return std::any_of(
- std::begin(biasCoupledToSystem_), std::end(biasCoupledToSystem_),
+ std::begin(biasCoupledToSystem_),
+ std::end(biasCoupledToSystem_),
[](const auto& coupledBias) { return coupledBias.bias_.hasFepLambdaDimension(); });
}
GMX_THROW(InvalidInputError("AWH biasing does not support shell particles."));
}
- auto awh = std::make_unique<Awh>(
- fplog, inputRecord, commRecord, multiSimRecord, *inputRecord.awhParams, biasInitFilename,
- pull_work, inputRecord.fepvals->n_lambda, inputRecord.fepvals->init_fep_state);
+ auto awh = std::make_unique<Awh>(fplog,
+ inputRecord,
+ commRecord,
+ multiSimRecord,
+ *inputRecord.awhParams,
+ biasInitFilename,
+ pull_work,
+ inputRecord.fepvals->n_lambda,
+ inputRecord.fepvals->init_fep_state);
if (startingFromCheckpoint)
{
state_.doSkippedUpdatesInNeighborhood(params_, grid_);
}
convolvedBias = state_.updateProbabilityWeightsAndConvolvedBias(
- dimParams_, grid_, moveUmbrella ? neighborLambdaEnergies : ArrayRef<const double>{},
- &probWeightNeighbor);
+ dimParams_, grid_, moveUmbrella ? neighborLambdaEnergies : ArrayRef<const double>{}, &probWeightNeighbor);
if (isSampleCoordStep)
{
double potential;
if (params_.convolveForce)
{
- state_.calcConvolvedForce(dimParams_, grid_, probWeightNeighbor,
+ state_.calcConvolvedForce(dimParams_,
+ grid_,
+ probWeightNeighbor,
moveUmbrella ? neighborLambdaDhdl : ArrayRef<const double>{},
- tempForce_, biasForce_);
+ tempForce_,
+ biasForce_);
potential = -convolvedBias * params_.invBeta;
}
"AWH bias grid point for the umbrella reference value is outside of the "
"target region.");
potential = state_.calcUmbrellaForceAndPotential(
- dimParams_, grid_, coordState.umbrellaGridpoint(),
- moveUmbrella ? neighborLambdaDhdl : ArrayRef<const double>{}, biasForce_);
+ dimParams_,
+ grid_,
+ coordState.umbrellaGridpoint(),
+ moveUmbrella ? neighborLambdaDhdl : ArrayRef<const double>{},
+ biasForce_);
/* Moving the umbrella results in a force correction and
* a new potential. The umbrella center is sampled as often as
if (moveUmbrella)
{
const bool onlySampleUmbrellaGridpoint = false;
- double newPotential = state_.moveUmbrella(dimParams_, grid_, probWeightNeighbor,
- neighborLambdaDhdl, biasForce_, step, seed,
- params_.biasIndex, onlySampleUmbrellaGridpoint);
- *potentialJump = newPotential - potential;
+ double newPotential = state_.moveUmbrella(dimParams_,
+ grid_,
+ probWeightNeighbor,
+ neighborLambdaDhdl,
+ biasForce_,
+ step,
+ seed,
+ params_.biasIndex,
+ onlySampleUmbrellaGridpoint);
+ *potentialJump = newPotential - potential;
}
}
/* Update the free energy estimates and bias and other history dependent method parameters */
if (params_.isUpdateFreeEnergyStep(step))
{
- state_.updateFreeEnergyAndAddSamplesToHistogram(dimParams_, grid_, params_, commRecord, ms,
- t, step, fplog, &updateList_);
+ state_.updateFreeEnergyAndAddSamplesToHistogram(
+ dimParams_, grid_, params_, commRecord, ms, t, step, fplog, &updateList_);
if (params_.convolveForce)
{
if (moveUmbrella && params_.convolveForce && grid_.hasLambdaAxis())
{
const bool onlySampleUmbrellaGridpoint = true;
- state_.moveUmbrella(dimParams_, grid_, probWeightNeighbor, neighborLambdaDhdl, biasForce_,
- step, seed, params_.biasIndex, onlySampleUmbrellaGridpoint);
+ state_.moveUmbrella(dimParams_,
+ grid_,
+ probWeightNeighbor,
+ neighborLambdaDhdl,
+ biasForce_,
+ step,
+ seed,
+ params_.biasIndex,
+ onlySampleUmbrellaGridpoint);
}
/* Return the potential. */
"The number of AWH updates in the checkpoint file (%" PRId64
") does not match the total number of AWH samples divided by the number of samples "
"per update for %d sharing AWH bias(es) (%" PRId64 "/%d=%" PRId64 ")",
- numUpdatesExpected, params.numSharedUpdate, numSamples,
- params.numSamplesUpdateFreeEnergy_ * params.numSharedUpdate, numUpdatesFromSamples);
+ numUpdatesExpected,
+ params.numSharedUpdate,
+ numSamples,
+ params.numSamplesUpdateFreeEnergy_ * params.numSharedUpdate,
+ numUpdatesFromSamples);
mesg += " Maybe you changed AWH parameters.";
/* Unfortunately we currently do not store the number of simulations
* sharing the bias or the state to checkpoint. But we can hint at
mesg += gmx::formatString(
" Or the run you continued from used %" PRId64
" sharing simulations, whereas you now specified %d sharing simulations.",
- numUpdatesFromSamples / state.histogramSize().numUpdates(), params.numSharedUpdate);
+ numUpdatesFromSamples / state.histogramSize().numUpdates(),
+ params.numSharedUpdate);
}
GMX_THROW(InvalidInputError(mesg));
}
*/
double blockLength = 0;
/* Construct the force correlation object. */
- forceCorrelationGrid_ = std::make_unique<CorrelationGrid>(
- state_.points().size(), ndim(), blockLength,
- CorrelationGrid::BlockLengthMeasure::Time, awhParams.nstSampleCoord * mdTimeStep);
+ forceCorrelationGrid_ =
+ std::make_unique<CorrelationGrid>(state_.points().size(),
+ ndim(),
+ blockLength,
+ CorrelationGrid::BlockLengthMeasure::Time,
+ awhParams.nstSampleCoord * mdTimeStep);
writer_ = std::make_unique<BiasWriter>(*this);
}
fprintf(fplog,
"%s initial force correlation block length = %g %s"
"%s force correlation number of blocks = %d",
- prefix.c_str(), forceCorrelationGrid().getBlockLength(),
+ prefix.c_str(),
+ forceCorrelationGrid().getBlockLength(),
forceCorrelationGrid().blockLengthMeasure == CorrelationGrid::BlockLengthMeasure::Weight
? ""
: "ps",
- prefix.c_str(), forceCorrelationGrid().getNumBlocks());
+ prefix.c_str(),
+ forceCorrelationGrid().getNumBlocks());
}
}
We actually add the force normalized by beta which has the units of 1/length. This means that the
resulting correlation time integral is directly in units of friction time/length^2 which is really what
we're interested in. */
- state_.calcUmbrellaForceAndPotential(dimParams_, grid_, indexNeighbor, neighborLambdaDhdl,
- forceFromNeighbor);
+ state_.calcUmbrellaForceAndPotential(
+ dimParams_, grid_, indexNeighbor, neighborLambdaDhdl, forceFromNeighbor);
/* Note: we might want to give a whole list of data to add instead and have this loop in the data adding function */
forceCorrelationGrid_->addData(indexNeighbor, weightNeighbor, forceFromNeighbor, t);
*/
bool hasFepLambdaDimension() const
{
- return std::any_of(std::begin(dimParams_), std::end(dimParams_),
- [](const auto& dimParam) { return dimParam.isFepLambdaDimension(); });
+ return std::any_of(std::begin(dimParams_), std::end(dimParams_), [](const auto& dimParam) {
+ return dimParam.isFepLambdaDimension();
+ });
}
/*! \brief
std::string mesg = gmx::formatString(
"Could not extract data properly from %s. Wrong data format?"
"\n\n%s",
- dataFilename.c_str(), correctFormatMessage.c_str());
+ dataFilename.c_str(),
+ correctFormatMessage.c_str());
GMX_THROW(InvalidInputError(mesg));
}
}
else
{
- axis_.emplace_back(data[d][0], data[d][numDataPoints - 1], grid.axis(d).period(),
- numPoints[d], false);
+ axis_.emplace_back(
+ data[d][0], data[d][numDataPoints - 1], grid.axis(d).period(), numPoints[d], false);
}
}
"%s does not contain data for all coordinate values. "
"Make sure your input data covers the whole sampling domain "
"and is correctly formatted. \n\n%s",
- dataFilename.c_str(), correctFormatMessage.c_str());
+ dataFilename.c_str(),
+ correctFormatMessage.c_str());
GMX_THROW(InvalidInputError(mesg));
}
(*gridpointToDatapoint)[m] = getNearestIndexInGrid(grid.point(m).coordValue, axis_);
*/
bool hasLambdaAxis() const
{
- return std::any_of(std::begin(axis_), std::end(axis_),
- [](const auto& axis) { return axis.isFepLambdaAxis(); });
+ return std::any_of(std::begin(axis_), std::end(axis_), [](const auto& axis) {
+ return axis.isFepLambdaAxis();
+ });
}
/*! \brief
/* Add the convolved PMF weights for the neighbors of this point.
Note that this function only adds point within the target > 0 region.
Sum weights, take the logarithm last to get the free energy. */
- double logWeight = biasedLogWeightFromPoint(dimParams, points_, grid, neighbor,
- biasNeighbor, point.coordValue, {}, m);
+ double logWeight = biasedLogWeightFromPoint(
+ dimParams, points_, grid, neighbor, biasNeighbor, point.coordValue, {}, m);
freeEnergyWeights += std::exp(logWeight);
}
}
"If you are not certain about your settings you might want to increase your "
"pull force constant or "
"modify your sampling region.\n",
- biasIndex + 1, t, pointValueString.c_str(), maxHistogramRatio);
+ biasIndex + 1,
+ t,
+ pointValueString.c_str(),
+ maxHistogramRatio);
gmx::TextLineWrapper wrapper;
wrapper.settings().setLineLength(c_linewidth);
fprintf(fplog, "%s", wrapper.wrapToString(warningMessage).c_str());
bool onlySampleUmbrellaGridpoint)
{
/* Generate and set a new coordinate reference value */
- coordState_.sampleUmbrellaGridpoint(grid, coordState_.gridpointIndex(), probWeightNeighbor,
- step, seed, indexSeed);
+ coordState_.sampleUmbrellaGridpoint(
+ grid, coordState_.gridpointIndex(), probWeightNeighbor, step, seed, indexSeed);
if (onlySampleUmbrellaGridpoint)
{
/* In between global updates the reference histogram size is kept constant so we trivially
know what the histogram size was at the time of the skipped update. */
double histogramSize = histogramSize_.histogramSize();
- setHistogramUpdateScaleFactors(params, histogramSize, histogramSize, weightHistScaling,
- logPmfSumScaling);
+ setHistogramUpdateScaleFactors(
+ params, histogramSize, histogramSize, weightHistScaling, logPmfSumScaling);
}
else
{
/* Label each point along each dimension as covered or not. */
for (int d = 0; d < grid.numDimensions(); d++)
{
- labelCoveredPoints(checkDim[d].visited, checkDim[d].checkCovering, grid.axis(d).numPoints(),
- grid.axis(d).numPointsInPeriod(), params.coverRadius()[d], checkDim[d].covered);
+ labelCoveredPoints(checkDim[d].visited,
+ checkDim[d].checkCovering,
+ grid.axis(d).numPoints(),
+ grid.axis(d).numPointsInPeriod(),
+ params.coverRadius()[d],
+ checkDim[d].covered);
}
/* Now check for global covering. Each dimension needs to be covered separately.
{
sumOverSimulations(
gmx::arrayRefFromArray(checkDim[d].covered.data(), grid.axis(d).numPoints()),
- commRecord, multiSimComm);
+ commRecord,
+ multiSimComm);
}
}
}
/* The weighthistogram size after this update. */
- double newHistogramSize = histogramSize_.newHistogramSize(params, t, detectedCovering, points_,
- weightSumCovering_, fplog);
+ double newHistogramSize = histogramSize_.newHistogramSize(
+ params, t, detectedCovering, points_, weightSumCovering_, fplog);
/* Make the update list. Usually we try to only update local points,
* but if the update has non-trivial or non-deterministic effects
}
double weightHistScalingNew;
double logPmfsumScalingNew;
- setHistogramUpdateScaleFactors(params, newHistogramSize, histogramSize_.histogramSize(),
- &weightHistScalingNew, &logPmfsumScalingNew);
+ setHistogramUpdateScaleFactors(
+ params, newHistogramSize, histogramSize_.histogramSize(), &weightHistScalingNew, &logPmfsumScalingNew);
/* Update free energy and reference weight histogram for points in the update list. */
for (int pointIndex : *updateList)
/* Do updates from previous update steps that were skipped because this point was at that time non-local. */
if (params.skipUpdates())
{
- pointStateToUpdate->performPreviouslySkippedUpdates(params, histogramSize_.numUpdates(),
- weightHistScalingSkipped,
- logPmfsumScalingSkipped);
+ pointStateToUpdate->performPreviouslySkippedUpdates(
+ params, histogramSize_.numUpdates(), weightHistScalingSkipped, logPmfsumScalingSkipped);
}
/* Now do an update with new sampling data. */
- pointStateToUpdate->updateWithNewSampling(params, histogramSize_.numUpdates(),
- weightHistScalingNew, logPmfsumScalingNew);
+ pointStateToUpdate->updateWithNewSampling(
+ params, histogramSize_.numUpdates(), weightHistScalingNew, logPmfsumScalingNew);
}
/* Only update the histogram size after we are done with the local point updates */
if (n < neighbors.size())
{
const int neighbor = neighbors[n];
- (*weight)[n] = biasedLogWeightFromPoint(
- dimParams, points_, grid, neighbor, points_[neighbor].bias(),
- coordState_.coordValue(), neighborLambdaEnergies, coordState_.gridpointIndex());
+ (*weight)[n] = biasedLogWeightFromPoint(dimParams,
+ points_,
+ grid,
+ neighbor,
+ points_[neighbor].bias(),
+ coordState_.coordValue(),
+ neighborLambdaEnergies,
+ coordState_.gridpointIndex());
}
else
{
{
continue;
}
- double logWeight = biasedLogWeightFromPoint(dimParams, points_, grid, neighbor,
- points_[neighbor].bias(), coordValue, {}, point);
+ double logWeight = biasedLogWeightFromPoint(
+ dimParams, points_, grid, neighbor, points_[neighbor].bias(), coordValue, {}, point);
weightSum += std::exp(logWeight);
}
std::vector<double> lambdaMarginalDistribution =
calculateFELambdaMarginalDistribution(grid, neighbors, probWeightNeighbor);
- awh_dvec coordValueAlongLambda = { coordState_.coordValue()[0], coordState_.coordValue()[1],
- coordState_.coordValue()[2], coordState_.coordValue()[3] };
+ awh_dvec coordValueAlongLambda = { coordState_.coordValue()[0],
+ coordState_.coordValue()[1],
+ coordState_.coordValue()[2],
+ coordState_.coordValue()[3] };
for (size_t i = 0; i < neighbors.size(); i++)
{
const int neighbor = neighbors[i];
gmx_bcast(points_.size() * sizeof(PointState), points_.data(), commRecord->mpi_comm_mygroup);
- gmx_bcast(weightSumCovering_.size() * sizeof(double), weightSumCovering_.data(),
- commRecord->mpi_comm_mygroup);
+ gmx_bcast(weightSumCovering_.size() * sizeof(double), weightSumCovering_.data(), commRecord->mpi_comm_mygroup);
gmx_bcast(sizeof(histogramSize_), &histogramSize_, commRecord->mpi_comm_mygroup);
}
if (numRows <= 0)
{
- std::string mesg = gmx::formatString("%s is empty!.\n\n%s", filename.c_str(),
- correctFormatMessage.c_str());
+ std::string mesg = gmx::formatString(
+ "%s is empty!.\n\n%s", filename.c_str(), correctFormatMessage.c_str());
GMX_THROW(InvalidInputError(mesg));
}
std::string mesg = gmx::formatString(
"%s contains too few data points (%d)."
"The minimum number of points is 2.",
- filename.c_str(), numRows);
+ filename.c_str(),
+ numRows);
GMX_THROW(InvalidInputError(mesg));
}
std::string mesg = gmx::formatString(
"The number of columns in %s should be at least %d."
"\n\n%s",
- filename.c_str(), numColumnsMin, correctFormatMessage.c_str());
+ filename.c_str(),
+ numColumnsMin,
+ correctFormatMessage.c_str());
GMX_THROW(InvalidInputError(mesg));
}
std::string mesg = gmx::formatString(
"Found %d trailing zero data rows in %s. Please remove trailing empty lines and "
"try again.",
- numZeroRows, filename.c_str());
+ numZeroRows,
+ filename.c_str());
GMX_THROW(InvalidInputError(mesg));
}
if (target < 0)
{
std::string mesg = gmx::formatString(
- "Target distribution weight at point %zu (%g) in %s is negative.", m, target,
+ "Target distribution weight at point %zu (%g) in %s is negative.",
+ m,
+ target,
filename.c_str());
GMX_THROW(InvalidInputError(mesg));
}
{
std::string mesg =
gmx::formatString("The target weights given in column %d in %s are all 0",
- columnIndexTarget, filename.c_str());
+ columnIndexTarget,
+ filename.c_str());
GMX_THROW(InvalidInputError(mesg));
}
"Coordinate %d of an AWH bias has a value %f which is more than %d sigma "
"out of the AWH range of [%f, %f]. You seem to have an unstable reaction "
"coordinate setup or an unequilibrated system.",
- dim + 1, coordValue[dim], c_marginInSigma, axis.origin(),
+ dim + 1,
+ coordValue[dim],
+ c_marginInSigma,
+ axis.origin(),
axis.origin() + axis.length());
GMX_THROW(SimulationInstabilityError(mesg));
}
{
CorrelationGridHistory correlationGridHistory;
- initCorrelationGridHistory(&correlationGridHistory, correlationGrid.tensors().size(),
- correlationGrid.tensorSize(), correlationGrid.blockDataListSize());
+ initCorrelationGridHistory(&correlationGridHistory,
+ correlationGrid.tensors().size(),
+ correlationGrid.tensorSize(),
+ correlationGrid.blockDataListSize());
return correlationGridHistory;
}
}
else if (!havePrintedAboutCovering_)
{
- fprintf(fplog, "%s covered but histogram not equilibrated at t = %g ps.\n",
- prefix.c_str(), t);
+ fprintf(fplog,
+ "%s covered but histogram not equilibrated at t = %g ps.\n",
+ prefix.c_str(),
+ t);
havePrintedAboutCovering_ = true; /* Just print once. */
}
}
namespace gmx
{
-const char* eawhtarget_names[eawhtargetNR + 1] = { "constant", "cutoff", "boltzmann",
- "local-boltzmann", nullptr };
+const char* eawhtarget_names[eawhtargetNR + 1] = { "constant",
+ "cutoff",
+ "boltzmann",
+ "local-boltzmann",
+ nullptr };
const char* eawhgrowth_names[eawhgrowthNR + 1] = { "exp-linear", "linear", nullptr };
gmx_fatal(FARGS,
"The given AWH coordinate index (%d) is larger than the number of pull "
"coordinates (%d)",
- dimParams->coordIndex + 1, pull_params.ncoord);
+ dimParams->coordIndex + 1,
+ pull_params.ncoord);
}
if (pull_params.coord[dimParams->coordIndex].rate != 0)
{
auto message = formatString(
"Setting pull-coord%d-rate (%g) is incompatible with AWH biasing this coordinate",
- dimParams->coordIndex + 1, pull_params.coord[dimParams->coordIndex].rate);
+ dimParams->coordIndex + 1,
+ pull_params.coord[dimParams->coordIndex].rate);
warning_error(wi, message);
}
auto message = formatString(
"The given interval length given by %s-start (%g) and %s-end (%g) is zero. "
"This will result in only one point along this axis in the coordinate value grid.",
- prefix.c_str(), dimParams->origin, prefix.c_str(), dimParams->end);
+ prefix.c_str(),
+ dimParams->origin,
+ prefix.c_str(),
+ dimParams->end);
warning(wi, message);
}
"%s-start (%g) or %s-end (%g) set to a negative value. With pull "
"geometry distance coordinate values are non-negative. "
"Perhaps you want to use geometry %s instead?",
- prefix.c_str(), dimParams->origin, prefix.c_str(), dimParams->end,
+ prefix.c_str(),
+ dimParams->origin,
+ prefix.c_str(),
+ dimParams->end,
EPULLGEOM(epullgDIR));
}
}
gmx_fatal(FARGS,
"%s-start (%g) and %s-end (%g) are outside of the allowed range "
"0 to 180 deg for pull geometries %s and %s ",
- prefix.c_str(), dimParams->origin, prefix.c_str(), dimParams->end,
- EPULLGEOM(epullgANGLE), EPULLGEOM(epullgANGLEAXIS));
+ prefix.c_str(),
+ dimParams->origin,
+ prefix.c_str(),
+ dimParams->end,
+ EPULLGEOM(epullgANGLE),
+ EPULLGEOM(epullgANGLEAXIS));
}
}
else if (eGeom == epullgDIHEDRAL)
gmx_fatal(FARGS,
"%s-start (%g) and %s-end (%g) are outside of the allowed range "
"-180 to 180 deg for pull geometry %s. ",
- prefix.c_str(), dimParams->origin, prefix.c_str(), dimParams->end,
+ prefix.c_str(),
+ dimParams->origin,
+ prefix.c_str(),
+ dimParams->end,
EPULLGEOM(epullgDIHEDRAL));
}
}
"When running AWH coupled to the free energy lambda state all lambda states "
"should be used as neighbors in order to get correct probabilities, i.e. "
"calc-lambda-neighbors (%d) must be %d.",
- lambdaParams->lambda_neighbors, -1);
+ lambdaParams->lambda_neighbors,
+ -1);
}
if (efep == efepSLOWGROWTH || lambdaParams->delta_lambda != 0)
gmx_fatal(FARGS,
"When running AWH coupled to the free energy lambda state the lower lambda state "
"for AWH, %s (%.0f), must be >= 0.",
- opt.c_str(), dimParams->origin);
+ opt.c_str(),
+ dimParams->origin);
}
if (dimParams->end >= lambdaParams->n_lambda)
{
gmx_fatal(FARGS,
"When running AWH coupled to the free energy lambda state the upper lambda state "
"for AWH, %s (%.0f), must be < n_lambda (%d).",
- opt.c_str(), dimParams->origin, lambdaParams->n_lambda);
+ opt.c_str(),
+ dimParams->origin,
+ lambdaParams->n_lambda);
}
if (gmx_within_tol(dimParams->end - dimParams->origin, 0, GMX_REAL_EPS))
{
"The given interval length given by %s-start (%g) and %s-end (%g) is zero. "
"This will result in only one lambda point along this free energy lambda state "
"axis in the coordinate value grid.",
- prefix.c_str(), dimParams->origin, prefix.c_str(), dimParams->end);
+ prefix.c_str(),
+ dimParams->origin,
+ prefix.c_str(),
+ dimParams->end);
warning(wi, message);
}
/* Check this before starting to read the AWH dimension parameters. */
if (awhBiasParams->ndim <= 0 || awhBiasParams->ndim > c_biasMaxNumDim)
{
- gmx_fatal(FARGS, "%s (%d) needs to be > 0 and at most %d\n", opt.c_str(),
- awhBiasParams->ndim, c_biasMaxNumDim);
+ gmx_fatal(FARGS, "%s (%d) needs to be > 0 and at most %d\n", opt.c_str(), awhBiasParams->ndim, c_biasMaxNumDim);
}
snew(awhBiasParams->dimParams, awhBiasParams->ndim);
for (int d = 0; d < awhBiasParams->ndim; d++)
{
auto message =
formatString("Option %s will only have an effect for histogram growth type '%s'.",
- opt.c_str(), EAWHGROWTH(eawhgrowthEXP_LINEAR));
+ opt.c_str(),
+ EAWHGROWTH(eawhgrowthEXP_LINEAR));
warning(wi, message);
}
"Target type '%s' combined with histogram growth type '%s' is not "
"expected to give stable bias updates. You probably want to use growth type "
"'%s' instead.",
- EAWHTARGET(eawhtargetLOCALBOLTZMANN), EAWHGROWTH(eawhgrowthEXP_LINEAR),
+ EAWHTARGET(eawhtargetLOCALBOLTZMANN),
+ EAWHGROWTH(eawhgrowthEXP_LINEAR),
EAWHGROWTH(eawhgrowthLINEAR));
warning(wi, message);
}
case eawhtargetLOCALBOLTZMANN:
if (awhBiasParams->targetBetaScaling < 0 || awhBiasParams->targetBetaScaling > 1)
{
- gmx_fatal(FARGS, "%s = %g is not useful for target type %s.", opt.c_str(),
- awhBiasParams->targetBetaScaling, EAWHTARGET(awhBiasParams->eTarget));
+ gmx_fatal(FARGS,
+ "%s = %g is not useful for target type %s.",
+ opt.c_str(),
+ awhBiasParams->targetBetaScaling,
+ EAWHTARGET(awhBiasParams->eTarget));
}
break;
default:
gmx_fatal(
FARGS,
"Value for %s (%g) set explicitly but will not be used for target type %s.",
- opt.c_str(), awhBiasParams->targetBetaScaling,
+ opt.c_str(),
+ awhBiasParams->targetBetaScaling,
EAWHTARGET(awhBiasParams->eTarget));
}
break;
case eawhtargetCUTOFF:
if (awhBiasParams->targetCutoff <= 0)
{
- gmx_fatal(FARGS, "%s = %g is not useful for target type %s.", opt.c_str(),
- awhBiasParams->targetCutoff, EAWHTARGET(awhBiasParams->eTarget));
+ gmx_fatal(FARGS,
+ "%s = %g is not useful for target type %s.",
+ opt.c_str(),
+ awhBiasParams->targetCutoff,
+ EAWHTARGET(awhBiasParams->eTarget));
}
break;
default:
gmx_fatal(
FARGS,
"Value for %s (%g) set explicitly but will not be used for target type %s.",
- opt.c_str(), awhBiasParams->targetCutoff, EAWHTARGET(awhBiasParams->eTarget));
+ opt.c_str(),
+ awhBiasParams->targetCutoff,
+ EAWHTARGET(awhBiasParams->eTarget));
}
break;
}
opt = prefix + "-ndim";
if (awhBiasParams->ndim <= 0 || awhBiasParams->ndim > c_biasMaxNumDim)
{
- gmx_fatal(FARGS, "%s (%d) needs to be > 0 and at most %d\n", opt.c_str(),
- awhBiasParams->ndim, c_biasMaxNumDim);
+ gmx_fatal(FARGS, "%s (%d) needs to be > 0 and at most %d\n", opt.c_str(), awhBiasParams->ndim, c_biasMaxNumDim);
}
if (awhBiasParams->ndim > 2)
{
"dimensions (awh%d-dim%d and awh%d-dim%d). "
"If this is really what you want to do you will have to duplicate "
"this pull coordinate.",
- awhBiasParams1.dimParams[d1].coordIndex + 1, k1 + 1, d1 + 1, k2 + 1,
+ awhBiasParams1.dimParams[d1].coordIndex + 1,
+ k1 + 1,
+ d1 + 1,
+ k2 + 1,
d2 + 1);
gmx_fatal(FARGS, "%s", errormsg);
}
if (awhParams->nstOut <= 0)
{
auto message = formatString("Not writing AWH output with AWH (%s = %d) does not make sense",
- opt.c_str(), awhParams->nstOut);
+ opt.c_str(),
+ awhParams->nstOut);
warning_error(wi, message);
}
/* This restriction can be removed by changing a flag of print_ebin() */
if (ir->nstenergy == 0 || awhParams->nstOut % ir->nstenergy != 0)
{
- auto message = formatString("%s (%d) should be a multiple of nstenergy (%d)", opt.c_str(),
- awhParams->nstOut, ir->nstenergy);
+ auto message = formatString(
+ "%s (%d) should be a multiple of nstenergy (%d)", opt.c_str(), awhParams->nstOut, ir->nstenergy);
warning_error(wi, message);
}
gmx_fatal(FARGS,
"The AWH interval (%f nm) for a pull coordinate is larger than the "
"box size (%f nm)",
- intervalLength, boxLength);
+ intervalLength,
+ boxLength);
}
if (intervalLength > periodicFraction * boxLength)
gmx_fatal(FARGS,
"For the non-periodic pull coordinates awh%d-dim%d-start (%f) cannot be "
"larger than awh%d-dim%d-end (%f)",
- k + 1, d + 1, origin, k + 1, d + 1, end);
+ k + 1,
+ d + 1,
+ origin,
+ k + 1,
+ d + 1,
+ end);
}
/* Currently we assume symmetric periodic intervals, meaning we use [-period/2, period/2] as the reference interval.
"values in between "
"minus half a period and plus half a period, i.e. in the interval [%.8g, "
"%.8g].",
- k + 1, d + 1, origin, k + 1, d + 1, end, period, -0.5 * period, 0.5 * period);
+ k + 1,
+ d + 1,
+ origin,
+ k + 1,
+ d + 1,
+ end,
+ period,
+ -0.5 * period,
+ 0.5 * period);
}
/* Warn if the pull initial coordinate value is not in the grid */
"(%.8g). "
"This can lead to large initial forces pulling the coordinate towards the "
"sampling interval.",
- coordValueInit, coordIndex + 1, k + 1, d + 1, origin, k + 1, d + 1, end);
+ coordValueInit,
+ coordIndex + 1,
+ k + 1,
+ d + 1,
+ origin,
+ k + 1,
+ d + 1,
+ end);
warning(wi, message);
}
}
"If the maximum distance between the groups is always "
"less than half the box size, "
"you can use geometry '%s' instead.",
- EPULLGEOM(epullgDIRPBC), EPULLGEOM(epullgDIR));
+ EPULLGEOM(epullgDIRPBC),
+ EPULLGEOM(epullgDIR));
}
dimParams->period = get_pull_coord_period(pullCoordParams, pbc, dimParams->end - dimParams->origin);
"AWH dimension %d of bias %d is periodic with pull geometry '%s', "
"while you should are applying pressure scaling to the "
"corresponding box vector, this is not supported.",
- dimIndex + 1, biasIndex + 1, EPULLGEOM(pullCoordParams.eGeom));
+ dimIndex + 1,
+ biasIndex + 1,
+ EPULLGEOM(pullCoordParams.eGeom));
warning(wi, mesg.c_str());
}
}
AwhDimParams* dimParams = &awhBiasParams->dimParams[d];
if (dimParams->eCoordProvider == eawhcoordproviderPULL)
{
- setStateDependentAwhPullDimParams(dimParams, k, d, &pull_params, pull_work, pbc,
- compressibility, wi);
+ setStateDependentAwhPullDimParams(
+ dimParams, k, d, &pull_params, pull_work, pbc, compressibility, wi);
}
else
{
"samples should be a multiple of the free-energy update interval (but "
"the test should also runs fine without this condition).");
- bias_ = std::make_unique<Bias>(-1, params.awhParams, params.awhBiasParams, params.dimParams,
- params.beta, mdTimeStep, 1, "", Bias::ThisRankWillDoIO::No,
+ bias_ = std::make_unique<Bias>(-1,
+ params.awhParams,
+ params.awhBiasParams,
+ params.dimParams,
+ params.beta,
+ mdTimeStep,
+ 1,
+ "",
+ Bias::ThisRankWillDoIO::No,
disableUpdateSkips);
}
};
awh_dvec coordValue = { coord, 0, 0, 0 };
double potential = 0;
- gmx::ArrayRef<const double> biasForce =
- bias.calcForceAndUpdateBias(coordValue, {}, {}, &potential, &potentialJump, nullptr,
- nullptr, step, step, seed_, nullptr);
+ gmx::ArrayRef<const double> biasForce = bias.calcForceAndUpdateBias(
+ coordValue, {}, {}, &potential, &potentialJump, nullptr, nullptr, step, step, seed_, nullptr);
force.push_back(biasForce[0]);
pot.push_back(potential);
const double mdTimeStep = 0.1;
- Bias bias(-1, params.awhParams, params.awhBiasParams, params.dimParams, params.beta, mdTimeStep,
- 1, "", Bias::ThisRankWillDoIO::No);
+ Bias bias(-1,
+ params.awhParams,
+ params.awhBiasParams,
+ params.dimParams,
+ params.beta,
+ mdTimeStep,
+ 1,
+ "",
+ Bias::ThisRankWillDoIO::No);
/* We use a trajectory of the sum of two sines to cover the reaction
* coordinate range in a semi-realistic way. The period is 4*pi=12.57.
awh_dvec coordValue = { coord, 0, 0, 0 };
double potential = 0;
double potentialJump = 0;
- bias.calcForceAndUpdateBias(coordValue, {}, {}, &potential, &potentialJump, nullptr,
- nullptr, step, step, params.awhParams.seed, nullptr);
+ bias.calcForceAndUpdateBias(coordValue,
+ {},
+ {},
+ &potential,
+ &potentialJump,
+ nullptr,
+ nullptr,
+ step,
+ step,
+ params.awhParams.seed,
+ nullptr);
inInitialStage = bias.state().inInitialStage();
if (!inInitialStage)
double mdTimeStep = 0.1;
- bias_ = std::make_unique<Bias>(-1, params.awhParams, params.awhBiasParams, params.dimParams,
- params.beta, mdTimeStep, 1, "", Bias::ThisRankWillDoIO::No,
+ bias_ = std::make_unique<Bias>(-1,
+ params.awhParams,
+ params.awhBiasParams,
+ params.dimParams,
+ params.beta,
+ mdTimeStep,
+ 1,
+ "",
+ Bias::ThisRankWillDoIO::No,
disableUpdateSkips);
}
};
int umbrellaGridpointIndex = bias.state().coordState().umbrellaGridpoint();
awh_dvec coordValue = { bias.getGridCoordValue(umbrellaGridpointIndex)[0], 0, 0, 0 };
double potential = 0;
- gmx::ArrayRef<const double> biasForce = bias.calcForceAndUpdateBias(
- coordValue, neighborLambdaEnergies, neighborLambdaDhdl, &potential, &potentialJump,
- nullptr, nullptr, step * mdTimeStep, step, seed_, nullptr);
+ gmx::ArrayRef<const double> biasForce = bias.calcForceAndUpdateBias(coordValue,
+ neighborLambdaEnergies,
+ neighborLambdaDhdl,
+ &potential,
+ &potentialJump,
+ nullptr,
+ nullptr,
+ step * mdTimeStep,
+ step,
+ seed_,
+ nullptr);
force.push_back(biasForce[0]);
pot.push_back(potential);
const double mdTimeStep = 0.1;
- Bias bias(-1, params.awhParams, params.awhBiasParams, params.dimParams, params.beta, mdTimeStep,
- 1, "", Bias::ThisRankWillDoIO::No);
+ Bias bias(-1,
+ params.awhParams,
+ params.awhBiasParams,
+ params.dimParams,
+ params.beta,
+ mdTimeStep,
+ 1,
+ "",
+ Bias::ThisRankWillDoIO::No);
const int64_t exitStepRef = 320;
double potential = 0;
double potentialJump = 0;
- bias.calcForceAndUpdateBias(coordValue, neighborLambdaEnergies, neighborLambdaDhdl,
- &potential, &potentialJump, nullptr, nullptr, step, step,
- params.awhParams.seed, nullptr);
+ bias.calcForceAndUpdateBias(coordValue,
+ neighborLambdaEnergies,
+ neighborLambdaDhdl,
+ &potential,
+ &potentialJump,
+ nullptr,
+ nullptr,
+ step,
+ step,
+ params.awhParams.seed,
+ nullptr);
inInitialStage = bias.state().inInitialStage();
if (!inInitialStage)
dimParams.push_back(DimParams::pullDimParams(1.0, 15.0, params.beta));
dimParams.push_back(DimParams::pullDimParams(1.0, 15.0, params.beta));
BiasGrid grid(dimParams, awhBiasParams.dimParams);
- BiasParams biasParams(awhParams, awhBiasParams, dimParams, 1.0, 1.0,
- BiasParams::DisableUpdateSkips::no, 1, grid.axis(), 0);
+ BiasParams biasParams(
+ awhParams, awhBiasParams, dimParams, 1.0, 1.0, BiasParams::DisableUpdateSkips::no, 1, grid.axis(), 0);
biasState_ = std::make_unique<BiasState>(awhBiasParams, 1.0, dimParams, grid);
// Here we initialize the grid point state using the input file
std::string filename = gmx::test::TestFileManager::getInputFilePath(GetParam());
- biasState_->initGridPointState(awhBiasParams, dimParams, grid, biasParams, filename,
- params.awhParams.numBias);
+ biasState_->initGridPointState(
+ awhBiasParams, dimParams, grid, biasParams, filename, params.awhParams.numBias);
sfree(params.awhParams.awhBiasParams[0].dimParams);
sfree(params.awhParams.awhBiasParams);
GMX_THROW(InternalError("Need to set reference density before normalizing it."));
}
- const real sumOfDensityData = std::accumulate(begin(referenceDensity_->asView()),
- end(referenceDensity_->asView()), 0.);
+ const real sumOfDensityData = std::accumulate(
+ begin(referenceDensity_->asView()), end(referenceDensity_->asView()), 0.);
for (float& referenceDensityVoxel : referenceDensity_->asView())
{
referenceDensityVoxel /= sumOfDensityData;
densityFittingSimulationParameters_.normalizeReferenceDensity();
}
forceProvider_ = std::make_unique<DensityFittingForceProvider>(
- parameters, densityFittingSimulationParameters_.referenceDensity(),
+ parameters,
+ densityFittingSimulationParameters_.referenceDensity(),
densityFittingSimulationParameters_.transformationToDensityLattice(),
densityFittingSimulationParameters_.localAtomSet(),
densityFittingSimulationParameters_.periodicBoundaryConditionType(),
- densityFittingSimulationParameters_.simulationTimeStep(), densityFittingState_);
+ densityFittingSimulationParameters_.simulationTimeStep(),
+ densityFittingState_);
forceProviders->addForceProvider(forceProvider_.get());
}
}
amplitude_.resize(localIndex.size());
}
- std::transform(std::begin(localIndex), std::end(localIndex), std::begin(amplitude_),
+ std::transform(std::begin(localIndex),
+ std::end(localIndex),
+ std::begin(amplitude_),
[&atoms](gmx::index index) { return atoms.chargeA[index]; });
return amplitude_;
}
amplitude_.resize(localIndex.size());
}
- std::transform(std::begin(localIndex), std::end(localIndex), std::begin(amplitude_),
+ std::transform(std::begin(localIndex),
+ std::end(localIndex),
+ std::begin(amplitude_),
[&atoms](gmx::index index) { return atoms.massT[index]; });
return amplitude_;
}
{
RVec sigmaInLatticeCoordinates{ sigma, sigma, sigma };
scaleToLattice(&sigmaInLatticeCoordinates);
- return { DVec{ sigmaInLatticeCoordinates[XX], sigmaInLatticeCoordinates[YY],
- sigmaInLatticeCoordinates[ZZ] },
+ return { DVec{ sigmaInLatticeCoordinates[XX], sigmaInLatticeCoordinates[YY], sigmaInLatticeCoordinates[ZZ] },
nSigma };
}
void DensityFittingForceProviderState::writeState(KeyValueTreeObjectBuilder kvtBuilder,
const std::string& identifier) const
{
- writeKvtCheckpointValue(stepsSinceLastCalculation_, stepsSinceLastCalculationName_, identifier,
- kvtBuilder);
- writeKvtCheckpointValue(adaptiveForceConstantScale_, adaptiveForceConstantScaleName_,
- identifier, kvtBuilder);
+ writeKvtCheckpointValue(
+ stepsSinceLastCalculation_, stepsSinceLastCalculationName_, identifier, kvtBuilder);
+ writeKvtCheckpointValue(
+ adaptiveForceConstantScale_, adaptiveForceConstantScaleName_, identifier, kvtBuilder);
KeyValueTreeObjectBuilder exponentialMovingAverageKvtEntry =
kvtBuilder.addObject(identifier + "-" + exponentialMovingAverageStateName_);
const std::string& identifier)
{
readKvtCheckpointValue(compat::make_not_null(&stepsSinceLastCalculation_),
- stepsSinceLastCalculationName_, identifier, kvtData);
+ stepsSinceLastCalculationName_,
+ identifier,
+ kvtData);
readKvtCheckpointValue(compat::make_not_null(&adaptiveForceConstantScale_),
- adaptiveForceConstantScaleName_, identifier, kvtData);
+ adaptiveForceConstantScaleName_,
+ identifier,
+ kvtData);
if (kvtData.keyExists(identifier + "-" + exponentialMovingAverageStateName_))
{
transformedCoordinates_.resize(localAtomSet_.numAtomsLocal());
// pick and copy atom coordinates
- std::transform(std::cbegin(localAtomSet_.localIndex()), std::cend(localAtomSet_.localIndex()),
+ std::transform(std::cbegin(localAtomSet_.localIndex()),
+ std::cend(localAtomSet_.localIndex()),
std::begin(transformedCoordinates_),
[&forceProviderInput](int index) { return forceProviderInput.x_[index]; });
{
// \todo update to real once GaussTransform class returns real
gmx_sumf(gaussTransform_.view().mapping().required_span_size(),
- gaussTransform_.view().data(), &forceProviderInput.cr_);
+ gaussTransform_.view().data(),
+ &forceProviderInput.cr_);
}
// calculate grid derivative
// calculate forces
forces_.resize(localAtomSet_.numAtomsLocal());
std::transform(
- std::begin(transformedCoordinates_), std::end(transformedCoordinates_), std::begin(amplitudes),
- std::begin(forces_), [&densityDerivative, this](const RVec r, real amplitude) {
+ std::begin(transformedCoordinates_),
+ std::end(transformedCoordinates_),
+ std::begin(amplitudes),
+ std::begin(forces_),
+ [&densityDerivative, this](const RVec r, real amplitude) {
return densityFittingForce_.evaluateForce({ r, amplitude }, densityDerivative);
});
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/math/exponentialmovingaverage.h"
#include "gromacs/mdspan/extensions.h"
#include "gromacs/mdtypes/iforceprovider.h"
-#include "gromacs/utility/classhelpers.h"
enum class PbcType : int;
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
const auto& stringIdentityTransform = [](std::string s) { return s; };
densityfittingMdpTransformFromString<bool>(rules, &fromStdString<bool>, c_activeTag_);
densityfittingMdpTransformFromString<std::string>(rules, stringIdentityTransform, c_groupTag_);
- densityfittingMdpTransformFromString<std::string>(rules, stringIdentityTransform,
- c_similarityMeasureTag_);
+ densityfittingMdpTransformFromString<std::string>(
+ rules, stringIdentityTransform, c_similarityMeasureTag_);
densityfittingMdpTransformFromString<std::string>(rules, stringIdentityTransform, c_amplitudeMethodTag_);
densityfittingMdpTransformFromString<real>(rules, &fromStdString<real>, c_forceConstantTag_);
- densityfittingMdpTransformFromString<real>(rules, &fromStdString<real>,
- c_gaussianTransformSpreadingWidthTag_);
+ densityfittingMdpTransformFromString<real>(
+ rules, &fromStdString<real>, c_gaussianTransformSpreadingWidthTag_);
densityfittingMdpTransformFromString<real>(
rules, &fromStdString<real>, c_gaussianTransformSpreadingRangeInMultiplesOfWidthTag_);
- densityfittingMdpTransformFromString<std::string>(rules, stringIdentityTransform,
- c_referenceDensityFileNameTag_);
- densityfittingMdpTransformFromString<std::int64_t>(rules, &fromStdString<std::int64_t>,
- c_everyNStepsTag_);
+ densityfittingMdpTransformFromString<std::string>(
+ rules, stringIdentityTransform, c_referenceDensityFileNameTag_);
+ densityfittingMdpTransformFromString<std::int64_t>(
+ rules, &fromStdString<std::int64_t>, c_everyNStepsTag_);
densityfittingMdpTransformFromString<bool>(rules, &fromStdString<bool>, c_normalizeDensitiesTag_);
densityfittingMdpTransformFromString<bool>(rules, &fromStdString<bool>, c_adaptiveForceScalingTag_);
- densityfittingMdpTransformFromString<real>(rules, &fromStdString<real>,
- c_adaptiveForceScalingTimeConstantTag_);
+ densityfittingMdpTransformFromString<real>(
+ rules, &fromStdString<real>, c_adaptiveForceScalingTimeConstantTag_);
const auto& stringRVecToStringRVecWithCheck = [](const std::string& str) {
return stringIdentityTransformWithArrayCheck<real, 3>(
- str, "Reading three real values as vector while parsing the .mdp input failed in "
- + DensityFittingModuleInfo::name_ + ".");
+ str,
+ "Reading three real values as vector while parsing the .mdp input failed in "
+ + DensityFittingModuleInfo::name_ + ".");
};
- densityfittingMdpTransformFromString<std::string>(rules, stringRVecToStringRVecWithCheck,
- c_translationTag_);
+ densityfittingMdpTransformFromString<std::string>(
+ rules, stringRVecToStringRVecWithCheck, c_translationTag_);
const auto& stringMatrixToStringMatrixWithCheck = [](const std::string& str) {
return stringIdentityTransformWithArrayCheck<real, 9>(
- str, "Reading nine real values as vector while parsing the .mdp input failed in "
- + DensityFittingModuleInfo::name_ + ".");
+ str,
+ "Reading nine real values as vector while parsing the .mdp input failed in "
+ + DensityFittingModuleInfo::name_ + ".");
};
- densityfittingMdpTransformFromString<std::string>(rules, stringMatrixToStringMatrixWithCheck,
- c_transformationMatrixTag_);
+ densityfittingMdpTransformFromString<std::string>(
+ rules, stringMatrixToStringMatrixWithCheck, c_transformationMatrixTag_);
}
//! Name the methods that may be used to evaluate similarity between densities
"cross-correlation",
c_similarityMeasureTag_);
addDensityFittingMdpOutputValue<std::string>(
- builder, c_densitySimilarityMeasureMethodNames[parameters_.similarityMeasureMethod_],
+ builder,
+ c_densitySimilarityMeasureMethodNames[parameters_.similarityMeasureMethod_],
c_similarityMeasureTag_);
addDensityFittingMdpOutputValueComment(
- builder, "; Atom amplitude for spreading onto grid: unity, mass, or charge",
- c_amplitudeMethodTag_);
+ builder, "; Atom amplitude for spreading onto grid: unity, mass, or charge", c_amplitudeMethodTag_);
addDensityFittingMdpOutputValue<std::string>(
- builder, c_densityFittingAmplitudeMethodNames[parameters_.amplitudeLookupMethod_],
+ builder,
+ c_densityFittingAmplitudeMethodNames[parameters_.amplitudeLookupMethod_],
c_amplitudeMethodTag_);
addDensityFittingMdpOutputValue(builder, parameters_.forceConstant_, c_forceConstantTag_);
- addDensityFittingMdpOutputValue(builder, parameters_.gaussianTransformSpreadingWidth_,
+ addDensityFittingMdpOutputValue(builder,
+ parameters_.gaussianTransformSpreadingWidth_,
c_gaussianTransformSpreadingWidthTag_);
- addDensityFittingMdpOutputValue(builder, parameters_.gaussianTransformSpreadingRangeInMultiplesOfWidth_,
+ addDensityFittingMdpOutputValue(builder,
+ parameters_.gaussianTransformSpreadingRangeInMultiplesOfWidth_,
c_gaussianTransformSpreadingRangeInMultiplesOfWidthTag_);
addDensityFittingMdpOutputValueComment(builder,
"; Reference density file location as absolute path "
addDensityFittingMdpOutputValueComment(
builder, "; Normalize the sum of density voxel values to one", c_normalizeDensitiesTag_);
addDensityFittingMdpOutputValue(builder, parameters_.normalizeDensities_, c_normalizeDensitiesTag_);
- addDensityFittingMdpOutputValueComment(builder, "; Apply adaptive force scaling",
- c_adaptiveForceScalingTag_);
- addDensityFittingMdpOutputValue(builder, parameters_.adaptiveForceScaling_,
- c_adaptiveForceScalingTag_);
+ addDensityFittingMdpOutputValueComment(
+ builder, "; Apply adaptive force scaling", c_adaptiveForceScalingTag_);
+ addDensityFittingMdpOutputValue(
+ builder, parameters_.adaptiveForceScaling_, c_adaptiveForceScalingTag_);
addDensityFittingMdpOutputValueComment(builder,
"; Time constant for adaptive force scaling in ps",
c_adaptiveForceScalingTimeConstantTag_);
- addDensityFittingMdpOutputValue(builder, parameters_.adaptiveForceScalingTimeConstant_,
+ addDensityFittingMdpOutputValue(builder,
+ parameters_.adaptiveForceScalingTimeConstant_,
c_adaptiveForceScalingTimeConstantTag_);
}
}
}
auto kvtIndexArray = tree[DensityFittingModuleInfo::name_ + "-" + c_groupTag_].asArray().values();
parameters_.indices_.resize(kvtIndexArray.size());
- std::transform(std::begin(kvtIndexArray), std::end(kvtIndexArray), std::begin(parameters_.indices_),
+ std::transform(std::begin(kvtIndexArray),
+ std::end(kvtIndexArray),
+ std::begin(parameters_.indices_),
[](const KeyValueTreeValue& val) { return val.cast<std::int64_t>(); });
}
public:
void addMdpOptionDensityFittingActive()
{
- mdpValueBuilder_.rootObject().addValue("density-guided-simulation-active",
- std::string("yes"));
+ mdpValueBuilder_.rootObject().addValue("density-guided-simulation-active", std::string("yes"));
}
void addMdpOptionReferenceDensity()
{
// Prepare MDP inputs
KeyValueTreeBuilder mdpValueBuilder;
- mdpValueBuilder.rootObject().addValue("density-guided-simulation-active",
- std::string("yes"));
+ mdpValueBuilder.rootObject().addValue("density-guided-simulation-active", std::string("yes"));
return mdpValueBuilder.build();
}
{
done_blocka(&defaultGroups_);
stupid_fill_blocka(&defaultGroups_, 3);
- std::vector<std::string> groupNames = { "A", "protein", "C" };
- const char* const namesAsConstChar[3] = { groupNames[0].c_str(), groupNames[1].c_str(),
+ std::vector<std::string> groupNames = { "A", "protein", "C" };
+ const char* const namesAsConstChar[3] = { groupNames[0].c_str(),
+ groupNames[1].c_str(),
groupNames[2].c_str() };
return { defaultGroups_, namesAsConstChar };
}
{
done_blocka(&defaultGroups_);
stupid_fill_blocka(&defaultGroups_, 3);
- std::vector<std::string> groupNames = { "protein", "C", "A" };
- const char* const namesAsConstChar[3] = { groupNames[0].c_str(), groupNames[1].c_str(),
+ std::vector<std::string> groupNames = { "protein", "C", "A" };
+ const char* const namesAsConstChar[3] = { groupNames[0].c_str(),
+ groupNames[1].c_str(),
groupNames[2].c_str() };
return { defaultGroups_, namesAsConstChar };
}
}
else
{
- fpField_ = xvgropen(opt2fn("-field", nfile, fnm), "Applied electric field",
- "Time (ps)", "E (V/nm)", oenv);
+ fpField_ = xvgropen(opt2fn("-field", nfile, fnm),
+ "Applied electric field",
+ "Time (ps)",
+ "E (V/nm)",
+ oenv);
}
}
}
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2012,2013,2014,2015,2019, by the GROMACS development team, led by
+# Copyright (c) 2012,2013,2014,2015,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.
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+add_library(commandline INTERFACE)
file(GLOB COMMANDLINE_SOURCES *.cpp)
set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${COMMANDLINE_SOURCES} PARENT_SCOPE)
+# Source files have the following private module dependencies.
+target_link_libraries(commandline PRIVATE
+# gmxlib
+# math
+# mdtypes
+# tng_io
+ )
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(commandline PUBLIC
+target_include_directories(commandline INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(commandline PUBLIC
+target_link_libraries(commandline INTERFACE
+ legacy_api
+ )
+
+# TODO: when commandline is an OBJECT target
+#target_link_libraries(commandline PUBLIC legacy_api)
+#target_link_libraries(commandline PRIVATE common)
+
+# Module dependencies
+# commandline interfaces convey transitive dependence on these modules.
+#target_link_libraries(commandline PUBLIC
+target_link_libraries(commandline INTERFACE
+ utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(commandline PRIVATE tng_io)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(commandline PRIVATE legacy_modules)
+
if (BUILD_TESTING)
add_subdirectory(tests)
endif()
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2013,2014,2015,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2018,2019,2021, 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.
#ifndef GMX_COMMANDLINE_CMDLINEHELPCONTEXT_H
#define GMX_COMMANDLINE_CMDLINEHELPCONTEXT_H
+#include <memory>
#include <string>
#include "gromacs/onlinehelp/helpwritercontext.h"
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
GMX_DISALLOW_ASSIGN(CommandLineHelpContext);
};
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team.
- * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/options/options.h"
#include "gromacs/utility/arrayref.h"
#include "gromacs/utility/baseversion.h"
+#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/fileredirector.h"
#include "gromacs/utility/gmxassert.h"
while (linksFile.readLine(&line))
{
links_.addLink("[REF]." + line + "[ref]",
- formatString(":ref:`.%s <%s>`", line.c_str(), line.c_str()), line);
+ formatString(":ref:`.%s <%s>`", line.c_str(), line.c_str()),
+ line);
links_.addLink("[REF]" + line + "[ref]", formatString(":ref:`%s`", line.c_str()), line);
}
linksFile.close();
{
indexFile_ = std::make_unique<TextWriter>(
outputRedirector_->openTextOutputFile("fragments/byname.rst"));
- indexFile_->writeLine(formatString("* :doc:`%s </onlinehelp/%s>` - %s", binaryName_.c_str(),
- binaryName_.c_str(), RootHelpText::title));
+ indexFile_->writeLine(formatString(
+ "* :doc:`%s </onlinehelp/%s>` - %s", binaryName_.c_str(), binaryName_.c_str(), RootHelpText::title));
manPagesFile_ =
std::make_unique<TextWriter>(outputRedirector_->openTextOutputFile("conf-man.py"));
manPagesFile_->writeLine("man_pages = [");
outputRedirector_->openTextOutputFile("onlinehelp/" + tag + ".rst");
TextWriter writer(file);
writer.writeLine(formatString(".. _%s:", displayName.c_str()));
- if (displayName == binaryName_ + " mdrun")
- {
- // Make an extra link target for the convenience of
- // MPI-specific documentation
- writer.writeLine(".. _mdrun_mpi:");
- }
writer.ensureEmptyLine();
CommandLineHelpContext context(&writer, eHelpOutputFormat_Rst, &links_, binaryName_);
" More information about |Gromacs| is available at <http://www.gromacs.org/>.");
file->close();
- indexFile_->writeLine(formatString("* :doc:`%s </onlinehelp/%s>` - %s", displayName.c_str(),
- tag.c_str(), module.shortDescription()));
+ indexFile_->writeLine(formatString(
+ "* :doc:`%s </onlinehelp/%s>` - %s", displayName.c_str(), tag.c_str(), module.shortDescription()));
manPagesFile_->writeLine(formatString(" ('onlinehelp/%s', '%s', \"%s\", '', 1),",
- tag.c_str(), tag.c_str(), module.shortDescription()));
+ tag.c_str(),
+ tag.c_str(),
+ module.shortDescription()));
}
void HelpExportReStructuredText::finishModuleExport()
indexFile_.reset();
// TODO: Generalize.
manPagesFile_->writeLine(formatString(" ('onlinehelp/%s', '%s', '%s', '', 1)",
- binaryName_.c_str(), binaryName_.c_str(), RootHelpText::title));
+ binaryName_.c_str(),
+ binaryName_.c_str(),
+ RootHelpText::title));
manPagesFile_->writeLine("]");
manPagesFile_->close();
manPagesFile_.reset();
GMX_RELEASE_ASSERT(dashPos != std::string::npos,
"There should always be at least one dash in the tag");
displayName[dashPos] = ' ';
- indexFile_->writeLine(formatString(":doc:`%s </onlinehelp/%s>`\n %s", displayName.c_str(),
- tag.c_str(), module->second));
+ indexFile_->writeLine(formatString(
+ ":doc:`%s </onlinehelp/%s>`\n %s", displayName.c_str(), tag.c_str(), module->second));
manPagesFile_->writeLine(formatString(":manpage:`%s(1)`\n %s", tag.c_str(), module->second));
}
}
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012,2013,2014,2015,2018 by the GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
#ifndef GMX_COMMANDLINE_CMDLINEHELPMODULE_H
#define GMX_COMMANDLINE_CMDLINEHELPMODULE_H
+#include <memory>
+
#include "gromacs/commandline/cmdlinemodule.h"
#include "gromacs/onlinehelp/ihelptopic.h"
-#include "gromacs/utility/classhelpers.h"
#include "cmdlinemodulemanager_impl.h"
private:
typedef CommandLineHelpModuleImpl Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2010-2018, The GROMACS development team.
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
SynopsisFormatter synopsisFormatter(writerContext);
synopsisFormatter.start(context.moduleDisplayName());
filter.formatSelected(OptionsFilter::eSelectInputFileOptions, &synopsisFormatter, impl_->options_);
- filter.formatSelected(OptionsFilter::eSelectInputOutputFileOptions, &synopsisFormatter,
- impl_->options_);
+ filter.formatSelected(
+ OptionsFilter::eSelectInputOutputFileOptions, &synopsisFormatter, impl_->options_);
filter.formatSelected(OptionsFilter::eSelectOutputFileOptions, &synopsisFormatter, impl_->options_);
filter.formatSelected(OptionsFilter::eSelectOtherOptions, &synopsisFormatter, impl_->options_);
synopsisFormatter.finish();
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2010,2011,2012,2013,2014 by the GROMACS development team.
- * Copyright (c) 2015,2017,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2015,2017,2019,2020,2021, 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.
#ifndef GMX_COMMANDLINE_CMDLINEHELPWRITER_H
#define GMX_COMMANDLINE_CMDLINEHELPWRITER_H
+#include <memory>
#include <string>
-#include "gromacs/utility/classhelpers.h"
-
namespace gmx
{
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2013,2014,2015,2019, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015,2019,2021, 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.
#ifndef GMX_COMMANDLINE_CMDLINEMODULE_H
#define GMX_COMMANDLINE_CMDLINEMODULE_H
-#include "gromacs/utility/classhelpers.h"
+#include <memory>
namespace gmx
{
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
/*! \brief
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <memory>
#include "gromacs/onlinehelp/ihelptopic.h"
-#include "gromacs/utility/classhelpers.h"
namespace gmx
{
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
/*! \libinternal \brief
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2010,2011,2012,2013,2014 by the GROMACS development team.
- * Copyright (c) 2016,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2016,2018,2019,2020,2021, 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.
#ifndef GMX_COMMANDLINE_CMDLINEPARSER_H
#define GMX_COMMANDLINE_CMDLINEPARSER_H
+#include <memory>
#include <string>
#include <vector>
-#include "gromacs/utility/classhelpers.h"
-
namespace gmx
{
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team.
- * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <cstdlib>
#include <cstring>
+#include <mutex>
#include <string>
#include <vector>
#include "buildinfo.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/gmxassert.h"
-#include "gromacs/utility/mutex.h"
#include "gromacs/utility/path.h"
#include "gromacs/utility/stringutil.h"
mutable std::string fullBinaryPath_;
mutable std::string installationPrefix_;
mutable bool bSourceLayout_;
- mutable Mutex binaryPathMutex_;
+ mutable std::mutex binaryPathMutex_;
};
CommandLineProgramContext::Impl::Impl() : programName_("GROMACS"), bSourceLayout_(false) {}
const char* CommandLineProgramContext::fullBinaryPath() const
{
- lock_guard<Mutex> lock(impl_->binaryPathMutex_);
+ std::lock_guard<std::mutex> lock(impl_->binaryPathMutex_);
impl_->findBinaryPath();
return impl_->fullBinaryPath_.c_str();
}
InstallationPrefixInfo CommandLineProgramContext::installationPrefix() const
{
- lock_guard<Mutex> lock(impl_->binaryPathMutex_);
+ std::lock_guard<std::mutex> lock(impl_->binaryPathMutex_);
if (impl_->installationPrefix_.empty())
{
impl_->findBinaryPath();
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012,2013,2014,2015,2018 by the GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <string>
#include <vector>
-#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/programcontext.h"
namespace gmx
* Returns the full path of the running binary.
*
* \throws std::bad_alloc if out of memory.
- * \throws tMPI::system_error on thread synchronization errors.
*
* Returns argv[0] if there was an error in finding the absolute path.
*/
* Returns the installation prefix (for finding \Gromacs data files).
*
* \throws std::bad_alloc if out of memory.
- * \throws tMPI::system_error on thread synchronization errors.
*
* Returns a hardcoded path set during configuration time if there is
* an error in finding the library data files.
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
{
//! Names for XvgFormat
-const gmx::EnumerationArray<XvgFormat, const char*> c_xvgFormatNames = { { "xmgrace", "xmgr",
- "none" } };
+const gmx::EnumerationArray<XvgFormat, const char*> c_xvgFormatNames = {
+ { "xmgrace", "xmgr", "none" }
+};
/*! \brief Returns the default xvg format, as modified by GMX_VIEW_XVG
* if that environment variable is set.
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2019, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2019,2021, 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.
#ifndef GMX_COMMANDLINE_SHELLCOMPLETIONS_H
#define GMX_COMMANDLINE_SHELLCOMPLETIONS_H
+#include <memory>
#include <string>
#include <vector>
-#include "gromacs/utility/classhelpers.h"
-
namespace gmx
{
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
{
gmx::StringOutputStream stream;
gmx::TextWriter streamWriter(&stream);
- gmx::CommandLineHelpContext context(&streamWriter, gmx::eHelpOutputFormat_Console, nullptr,
- "test");
+ gmx::CommandLineHelpContext context(
+ &streamWriter, gmx::eHelpOutputFormat_Console, nullptr, "test");
context.setShowHidden(bHidden_);
writer->writeHelp(context);
stream.close();
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2013,2014,2015,2019, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015,2019,2020,2021, 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.
void CommandLineModuleManagerTestBase::initManager(const CommandLine& args, const char* realBinaryName)
{
GMX_RELEASE_ASSERT(impl_ == nullptr, "initManager() called more than once in test");
- impl_.reset(new Impl(args, realBinaryName));
+ impl_ = std::make_unique<Impl>(args, realBinaryName);
}
MockModule& CommandLineModuleManagerTestBase::addModule(const char* name, const char* description)
{
std::unique_ptr<MockOptionsModule> modulePtr(new MockOptionsModule());
MockOptionsModule* module = modulePtr.get();
- gmx::ICommandLineOptionsModule::registerModuleDirect(&manager(), name, description,
- std::move(modulePtr));
+ gmx::ICommandLineOptionsModule::registerModuleDirect(
+ &manager(), name, description, std::move(modulePtr));
return *module;
}
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012,2013,2014,2015,2018 by the GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
#ifndef GMX_COMMANDLINE_CMDLINEMODULEMANAGERTEST_H
#define GMX_COMMANDLINE_CMDLINEMODULEMANAGERTEST_H
+#include <memory>
#include <string>
#include <gmock/gmock.h>
#include "gromacs/commandline/cmdlinehelpcontext.h"
#include "gromacs/commandline/cmdlinemodule.h"
#include "gromacs/commandline/cmdlineoptionsmodule.h"
-#include "gromacs/utility/classhelpers.h"
#include "testutils/stringtest.h"
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace test
void parseFromArgs(unsigned long flags, gmx::ArrayRef<t_filenm> fnm, gmx::ArrayRef<t_pargs> pa)
{
fileCount_ = fnm.size();
- bool bOk = parse_common_args(&args_.argc(), args_.argv(), flags, fnm.size(), fnm.data(),
- pa.size(), pa.data(), 0, nullptr, 0, nullptr, &oenv_);
+ bool bOk = parse_common_args(
+ &args_.argc(), args_.argv(), flags, fnm.size(), fnm.data(), pa.size(), pa.data(), 0, nullptr, 0, nullptr, &oenv_);
EXPECT_TRUE(bOk);
}
void parseFromArray(gmx::ArrayRef<const char* const> cmdline,
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2018,2019, by the GROMACS development team, led by
+# Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
# and including many others, as listed in the AUTHORS file in the
# top-level source directory and 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.
+add_library(compat INTERFACE)
+
+# Source files have the following private module dependencies.
+target_link_libraries(compat PRIVATE
+ )
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(compat PUBLIC
+target_include_directories(compat INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(compat PUBLIC
+target_link_libraries(compat INTERFACE
+ legacy_api
+ )
+
+# TODO: when compat is an OBJECT target
+#target_link_libraries(compat PUBLIC legacy_api)
+#target_link_libraries(compat PRIVATE common)
+
+# Module dependencies
+# compat interfaces convey transitive dependence on these modules.
+#target_link_libraries(compat PUBLIC
+target_link_libraries(compat INTERFACE
+ utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(compat PRIVATE tng_io)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(compat PRIVATE legacy_modules)
+
if (BUILD_TESTING)
add_subdirectory(tests)
endif()
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
//! Contract-assurance macros that work like a simple version of the GSL ones
//! \{
-#if !defined(__INTEL_COMPILER) || !(__INTEL_COMPILER == 1800 && __INTEL_COMPILER_UPDATE == 0)
-# define Expects(cond) GMX_ASSERT((cond), "Precondition violation")
-# define Ensures(cond) GMX_ASSERT((cond), "Postcondition violation")
-#else
-// icc 18.0.0 in a RelWithAssert build has an ICE, even if we directly
-// embed the contents of GMX_ASSERT, so it seems the lambda in
-// GMX_ASSERT is too complex for it in this use case.
-# define Expects(cond)
-# define Ensures(cond)
-#endif
+#define Expects(cond) GMX_ASSERT((cond), "Precondition violation")
+#define Ensures(cond) GMX_ASSERT((cond), "Postcondition violation")
//! \}
/*! \libinternal
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
not_null<std::shared_ptr<int>> sharedPointer(std::make_shared<int>(10));
#ifndef NDEBUG
-/* The workaround here is needed because the intel implementation
- * will not trigger the assert when using the pointer without
- * a valid object. This was needed due to an internal error
- * being triggered instead with the compiler under this condition.
- *
- * Death tests can also not be used safely in a parallel environment.
- */
-# if !defined(__INTEL_COMPILER) || !(__INTEL_COMPILER == 1800 && __INTEL_COMPILER_UPDATE == 0)
int* nullPointer = nullptr;
GMX_EXPECT_DEATH_IF_SUPPORTED(not_null<int*> invalidNullPointer(nullPointer), "");
-# endif
#endif
int value = 20;
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2019, by the GROMACS development team, led by
+# Copyright (c) 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.
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+# Set up the module library
+add_library(coordinateio INTERFACE)
file(GLOB COORDINATEIO_SOURCES *.cpp outputadapters/*.cpp)
-
set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${COORDINATEIO_SOURCES} PARENT_SCOPE)
+# Source files have the following dependencies on library infrastructure.
+#target_link_libraries(coordinateio PRIVATE
+# common
+# legacy_modules
+#)
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(coordinateio PUBLIC
+target_include_directories(coordinateio INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(coordinateio PUBLIC
+target_link_libraries(coordinateio INTERFACE
+ legacy_api
+ )
+
+# TODO: when coordinateio is an OBJECT target
+#target_link_libraries(coordinateio PUBLIC legacy_api)
+#target_link_libraries(coordinateio PRIVATE common)
+
+# Module dependencies
+# coordinateio interfaces convey transitive dependence on these modules.
+#target_link_libraries(coordinateio PUBLIC
+target_link_libraries(coordinateio INTERFACE
+ utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(coordinateio PRIVATE NOTHING)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(coordinateio PRIVATE legacy_modules)
+
if (BUILD_TESTING)
add_subdirectory(tests)
endif()
if (sel.isValid())
{
GMX_ASSERT(sel.hasOnlyAtoms(), "Can only work with selections consisting out of atoms");
- return trjtools_gmx_prepare_tng_writing(name.c_str(), filemode[0],
+ return trjtools_gmx_prepare_tng_writing(name.c_str(),
+ filemode[0],
nullptr, // infile_, //how to get the input file here?
- nullptr, sel.atomCount(), mtop, sel.atomIndices(),
+ nullptr,
+ sel.atomCount(),
+ mtop,
+ sel.atomIndices(),
sel.name());
}
else
{
- return trjtools_gmx_prepare_tng_writing(name.c_str(), filemode[0],
+ return trjtools_gmx_prepare_tng_writing(name.c_str(),
+ filemode[0],
nullptr, // infile_, //how to get the input file here?
- nullptr, mtop->natoms, mtop, get_atom_index(mtop),
+ nullptr,
+ mtop->natoms,
+ mtop,
+ get_atom_index(mtop),
"System");
}
}
{
localF_.resize(input.natoms);
}
- deepCopy_t_trxframe(input, &local, localX_.data(), localV_.data(), localF_.data(),
- localIndex_.data());
+ deepCopy_t_trxframe(
+ input, &local, localX_.data(), localV_.data(), localF_.data(), localIndex_.data());
for (const auto& outputAdapter : outputAdapters_.getAdapters())
{
if (outputAdapter)
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
bool OutputAdapterContainer::isEmpty() const
{
- return std::none_of(outputAdapters_.begin(), outputAdapters_.end(),
- [](const auto& adapter) { return adapter != nullptr; });
+ return std::none_of(outputAdapters_.begin(), outputAdapters_.end(), [](const auto& adapter) {
+ return adapter != nullptr;
+ });
}
} // namespace gmx
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 2019,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/coordinateio/ioutputadapter.h"
#include "gromacs/utility/arrayref.h"
-#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/enumerationhelpers.h"
namespace gmx
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
const Selection& selection,
OutputRequirements requirements)
{
- return createTrajectoryFrameWriter(topology.mtop(), selection, filename,
+ return createTrajectoryFrameWriter(topology.mtop(),
+ selection,
+ filename,
topology.hasTopology() ? topology.copyAtoms() : nullptr,
requirements);
}
#if GMX_USE_TNG
"spc2-traj.tng",
#endif
- "spc2-traj.xtc", "spc2-traj.g96" };
+ "spc2-traj.xtc",
+ "spc2-traj.g96" };
//! Names here work for setVelocity module
const char* const setVelocitySupported[] = {
};
//! Names here don't work for setForce module
-const char* const setForceUnSupported[] = { "spc2-traj.xtc", "spc2-traj.pdb", "spc2-traj.gro",
+const char* const setForceUnSupported[] = { "spc2-traj.xtc",
+ "spc2-traj.pdb",
+ "spc2-traj.gro",
"spc2-traj.g96" };
//! Names here work for setPrecision module
};
//! Names here don't work for setPrecision module
-const char* const setPrecisionUnSupported[] = { "spc2-traj.trr", "spc2-traj.pdb", "spc2-traj.gro",
+const char* const setPrecisionUnSupported[] = { "spc2-traj.trr",
+ "spc2-traj.pdb",
+ "spc2-traj.gro",
"spc2-traj.g96" };
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2014,2015,2016, by the GROMACS development team, led by
+# Copyright (c) 2014,2015,2016,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.
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+# Set up the module library
+add_library(correlationfunctions INTERFACE)
+
file(GLOB GMXCORRFUNC_SOURCES *.cpp)
set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${GMXCORRFUNC_SOURCES} PARENT_SCOPE)
+
+# Source files have the following private module dependencies.
+target_link_libraries(correlationfunctions PRIVATE
+ # gmxlib
+ # math
+ # mdtypes
+ # tng_io
+ )
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(correlationfunctions PUBLIC
+target_include_directories(correlationfunctions INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(correlationfunctions PUBLIC
+target_link_libraries(correlationfunctions INTERFACE
+ legacy_api
+ )
+
+# TODO: when fileio is an OBJECT target
+#target_link_libraries(correlationfunctions PUBLIC legacy_api)
+#target_link_libraries(correlationfunctions PRIVATE common)
+
+# Module dependencies
+# This module convey transitive dependence on these modules.
+#target_link_libraries(correlationfunctions PUBLIC
+target_link_libraries(correlationfunctions INTERFACE
+ # utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(correlationfunctions PRIVATE tng_io)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(correlationfunctions PRIVATE legacy_modules)
+
if (BUILD_TESTING)
add_subdirectory(tests)
endif()
}
if (debug)
{
- fprintf(debug, "Starting do_ac_core: nframes=%d, nout=%d, nrestart=%d,mode=%lu\n", nframes,
- nout, nrestart, mode);
+ fprintf(debug, "Starting do_ac_core: nframes=%d, nout=%d, nrestart=%d,mode=%lu\n", nframes, nout, nrestart, mode);
}
for (j = 0; (j < nout); j++)
if (cth - 1.0 > 1.0e-15)
{
- printf("j: %d, k: %d, xj:(%g,%g,%g), xk:(%g,%g,%g)\n", j, k, xj[XX], xj[YY],
- xj[ZZ], xk[XX], xk[YY], xk[ZZ]);
+ printf("j: %d, k: %d, xj:(%g,%g,%g), xk:(%g,%g,%g)\n",
+ j,
+ k,
+ xj[XX],
+ xj[YY],
+ xj[ZZ],
+ xk[XX],
+ xk[YY],
+ xk[ZZ]);
}
mmm = 1;
if (MODE(eacP2))
/* Print flags and parameters */
if (bVerbose)
{
- printf("Will calculate %s of %d thingies for %d frames\n",
- title ? title : "autocorrelation", nitem, nframes);
- printf("bAver = %s, bFour = %s bNormalize= %s\n", gmx::boolToString(bAver),
- gmx::boolToString(bFour), gmx::boolToString(bNormalize));
+ printf("Will calculate %s of %d thingies for %d frames\n", title ? title : "autocorrelation", nitem, nframes);
+ printf("bAver = %s, bFour = %s bNormalize= %s\n",
+ gmx::boolToString(bAver),
+ gmx::boolToString(bFour),
+ gmx::boolToString(bNormalize));
printf("mode = %lu, dt = %g, nrestart = %d\n", mode, dt, nrestart);
}
/* Allocate temp arrays */
{
Ctav /= nitem;
Ct2av /= nitem;
- printf("Average correlation time %.3f Std. Dev. %.3f Error %.3f (ps)\n", Ctav,
+ printf("Average correlation time %.3f Std. Dev. %.3f Error %.3f (ps)\n",
+ Ctav,
std::sqrt((Ct2av - gmx::square(Ctav))),
std::sqrt((Ct2av - gmx::square(Ctav)) / (nitem - 1)));
}
default: break;
}
- low_do_autocorr(fn, oenv, title, nframes, nitem, acf.nout, c1, dt, mode, acf.nrestart, bAver,
- acf.bNormalize, bDebugMode(), acf.tbeginfit, acf.tendfit, acf.fitfn);
+ low_do_autocorr(fn,
+ oenv,
+ title,
+ nframes,
+ nitem,
+ acf.nout,
+ c1,
+ dt,
+ mode,
+ acf.nrestart,
+ bAver,
+ acf.bNormalize,
+ bDebugMode(),
+ acf.tbeginfit,
+ acf.tendfit,
+ acf.fitfn);
}
int get_acfnout()
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013-2019, by the GROMACS development team, led by
+ * Copyright (c) 2013-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.
double yfit = lmcurves[eFitFn](x[i], fitparms);
chi2 += gmx::square(y[i] - yfit);
}
- fprintf(fp, "There are %d data points, %d parameters, %s chi2 = %g\nparams:", nfitpnts,
- effnNparams(eFitFn), label, chi2);
+ fprintf(fp,
+ "There are %d data points, %d parameters, %s chi2 = %g\nparams:",
+ nfitpnts,
+ effnNparams(eFitFn),
+ label,
+ chi2);
for (i = 0; (i < effnNparams(eFitFn)); i++)
{
fprintf(fp, " %10g", fitparms[i]);
if (debug)
{
fprintf(debug, "There are %d points to fit %d vars!\n", ndata, effnNparams(eFitFn));
- fprintf(debug, "Fit to function %d from %g through %g, dt=%g\n", eFitFn, begintimefit,
- endtimefit, dt);
+ fprintf(debug, "Fit to function %d from %g through %g, dt=%g\n", eFitFn, begintimefit, endtimefit, dt);
}
snew(x, ndata);
if (bPrint)
{
- printf("COR: Correlation time (plain integral from %6.3f to %6.3f ps) = %8.5f ps\n", 0.0,
- dt * nf_int, sum);
+ printf("COR: Correlation time (plain integral from %6.3f to %6.3f ps) = %8.5f ps\n", 0.0, dt * nf_int, sum);
printf("COR: Relaxation times are computed as fit to an exponential:\n");
printf("COR: %s\n", effnDescription(fitfn));
printf("COR: Fit to correlation function from %6.3f ps to %6.3f ps, results in a\n",
- tbeginfit, std::min(ncorr * dt, tendfit));
+ tbeginfit,
+ std::min(ncorr * dt, tendfit));
}
tStart = 0;
if (bPrint)
{
- printf("COR:%11s%11s%11s%11s%11s%11s%11s\n", "Fit from", "Integral", "Tail Value",
- "Sum (ps)", " a1 (ps)", (effnNparams(fitfn) >= 2) ? " a2 ()" : "",
+ printf("COR:%11s%11s%11s%11s%11s%11s%11s\n",
+ "Fit from",
+ "Integral",
+ "Tail Value",
+ "Sum (ps)",
+ " a1 (ps)",
+ (effnNparams(fitfn) >= 2) ? " a2 ()" : "",
(effnNparams(fitfn) >= 3) ? " a3 (ps)" : "");
}
nf_int = std::min(ncorr, static_cast<int>((tStart + 1e-4) / dt));
sum = print_and_integrate(debug, nf_int, dt, c1, nullptr, 1);
- tail_corr = do_lmfit(ncorr, c1, sig, dt, nullptr, tStart, tendfit, oenv, bDebugMode(),
- fitfn, fitparm, 0, nullptr);
- sumtot = sum + tail_corr;
+ tail_corr = do_lmfit(
+ ncorr, c1, sig, dt, nullptr, tStart, tendfit, oenv, bDebugMode(), fitfn, fitparm, 0, nullptr);
+ sumtot = sum + tail_corr;
if (fit && ((jmax == 1) || (j == 1)))
{
double mfp[3];
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
chisq = gmx::square(status->fnorm);
if (bVerbose)
{
- printf("status: fnorm = %g, nfev = %d, userbreak = %d\noutcome = %s\n", status->fnorm,
- status->nfev, status->userbreak, lm_infmsg[status->outcome]);
+ printf("status: fnorm = %g, nfev = %d, userbreak = %d\noutcome = %s\n",
+ status->fnorm,
+ status->nfev,
+ status->userbreak,
+ lm_infmsg[status->outcome]);
}
if (bVerbose)
{
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014,2015,2016,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015,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.
if ((*c)[i].size() != ndata)
{
char buf[256];
- snprintf(buf, sizeof(buf), "Vectors of different lengths supplied (%d %d)",
- static_cast<int>((*c)[i].size()), static_cast<int>(ndata));
+ snprintf(buf,
+ sizeof(buf),
+ "Vectors of different lengths supplied (%d %d)",
+ static_cast<int>((*c)[i].size()),
+ static_cast<int>(ndata));
GMX_THROW(gmx::InconsistentInputError(buf));
}
}
}
}
real* ptr = result.data();
- low_do_autocorr(nullptr, nullptr, nullptr, nrFrames_, 1, get_acfnout(), &ptr,
- data_->getDt(), mode, nrRestart, bAverage, bNormalize, bVerbose,
- data_->getStartTime(), data_->getEndTime(), effnNONE);
+ low_do_autocorr(nullptr,
+ nullptr,
+ nullptr,
+ nrFrames_,
+ 1,
+ get_acfnout(),
+ &ptr,
+ data_->getDt(),
+ mode,
+ nrRestart,
+ bAverage,
+ bNormalize,
+ bVerbose,
+ data_->getStartTime(),
+ data_->getEndTime(),
+ effnNONE);
double testResult = 0;
for (int i = 0; i < get_acfnout(); i++)
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014,2019, by the GROMACS development team, led by
+ * Copyright (c) 2014,2019,2021, 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.
#ifndef GMX_CORRELATIONDATASET_H
#define GMX_CORRELATIONDATASET_H
+#include <memory>
#include <string>
#include <vector>
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014,2015,2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015,2017,2018,2019,2020, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
GMX_THROW(InvalidInputError("testType out of range"));
}
output_env_init_default(&oenv);
- do_lmfit(data_[testType].nrLines_, &(data_[testType].y_[0]), nullptr, data_[testType].dt_,
- &(data_[testType].x_[0]), data_[testType].startTime_, data_[testType].endTime_,
- oenv, false, type, result, 0, nullptr);
+ do_lmfit(data_[testType].nrLines_,
+ &(data_[testType].y_[0]),
+ nullptr,
+ data_[testType].dt_,
+ &(data_[testType].x_[0]),
+ data_[testType].startTime_,
+ data_[testType].endTime_,
+ oenv,
+ false,
+ type,
+ result,
+ 0,
+ nullptr);
output_env_done(oenv);
checker_.setDefaultTolerance(test::relativeToleranceAsFloatingPoint(1, tolerance));
checker_.checkSequenceArray(nfitparm, result, "result");
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+# Set up the module library
+add_library(domdec INTERFACE)
file(GLOB DOMDEC_SOURCES *.cpp)
if(GMX_GPU_CUDA)
set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${DOMDEC_SOURCES} ${DOMDEC_CUDA_SOURCES} PARENT_SCOPE)
+# Source files have the following dependencies on library infrastructure.
+#target_link_libraries(domdec PRIVATE
+# common
+# legacy_modules
+#)
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(domdec PUBLIC
+target_include_directories(domdec INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(domdec PUBLIC
+target_link_libraries(domdec INTERFACE
+ legacy_api
+ )
+
+# TODO: when domdec is an OBJECT target
+#target_link_libraries(domdec PUBLIC legacy_api)
+#target_link_libraries(domdec PRIVATE common)
+
+# Module dependencies
+# domdec interfaces convey transitive dependence on these modules.
+#target_link_libraries(domdec PUBLIC
+target_link_libraries(domdec INTERFACE
+ utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(domdec PRIVATE NOTHING)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(domdec PRIVATE legacy_modules)
+
if (BUILD_TESTING)
add_subdirectory(tests)
endif()
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2009,2010,2014,2015,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
/*! \brief Determines if dimensions require triclinic treatment and stores this info in ddbox */
static void set_tric_dir(const ivec* dd_nc, gmx_ddbox_t* ddbox, const matrix box)
{
- int npbcdim, d, i, j;
- rvec *v, *normal;
- real dep, inv_skew_fac2;
-
- npbcdim = ddbox->npbcdim;
- normal = ddbox->normal;
- for (d = 0; d < DIM; d++)
+ int npbcdim = ddbox->npbcdim;
+ rvec* normal = ddbox->normal;
+ for (int d = 0; d < DIM; d++)
{
ddbox->tric_dir[d] = 0;
- for (j = d + 1; j < npbcdim; j++)
+ for (int j = d + 1; j < npbcdim; j++)
{
if (box[j][d] != 0)
{
"Domain decomposition has not been implemented for box vectors that "
"have non-zero components in directions that do not use domain "
"decomposition: ncells = %d %d %d, box vector[%d] = %f %f %f",
- (*dd_nc)[XX], (*dd_nc)[YY], (*dd_nc)[ZZ], j + 1, box[j][XX],
- box[j][YY], box[j][ZZ]);
+ (*dd_nc)[XX],
+ (*dd_nc)[YY],
+ (*dd_nc)[ZZ],
+ j + 1,
+ box[j][XX],
+ box[j][YY],
+ box[j][ZZ]);
}
}
}
*/
if (ddbox->tric_dir[d])
{
- inv_skew_fac2 = 1;
- v = ddbox->v[d];
+ real inv_skew_fac2 = 1;
+ rvec* v = ddbox->v[d];
if (d == XX || d == YY)
{
/* Normalize such that the "diagonal" is 1 */
svmul(1 / box[d + 1][d + 1], box[d + 1], v[d + 1]);
- for (i = 0; i < d; i++)
+ for (int i = 0; i < d; i++)
{
v[d + 1][i] = 0;
}
/* Normalize such that the "diagonal" is 1 */
svmul(1 / box[d + 2][d + 2], box[d + 2], v[d + 2]);
/* Set v[d+2][d+1] to zero by shifting along v[d+1] */
- dep = v[d + 2][d + 1] / v[d + 1][d + 1];
- for (i = 0; i < DIM; i++)
+ const real dep = v[d + 2][d + 1] / v[d + 1][d + 1];
+ for (int i = 0; i < DIM; i++)
{
v[d + 2][i] -= dep * v[d + 1][i];
}
if (debug)
{
fprintf(debug, "box[%d] %.3f %.3f %.3f\n", d, box[d][XX], box[d][YY], box[d][ZZ]);
- for (i = d + 1; i < DIM; i++)
+ for (int i = d + 1; i < DIM; i++)
{
fprintf(debug, " v[%d] %.3f %.3f %.3f\n", i, v[i][XX], v[i][YY], v[i][ZZ]);
}
}
ddbox->skew_fac[d] = 1.0 / std::sqrt(inv_skew_fac2);
/* Set the normal vector length to skew_fac */
- dep = ddbox->skew_fac[d] / norm(normal[d]);
+ const real dep = ddbox->skew_fac[d] / norm(normal[d]);
svmul(dep, normal[d], normal[d]);
if (debug)
{
fprintf(debug, "skew_fac[%d] = %f\n", d, ddbox->skew_fac[d]);
- fprintf(debug, "normal[%d] %.3f %.3f %.3f\n", d, normal[d][XX], normal[d][YY],
- normal[d][ZZ]);
+ fprintf(debug, "normal[%d] %.3f %.3f %.3f\n", d, normal[d][XX], normal[d][YY], normal[d][ZZ]);
}
}
else
{
ddbox->skew_fac[d] = 1;
- for (i = 0; i < DIM; i++)
+ for (int i = 0; i < DIM; i++)
{
clear_rvec(ddbox->v[d][i]);
ddbox->v[d][i][i] = 1;
gmx_ddbox_t* ddbox)
{
rvec av, stddev;
- real b0, b1;
- int d;
ddbox->npbcdim = numPbcDimensions;
ddbox->nboundeddim = numBoundedDimensions;
- for (d = 0; d < numBoundedDimensions; d++)
+ for (int d = 0; d < numBoundedDimensions; d++)
{
ddbox->box0[d] = 0;
ddbox->box_size[d] = box[d][d];
* gives a uniform load for a rectangular block of cg's.
* For a sphere it is not a bad approximation for 4x1x1 up to 4x2x2.
*/
- for (d = ddbox->nboundeddim; d < DIM; d++)
+ for (int d = ddbox->nboundeddim; d < DIM; d++)
{
- b0 = av[d] - GRID_STDDEV_FAC * stddev[d];
- b1 = av[d] + GRID_STDDEV_FAC * stddev[d];
+ const real b0 = av[d] - GRID_STDDEV_FAC * stddev[d];
+ const real b1 = av[d] + GRID_STDDEV_FAC * stddev[d];
if (debug)
{
fprintf(debug, "Setting global DD grid boundaries to %f - %f\n", b0, b1);
gmx::ArrayRef<const gmx::RVec> xRef = constArrayRefFromArray(
x.data(), masterRankHasTheSystemState ? x.size() : dd.comm->atomRanges.numHomeAtoms());
- low_set_ddbox(dd.unitCellInfo.npbcdim, dd.unitCellInfo.numBoundedDimensions, &dd.numCells,
- box, calculateUnboundedSize, xRef,
- needToReduceCoordinateData ? &dd.mpi_comm_all : nullptr, ddbox);
+ low_set_ddbox(dd.unitCellInfo.npbcdim,
+ dd.unitCellInfo.numBoundedDimensions,
+ &dd.numCells,
+ box,
+ calculateUnboundedSize,
+ xRef,
+ needToReduceCoordinateData ? &dd.mpi_comm_all : nullptr,
+ ddbox);
}
if (masterRankHasTheSystemState)
{
if (ddRole == DDRole::Master)
{
- low_set_ddbox(numPbcDimensions(ir.pbcType), inputrec2nboundeddim(&ir), dd_nc, box, true, x,
- nullptr, ddbox);
+ low_set_ddbox(
+ numPbcDimensions(ir.pbcType), inputrec2nboundeddim(&ir), dd_nc, box, true, x, nullptr, ddbox);
}
gmx_bcast(sizeof(gmx_ddbox_t), ddbox, communicator);
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
#ifndef GMX_DOMDEC_BUILDER_H
#define GMX_DOMDEC_BUILDER_H
+#include <memory>
+
#include "gromacs/math/vectypes.h"
#include "gromacs/utility/basedefinitions.h"
-#include "gromacs/utility/classhelpers.h"
struct gmx_domdec_t;
struct gmx_mtop_t;
private:
class Impl;
//! Pimpl to hide implementation details
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
const gmx_ddbox_t* ddbox,
const real* cellFrac)
{
- gmx_domdec_comm_t* comm;
- int nc, ns, s;
- int * xmin, *xmax;
- real range, pme_boundary;
- int sh;
+ int sh = 0;
- comm = dd->comm;
- nc = dd->numCells[ddpme->dim];
- ns = ddpme->nslab;
+ gmx_domdec_comm_t* comm = dd->comm;
+ const int nc = dd->numCells[ddpme->dim];
+ const int ns = ddpme->nslab;
if (!ddpme->dim_match)
{
/* We need to check for all pme nodes which nodes they
* could possibly need to communicate with.
*/
- xmin = ddpme->pp_min;
- xmax = ddpme->pp_max;
+ const int* xmin = ddpme->pp_min;
+ const int* xmax = ddpme->pp_max;
/* Allow for atoms to be maximally 2/3 times the cut-off
* out of their DD cell. This is a reasonable balance between
* between performance and support for most charge-group/cut-off
* combinations.
*/
- range = 2.0 / 3.0 * comm->systemInfo.cutoff / ddbox->box_size[ddpme->dim];
+ real range = 2.0 / 3.0 * comm->systemInfo.cutoff / ddbox->box_size[ddpme->dim];
/* Avoid extra communication when we are exactly at a boundary */
range *= 0.999;
sh = 1;
- for (s = 0; s < ns; s++)
+ for (int s = 0; s < ns; s++)
{
/* PME slab s spreads atoms between box frac. s/ns and (s+1)/ns */
- pme_boundary = static_cast<real>(s) / ns;
+ real pme_boundary = static_cast<real>(s) / ns;
while (sh + 1 < ns
&& ((s - (sh + 1) >= 0 && cellFrac[xmax[s - (sh + 1)] + 1] + range > pme_boundary)
|| (s - (sh + 1) < 0 && cellFrac[xmax[s - (sh + 1) + ns] + 1] - 1 + range > pme_boundary)))
static void check_box_size(const gmx_domdec_t* dd, const gmx_ddbox_t* ddbox)
{
- int d, dim;
-
- for (d = 0; d < dd->ndim; d++)
+ for (int d = 0; d < dd->ndim; d++)
{
- dim = dd->dim[d];
+ const int dim = dd->dim[d];
if (dim < ddbox->nboundeddim
&& ddbox->box_size[dim] * ddbox->skew_fac[dim]
< dd->numCells[dim] * dd->comm->cellsize_limit * DD_CELL_MARGIN)
FARGS,
"The %c-size of the box (%f) times the triclinic skew factor (%f) is smaller "
"than the number of DD cells (%d) times the smallest allowed cell size (%f)\n",
- dim2char(dim), ddbox->box_size[dim], ddbox->skew_fac[dim], dd->numCells[dim],
+ dim2char(dim),
+ ddbox->box_size[dim],
+ ddbox->skew_fac[dim],
+ dd->numCells[dim],
dd->comm->cellsize_limit);
}
}
real grid_jump_limit(const gmx_domdec_comm_t* comm, real cutoff, int dim_ind)
{
- real grid_jump_limit;
-
/* The distance between the boundaries of cells at distance
* x+-1,y+-1 or y+-1,z+-1 is limited by the cut-off restrictions
* and by the fact that cells should not be shifted by more than
* half their size, such that cg's only shift by one cell
* at redecomposition.
*/
- grid_jump_limit = comm->cellsize_limit;
+ real grid_jump_limit = comm->cellsize_limit;
if (!comm->bVacDLBNoLimit)
{
if (comm->bPMELoadBalDLBLimits)
*/
static real cellsize_min_dlb(gmx_domdec_comm_t* comm, int dim_ind, int dim)
{
- real cellsize_min;
-
- cellsize_min = comm->cellsize_min[dim];
+ real cellsize_min = comm->cellsize_min[dim];
if (!comm->bVacDLBNoLimit)
{
"The box size in direction %c (%f) times the triclinic skew factor (%f) is too "
"small for a cut-off of %f with %d domain decomposition cells, use 1 or more "
"than %d %s or increase the box size in this direction",
- dim2char(d), ddbox->box_size[d], ddbox->skew_fac[d], comm->systemInfo.cutoff,
- dd->numCells[d], dd->numCells[d], dd->nnodes > dd->numCells[d] ? "cells" : "ranks");
+ dim2char(d),
+ ddbox->box_size[d],
+ ddbox->skew_fac[d],
+ comm->systemInfo.cutoff,
+ dd->numCells[d],
+ dd->numCells[d],
+ dd->nnodes > dd->numCells[d] ? "cells" : "ranks");
if (setmode == setcellsizeslbLOCAL)
{
DDRankSetup& ddRankSetup = comm->ddRankSetup;
for (int d = 0; d < ddRankSetup.npmedecompdim; d++)
{
- set_pme_maxshift(dd, &ddRankSetup.ddpme[d], comm->slb_frac[dd->dim[d]] == nullptr, ddbox,
+ set_pme_maxshift(dd,
+ &ddRankSetup.ddpme[d],
+ comm->slb_frac[dd->dim[d]] == nullptr,
+ ddbox,
ddRankSetup.ddpme[d].slb_dim_f);
}
real cellsize_limit_f,
int range[])
{
- gmx_domdec_comm_t* comm;
- real halfway, cellsize_limit_f_i, region_size;
- gmx_bool bLastHi = FALSE;
- int nrange[] = { range[0], range[1] };
+ gmx_bool bLastHi = FALSE;
+ int nrange[] = { range[0], range[1] };
- region_size = rowMaster->cellFrac[range[1]] - rowMaster->cellFrac[range[0]];
+ const real region_size = rowMaster->cellFrac[range[1]] - rowMaster->cellFrac[range[0]];
GMX_ASSERT(region_size >= (range[1] - range[0]) * cellsize_limit_f,
"The region should fit all cells at minimum size");
- comm = dd->comm;
+ gmx_domdec_comm_t* comm = dd->comm;
const int ncd = dd->numCells[dim];
{
rowMaster->isCellMin[i] = false;
}
- int nmin = 0;
- int nmin_old;
+ int nmin = 0;
+ int nmin_old = 0;
do
{
nmin_old = nmin;
if (!rowMaster->isCellMin[i])
{
cell_size[i] *= fac;
- if (!dimHasPbc && (i == 0 || i == dd->numCells[dim] - 1))
- {
- cellsize_limit_f_i = 0;
- }
- else
- {
- cellsize_limit_f_i = cellsize_limit_f;
- }
+ const real cellsize_limit_f_i =
+ (!dimHasPbc && (i == 0 || i == dd->numCells[dim] - 1)) ? 0 : cellsize_limit_f;
if (cell_size[i] < cellsize_limit_f_i)
{
rowMaster->isCellMin[i] = true;
gmx_fatal(FARGS,
"step %s: the dynamic load balancing could not balance dimension %c: box size "
"%f, triclinic skew factor %f, #cells %d, minimum cell size %f\n",
- gmx_step_str(step, buf), dim2char(dim), ddbox->box_size[dim],
- ddbox->skew_fac[dim], ncd, comm->cellsize_min[dim]);
+ gmx_step_str(step, buf),
+ dim2char(dim),
+ ddbox->box_size[dim],
+ ddbox->skew_fac[dim],
+ ncd,
+ comm->cellsize_min[dim]);
}
rowMaster->dlbIsLimited = (nmin > 0) || (range[0] > 0) || (range[1] < ncd);
*/
for (int i = range[0] + 1; i < range[1]; i++)
{
- halfway = 0.5 * (rowMaster->oldCellFrac[i] + rowMaster->oldCellFrac[i - 1]);
+ real halfway = 0.5 * (rowMaster->oldCellFrac[i] + rowMaster->oldCellFrac[i - 1]);
if (rowMaster->cellFrac[i] < halfway)
{
rowMaster->cellFrac[i] = halfway;
rowMaster->cellFrac[i] = 0.5 * (bounds.boundMin + bounds.boundMax);
nrange[0] = range[0];
nrange[1] = i;
- dd_cell_sizes_dlb_root_enforce_limits(dd, d, dim, rowMaster, ddbox, bUniform,
- step, cellsize_limit_f, nrange);
+ dd_cell_sizes_dlb_root_enforce_limits(
+ dd, d, dim, rowMaster, ddbox, bUniform, step, cellsize_limit_f, nrange);
nrange[0] = i;
nrange[1] = range[1];
- dd_cell_sizes_dlb_root_enforce_limits(dd, d, dim, rowMaster, ddbox, bUniform,
- step, cellsize_limit_f, nrange);
+ dd_cell_sizes_dlb_root_enforce_limits(
+ dd, d, dim, rowMaster, ddbox, bUniform, step, cellsize_limit_f, nrange);
return;
}
if (nrange[1] < range[1]) /* found a LimLo before */
{
rowMaster->cellFrac[nrange[1]] = rowMaster->bounds[nrange[1]].boundMin;
- dd_cell_sizes_dlb_root_enforce_limits(dd, d, dim, rowMaster, ddbox, bUniform,
- step, cellsize_limit_f, nrange);
+ dd_cell_sizes_dlb_root_enforce_limits(
+ dd, d, dim, rowMaster, ddbox, bUniform, step, cellsize_limit_f, nrange);
nrange[0] = nrange[1];
}
rowMaster->cellFrac[i] = rowMaster->bounds[i].boundMax;
nrange[1] = i;
- dd_cell_sizes_dlb_root_enforce_limits(dd, d, dim, rowMaster, ddbox, bUniform,
- step, cellsize_limit_f, nrange);
+ dd_cell_sizes_dlb_root_enforce_limits(
+ dd, d, dim, rowMaster, ddbox, bUniform, step, cellsize_limit_f, nrange);
nrange[0] = i;
nrange[1] = range[1];
}
if (nrange[1] < range[1]) /* found last a LimLo */
{
rowMaster->cellFrac[nrange[1]] = rowMaster->bounds[nrange[1]].boundMin;
- dd_cell_sizes_dlb_root_enforce_limits(dd, d, dim, rowMaster, ddbox, bUniform, step,
- cellsize_limit_f, nrange);
+ dd_cell_sizes_dlb_root_enforce_limits(
+ dd, d, dim, rowMaster, ddbox, bUniform, step, cellsize_limit_f, nrange);
nrange[0] = nrange[1];
nrange[1] = range[1];
- dd_cell_sizes_dlb_root_enforce_limits(dd, d, dim, rowMaster, ddbox, bUniform, step,
- cellsize_limit_f, nrange);
+ dd_cell_sizes_dlb_root_enforce_limits(
+ dd, d, dim, rowMaster, ddbox, bUniform, step, cellsize_limit_f, nrange);
}
else if (nrange[0] > range[0]) /* found at least one LimHi */
{
- dd_cell_sizes_dlb_root_enforce_limits(dd, d, dim, rowMaster, ddbox, bUniform, step,
- cellsize_limit_f, nrange);
+ dd_cell_sizes_dlb_root_enforce_limits(
+ dd, d, dim, rowMaster, ddbox, bUniform, step, cellsize_limit_f, nrange);
}
}
}
{
real load_aver = comm->load[d].sum_m / ncd;
real change_max = 0;
- real load_i;
- real change;
for (int i = 0; i < ncd; i++)
{
/* Determine the relative imbalance of cell i */
- load_i = comm->load[d].load[i * comm->load[d].nload + 2];
- real imbalance = (load_i - load_aver) / (load_aver > 0 ? load_aver : 1);
+ const real load_i = comm->load[d].load[i * comm->load[d].nload + 2];
+ const real imbalance = (load_i - load_aver) / (load_aver > 0 ? load_aver : 1);
/* Determine the change of the cell size using underrelaxation */
- change = -c_relax * imbalance;
- change_max = std::max(change_max, std::max(change, -change));
+ const real change = -c_relax * imbalance;
+ change_max = std::max(change_max, std::max(change, -change));
}
/* Limit the amount of scaling.
* We need to use the same rescaling for all cells in one row,
for (int i = 0; i < ncd; i++)
{
/* Determine the relative imbalance of cell i */
- load_i = comm->load[d].load[i * comm->load[d].nload + 2];
- real imbalance = (load_i - load_aver) / (load_aver > 0 ? load_aver : 1);
+ const real load_i = comm->load[d].load[i * comm->load[d].nload + 2];
+ const real imbalance = (load_i - load_aver) / (load_aver > 0 ? load_aver : 1);
/* Determine the change of the cell size using underrelaxation */
- change = -sc * imbalance;
+ const real change = -sc * imbalance;
cell_size[i] = (rowMaster->cellFrac[i + 1] - rowMaster->cellFrac[i]) * (1 + change);
}
}
}
if (debug)
{
- fprintf(debug, "dim %d boundary %d %.3f < %.3f < %.3f < %.3f < %.3f\n", d, i,
- boundsNeighbor.cellFracLowerMax + dist_min_f, bounds.boundMin,
- rowMaster->cellFrac[i], bounds.boundMax, bounds.cellFracUpperMin - dist_min_f);
+ fprintf(debug,
+ "dim %d boundary %d %.3f < %.3f < %.3f < %.3f < %.3f\n",
+ d,
+ i,
+ boundsNeighbor.cellFracLowerMax + dist_min_f,
+ bounds.boundMin,
+ rowMaster->cellFrac[i],
+ bounds.boundMax,
+ bounds.cellFracUpperMin - dist_min_f);
}
}
}
range[1] = ncd;
rowMaster->cellFrac[0] = 0;
rowMaster->cellFrac[ncd] = 1;
- dd_cell_sizes_dlb_root_enforce_limits(dd, d, dim, rowMaster, ddbox, bUniform, step,
- cellsize_limit_f, range);
+ dd_cell_sizes_dlb_root_enforce_limits(
+ dd, d, dim, rowMaster, ddbox, bUniform, step, cellsize_limit_f, range);
/* After the checks above, the cells should obey the cut-off
{
if (debug)
{
- fprintf(debug, "Relative bounds dim %d cell %d: %f %f\n", dim, i,
- rowMaster->cellFrac[i], rowMaster->cellFrac[i + 1]);
+ fprintf(debug,
+ "Relative bounds dim %d cell %d: %f %f\n",
+ dim,
+ i,
+ rowMaster->cellFrac[i],
+ rowMaster->cellFrac[i + 1]);
}
if ((bPBC || (i != 0 && i != dd->numCells[dim] - 1))
&& rowMaster->cellFrac[i + 1] - rowMaster->cellFrac[i] < cellsize_limit_f / DD_CELL_MARGIN)
{
char buf[22];
- fprintf(stderr, "\nWARNING step %s: direction %c, cell %d too small: %f\n",
- gmx_step_str(step, buf), dim2char(dim), i,
+ fprintf(stderr,
+ "\nWARNING step %s: direction %c, cell %d too small: %f\n",
+ gmx_step_str(step, buf),
+ dim2char(dim),
+ i,
(rowMaster->cellFrac[i + 1] - rowMaster->cellFrac[i]) * ddbox->box_size[dim]
* ddbox->skew_fac[dim]);
}
/* Each node would only need to know two fractions,
* but it is probably cheaper to broadcast the whole array.
*/
- MPI_Bcast(cellFracRow.data(), ddCellFractionBufferSize(dd, d) * sizeof(real), MPI_BYTE, 0,
+ MPI_Bcast(cellFracRow.data(),
+ ddCellFractionBufferSize(dd, d) * sizeof(real),
+ MPI_BYTE,
+ 0,
comm.mpi_comm_load[d]);
#endif
/* Copy the fractions for this dimension from the buffer */
static void set_dd_cell_sizes_dlb_nochange(gmx_domdec_t* dd, const gmx_ddbox_t* ddbox)
{
- int d;
-
/* This function assumes the box is static and should therefore
* not be called when the box has changed since the last
* call to dd_partition_system.
*/
- for (d = 0; d < dd->ndim; d++)
+ for (int d = 0; d < dd->ndim; d++)
{
relative_to_absolute_cell_bounds(dd, ddbox, d);
}
int64_t step,
gmx_wallcycle_t wcycle)
{
- gmx_domdec_comm_t* comm;
- int dim;
-
- comm = dd->comm;
+ gmx_domdec_comm_t* comm = dd->comm;
if (bDoDLB)
{
}
/* Set the dimensions for which no DD is used */
- for (dim = 0; dim < DIM; dim++)
+ for (int dim = 0; dim < DIM; dim++)
{
if (dd->numCells[dim] == 1)
{
fprintf(debug,
"Changing the number of halo communication pulses along dim %c from %d "
"to %d\n",
- dim2char(dd->dim[d]), cd.numPulses(), numPulsesDim);
+ dim2char(dd->dim[d]),
+ cd.numPulses(),
+ numPulsesDim);
}
cd.ind.resize(numPulsesDim);
}
{
for (int d = 0; d < DIM; d++)
{
- fprintf(debug, "cell_x[%d] %f - %f skew_fac %f\n", d, comm->cell_x0[d],
- comm->cell_x1[d], ddbox->skew_fac[d]);
+ fprintf(debug,
+ "cell_x[%d] %f - %f skew_fac %f\n",
+ d,
+ comm->cell_x0[d],
+ comm->cell_x1[d],
+ ddbox->skew_fac[d]);
}
}
}
}
/* Collect the charge group indices on the master */
- dd_gatherv(dd, atomGroups.size() * sizeof(int), atomGroups.data(),
+ dd_gatherv(dd,
+ atomGroups.size() * sizeof(int),
+ atomGroups.data(),
DDMASTER(dd) ? ma->intBuffer.data() : nullptr,
DDMASTER(dd) ? ma->intBuffer.data() + dd->nnodes : nullptr,
DDMASTER(dd) ? ma->atomGroups.data() : nullptr);
#if GMX_MPI
const int numHomeAtoms = dd->comm->atomRanges.numHomeAtoms();
MPI_Send(const_cast<void*>(static_cast<const void*>(lv.data())),
- numHomeAtoms * sizeof(rvec), MPI_BYTE, dd->masterrank, dd->rank, dd->mpi_comm_all);
+ numHomeAtoms * sizeof(rvec),
+ MPI_BYTE,
+ dd->masterrank,
+ dd->rank,
+ dd->mpi_comm_all);
#endif
}
else
}
#if GMX_MPI
- MPI_Recv(ma.rvecBuffer.data(), domainGroups.numAtoms * sizeof(rvec), MPI_BYTE, rank,
- rank, dd->mpi_comm_all, MPI_STATUS_IGNORE);
+ MPI_Recv(ma.rvecBuffer.data(),
+ domainGroups.numAtoms * sizeof(rvec),
+ MPI_BYTE,
+ rank,
+ rank,
+ dd->mpi_comm_all,
+ MPI_STATUS_IGNORE);
#endif
int localAtom = 0;
for (const int& globalAtom : domainGroups.atomGroups)
}
const int numHomeAtoms = dd->comm->atomRanges.numHomeAtoms();
- dd_gatherv(dd, numHomeAtoms * sizeof(rvec), lv.data(), recvCounts, displacements,
+ dd_gatherv(dd,
+ numHomeAtoms * sizeof(rvec),
+ lv.data(),
+ recvCounts,
+ displacements,
DDMASTER(dd) ? dd->ma->rvecBuffer.data() : nullptr);
if (DDMASTER(dd))
if (state_local->flags & (1 << estX))
{
auto globalXRef = state ? state->x : gmx::ArrayRef<gmx::RVec>();
- dd_collect_vec(dd, state_local->ddp_count, state_local->ddp_count_cg_gl, state_local->cg_gl,
- state_local->x, globalXRef);
+ dd_collect_vec(dd,
+ state_local->ddp_count,
+ state_local->ddp_count_cg_gl,
+ state_local->cg_gl,
+ state_local->x,
+ globalXRef);
}
if (state_local->flags & (1 << estV))
{
auto globalVRef = state ? state->v : gmx::ArrayRef<gmx::RVec>();
- dd_collect_vec(dd, state_local->ddp_count, state_local->ddp_count_cg_gl, state_local->cg_gl,
- state_local->v, globalVRef);
+ dd_collect_vec(dd,
+ state_local->ddp_count,
+ state_local->ddp_count_cg_gl,
+ state_local->cg_gl,
+ state_local->v,
+ globalVRef);
}
if (state_local->flags & (1 << estCGP))
{
auto globalCgpRef = state ? state->cg_p : gmx::ArrayRef<gmx::RVec>();
- dd_collect_vec(dd, state_local->ddp_count, state_local->ddp_count_cg_gl, state_local->cg_gl,
- state_local->cg_p, globalCgpRef);
+ dd_collect_vec(dd,
+ state_local->ddp_count,
+ state_local->ddp_count_cg_gl,
+ state_local->cg_gl,
+ state_local->cg_p,
+ globalCgpRef);
}
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
"The index count and number of indices should match");
#if GMX_MPI
- MPI_Send(buffer.data(), domainGroups.numAtoms * sizeof(gmx::RVec), MPI_BYTE, rank,
- rank, dd->mpi_comm_all);
+ MPI_Send(buffer.data(), domainGroups.numAtoms * sizeof(gmx::RVec), MPI_BYTE, rank, rank, dd->mpi_comm_all);
#endif
}
}
{
#if GMX_MPI
int numHomeAtoms = dd->comm->atomRanges.numHomeAtoms();
- MPI_Recv(localVec.data(), numHomeAtoms * sizeof(gmx::RVec), MPI_BYTE, dd->masterrank,
- MPI_ANY_TAG, dd->mpi_comm_all, MPI_STATUS_IGNORE);
+ MPI_Recv(localVec.data(),
+ numHomeAtoms * sizeof(gmx::RVec),
+ MPI_BYTE,
+ dd->masterrank,
+ MPI_ANY_TAG,
+ dd->mpi_comm_all,
+ MPI_STATUS_IGNORE);
#endif
}
}
}
int numHomeAtoms = dd->comm->atomRanges.numHomeAtoms();
- dd_scatterv(dd, sendCounts, displacements, DDMASTER(dd) ? dd->ma->rvecBuffer.data() : nullptr,
- numHomeAtoms * sizeof(gmx::RVec), localVec.data());
+ dd_scatterv(dd,
+ sendCounts,
+ displacements,
+ DDMASTER(dd) ? dd->ma->rvecBuffer.data() : nullptr,
+ numHomeAtoms * sizeof(gmx::RVec),
+ localVec.data());
}
static void distributeVec(gmx_domdec_t* dd,
{
for (int g = 0; g < updateGrouping.numBlocks(); g++)
{
- const auto& block = updateGrouping.block(g);
- const int atomBegin = atomOffset + block.begin();
- const int atomEnd = atomOffset + block.end();
- const int domainIndex =
- computeAtomGroupDomainIndex(*dd, ddbox, triclinicCorrectionMatrix,
- cellBoundaries, atomBegin, atomEnd, box, pos);
+ const auto& block = updateGrouping.block(g);
+ const int atomBegin = atomOffset + block.begin();
+ const int atomEnd = atomOffset + block.end();
+ const int domainIndex = computeAtomGroupDomainIndex(
+ *dd, ddbox, triclinicCorrectionMatrix, cellBoundaries, atomBegin, atomEnd, box, pos);
for (int atomIndex : block)
{
/* Compute the center of geometry for all atoms */
for (int atom = 0; atom < mtop.natoms; atom++)
{
- int domainIndex = computeAtomGroupDomainIndex(*dd, ddbox, triclinicCorrectionMatrix,
- cellBoundaries, atom, atom + 1, box, pos);
+ int domainIndex = computeAtomGroupDomainIndex(
+ *dd, ddbox, triclinicCorrectionMatrix, cellBoundaries, atom, atom + 1, box, pos);
indices[domainIndex].push_back(atom);
ma.domainGroups[domainIndex].numAtoms += 1;
{
// Use double for the sums to avoid natoms^2 overflowing
// (65537^2 > 2^32)
- int nat_sum, nat_min, nat_max;
- double nat2_sum;
-
- nat_sum = 0;
- nat2_sum = 0;
- nat_min = ma.domainGroups[0].numAtoms;
- nat_max = ma.domainGroups[0].numAtoms;
+ int nat_sum = 0;
+ double nat2_sum = 0;
+ int nat_min = ma.domainGroups[0].numAtoms;
+ int nat_max = ma.domainGroups[0].numAtoms;
for (int rank = 0; rank < dd->nnodes; rank++)
{
int numAtoms = ma.domainGroups[rank].numAtoms;
GMX_LOG(mdlog.info)
.appendTextFormatted(
"Atom distribution over %d domains: av %d stddev %d min %d max %d",
- dd->nnodes, nat_sum,
+ dd->nnodes,
+ nat_sum,
gmx::roundToInt(std::sqrt(nat2_sum - gmx::square(static_cast<double>(nat_sum)))),
- nat_min, nat_max);
+ nat_min,
+ nat_max);
}
return indices;
const gmx_ddbox_t* ddbox,
rvec pos[])
{
- AtomDistribution* ma = dd->ma.get();
- int * ibuf, buf2[2] = { 0, 0 };
+ AtomDistribution* ma = dd->ma.get();
+ int * ibuf = nullptr, buf2[2] = { 0, 0 };
gmx_bool bMaster = DDMASTER(dd);
std::vector<std::vector<int>> groupIndices;
ma->intBuffer[rank] = groupIndices[rank].size() * sizeof(int);
ma->intBuffer[dd->nnodes + rank] = groupOffset * sizeof(int);
- ma->atomGroups.insert(ma->atomGroups.end(), groupIndices[rank].begin(),
- groupIndices[rank].end());
+ ma->atomGroups.insert(
+ ma->atomGroups.end(), groupIndices[rank].begin(), groupIndices[rank].end());
ma->domainGroups[rank].atomGroups = gmx::constArrayRefFromArray(
ma->atomGroups.data() + groupOffset, groupIndices[rank].size());
}
}
- dd_scatterv(dd, bMaster ? ma->intBuffer.data() : nullptr,
+ dd_scatterv(dd,
+ bMaster ? ma->intBuffer.data() : nullptr,
bMaster ? ma->intBuffer.data() + dd->nnodes : nullptr,
- bMaster ? ma->atomGroups.data() : nullptr, dd->ncg_home * sizeof(int),
+ bMaster ? ma->atomGroups.data() : nullptr,
+ dd->ncg_home * sizeof(int),
dd->globalAtomGroupIndices.data());
if (debug)
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2021, 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.
//! Accumulates flop counts for force calculations.
static double force_flop_count(const t_nrnb* nrnb)
{
- int i;
- double sum;
- const char* name;
-
- sum = 0;
- for (i = 0; i < eNR_NBKERNEL_FREE_ENERGY; i++)
+ double sum = 0;
+ for (int i = 0; i < eNR_NBKERNEL_FREE_ENERGY; i++)
{
/* To get closer to the real timings, we half the count
* for the normal loops and again half it for water loops.
*/
- name = nrnb_str(i);
+ const char* name = nrnb_str(i);
if (strstr(name, "W3") != nullptr || strstr(name, "W4") != nullptr)
{
sum += nrnb->n[i] * 0.25 * cost_nrnb(i);
sum += nrnb->n[i] * 0.50 * cost_nrnb(i);
}
}
- for (i = eNR_NBKERNEL_FREE_ENERGY; i <= eNR_NB14; i++)
+ for (int i = eNR_NBKERNEL_FREE_ENERGY; i <= eNR_NB14; i++)
{
- name = nrnb_str(i);
+ const char* name = nrnb_str(i);
if (strstr(name, "W3") != nullptr || strstr(name, "W4") != nullptr)
{
sum += nrnb->n[i] * cost_nrnb(i);
}
}
- for (i = eNR_BONDS; i <= eNR_WALLS; i++)
+ for (int i = eNR_BONDS; i <= eNR_WALLS; i++)
{
sum += nrnb->n[i] * cost_nrnb(i);
}
void clear_dd_cycle_counts(gmx_domdec_t* dd)
{
- int i;
-
- for (i = 0; i < ddCyclNr; i++)
+ for (int i = 0; i < ddCyclNr; i++)
{
dd->comm->cycl[i] = 0;
dd->comm->cycl_n[i] = 0;
* Copyright (c) 2005,2006,2007,2008,2009 by the GROMACS development team.
* Copyright (c) 2010,2011,2012,2013,2014 by the GROMACS development team.
* Copyright (c) 2015,2016,2017,2018,2019 by the GROMACS development team.
- * Copyright (c) 2020, by the GROMACS development team, led by
+ * Copyright (c) 2020,2021, 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.
int ddglatnr(const gmx_domdec_t* dd, int i)
{
- int atnr;
+ int atnr = 0;
if (dd == nullptr)
{
{
gmx_fatal(FARGS,
"glatnr called with %d, which is larger than the local number of atoms (%d)",
- i, dd->comm->atomRanges.numAtomsTotal());
+ i,
+ dd->comm->atomRanges.numAtomsTotal());
}
atnr = dd->globalAtomIndices[i] + 1;
}
void dd_store_state(gmx_domdec_t* dd, t_state* state)
{
- int i;
-
if (state->ddp_count != dd->ddp_count)
{
gmx_incons("The MD state does not match the domain decomposition state");
}
state->cg_gl.resize(dd->ncg_home);
- for (i = 0; i < dd->ncg_home; i++)
+ for (int i = 0; i < dd->ncg_home; i++)
{
state->cg_gl[i] = dd->globalAtomGroupIndices[i];
}
{
wallcycle_start(wcycle, ewcMOVEX);
- int nzone, nat_tot;
- gmx_domdec_comm_t* comm;
- gmx_domdec_comm_dim_t* cd;
- rvec shift = { 0, 0, 0 };
- gmx_bool bPBC, bScrew;
+ rvec shift = { 0, 0, 0 };
- comm = dd->comm;
+ gmx_domdec_comm_t* comm = dd->comm;
- nzone = 1;
- nat_tot = comm->atomRanges.numHomeAtoms();
+ int nzone = 1;
+ int nat_tot = comm->atomRanges.numHomeAtoms();
for (int d = 0; d < dd->ndim; d++)
{
- bPBC = (dd->ci[dd->dim[d]] == 0);
- bScrew = (bPBC && dd->unitCellInfo.haveScrewPBC && dd->dim[d] == XX);
+ const bool bPBC = (dd->ci[dd->dim[d]] == 0);
+ const bool bScrew = (bPBC && dd->unitCellInfo.haveScrewPBC && dd->dim[d] == XX);
if (bPBC)
{
copy_rvec(box[dd->dim[d]], shift);
}
- cd = &comm->cd[d];
+ gmx_domdec_comm_dim_t* cd = &comm->cd[d];
for (const gmx_domdec_ind_t& ind : cd->ind)
{
DDBufferAccess<gmx::RVec> sendBufferAccess(comm->rvecBuffer, ind.nsend[nzone + 1]);
void dd_atom_spread_real(gmx_domdec_t* dd, real v[])
{
- int nzone, nat_tot;
- gmx_domdec_comm_t* comm;
- gmx_domdec_comm_dim_t* cd;
-
- comm = dd->comm;
+ gmx_domdec_comm_t* comm = dd->comm;
- nzone = 1;
- nat_tot = comm->atomRanges.numHomeAtoms();
+ int nzone = 1;
+ int nat_tot = comm->atomRanges.numHomeAtoms();
for (int d = 0; d < dd->ndim; d++)
{
- cd = &comm->cd[d];
+ gmx_domdec_comm_dim_t* cd = &comm->cd[d];
for (const gmx_domdec_ind_t& ind : cd->ind)
{
/* Note: We provision for RVec instead of real, so a factor of 3
void dd_atom_sum_real(gmx_domdec_t* dd, real v[])
{
- int nzone, nat_tot;
- gmx_domdec_comm_t* comm;
- gmx_domdec_comm_dim_t* cd;
-
- comm = dd->comm;
+ gmx_domdec_comm_t* comm = dd->comm;
- nzone = comm->zones.n / 2;
- nat_tot = comm->atomRanges.end(DDAtomRanges::Type::Zones);
+ int nzone = comm->zones.n / 2;
+ int nat_tot = comm->atomRanges.end(DDAtomRanges::Type::Zones);
for (int d = dd->ndim - 1; d >= 0; d--)
{
- cd = &comm->cd[d];
+ gmx_domdec_comm_dim_t* cd = &comm->cd[d];
for (int p = cd->numPulses() - 1; p >= 0; p--)
{
const gmx_domdec_ind_t& ind = cd->ind[p];
real dd_cutoff_twobody(const gmx_domdec_t* dd)
{
- real r_mb;
-
- r_mb = dd_cutoff_multibody(dd);
+ const real r_mb = dd_cutoff_multibody(dd);
return std::max(dd->comm->systemInfo.cutoff, r_mb);
}
static int gmx_ddcoord2pmeindex(const t_commrec* cr, int x, int y, int z)
{
- gmx_domdec_t* dd;
- ivec coords;
- int slab;
+ ivec coords;
- dd = cr->dd;
- coords[XX] = x;
- coords[YY] = y;
- coords[ZZ] = z;
- slab = ddindex2pmeindex(dd->comm->ddRankSetup, dd_index(dd->numCells, coords));
+ gmx_domdec_t* dd = cr->dd;
+ coords[XX] = x;
+ coords[YY] = y;
+ coords[ZZ] = z;
+ const int slab = ddindex2pmeindex(dd->comm->ddRankSetup, dd_index(dd->numCells, coords));
return slab;
}
static gmx_bool receive_vir_ener(const gmx_domdec_t* dd, gmx::ArrayRef<const int> pmeRanks, const t_commrec* cr)
{
- gmx_bool bReceive = TRUE;
+ bool bReceive = true;
const DDRankSetup& ddRankSetup = dd->comm->ddRankSetup;
if (ddRankSetup.usePmeOnlyRanks)
coords[cartSetup.cartpmedim]++;
if (coords[cartSetup.cartpmedim] < dd->numCells[cartSetup.cartpmedim])
{
- int rank;
+ int rank = 0;
MPI_Cart_rank(cr->mpi_comm_mysim, coords, &rank);
if (dd_simnode2pmenode(ddRankSetup, cartSetup, pmeRanks, cr, rank) == pmenode)
{
static void set_slb_pme_dim_f(gmx_domdec_t* dd, int dim, real** dim_f)
{
- gmx_domdec_comm_t* comm;
- int i;
-
- comm = dd->comm;
+ gmx_domdec_comm_t* comm = dd->comm;
snew(*dim_f, dd->numCells[dim] + 1);
(*dim_f)[0] = 0;
- for (i = 1; i < dd->numCells[dim]; i++)
+ for (int i = 1; i < dd->numCells[dim]; i++)
{
if (comm->slb_frac[dim])
{
*/
if (dimind == 0 || xyz[XX] == dd->ci[XX])
{
- const int pmeindex = ddindex2pmeindex(ddRankSetup, i);
- int slab;
- if (dimind == 0)
- {
- slab = pmeindex / nso;
- }
- else
- {
- slab = pmeindex % ddpme->nslab;
- }
+ const int pmeindex = ddindex2pmeindex(ddRankSetup, i);
+ const int slab = (dimind == 0) ? (pmeindex / nso) : (pmeindex % ddpme->nslab);
ddpme->pp_min[slab] = std::min(ddpme->pp_min[slab], xyz[dimind]);
ddpme->pp_max[slab] = std::max(ddpme->pp_max[slab], xyz[dimind]);
}
#if GMX_MPI
static void make_load_communicator(gmx_domdec_t* dd, int dim_ind, ivec loc)
{
- MPI_Comm c_row;
- int dim, i, rank;
+ MPI_Comm c_row = MPI_COMM_NULL;
ivec loc_c;
- gmx_bool bPartOfGroup = FALSE;
+ bool bPartOfGroup = false;
- dim = dd->dim[dim_ind];
+ const int dim = dd->dim[dim_ind];
copy_ivec(loc, loc_c);
- for (i = 0; i < dd->numCells[dim]; i++)
+ for (int i = 0; i < dd->numCells[dim]; i++)
{
- loc_c[dim] = i;
- rank = dd_index(dd->numCells, loc_c);
+ loc_c[dim] = i;
+ const int rank = dd_index(dd->numCells, loc_c);
if (rank == dd->rank)
{
/* This process is part of the group */
void dd_setup_dlb_resource_sharing(const t_commrec* cr, int gpu_id)
{
#if GMX_MPI
- int physicalnode_id_hash;
- gmx_domdec_t* dd;
- MPI_Comm mpi_comm_pp_physicalnode;
+ MPI_Comm mpi_comm_pp_physicalnode = MPI_COMM_NULL;
if (!thisRankHasDuty(cr, DUTY_PP) || gpu_id < 0)
{
return;
}
- physicalnode_id_hash = gmx_physicalnode_id_hash();
+ const int physicalnode_id_hash = gmx_physicalnode_id_hash();
- dd = cr->dd;
+ gmx_domdec_t* dd = cr->dd;
if (debug)
{
fprintf(debug, "dd_setup_dd_dlb_gpu_sharing:\n");
- fprintf(debug, "DD PP rank %d physical node hash %d gpu_id %d\n", dd->rank,
- physicalnode_id_hash, gpu_id);
+ fprintf(debug, "DD PP rank %d physical node hash %d gpu_id %d\n", dd->rank, physicalnode_id_hash, gpu_id);
}
/* Split the PP communicator over the physical nodes */
/* TODO: See if we should store this (before), as it's also used for
static void make_load_communicators(gmx_domdec_t gmx_unused* dd)
{
#if GMX_MPI
- int dim0, dim1, i, j;
ivec loc;
if (debug)
make_load_communicator(dd, 0, loc);
if (dd->ndim > 1)
{
- dim0 = dd->dim[0];
- for (i = 0; i < dd->numCells[dim0]; i++)
+ const int dim0 = dd->dim[0];
+ for (int i = 0; i < dd->numCells[dim0]; i++)
{
loc[dim0] = i;
make_load_communicator(dd, 1, loc);
}
if (dd->ndim > 2)
{
- dim0 = dd->dim[0];
- for (i = 0; i < dd->numCells[dim0]; i++)
+ const int dim0 = dd->dim[0];
+ for (int i = 0; i < dd->numCells[dim0]; i++)
{
- loc[dim0] = i;
- dim1 = dd->dim[1];
- for (j = 0; j < dd->numCells[dim1]; j++)
+ loc[dim0] = i;
+ const int dim1 = dd->dim[1];
+ for (int j = 0; j < dd->numCells[dim1]; j++)
{
loc[dim1] = j;
make_load_communicator(dd, 2, loc);
/*! \brief Sets up the relation between neighboring domains and zones */
static void setup_neighbor_relations(gmx_domdec_t* dd)
{
- int d, dim, m;
- ivec tmp, s;
- gmx_domdec_zones_t* zones;
+ ivec tmp, s;
GMX_ASSERT((dd->ndim >= 0) && (dd->ndim <= DIM), "Must have valid number of dimensions for DD");
- for (d = 0; d < dd->ndim; d++)
+ for (int d = 0; d < dd->ndim; d++)
{
- dim = dd->dim[d];
+ const int dim = dd->dim[d];
copy_ivec(dd->ci, tmp);
tmp[dim] = (tmp[dim] + 1) % dd->numCells[dim];
dd->neighbor[d][0] = ddcoord2ddnodeid(dd, tmp);
dd->neighbor[d][1] = ddcoord2ddnodeid(dd, tmp);
if (debug)
{
- fprintf(debug, "DD rank %d neighbor ranks in dir %d are + %d - %d\n", dd->rank, dim,
- dd->neighbor[d][0], dd->neighbor[d][1]);
+ fprintf(debug,
+ "DD rank %d neighbor ranks in dir %d are + %d - %d\n",
+ dd->rank,
+ dim,
+ dd->neighbor[d][0],
+ dd->neighbor[d][1]);
}
}
int nizone = (1 << std::max(dd->ndim - 1, 0));
assert(nizone >= 1 && nizone <= DD_MAXIZONE);
- zones = &dd->comm->zones;
+ gmx_domdec_zones_t* zones = &dd->comm->zones;
for (int i = 0; i < nzone; i++)
{
- m = 0;
+ int m = 0;
clear_ivec(zones->shift[i]);
- for (d = 0; d < dd->ndim; d++)
+ for (int d = 0; d < dd->ndim; d++)
{
zones->shift[i][dd->dim[d]] = dd_zo[i][m++];
}
zones->n = nzone;
for (int i = 0; i < nzone; i++)
{
- for (d = 0; d < DIM; d++)
+ for (int d = 0; d < DIM; d++)
{
s[d] = dd->ci[d] - zones->shift[i][d];
if (s[d] < 0)
*/
iZone.jZoneRange = gmx::Range<int>(std::min(ddNonbondedZonePairRanges[iZoneIndex][1], nzone),
std::min(ddNonbondedZonePairRanges[iZoneIndex][2], nzone));
- for (dim = 0; dim < DIM; dim++)
+ for (int dim = 0; dim < DIM; dim++)
{
if (dd->numCells[dim] == 1)
{
/* Set up cartesian communication for the particle-particle part */
GMX_LOG(mdlog.info)
.appendTextFormatted("Will use a Cartesian communicator: %d x %d x %d",
- dd->numCells[XX], dd->numCells[YY], dd->numCells[ZZ]);
+ dd->numCells[XX],
+ dd->numCells[YY],
+ dd->numCells[ZZ]);
ivec periods;
for (int i = 0; i < DIM; i++)
{
periods[i] = TRUE;
}
- MPI_Comm comm_cart;
- MPI_Cart_create(cr->mpi_comm_mygroup, DIM, dd->numCells, periods, static_cast<int>(reorder),
- &comm_cart);
+ MPI_Comm comm_cart = MPI_COMM_NULL;
+ MPI_Cart_create(cr->mpi_comm_mygroup, DIM, dd->numCells, periods, static_cast<int>(reorder), &comm_cart);
/* We overwrite the old communicator with the new cartesian one */
cr->mpi_comm_mygroup = comm_cart;
}
/* Get the rank of the DD master,
* above we made sure that the master node is a PP node.
*/
- int rank;
- if (MASTER(cr))
- {
- rank = dd->rank;
- }
- else
- {
- rank = 0;
- }
+ int rank = MASTER(cr) ? dd->rank : 0;
MPI_Allreduce(&rank, &dd->masterrank, 1, MPI_INT, MPI_SUM, dd->mpi_comm_all);
}
else if (cartSetup.bCartesianPP)
buf[dd_index(dd->numCells, dd->ci)] = cr->sim_nodeid;
}
/* Communicate the ddindex to simulation nodeid index */
- MPI_Allreduce(buf.data(), cartSetup.ddindex2simnodeid.data(), dd->nnodes, MPI_INT, MPI_SUM,
- cr->mpi_comm_mysim);
+ MPI_Allreduce(buf.data(), cartSetup.ddindex2simnodeid.data(), dd->nnodes, MPI_INT, MPI_SUM, cr->mpi_comm_mysim);
/* Determine the master coordinates and rank.
* The DD master should be the same node as the master of this sim.
#endif
GMX_LOG(mdlog.info)
- .appendTextFormatted("Domain decomposition rank %d, coordinates %d %d %d\n", dd->rank,
- dd->ci[XX], dd->ci[YY], dd->ci[ZZ]);
+ .appendTextFormatted("Domain decomposition rank %d, coordinates %d %d %d\n",
+ dd->rank,
+ dd->ci[XX],
+ dd->ci[YY],
+ dd->ci[ZZ]);
if (debug)
{
- fprintf(debug, "Domain decomposition rank %d, coordinates %d %d %d\n\n", dd->rank,
- dd->ci[XX], dd->ci[YY], dd->ci[ZZ]);
+ fprintf(debug,
+ "Domain decomposition rank %d, coordinates %d %d %d\n\n",
+ dd->rank,
+ dd->ci[XX],
+ dd->ci[YY],
+ dd->ci[ZZ]);
}
}
buf[dd_index(dd->numCells, dd->ci)] = cr->sim_nodeid;
}
/* Communicate the ddindex to simulation nodeid index */
- MPI_Allreduce(buf.data(), cartSetup.ddindex2simnodeid.data(), dd->nnodes, MPI_INT, MPI_SUM,
- cr->mpi_comm_mysim);
+ MPI_Allreduce(buf.data(), cartSetup.ddindex2simnodeid.data(), dd->nnodes, MPI_INT, MPI_SUM, cr->mpi_comm_mysim);
}
#else
GMX_UNUSED_VALUE(dd);
.appendTextFormatted(
"Number of PME-only ranks (%d) is not a multiple of nx*ny (%d*%d) or "
"nx*nz (%d*%d)",
- ddRankSetup.numRanksDoingPme, numDDCells[XX], numDDCells[YY],
- numDDCells[XX], numDDCells[ZZ]);
+ ddRankSetup.numRanksDoingPme,
+ numDDCells[XX],
+ numDDCells[YY],
+ numDDCells[XX],
+ numDDCells[ZZ]);
GMX_LOG(mdlog.info)
.appendText("Will not use a Cartesian communicator for PP <-> PME\n");
}
if (cartSetup.bCartesianPP_PME)
{
#if GMX_MPI
- int rank;
+ int rank = 0;
ivec periods;
GMX_LOG(mdlog.info)
.appendTextFormatted(
"Will use a Cartesian communicator for PP <-> PME: %d x %d x %d",
- cartSetup.ntot[XX], cartSetup.ntot[YY], cartSetup.ntot[ZZ]);
+ cartSetup.ntot[XX],
+ cartSetup.ntot[YY],
+ cartSetup.ntot[ZZ]);
for (int i = 0; i < DIM; i++)
{
periods[i] = TRUE;
}
- MPI_Comm comm_cart;
- MPI_Cart_create(cr->mpi_comm_mysim, DIM, cartSetup.ntot, periods, static_cast<int>(reorder),
- &comm_cart);
+ MPI_Comm comm_cart = MPI_COMM_NULL;
+ MPI_Cart_create(cr->mpi_comm_mysim, DIM, cartSetup.ntot, periods, static_cast<int>(reorder), &comm_cart);
MPI_Comm_rank(comm_cart, &rank);
if (MASTER(cr) && rank != 0)
{
MPI_Cart_coords(cr->mpi_comm_mysim, cr->sim_nodeid, DIM, ddCellIndex);
GMX_LOG(mdlog.info)
- .appendTextFormatted("Cartesian rank %d, coordinates %d %d %d\n", cr->sim_nodeid,
- ddCellIndex[XX], ddCellIndex[YY], ddCellIndex[ZZ]);
+ .appendTextFormatted("Cartesian rank %d, coordinates %d %d %d\n",
+ cr->sim_nodeid,
+ ddCellIndex[XX],
+ ddCellIndex[YY],
+ ddCellIndex[ZZ]);
if (ddCellIndex[cartSetup.cartpmedim] < numDDCells[cartSetup.cartpmedim])
{
}
/* Split the sim communicator into PP and PME only nodes */
- MPI_Comm_split(cr->mpi_comm_mysim, getThisRankDuties(cr),
- dd_index(cartSetup.ntot, ddCellIndex), &cr->mpi_comm_mygroup);
+ MPI_Comm_split(cr->mpi_comm_mysim,
+ getThisRankDuties(cr),
+ dd_index(cartSetup.ntot, ddCellIndex),
+ &cr->mpi_comm_mygroup);
#else
GMX_UNUSED_VALUE(ddCellIndex);
#endif
if (ddRankSetup.usePmeOnlyRanks)
{
/* Split the communicator into a PP and PME part */
- cartSetup = split_communicator(mdlog, cr, ddRankOrder, ddSettings.useCartesianReorder,
- ddRankSetup, ddCellIndex, pmeRanks);
+ cartSetup = split_communicator(
+ mdlog, cr, ddRankOrder, ddSettings.useCartesianReorder, ddRankSetup, ddCellIndex, pmeRanks);
}
else
{
dd->pme_receive_vir_ener = receive_vir_ener(dd, pmeRanks, cr);
if (debug)
{
- fprintf(debug, "My pme_nodeid %d receive ener %s\n", dd->pme_nodeid,
+ fprintf(debug,
+ "My pme_nodeid %d receive ener %s\n",
+ dd->pme_nodeid,
gmx::boolToString(dd->pme_receive_vir_ener));
}
}
static real* get_slb_frac(const gmx::MDLogger& mdlog, const char* dir, int nc, const char* size_string)
{
- real * slb_frac, tot;
- int i, n;
- double dbl;
-
- slb_frac = nullptr;
+ real* slb_frac = nullptr;
if (nc > 1 && size_string != nullptr)
{
GMX_LOG(mdlog.info).appendTextFormatted("Using static load balancing for the %s direction", dir);
snew(slb_frac, nc);
- tot = 0;
- for (i = 0; i < nc; i++)
+ real tot = 0;
+ for (int i = 0; i < nc; i++)
{
- dbl = 0;
+ double dbl = 0;
+ int n = 0;
sscanf(size_string, "%20lf%n", &dbl, &n);
if (dbl == 0)
{
gmx_fatal(FARGS,
"Incorrect or not enough DD cell size entries for direction %s: '%s'",
- dir, size_string);
+ dir,
+ size_string);
}
slb_frac[i] = dbl;
size_string += n;
}
/* Normalize */
std::string relativeCellSizes = "Relative cell sizes:";
- for (i = 0; i < nc; i++)
+ for (int i = 0; i < nc; i++)
{
slb_frac[i] /= tot;
relativeCellSizes += gmx::formatString(" %5.3f", slb_frac[i]);
{
int n = 0;
gmx_mtop_ilistloop_t iloop = gmx_mtop_ilistloop_init(mtop);
- int nmol;
+ int nmol = 0;
while (const InteractionLists* ilists = gmx_mtop_ilistloop_next(iloop, &nmol))
{
for (auto& ilist : extractILists(*ilists, IF_BOND))
static int dd_getenv(const gmx::MDLogger& mdlog, const char* env_var, int def)
{
- char* val;
- int nst;
-
- nst = def;
- val = getenv(env_var);
+ int nst = def;
+ char* val = getenv(env_var);
if (val)
{
if (sscanf(val, "%20d", &nst) <= 0)
if (ir->pbcType == PbcType::Screw
&& (dd->numCells[XX] == 1 || dd->numCells[YY] > 1 || dd->numCells[ZZ] > 1))
{
- gmx_fatal(FARGS, "With pbc=%s can only do domain decomposition in the x-direction",
+ gmx_fatal(FARGS,
+ "With pbc=%s can only do domain decomposition in the x-direction",
c_pbcTypeNames[ir->pbcType].c_str());
}
"ensured.",
mdlog);
default:
- gmx_fatal(FARGS, "Death horror: undefined case (%d) for load balancing choice",
+ gmx_fatal(FARGS,
+ "Death horror: undefined case (%d) for load balancing choice",
static_cast<int>(dlbState));
}
}
/* Returns whether mtop contains constraints and/or vsites */
static bool systemHasConstraintsOrVsites(const gmx_mtop_t& mtop)
{
- auto ilistLoop = gmx_mtop_ilistloop_init(mtop);
- int nmol;
+ auto* ilistLoop = gmx_mtop_ilistloop_init(mtop);
+ int nmol = 0;
while (const InteractionLists* ilists = gmx_mtop_ilistloop_next(ilistLoop, &nmol))
{
if (!extractILists(*ilists, IF_CONSTRAINT | IF_VSITE).empty())
.appendTextFormatted(
"Using update groups, nr %d, average size %.1f atoms, max. radius %.3f "
"nm\n",
- numUpdateGroups, mtop.natoms / static_cast<double>(numUpdateGroups),
+ numUpdateGroups,
+ mtop.natoms / static_cast<double>(numUpdateGroups),
systemInfo->maxUpdateGroupRadius);
}
else
}
else
{
- real r_2b, r_mb;
+ real r_2b = 0;
+ real r_mb = 0;
if (ddRole == DDRole::Master)
{
- dd_bonded_cg_distance(mdlog, &mtop, &ir, xGlobal, box,
- options.checkBondedInteractions, &r_2b, &r_mb);
+ dd_bonded_cg_distance(
+ mdlog, &mtop, &ir, xGlobal, box, options.checkBondedInteractions, &r_2b, &r_mb);
}
gmx_bcast(sizeof(r_2b), &r_2b, communicator);
gmx_bcast(sizeof(r_mb), &r_mb, communicator);
{
if (options.numCells[XX] <= 0 && (ddGridSetup.numDomains[XX] == 0))
{
- char buf[STRLEN];
- gmx_bool bC = (systemInfo.haveSplitConstraints
- && systemInfo.constraintCommunicationRange > systemInfo.minCutoffForMultiBody);
- sprintf(buf, "Change the number of ranks or mdrun option %s%s%s", !bC ? "-rdd" : "-rcon",
- ddSettings.initialDlbState != DlbState::offUser ? " or -dds" : "",
- bC ? " or your LINCS settings" : "");
-
- gmx_fatal_collective(FARGS, communicator, ddRole == DDRole::Master,
+ const bool bC = (systemInfo.haveSplitConstraints
+ && systemInfo.constraintCommunicationRange > systemInfo.minCutoffForMultiBody);
+ std::string message =
+ gmx::formatString("Change the number of ranks or mdrun option %s%s%s",
+ !bC ? "-rdd" : "-rcon",
+ ddSettings.initialDlbState != DlbState::offUser ? " or -dds" : "",
+ bC ? " or your LINCS settings" : "");
+
+ gmx_fatal_collective(FARGS,
+ communicator,
+ ddRole == DDRole::Master,
"There is no domain decomposition for %d ranks that is compatible "
"with the given box and a minimum cell size of %g nm\n"
"%s\n"
"Look in the log file for details on the domain decomposition",
- numNodes - ddGridSetup.numPmeOnlyRanks, cellsizeLimit, buf);
+ numNodes - ddGridSetup.numPmeOnlyRanks,
+ cellsizeLimit,
+ message.c_str());
}
const real acs = average_cellsize_min(ddbox, ddGridSetup.numDomains);
else
{
gmx_fatal_collective(
- FARGS, communicator, ddRole == DDRole::Master,
+ FARGS,
+ communicator,
+ ddRole == DDRole::Master,
"The initial cell size (%f) is smaller than the cell size limit (%f), change "
"options -dd, -rdd or -rcon, see the log file for details",
- acs, cellsizeLimit);
+ acs,
+ cellsizeLimit);
}
}
ddGridSetup.numDomains[XX] * ddGridSetup.numDomains[YY] * ddGridSetup.numDomains[ZZ];
if (numNodes - numPPRanks != ddGridSetup.numPmeOnlyRanks)
{
- gmx_fatal_collective(FARGS, communicator, ddRole == DDRole::Master,
+ gmx_fatal_collective(FARGS,
+ communicator,
+ ddRole == DDRole::Master,
"The size of the domain decomposition grid (%d) does not match the "
"number of PP ranks (%d). The total number of ranks is %d",
- numPPRanks, numNodes - ddGridSetup.numPmeOnlyRanks, numNodes);
+ numPPRanks,
+ numNodes - ddGridSetup.numPmeOnlyRanks,
+ numNodes);
}
if (ddGridSetup.numPmeOnlyRanks > numPPRanks)
{
- gmx_fatal_collective(FARGS, communicator, ddRole == DDRole::Master,
+ gmx_fatal_collective(FARGS,
+ communicator,
+ ddRole == DDRole::Master,
"The number of separate PME ranks (%d) is larger than the number of "
"PP ranks (%d), this is not supported.",
- ddGridSetup.numPmeOnlyRanks, numPPRanks);
+ ddGridSetup.numPmeOnlyRanks,
+ numPPRanks);
}
}
{
GMX_LOG(mdlog.info)
.appendTextFormatted("Domain decomposition grid %d x %d x %d, separate PME ranks %d",
- ddGridSetup.numDomains[XX], ddGridSetup.numDomains[YY],
- ddGridSetup.numDomains[ZZ], ddGridSetup.numPmeOnlyRanks);
+ ddGridSetup.numDomains[XX],
+ ddGridSetup.numDomains[YY],
+ ddGridSetup.numDomains[ZZ],
+ ddGridSetup.numPmeOnlyRanks);
DDRankSetup ddRankSetup;
}
GMX_LOG(mdlog.info)
.appendTextFormatted("PME domain decomposition: %d x %d x %d",
- ddRankSetup.npmenodes_x, ddRankSetup.npmenodes_y, 1);
+ ddRankSetup.npmenodes_x,
+ ddRankSetup.npmenodes_y,
+ 1);
}
else
{
*/
const int homeAtomCountEstimate = mtop->natoms / numPPRanks;
comm->updateGroupsCog = std::make_unique<gmx::UpdateGroupsCog>(
- *mtop, systemInfo.updateGroupingPerMoleculetype, maxReferenceTemperature(*ir),
- homeAtomCountEstimate);
+ *mtop, systemInfo.updateGroupingPerMoleculetype, maxReferenceTemperature(*ir), homeAtomCountEstimate);
}
/* Set the DD setup given by ddGridSetup */
fprintf(debug,
"Bonded atom communication beyond the cut-off: %s\n"
"cellsize limit %f\n",
- gmx::boolToString(systemInfo.filterBondedCommunication), comm->cellsize_limit);
+ gmx::boolToString(systemInfo.filterBondedCommunication),
+ comm->cellsize_limit);
}
if (ddRole == DDRole::Master)
gmx_bool bBCheck,
gmx::ArrayRef<cginfo_mb_t> cginfo_mb)
{
- gmx_domdec_comm_t* comm;
-
dd_make_reverse_top(fplog, dd, &mtop, vsite, ir, bBCheck);
- comm = dd->comm;
+ gmx_domdec_comm_t* comm = dd->comm;
if (comm->systemInfo.filterBondedCommunication)
{
real dlb_scale,
const gmx_ddbox_t* ddbox)
{
- gmx_domdec_comm_t* comm;
- int d;
- ivec np;
- real limit, shrink;
-
- comm = dd->comm;
+ gmx_domdec_comm_t* comm = dd->comm;
if (bDynLoadBal)
{
log->writeString("The maximum number of communication pulses is:");
- for (d = 0; d < dd->ndim; d++)
+ for (int d = 0; d < dd->ndim; d++)
{
log->writeStringFormatted(" %c %d", dim2char(dd->dim[d]), comm->cd[d].np_dlb);
}
comm->cellsize_limit);
log->writeLineFormatted("The requested allowed shrink of DD cells (option -dds) is: %.2f", dlb_scale);
log->writeString("The allowed shrink of domain decomposition cells is:");
- for (d = 0; d < DIM; d++)
+ for (int d = 0; d < DIM; d++)
{
if (dd->numCells[d] > 1)
{
- if (d >= ddbox->npbcdim && dd->numCells[d] == 2)
- {
- shrink = 0;
- }
- else
- {
- shrink = comm->cellsize_min_dlb[d]
- / (ddbox->box_size[d] * ddbox->skew_fac[d] / dd->numCells[d]);
- }
+ const real shrink =
+ (d >= ddbox->npbcdim && dd->numCells[d] == 2)
+ ? 0
+ : comm->cellsize_min_dlb[d]
+ / (ddbox->box_size[d] * ddbox->skew_fac[d] / dd->numCells[d]);
log->writeStringFormatted(" %c %.2f", dim2char(d), shrink);
}
}
}
else
{
+ ivec np;
set_dd_cell_sizes_slb(dd, ddbox, setcellsizeslbPULSE_ONLY, np);
log->writeString("The initial number of communication pulses is:");
- for (d = 0; d < dd->ndim; d++)
+ for (int d = 0; d < dd->ndim; d++)
{
log->writeStringFormatted(" %c %d", dim2char(dd->dim[d]), np[dd->dim[d]]);
}
log->ensureLineBreak();
log->writeString("The initial domain decomposition cell size is:");
- for (d = 0; d < DIM; d++)
+ for (int d = 0; d < DIM; d++)
{
if (dd->numCells[d] > 1)
{
log->writeLineFormatted("The maximum allowed distance for %s involved in interactions is:",
decompUnits.c_str());
- log->writeLineFormatted("%40s %-7s %6.3f nm", "non-bonded interactions", "",
- comm->systemInfo.cutoff);
+ log->writeLineFormatted(
+ "%40s %-7s %6.3f nm", "non-bonded interactions", "", comm->systemInfo.cutoff);
+ real limit = 0;
if (bDynLoadBal)
{
limit = dd->comm->cellsize_limit;
"deformation)");
}
limit = dd->comm->cellsize_min[XX];
- for (d = 1; d < DIM; d++)
+ for (int d = 1; d < DIM; d++)
{
limit = std::min(limit, dd->comm->cellsize_min[d]);
}
if (comm->systemInfo.haveInterDomainBondeds)
{
- log->writeLineFormatted("%40s %-7s %6.3f nm", "two-body bonded interactions", "(-rdd)",
+ log->writeLineFormatted("%40s %-7s %6.3f nm",
+ "two-body bonded interactions",
+ "(-rdd)",
std::max(comm->systemInfo.cutoff, comm->cutoff_mbody));
- log->writeLineFormatted("%40s %-7s %6.3f nm", "multi-body bonded interactions",
+ log->writeLineFormatted("%40s %-7s %6.3f nm",
+ "multi-body bonded interactions",
"(-rdd)",
(comm->systemInfo.filterBondedCommunication || isDlbOn(dd->comm))
? comm->cutoff_mbody
const t_inputrec* ir,
const gmx_ddbox_t* ddbox)
{
- gmx_domdec_comm_t* comm;
- int d, dim, npulse, npulse_d_max, npulse_d;
- gmx_bool bNoCutOff;
+ int npulse = 0;
+ int npulse_d_max = 0;
+ int npulse_d = 0;
- comm = dd->comm;
+ gmx_domdec_comm_t* comm = dd->comm;
- bNoCutOff = (ir->rvdw == 0 || ir->rcoulomb == 0);
+ bool bNoCutOff = (ir->rvdw == 0 || ir->rcoulomb == 0);
/* Determine the maximum number of comm. pulses in one dimension */
{
/* See if we can do with less pulses, based on dlb_scale */
npulse_d_max = 0;
- for (d = 0; d < dd->ndim; d++)
+ for (int d = 0; d < dd->ndim; d++)
{
- dim = dd->dim[d];
+ int dim = dd->dim[d];
npulse_d = static_cast<int>(
1
+ dd->numCells[dim] * comm->systemInfo.cutoff
}
/* This env var can override npulse */
- d = dd_getenv(mdlog, "GMX_DD_NPULSE", 0);
- if (d > 0)
+ const int ddPulseEnv = dd_getenv(mdlog, "GMX_DD_NPULSE", 0);
+ if (ddPulseEnv > 0)
{
- npulse = d;
+ npulse = ddPulseEnv;
}
comm->maxpulse = 1;
comm->bVacDLBNoLimit = (ir->pbcType == PbcType::No);
- for (d = 0; d < dd->ndim; d++)
+ for (int d = 0; d < dd->ndim; d++)
{
comm->cd[d].np_dlb = std::min(npulse, dd->numCells[dd->dim[d]] - 1);
comm->maxpulse = std::max(comm->maxpulse, comm->cd[d].np_dlb);
}
comm->cellsize_limit = std::max(comm->cellsize_limit, comm->cutoff_mbody);
/* Set the minimum cell size for each DD dimension */
- for (d = 0; d < dd->ndim; d++)
+ for (int d = 0; d < dd->ndim; d++)
{
if (comm->bVacDLBNoLimit || comm->cd[d].np_dlb * comm->cellsize_limit >= comm->systemInfo.cutoff)
{
ddRankSetup.numRanksDoingPme = 0;
if (dd->pme_nodeid >= 0)
{
- gmx_fatal_collective(FARGS, dd->mpi_comm_all, DDMASTER(dd),
+ gmx_fatal_collective(FARGS,
+ dd->mpi_comm_all,
+ DDMASTER(dd),
"Can not have separate PME ranks without PME electrostatics");
}
}
logSettings(mdlog, dd, mtop, ir, dlb_scale, ddbox);
- real vol_frac;
- if (ir->pbcType == PbcType::No)
- {
- vol_frac = 1 - 1 / static_cast<double>(dd->nnodes);
- }
- else
- {
- vol_frac = (1 + comm_box_frac(dd->numCells, comm->systemInfo.cutoff, *ddbox))
- / static_cast<double>(dd->nnodes);
- }
+ const real vol_frac = (ir->pbcType == PbcType::No)
+ ? (1 - 1 / static_cast<double>(dd->nnodes))
+ : ((1 + comm_box_frac(dd->numCells, comm->systemInfo.cutoff, *ddbox))
+ / static_cast<double>(dd->nnodes));
if (debug)
{
fprintf(debug, "Volume fraction for all DD zones: %f\n", vol_frac);
ddSettings.recordLoad = (wallcycle_have_counter() && recload > 0);
}
- ddSettings.initialDlbState = determineInitialDlbState(mdlog, options.dlbOption,
- ddSettings.recordLoad, mdrunOptions, &ir);
+ ddSettings.initialDlbState = determineInitialDlbState(
+ mdlog, options.dlbOption, ddSettings.recordLoad, mdrunOptions, &ir);
GMX_LOG(mdlog.info)
.appendTextFormatted("Dynamic load balancing: %s",
edlbs_names[static_cast<int>(ddSettings.initialDlbState)]);
srand(1 + cr_->rankInDefaultCommunicator);
}
- systemInfo_ = getSystemInfo(mdlog_, MASTER(cr_) ? DDRole::Master : DDRole::Agent,
- cr->mpiDefaultCommunicator, options_, mtop_, ir_, box, xGlobal);
+ systemInfo_ = getSystemInfo(mdlog_,
+ MASTER(cr_) ? DDRole::Master : DDRole::Agent,
+ cr->mpiDefaultCommunicator,
+ options_,
+ mtop_,
+ ir_,
+ box,
+ xGlobal);
const int numRanksRequested = cr_->sizeOfDefaultCommunicator;
const bool checkForLargePrimeFactors = (options_.numCells[0] <= 0);
- checkForValidRankCountRequests(numRanksRequested, EEL_PME(ir_.coulombtype),
- options_.numPmeRanks, checkForLargePrimeFactors);
+ checkForValidRankCountRequests(
+ numRanksRequested, EEL_PME(ir_.coulombtype), options_.numPmeRanks, checkForLargePrimeFactors);
// DD grid setup uses a more different cell size limit for
// automated setup than the one in systemInfo_. The latter is used
// in set_dd_limits() to configure DLB, for example.
const real gridSetupCellsizeLimit =
- getDDGridSetupCellSizeLimit(mdlog_, !isDlbDisabled(ddSettings_.initialDlbState),
- options_.dlbScaling, ir_, systemInfo_.cellsizeLimit);
- ddGridSetup_ =
- getDDGridSetup(mdlog_, MASTER(cr_) ? DDRole::Master : DDRole::Agent,
- cr->mpiDefaultCommunicator, numRanksRequested, options_, ddSettings_,
- systemInfo_, gridSetupCellsizeLimit, mtop_, ir_, box, xGlobal, &ddbox_);
- checkDDGridSetup(ddGridSetup_, MASTER(cr_) ? DDRole::Master : DDRole::Agent,
- cr->mpiDefaultCommunicator, cr->sizeOfDefaultCommunicator, options_,
- ddSettings_, systemInfo_, gridSetupCellsizeLimit, ddbox_);
+ getDDGridSetupCellSizeLimit(mdlog_,
+ !isDlbDisabled(ddSettings_.initialDlbState),
+ options_.dlbScaling,
+ ir_,
+ systemInfo_.cellsizeLimit);
+ ddGridSetup_ = getDDGridSetup(mdlog_,
+ MASTER(cr_) ? DDRole::Master : DDRole::Agent,
+ cr->mpiDefaultCommunicator,
+ numRanksRequested,
+ options_,
+ ddSettings_,
+ systemInfo_,
+ gridSetupCellsizeLimit,
+ mtop_,
+ ir_,
+ box,
+ xGlobal,
+ &ddbox_);
+ checkDDGridSetup(ddGridSetup_,
+ MASTER(cr_) ? DDRole::Master : DDRole::Agent,
+ cr->mpiDefaultCommunicator,
+ cr->sizeOfDefaultCommunicator,
+ options_,
+ ddSettings_,
+ systemInfo_,
+ gridSetupCellsizeLimit,
+ ddbox_);
cr_->npmenodes = ddGridSetup_.numPmeOnlyRanks;
ddRankSetup_ = getDDRankSetup(mdlog_, cr_->sizeOfDefaultCommunicator, ddGridSetup_, ir_);
/* Generate the group communicator, also decides the duty of each rank */
- cartSetup_ = makeGroupCommunicators(mdlog_, ddSettings_, options_.rankOrder, ddRankSetup_, cr_,
- ddCellIndex_, &pmeRanks_);
+ cartSetup_ = makeGroupCommunicators(
+ mdlog_, ddSettings_, options_.rankOrder, ddRankSetup_, cr_, ddCellIndex_, &pmeRanks_);
}
gmx_domdec_t* DomainDecompositionBuilder::Impl::build(LocalAtomSetManager* atomSets)
dd->comm->ddRankSetup = ddRankSetup_;
dd->comm->cartesianRankSetup = cartSetup_;
- set_dd_limits(mdlog_, MASTER(cr_) ? DDRole::Master : DDRole::Agent, dd, options_, ddSettings_,
- systemInfo_, ddGridSetup_, ddRankSetup_.numPPRanks, &mtop_, &ir_, ddbox_);
+ set_dd_limits(mdlog_,
+ MASTER(cr_) ? DDRole::Master : DDRole::Agent,
+ dd,
+ options_,
+ ddSettings_,
+ systemInfo_,
+ ddGridSetup_,
+ ddRankSetup_.numPPRanks,
+ &mtop_,
+ &ir_,
+ ddbox_);
setupGroupCommunication(mdlog_, ddSettings_, pmeRanks_, cr_, mtop_.natoms, dd);
}
/* Set overallocation to avoid frequent reallocation of arrays */
- set_over_alloc_dd(TRUE);
+ set_over_alloc_dd(true);
dd->atomSets = atomSets;
static gmx_bool test_dd_cutoff(const t_commrec* cr, const matrix box, gmx::ArrayRef<const gmx::RVec> x, real cutoffRequested)
{
gmx_ddbox_t ddbox;
- int d, dim, np;
- real inv_cell_size;
- int LocallyLimited;
+ int LocallyLimited = 0;
const auto* dd = cr->dd;
LocallyLimited = 0;
- for (d = 0; d < dd->ndim; d++)
+ for (int d = 0; d < dd->ndim; d++)
{
- dim = dd->dim[d];
+ const int dim = dd->dim[d];
- inv_cell_size = DD_CELL_MARGIN * dd->numCells[dim] / ddbox.box_size[dim];
+ real inv_cell_size = DD_CELL_MARGIN * dd->numCells[dim] / ddbox.box_size[dim];
if (dd->unitCellInfo.ddBoxIsDynamic)
{
inv_cell_size *= DD_PRES_SCALE_MARGIN;
}
- np = 1 + static_cast<int>(cutoffRequested * inv_cell_size * ddbox.skew_fac[dim]);
+ const int np = 1 + static_cast<int>(cutoffRequested * inv_cell_size * ddbox.skew_fac[dim]);
if (!isDlbDisabled(dd->comm) && (dim < ddbox.npbcdim) && (dd->comm->cd[d].np_dlb > 0))
{
gmx_bool change_dd_cutoff(t_commrec* cr, const matrix box, gmx::ArrayRef<const gmx::RVec> x, real cutoffRequested)
{
- gmx_bool bCutoffAllowed;
-
- bCutoffAllowed = test_dd_cutoff(cr, box, x, cutoffRequested);
+ bool bCutoffAllowed = test_dd_cutoff(cr, box, x, cutoffRequested);
if (bCutoffAllowed)
{
for (int pulse = cr.dd->gpuHaloExchange[d].size(); pulse < cr.dd->comm->cd[d].numPulses(); pulse++)
{
cr.dd->gpuHaloExchange[d].push_back(std::make_unique<gmx::GpuHaloExchange>(
- cr.dd, d, cr.mpi_comm_mysim, deviceStreamManager.context(),
+ cr.dd,
+ d,
+ cr.mpi_comm_mysim,
+ deviceStreamManager.context(),
deviceStreamManager.stream(gmx::DeviceStreamType::NonBondedLocal),
- deviceStreamManager.stream(gmx::DeviceStreamType::NonBondedNonLocal), pulse, wcycle));
+ deviceStreamManager.stream(gmx::DeviceStreamType::NonBondedNonLocal),
+ pulse,
+ wcycle));
}
}
}
*
* Copyright (c) 2006,2007,2008,2009,2010 by the GROMACS development team.
* Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team.
- * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
{
if (dd->constraint_comm)
{
- dd_move_x_specat(dd, dd->constraint_comm, box, as_rvec_array(x0.data()),
- as_rvec_array(x1.data()), bX1IsCoord);
+ dd_move_x_specat(
+ dd, dd->constraint_comm, box, as_rvec_array(x0.data()), as_rvec_array(x1.data()), bX1IsCoord);
ddReopenBalanceRegionCpu(dd);
}
{
/* Walk further */
const int* iap = constr_iatomptr(ia1, ia2, coni);
- int b;
- if (a == iap[1])
- {
- b = iap[2];
- }
- else
- {
- b = iap[1];
- }
+ const int b = (a == iap[1]) ? iap[2] : iap[1];
if (!ga2la.findHome(offset + b))
{
- walk_out(coni, con_offset, b, offset, nrec - 1, ia1, ia2, at2con, ga2la, FALSE,
- dc, dcc, il_local, ireq);
+ walk_out(coni, con_offset, b, offset, nrec - 1, ia1, ia2, at2con, ga2la, FALSE, dc, dcc, il_local, ireq);
}
}
}
{
if (GET_CGINFO_SETTLE(cginfo[a]))
{
- int a_gl = dd->globalAtomIndices[a];
- int a_mol;
+ int a_gl = dd->globalAtomIndices[a];
+ int a_mol = 0;
mtopGetMolblockIndex(mtop, a_gl, &mb, nullptr, &a_mol);
const gmx_molblock_t* molb = &mtop->molblock[mb];
{
if (GET_CGINFO_CONSTR(cginfo[a]))
{
- int a_gl = dd->globalAtomIndices[a];
- int molnr, a_mol;
+ int a_gl = dd->globalAtomIndices[a];
+ int molnr = 0;
+ int a_mol = 0;
mtopGetMolblockIndex(mtop, a_gl, &mb, &molnr, &a_mol);
const gmx_molblock_t& molb = mtop->molblock[mb];
const auto& at2con = at2con_mt[molb.type];
for (const int con : at2con[a_mol])
{
- const int* iap = constr_iatomptr(ia1, ia2, con);
- int b_mol;
+ const int* iap = constr_iatomptr(ia1, ia2, con);
+ int b_mol = 0;
if (a_mol == iap[1])
{
b_mol = iap[2];
* Therefore we call walk_out with nrec recursions to go
* after this first call.
*/
- walk_out(con, con_offset, b_mol, offset, nrec, ia1, ia2, at2con, ga2la, TRUE,
- dc, dcc, ilc_local, ireq);
+ walk_out(con, con_offset, b_mol, offset, nrec, ia1, ia2, at2con, ga2la, TRUE, dc, dcc, ilc_local, ireq);
}
}
}
if (debug)
{
- fprintf(debug, "Constraints: home %3d border %3d atoms: %3zu\n", nhome, dc->ncon - nhome,
+ fprintf(debug,
+ "Constraints: home %3d border %3d atoms: %3zu\n",
+ nhome,
+ dc->ncon - nhome,
dd->constraint_comm ? ireq->size() : 0);
}
}
int nrec,
gmx::ArrayRef<InteractionList> il_local)
{
- gmx_domdec_constraints_t* dc;
- InteractionList * ilc_local, *ils_local;
- gmx::HashedMap<int>* ga2la_specat;
- int at_end, i, j;
-
// This code should not be called unless this condition is true,
// because that's the only time init_domdec_constraints is
// called...
// true. dd->constraint_comm is unilaterally dereferenced before
// the call to atoms_to_settles.
- dc = dd->constraints;
+ gmx_domdec_constraints_t* dc = dd->constraints;
- ilc_local = &il_local[F_CONSTR];
- ils_local = &il_local[F_SETTLE];
+ InteractionList* ilc_local = &il_local[F_CONSTR];
+ InteractionList* ils_local = &il_local[F_SETTLE];
dc->ncon = 0;
gmx::ArrayRef<const ListOfLists<int>> at2con_mt;
}
else
{
- int t0_set;
-
/* Do the constraints, if present, on the first thread.
* Do the settles on all other threads.
*/
- t0_set = ((!at2con_mt.empty() && dc->nthread > 1) ? 1 : 0);
+ const int t0_set = ((!at2con_mt.empty() && dc->nthread > 1) ? 1 : 0);
#pragma omp parallel for num_threads(dc->nthread) schedule(static)
for (int thread = 0; thread < dc->nthread; thread++)
if (thread >= t0_set)
{
- int cg0, cg1;
- InteractionList* ilst;
-
/* Distribute the settle check+assignments over
* dc->nthread or dc->nthread-1 threads.
*/
- cg0 = (dd->ncg_home * (thread - t0_set)) / (dc->nthread - t0_set);
- cg1 = (dd->ncg_home * (thread - t0_set + 1)) / (dc->nthread - t0_set);
+ const int cg0 = (dd->ncg_home * (thread - t0_set)) / (dc->nthread - t0_set);
+ const int cg1 = (dd->ncg_home * (thread - t0_set + 1)) / (dc->nthread - t0_set);
- if (thread == t0_set)
- {
- ilst = ils_local;
- }
- else
- {
- ilst = &dc->ils[thread];
- }
+ InteractionList* ilst = (thread == t0_set) ? ils_local : &dc->ils[thread];
ilst->clear();
std::vector<int>& ireqt = dc->requestedGlobalAtomIndices[thread];
}
}
+ int at_end = 0;
if (dd->constraint_comm)
{
- int nral1;
-
- at_end = setup_specat_communication(dd, ireq, dd->constraint_comm, dd->constraints->ga2la.get(),
- at_start, 2, "constraint", " or lincs-order");
+ at_end = setup_specat_communication(dd,
+ ireq,
+ dd->constraint_comm,
+ dd->constraints->ga2la.get(),
+ at_start,
+ 2,
+ "constraint",
+ " or lincs-order");
/* Fill in the missing indices */
- ga2la_specat = dd->constraints->ga2la.get();
+ gmx::HashedMap<int>* ga2la_specat = dd->constraints->ga2la.get();
- nral1 = 1 + NRAL(F_CONSTR);
- for (i = 0; i < ilc_local->size(); i += nral1)
+ int nral1 = 1 + NRAL(F_CONSTR);
+ for (int i = 0; i < ilc_local->size(); i += nral1)
{
int* iap = ilc_local->iatoms.data() + i;
- for (j = 1; j < nral1; j++)
+ for (int j = 1; j < nral1; j++)
{
if (iap[j] < 0)
{
}
nral1 = 1 + NRAL(F_SETTLE);
- for (i = 0; i < ils_local->size(); i += nral1)
+ for (int i = 0; i < ils_local->size(); i += nral1)
{
int* iap = ils_local->iatoms.data() + i;
- for (j = 1; j < nral1; j++)
+ for (int j = 1; j < nral1; j++)
{
if (iap[j] < 0)
{
void init_domdec_constraints(gmx_domdec_t* dd, const gmx_mtop_t* mtop)
{
- gmx_domdec_constraints_t* dc;
- const gmx_molblock_t* molb;
-
if (debug)
{
fprintf(debug, "Begin init_domdec_constraints\n");
}
- dd->constraints = new gmx_domdec_constraints_t;
- dc = dd->constraints;
+ dd->constraints = new gmx_domdec_constraints_t;
+ gmx_domdec_constraints_t* dc = dd->constraints;
dc->molb_con_offset.resize(mtop->molblock.size());
dc->molb_ncon_mol.resize(mtop->molblock.size());
int ncon = 0;
for (size_t mb = 0; mb < mtop->molblock.size(); mb++)
{
- molb = &mtop->molblock[mb];
- dc->molb_con_offset[mb] = ncon;
- dc->molb_ncon_mol[mb] = mtop->moltype[molb->type].ilist[F_CONSTR].size() / 3
+ const gmx_molblock_t* molb = &mtop->molblock[mb];
+ dc->molb_con_offset[mb] = ncon;
+ dc->molb_ncon_mol[mb] = mtop->moltype[molb->type].ilist[F_CONSTR].size() / 3
+ mtop->moltype[molb->type].ilist[F_CONSTRNC].size() / 3;
ncon += molb->nmol * dc->molb_ncon_mol[mb];
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2008-2019, by the GROMACS development team, led by
+ * Copyright (c) 2008-2019,2020,2021, 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.
MPI_Status mpiStatus;
if (numElementsToSend > 0 && numElementsToReceive > 0)
{
- MPI_Sendrecv(sendBuffer, numElementsToSend * sizeof(T), MPI_BYTE, sendRank, mpiTag,
- receiveBuffer, numElementsToReceive * sizeof(T), MPI_BYTE, receiveRank, mpiTag,
- dd->mpi_comm_all, &mpiStatus);
+ MPI_Sendrecv(sendBuffer,
+ numElementsToSend * sizeof(T),
+ MPI_BYTE,
+ sendRank,
+ mpiTag,
+ receiveBuffer,
+ numElementsToReceive * sizeof(T),
+ MPI_BYTE,
+ receiveRank,
+ mpiTag,
+ dd->mpi_comm_all,
+ &mpiStatus);
}
else if (numElementsToSend > 0)
{
}
else if (numElementsToReceive > 0)
{
- MPI_Recv(receiveBuffer, numElementsToReceive * sizeof(T), MPI_BYTE, receiveRank, mpiTag,
- dd->mpi_comm_all, &mpiStatus);
+ MPI_Recv(receiveBuffer, numElementsToReceive * sizeof(T), MPI_BYTE, receiveRank, mpiTag, dd->mpi_comm_all, &mpiStatus);
}
#else // GMX_MPI
GMX_UNUSED_VALUE(dd);
gmx::ArrayRef<T> sendBuffer,
gmx::ArrayRef<T> receiveBuffer)
{
- ddSendrecv(dd, ddDimensionIndex, direction, sendBuffer.data(), sendBuffer.size(),
- receiveBuffer.data(), receiveBuffer.size());
+ ddSendrecv(dd,
+ ddDimensionIndex,
+ direction,
+ sendBuffer.data(),
+ sendBuffer.size(),
+ receiveBuffer.data(),
+ receiveBuffer.size());
}
//! Specialization of extern template for int
int gmx_unused n_r_bw)
{
#if GMX_MPI
- int rank_fw, rank_bw, nreq;
MPI_Request req[4];
MPI_Status stat[4];
- rank_fw = dd->neighbor[ddimind][0];
- rank_bw = dd->neighbor[ddimind][1];
+ int rank_fw = dd->neighbor[ddimind][0];
+ int rank_bw = dd->neighbor[ddimind][1];
if (!dd->comm->ddSettings.useSendRecv2)
{
* are slower.
* SendRecv2 can be turned on with the env.var. GMX_DD_SENDRECV2
*/
- nreq = 0;
+ int nreq = 0;
if (n_r_fw)
{
- MPI_Irecv(buf_r_fw[0], n_r_fw * sizeof(rvec), MPI_BYTE, rank_bw, 0, dd->mpi_comm_all,
- &req[nreq++]);
+ MPI_Irecv(buf_r_fw[0], n_r_fw * sizeof(rvec), MPI_BYTE, rank_bw, 0, dd->mpi_comm_all, &req[nreq++]);
}
if (n_r_bw)
{
- MPI_Irecv(buf_r_bw[0], n_r_bw * sizeof(rvec), MPI_BYTE, rank_fw, 1, dd->mpi_comm_all,
- &req[nreq++]);
+ MPI_Irecv(buf_r_bw[0], n_r_bw * sizeof(rvec), MPI_BYTE, rank_fw, 1, dd->mpi_comm_all, &req[nreq++]);
}
if (n_s_fw)
{
- MPI_Isend(buf_s_fw[0], n_s_fw * sizeof(rvec), MPI_BYTE, rank_fw, 0, dd->mpi_comm_all,
- &req[nreq++]);
+ MPI_Isend(buf_s_fw[0], n_s_fw * sizeof(rvec), MPI_BYTE, rank_fw, 0, dd->mpi_comm_all, &req[nreq++]);
}
if (n_s_bw)
{
- MPI_Isend(buf_s_bw[0], n_s_bw * sizeof(rvec), MPI_BYTE, rank_bw, 1, dd->mpi_comm_all,
- &req[nreq++]);
+ MPI_Isend(buf_s_bw[0], n_s_bw * sizeof(rvec), MPI_BYTE, rank_bw, 1, dd->mpi_comm_all, &req[nreq++]);
}
if (nreq)
{
* with a single full-duplex network connection per machine.
*/
/* Forward */
- MPI_Sendrecv(buf_s_fw[0], n_s_fw * sizeof(rvec), MPI_BYTE, rank_fw, 0, buf_r_fw[0],
- n_r_fw * sizeof(rvec), MPI_BYTE, rank_bw, 0, dd->mpi_comm_all, &stat[0]);
+ MPI_Sendrecv(buf_s_fw[0],
+ n_s_fw * sizeof(rvec),
+ MPI_BYTE,
+ rank_fw,
+ 0,
+ buf_r_fw[0],
+ n_r_fw * sizeof(rvec),
+ MPI_BYTE,
+ rank_bw,
+ 0,
+ dd->mpi_comm_all,
+ &stat[0]);
/* Backward */
- MPI_Sendrecv(buf_s_bw[0], n_s_bw * sizeof(rvec), MPI_BYTE, rank_bw, 0, buf_r_bw[0],
- n_r_bw * sizeof(rvec), MPI_BYTE, rank_fw, 0, dd->mpi_comm_all, &stat[0]);
+ MPI_Sendrecv(buf_s_bw[0],
+ n_s_bw * sizeof(rvec),
+ MPI_BYTE,
+ rank_bw,
+ 0,
+ buf_r_bw[0],
+ n_r_bw * sizeof(rvec),
+ MPI_BYTE,
+ rank_fw,
+ 0,
+ dd->mpi_comm_all,
+ &stat[0]);
}
#endif
}
if (dd->nnodes > 1)
{
/* Some MPI implementions don't specify const */
- MPI_Scatter(const_cast<void*>(src), nbytes, MPI_BYTE, dest, nbytes, MPI_BYTE,
- DDMASTERRANK(dd), dd->mpi_comm_all);
+ MPI_Scatter(const_cast<void*>(src), nbytes, MPI_BYTE, dest, nbytes, MPI_BYTE, DDMASTERRANK(dd), dd->mpi_comm_all);
}
else
#endif
{
#if GMX_MPI
/* Some MPI implementions don't specify const */
- MPI_Gather(const_cast<void*>(src), nbytes, MPI_BYTE, dest, nbytes, MPI_BYTE, DDMASTERRANK(dd),
- dd->mpi_comm_all);
+ MPI_Gather(const_cast<void*>(src), nbytes, MPI_BYTE, dest, nbytes, MPI_BYTE, DDMASTERRANK(dd), dd->mpi_comm_all);
#endif
}
void* rbuf)
{
#if GMX_MPI
- int dum;
+ int dum = 0;
if (dd->nnodes > 1)
{
rbuf = &dum;
}
/* Some MPI implementions don't specify const */
- MPI_Scatterv(const_cast<void*>(sbuf), scounts, disps, MPI_BYTE, rbuf, rcount, MPI_BYTE,
- DDMASTERRANK(dd), dd->mpi_comm_all);
+ MPI_Scatterv(
+ const_cast<void*>(sbuf), scounts, disps, MPI_BYTE, rbuf, rcount, MPI_BYTE, DDMASTERRANK(dd), dd->mpi_comm_all);
}
else
#endif
void gmx_unused* rbuf)
{
#if GMX_MPI
- int dum;
+ int dum = 0;
if (scount == 0)
{
sbuf = &dum;
}
/* Some MPI implementions don't specify const */
- MPI_Gatherv(const_cast<void*>(sbuf), scount, MPI_BYTE, rbuf, rcounts, disps, MPI_BYTE,
- DDMASTERRANK(dd), dd->mpi_comm_all);
+ MPI_Gatherv(
+ const_cast<void*>(sbuf), scount, MPI_BYTE, rbuf, rcounts, disps, MPI_BYTE, DDMASTERRANK(dd), dd->mpi_comm_all);
#endif
}
*
* Copyright (c) 2008,2009,2010,2011,2012 by the GROMACS development team.
* Copyright (c) 2013,2014,2015,2017,2018 by the GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <cmath>
#include <cstdio>
+#include <numeric>
+
#include "gromacs/domdec/domdec.h"
#include "gromacs/domdec/domdec_struct.h"
#include "gromacs/domdec/options.h"
return div.back();
}
-/*! \brief Compute largest common divisor of \p n1 and \b n2 */
-static int lcd(int n1, int n2)
-{
- int d, i;
-
- d = 1;
- for (i = 2; (i <= n1 && i <= n2); i++)
- {
- if (n1 % i == 0 && n2 % i == 0)
- {
- d = i;
- }
- }
-
- return d;
-}
-
/*! \brief Returns TRUE when there are enough PME ranks for the ratio */
static gmx_bool fits_pme_ratio(int nrank_tot, int nrank_pme, float ratio)
{
* The factor of 2 allows for a maximum ratio of 2^2=4
* between nx_pme and ny_pme.
*/
- if (lcd(ntot - npme, npme) * 2 < npme_root2)
+ if (std::gcd(ntot - npme, npme) * 2 < npme_root2)
{
return FALSE;
}
const matrix box,
int nrank_tot)
{
- float ratio;
- int npme;
-
- ratio = pme_load_estimate(mtop, ir, box);
+ float ratio = pme_load_estimate(mtop, ir, box);
GMX_LOG(mdlog.info).appendTextFormatted("Guess for relative PME load: %.2f", ratio);
* We start with a minimum PME node fraction of 1/16
* and avoid ratios which lead to large prime factors in nnodes-npme.
*/
- npme = (nrank_tot + 15) / 16;
+ int npme = (nrank_tot + 15) / 16;
while (npme <= nrank_tot / 3)
{
if (nrank_tot % npme == 0)
"grid_y=%d).\n"
"Use the -npme option of mdrun or change the number of ranks or the PME grid "
"dimensions, see the manual for details.",
- ratio, gmx::roundToInt(0.95 * ratio * nrank_tot), nrank_tot / 2, ir.nkx, ir.nky);
+ ratio,
+ gmx::roundToInt(0.95 * ratio * nrank_tot),
+ nrank_tot / 2,
+ ir.nkx,
+ ir.nky);
}
else
{
.appendTextFormatted(
"Will use %d particle-particle and %d PME only ranks\n"
"This is a guess, check the performance at the end of the log file",
- nrank_tot - npme, npme);
+ nrank_tot - npme,
+ npme);
}
return npme;
real comm_box_frac(const gmx::IVec& dd_nc, real cutoff, const gmx_ddbox_t& ddbox)
{
- int i, j, k;
rvec nw;
- real comm_vol;
- for (i = 0; i < DIM; i++)
+ for (int i = 0; i < DIM; i++)
{
real bt = ddbox.box_size[i] * ddbox.skew_fac[i];
nw[i] = dd_nc[i] * cutoff / bt;
}
- comm_vol = 0;
- for (i = 0; i < DIM; i++)
+ real comm_vol = 0;
+ for (int i = 0; i < DIM; i++)
{
if (dd_nc[i] > 1)
{
comm_vol += nw[i];
- for (j = i + 1; j < DIM; j++)
+ for (int j = i + 1; j < DIM; j++)
{
if (dd_nc[j] > 1)
{
comm_vol += nw[i] * nw[j] * M_PI / 4;
- for (k = j + 1; k < DIM; k++)
+ for (int k = j + 1; k < DIM; k++)
{
if (dd_nc[k] > 1)
{
static float comm_pme_cost_vol(int npme, int a, int b, int c)
{
/* We use a float here, since an integer might overflow */
- float comm_vol;
-
- comm_vol = npme - 1;
+ float comm_vol = npme - 1;
comm_vol *= npme;
comm_vol *= div_up(a, npme);
comm_vol *= div_up(b, npme);
const gmx::IVec& nc)
{
gmx::IVec npme = { 1, 1, 1 };
- int i, j, nk, overlap;
rvec bt;
- float comm_vol, comm_vol_xf, comm_pme, cost_pbcdx;
/* This is the cost of a pbc_dx call relative to the cost
* of communicating the coordinate and force of an atom.
* This will be machine dependent.
*/
float pbcdx_rect_fac = 0.1;
float pbcdx_tric_fac = 0.2;
- float temp;
/* Check the DD algorithm restrictions */
if ((ir.pbcType == PbcType::XY && ir.nwall < 2 && nc[ZZ] > 1)
assert(ddbox.npbcdim <= DIM);
/* Check if the triclinic requirements are met */
- for (i = 0; i < DIM; i++)
+ for (int i = 0; i < DIM; i++)
{
- for (j = i + 1; j < ddbox.npbcdim; j++)
+ for (int j = i + 1; j < ddbox.npbcdim; j++)
{
- if (box[j][i] != 0 || ir.deform[j][i] != 0 || (ir.epc != epcNO && ir.compress[j][i] != 0))
+ if (box[j][i] != 0 || ir.deform[j][i] != 0
+ || (ir.epc != PressureCoupling::No && ir.compress[j][i] != 0))
{
if (nc[j] > 1 && nc[i] == 1)
{
}
}
- for (i = 0; i < DIM; i++)
+ for (int i = 0; i < DIM; i++)
{
bt[i] = ddbox.box_size[i] * ddbox.skew_fac[i];
*/
bool useThreads = true;
bool errorsAreFatal = false;
- if (!gmx_pme_check_restrictions(ir.pme_order, ir.nkx, ir.nky, ir.nkz, npme_x, useThreads,
- errorsAreFatal))
+ if (!gmx_pme_check_restrictions(
+ ir.pme_order, ir.nkx, ir.nky, ir.nkz, npme_x, useThreads, errorsAreFatal))
{
return -1;
}
* for the smallest index, so the decomposition does not
* depend sensitively on the rounding of the box elements.
*/
- for (i = 0; i < DIM; i++)
+ for (int i = 0; i < DIM; i++)
{
- for (j = i + 1; j < DIM; j++)
+ for (int j = i + 1; j < DIM; j++)
{
/* Check if the box size is nearly identical,
* in that case we prefer nx > ny and ny > nz.
* and the "back"-communication cost is identical to the forward cost.
*/
- comm_vol = comm_box_frac(nc, cutoff, ddbox);
+ float comm_vol = comm_box_frac(nc, cutoff, ddbox);
- comm_pme = 0;
- for (i = 0; i < 2; i++)
+ float comm_pme = 0;
+ for (int i = 0; i < 2; i++)
{
/* Determine the largest volume for PME x/f redistribution */
if (nc[i] % npme[i] != 0)
{
- if (nc[i] > npme[i])
- {
- comm_vol_xf = (npme[i] == 2 ? 1.0 / 3.0 : 0.5);
- }
- else
- {
- comm_vol_xf = 1.0 - lcd(nc[i], npme[i]) / static_cast<double>(npme[i]);
- }
+ float comm_vol_xf =
+ (nc[i] > npme[i]) ? (npme[i] == 2 ? 1.0 / 3.0 : 0.5)
+ : (1.0 - std::gcd(nc[i], npme[i]) / static_cast<double>(npme[i]));
comm_pme += 3 * natoms * comm_vol_xf;
}
/* Grid overlap communication */
if (npme[i] > 1)
{
- nk = (i == 0 ? ir.nkx : ir.nky);
- overlap = (nk % npme[i] == 0 ? ir.pme_order - 1 : ir.pme_order);
- temp = npme[i];
+ const int nk = (i == 0 ? ir.nkx : ir.nky);
+ const int overlap = (nk % npme[i] == 0 ? ir.pme_order - 1 : ir.pme_order);
+ float temp = npme[i];
temp *= overlap;
temp *= ir.nkx;
temp *= ir.nky;
comm_pme += comm_pme_cost_vol(npme[XX], ir.nkx, ir.nky, ir.nkz);
/* Add cost of pbc_dx for bondeds */
- cost_pbcdx = 0;
+ float cost_pbcdx = 0;
if ((nc[XX] == 1 || nc[YY] == 1) || (nc[ZZ] == 1 && ir.pbcType != PbcType::XY))
{
if ((ddbox.tric_dir[XX] && nc[XX] == 1) || (ddbox.tric_dir[YY] && nc[YY] == 1))
if (debug)
{
- fprintf(debug, "nc %2d %2d %2d %2d %2d vol pp %6.4f pbcdx %6.4f pme %9.3e tot %9.3e\n",
- nc[XX], nc[YY], nc[ZZ], npme[XX], npme[YY], comm_vol, cost_pbcdx,
- comm_pme / (3 * natoms), comm_vol + cost_pbcdx + comm_pme / (3 * natoms));
+ fprintf(debug,
+ "nc %2d %2d %2d %2d %2d vol pp %6.4f pbcdx %6.4f pme %9.3e tot %9.3e\n",
+ nc[XX],
+ nc[YY],
+ nc[ZZ],
+ npme[XX],
+ npme[YY],
+ comm_vol,
+ cost_pbcdx,
+ comm_pme / (3 * natoms),
+ comm_vol + cost_pbcdx + comm_pme / (3 * natoms));
}
return 3 * natoms * (comm_vol + cost_pbcdx) + comm_pme;
gmx::IVec* irTryPtr,
gmx::IVec* opt)
{
- int x, y, i;
- float ce;
gmx::IVec& ir_try = *irTryPtr;
if (ndiv == 0)
{
- ce = comm_cost_est(limit, cutoff, box, ddbox, natoms, ir, pbcdxr, npme, ir_try);
+ const float ce = comm_cost_est(limit, cutoff, box, ddbox, natoms, ir, pbcdxr, npme, ir_try);
if (ce >= 0
&& ((*opt)[XX] == 0
|| ce < comm_cost_est(limit, cutoff, box, ddbox, natoms, ir, pbcdxr, npme, *opt)))
return;
}
- for (x = mdiv[0]; x >= 0; x--)
+ for (int x = mdiv[0]; x >= 0; x--)
{
- for (i = 0; i < x; i++)
+ for (int i = 0; i < x; i++)
{
ir_try[XX] *= div[0];
}
- for (y = mdiv[0] - x; y >= 0; y--)
+ for (int y = mdiv[0] - x; y >= 0; y--)
{
- for (i = 0; i < y; i++)
+ for (int i = 0; i < y; i++)
{
ir_try[YY] *= div[0];
}
- for (i = 0; i < mdiv[0] - x - y; i++)
+ for (int i = 0; i < mdiv[0] - x - y; i++)
{
ir_try[ZZ] *= div[0];
}
/* recurse */
- assign_factors(limit, cutoff, box, ddbox, natoms, ir, pbcdxr, npme, ndiv - 1, div + 1,
- mdiv + 1, irTryPtr, opt);
+ assign_factors(
+ limit, cutoff, box, ddbox, natoms, ir, pbcdxr, npme, ndiv - 1, div + 1, mdiv + 1, irTryPtr, opt);
- for (i = 0; i < mdiv[0] - x - y; i++)
+ for (int i = 0; i < mdiv[0] - x - y; i++)
{
ir_try[ZZ] /= div[0];
}
- for (i = 0; i < y; i++)
+ for (int i = 0; i < y; i++)
{
ir_try[YY] /= div[0];
}
}
- for (i = 0; i < x; i++)
+ for (int i = 0; i < x; i++)
{
ir_try[XX] /= div[0];
}
const t_inputrec& ir,
const DDSystemInfo& systemInfo)
{
- double pbcdxr;
+ double pbcdxr = 0;
const int numPPRanks = numRanksRequested - numPmeOnlyRanks;
GMX_LOG(mdlog.info)
.appendTextFormatted(
"Optimizing the DD grid for %d cells with a minimum initial size of %.3f nm",
- numPPRanks, cellSizeLimit);
+ numPPRanks,
+ cellSizeLimit);
if (inhomogeneous_z(ir))
{
GMX_LOG(mdlog.info)
gmx::IVec itry = { 1, 1, 1 };
gmx::IVec numDomains = { 0, 0, 0 };
- assign_factors(cellSizeLimit, systemInfo.cutoff, box, ddbox, mtop.natoms, ir, pbcdxr,
- numRanksDoingPmeWork, div.size(), div.data(), mdiv.data(), &itry, &numDomains);
+ assign_factors(cellSizeLimit,
+ systemInfo.cutoff,
+ box,
+ ddbox,
+ mtop.natoms,
+ ir,
+ pbcdxr,
+ numRanksDoingPmeWork,
+ div.size(),
+ div.data(),
+ mdiv.data(),
+ &itry,
+ &numDomains);
return numDomains;
}
}
GMX_LOG(mdlog.info)
.appendTextFormatted(
- "Scaling the initial minimum size with 1/%g (option -dds) = %g", dlb_scale,
- 1 / dlb_scale);
+ "Scaling the initial minimum size with 1/%g (option -dds) = %g", dlb_scale, 1 / dlb_scale);
cellSizeLimit /= dlb_scale;
}
- else if (ir.epc != epcNO)
+ else if (ir.epc != PressureCoupling::No)
{
GMX_LOG(mdlog.info)
.appendTextFormatted(
gmx_fatal(FARGS,
"Cannot have %d separate PME ranks with only %d PP ranks, choose fewer or no "
"separate PME ranks",
- numPmeRanksRequested, numPPRanksRequested);
+ numPmeRanksRequested,
+ numPPRanksRequested);
}
}
"contains a large prime factor %d. In most cases this will lead to "
"bad performance. Choose a number with smaller prime factors or "
"set the decomposition (option -dd) manually.",
- numPPRanksRequested, largestDivisor);
+ numPPRanksRequested,
+ largestDivisor);
}
}
}
const matrix box,
const int numRanksRequested)
{
- int numPmeOnlyRanks;
- const char* extraMessage = "";
+ int numPmeOnlyRanks = 0;
+ const char* extraMessage = "";
if (options.numCells[XX] > 0)
{
if (ddRole == DDRole::Master)
{
- numDomains = optimizeDDCells(mdlog, numRanksRequested, numPmeOnlyRanks, cellSizeLimit,
- mtop, box, *ddbox, ir, systemInfo);
+ numDomains = optimizeDDCells(
+ mdlog, numRanksRequested, numPmeOnlyRanks, cellSizeLimit, mtop, box, *ddbox, ir, systemInfo);
}
}
*
* Copyright (c) 2006,2007,2008,2009,2010 by the GROMACS development team.
* Copyright (c) 2012,2013,2014,2015,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
void dd_move_f_specat(const gmx_domdec_t* dd, gmx_domdec_specat_comm_t* spac, rvec* f, rvec* fshift)
{
- gmx_specatsend_t* spas;
- rvec* vbuf;
- int n, n0, n1, dim, dir;
- ivec vis;
- int is;
- gmx_bool bPBC, bScrew;
+ ivec vis;
- n = spac->at_end;
+ int n = spac->at_end;
for (int d = dd->ndim - 1; d >= 0; d--)
{
- dim = dd->dim[d];
+ const int dim = dd->dim[d];
if (dd->numCells[dim] > 2)
{
/* Pulse the grid forward and backward */
- spas = spac->spas[d];
- n0 = spas[0].nrecv;
- n1 = spas[1].nrecv;
+ gmx_specatsend_t* spas = spac->spas[d];
+ int n0 = spas[0].nrecv;
+ int n1 = spas[1].nrecv;
n -= n1 + n0;
- vbuf = as_rvec_array(spac->vbuf.data());
+ rvec* vbuf = as_rvec_array(spac->vbuf.data());
/* Send and receive the coordinates */
- dd_sendrecv2_rvec(dd, d, f + n + n1, n0, vbuf, spas[0].a.size(), f + n, n1,
- vbuf + spas[0].a.size(), spas[1].a.size());
- for (dir = 0; dir < 2; dir++)
+ dd_sendrecv2_rvec(dd,
+ d,
+ f + n + n1,
+ n0,
+ vbuf,
+ spas[0].a.size(),
+ f + n,
+ n1,
+ vbuf + spas[0].a.size(),
+ spas[1].a.size());
+ for (int dir = 0; dir < 2; dir++)
{
- bPBC = ((dir == 0 && dd->ci[dim] == 0)
- || (dir == 1 && dd->ci[dim] == dd->numCells[dim] - 1));
- bScrew = (bPBC && dd->unitCellInfo.haveScrewPBC && dim == XX);
+ bool bPBC = ((dir == 0 && dd->ci[dim] == 0)
+ || (dir == 1 && dd->ci[dim] == dd->numCells[dim] - 1));
+ bool bScrew = (bPBC && dd->unitCellInfo.haveScrewPBC && dim == XX);
- spas = &spac->spas[d][dir];
+ gmx_specatsend_t* spas = &spac->spas[d][dir];
/* Sum the buffer into the required forces */
if (!bPBC || (!bScrew && fshift == nullptr))
{
{
clear_ivec(vis);
vis[dim] = (dir == 0 ? 1 : -1);
- is = IVEC2IS(vis);
+ int is = IVEC2IS(vis);
if (!bScrew)
{
/* Sum and add to shift forces */
else
{
/* Two cells, so we only need to communicate one way */
- spas = &spac->spas[d][0];
+ gmx_specatsend_t* spas = &spac->spas[d][0];
n -= spas->nrecv;
/* Send and receive the coordinates */
- ddSendrecv(dd, d, dddirForward, f + n, spas->nrecv, as_rvec_array(spac->vbuf.data()),
- spas->a.size());
+ ddSendrecv(dd, d, dddirForward, f + n, spas->nrecv, as_rvec_array(spac->vbuf.data()), spas->a.size());
/* Sum the buffer into the required forces */
if (dd->unitCellInfo.haveScrewPBC && dim == XX
&& (dd->ci[dim] == 0 || dd->ci[dim] == dd->numCells[dim] - 1))
rvec* x1,
gmx_bool bX1IsCoord)
{
- gmx_specatsend_t* spas;
- int nvec, v, n, nn, ns0, ns1, nr0, nr1, nr, d, dim, dir, i;
- gmx_bool bPBC, bScrew = FALSE;
- rvec shift = { 0, 0, 0 };
+ rvec shift = { 0, 0, 0 };
- nvec = 1;
+ int nvec = 1;
if (x1 != nullptr)
{
nvec++;
}
- n = spac->at_start;
- for (d = 0; d < dd->ndim; d++)
+ int n = spac->at_start;
+ for (int d = 0; d < dd->ndim; d++)
{
- dim = dd->dim[d];
+ int dim = dd->dim[d];
if (dd->numCells[dim] > 2)
{
/* Pulse the grid forward and backward */
rvec* vbuf = as_rvec_array(spac->vbuf.data());
- for (dir = 0; dir < 2; dir++)
+ for (int dir = 0; dir < 2; dir++)
{
+ bool bPBC = false;
+ bool bScrew = false;
if (dir == 0 && dd->ci[dim] == 0)
{
- bPBC = TRUE;
+ bPBC = true;
bScrew = (dd->unitCellInfo.haveScrewPBC && dim == XX);
copy_rvec(box[dim], shift);
}
else if (dir == 1 && dd->ci[dim] == dd->numCells[dim] - 1)
{
- bPBC = TRUE;
+ bPBC = true;
bScrew = (dd->unitCellInfo.haveScrewPBC && dim == XX);
- for (i = 0; i < DIM; i++)
+ for (int i = 0; i < DIM; i++)
{
shift[i] = -box[dim][i];
}
}
- else
- {
- bPBC = FALSE;
- bScrew = FALSE;
- }
- spas = &spac->spas[d][dir];
- for (v = 0; v < nvec; v++)
+ gmx_specatsend_t* spas = &spac->spas[d][dir];
+ for (int v = 0; v < nvec; v++)
{
rvec* x = (v == 0 ? x0 : x1);
/* Copy the required coordinates to the send buffer */
}
}
/* Send and receive the coordinates */
- spas = spac->spas[d];
- ns0 = spas[0].a.size();
- nr0 = spas[0].nrecv;
- ns1 = spas[1].a.size();
- nr1 = spas[1].nrecv;
+ gmx_specatsend_t* spas = spac->spas[d];
+ int ns0 = spas[0].a.size();
+ int nr0 = spas[0].nrecv;
+ int ns1 = spas[1].a.size();
+ int nr1 = spas[1].nrecv;
if (nvec == 1)
{
rvec* vbuf = as_rvec_array(spac->vbuf.data());
rvec* vbuf = as_rvec_array(spac->vbuf.data());
/* Communicate both vectors in one buffer */
rvec* rbuf = as_rvec_array(spac->vbuf2.data());
- dd_sendrecv2_rvec(dd, d, vbuf + 2 * ns0, 2 * ns1, rbuf, 2 * nr1, vbuf, 2 * ns0,
- rbuf + 2 * nr1, 2 * nr0);
+ dd_sendrecv2_rvec(
+ dd, d, vbuf + 2 * ns0, 2 * ns1, rbuf, 2 * nr1, vbuf, 2 * ns0, rbuf + 2 * nr1, 2 * nr0);
/* Split the buffer into the two vectors */
- nn = n;
- for (dir = 1; dir >= 0; dir--)
+ int nn = n;
+ for (int dir = 1; dir >= 0; dir--)
{
- nr = spas[dir].nrecv;
- for (v = 0; v < 2; v++)
+ int nr = spas[dir].nrecv;
+ for (int v = 0; v < 2; v++)
{
rvec* x = (v == 0 ? x0 : x1);
- for (i = 0; i < nr; i++)
+ for (int i = 0; i < nr; i++)
{
copy_rvec(*rbuf, x[nn + i]);
rbuf++;
}
else
{
- spas = &spac->spas[d][0];
+ gmx_specatsend_t* spas = &spac->spas[d][0];
/* Copy the required coordinates to the send buffer */
rvec* vbuf = as_rvec_array(spac->vbuf.data());
- for (v = 0; v < nvec; v++)
+ for (int v = 0; v < nvec; v++)
{
rvec* x = (v == 0 ? x0 : x1);
if (dd->unitCellInfo.haveScrewPBC && dim == XX
rvec* rbuf = as_rvec_array(spac->vbuf2.data());
ddSendrecv(dd, d, dddirBackward, vbuf, 2 * spas->a.size(), rbuf, 2 * spas->nrecv);
/* Split the buffer into the two vectors */
- nr = spas[0].nrecv;
- for (v = 0; v < 2; v++)
+ int nr = spas[0].nrecv;
+ for (int v = 0; v < 2; v++)
{
rvec* x = (v == 0 ? x0 : x1);
- for (i = 0; i < nr; i++)
+ for (int i = 0; i < nr; i++)
{
copy_rvec(*rbuf, x[n + i]);
rbuf++;
const char* specat_type,
const char* add_err)
{
- int nsend[2], nlast, nsend_zero[2] = { 0, 0 }, *nsend_ptr;
- int dim, ndir, nr, ns, nrecv_local, n0, start, buf[2];
- int nat_tot_specat, nat_tot_prev;
- gmx_bool bPBC;
- gmx_specatsend_t* spas;
+ int nsend[2], nsend_zero[2] = { 0, 0 };
+ int buf[2];
if (debug)
{
const int numRequested = ireq->size();
nsend[0] = ireq->size();
nsend[1] = nsend[0];
- nlast = nsend[1];
+ int nlast = nsend[1];
for (int d = dd->ndim - 1; d >= 0; d--)
{
/* Pulse the grid forward and backward */
- dim = dd->dim[d];
- bPBC = (dim < dd->unitCellInfo.npbcdim);
- if (dd->numCells[dim] == 2)
- {
- /* Only 2 cells, so we only need to communicate once */
- ndir = 1;
- }
- else
- {
- ndir = 2;
- }
+ int dim = dd->dim[d];
+ bool bPBC = (dim < dd->unitCellInfo.npbcdim);
+ const int ndir = (dd->numCells[dim] == 2)
+ ?
+ /* Only 2 cells, so we only need to communicate once */
+ 1
+ : 2;
+ int* nsend_ptr = nullptr;
for (int dir = 0; dir < ndir; dir++)
{
if (!bPBC && dd->numCells[dim] > 2
nsend_ptr = nsend;
}
/* Communicate the number of indices */
- ddSendrecv(dd, d, dir == 0 ? dddirForward : dddirBackward, nsend_ptr, 2,
- spac->nreq[d][dir], 2);
- nr = spac->nreq[d][dir][1];
+ ddSendrecv(dd, d, dir == 0 ? dddirForward : dddirBackward, nsend_ptr, 2, spac->nreq[d][dir], 2);
+ int nr = spac->nreq[d][dir][1];
ireq->resize(nlast + nr);
/* Communicate the indices */
- ddSendrecv(dd, d, dir == 0 ? dddirForward : dddirBackward, ireq->data(), nsend_ptr[1],
- ireq->data() + nlast, nr);
+ ddSendrecv(dd,
+ d,
+ dir == 0 ? dddirForward : dddirBackward,
+ ireq->data(),
+ nsend_ptr[1],
+ ireq->data() + nlast,
+ nr);
nlast += nr;
}
nsend[1] = nlast;
}
/* Search for the requested atoms and communicate the indices we have */
- nat_tot_specat = at_start;
- nrecv_local = 0;
+ int nat_tot_specat = at_start;
+ int nrecv_local = 0;
for (int d = 0; d < dd->ndim; d++)
{
/* Pulse the grid forward and backward */
- if (dd->dim[d] >= dd->unitCellInfo.npbcdim || dd->numCells[dd->dim[d]] > 2)
- {
- ndir = 2;
- }
- else
- {
- ndir = 1;
- }
- nat_tot_prev = nat_tot_specat;
+ const int ndir = (dd->dim[d] >= dd->unitCellInfo.npbcdim || dd->numCells[dd->dim[d]] > 2) ? 2 : 1;
+ int nat_tot_prev = nat_tot_specat;
for (int dir = ndir - 1; dir >= 0; dir--)
{
/* To avoid cost of clearing by resize(), we only increase size */
/* Note: resize initializes new elements to false, which is actually needed here */
spac->sendAtom.resize(nat_tot_specat);
}
- spas = &spac->spas[d][dir];
- n0 = spac->nreq[d][dir][0];
- nr = spac->nreq[d][dir][1];
+ gmx_specatsend_t* spas = &spac->spas[d][dir];
+ const int n0 = spac->nreq[d][dir][0];
+ const int nr = spac->nreq[d][dir][1];
if (debug)
{
fprintf(debug, "dim=%d, dir=%d, searching for %d atoms\n", d, dir, nr);
}
- start = nlast - nr;
+ const int start = nlast - nr;
spas->a.clear();
spac->ibuf.clear();
nsend[0] = 0;
for (int i = 0; i < nr; i++)
{
const int indr = (*ireq)[start + i];
- int ind;
+ int ind = 0;
/* Check if this is a home atom and if so ind will be set */
if (const int* homeIndex = dd->ga2la->findHome(indr))
{
fprintf(debug,
"Send to rank %d, %d (%d) indices, "
"receive from rank %d, %d (%d) indices\n",
- dd->neighbor[d][1 - dir], nsend[1], nsend[0], dd->neighbor[d][dir], buf[1],
+ dd->neighbor[d][1 - dir],
+ nsend[1],
+ nsend[0],
+ dd->neighbor[d][dir],
+ buf[1],
buf[0]);
if (gmx_debug_at)
{
spas->nrecv = buf[1];
dd->globalAtomIndices.resize(nat_tot_specat + spas->nrecv);
/* Send and receive the indices */
- ddSendrecv(dd, d, dir == 0 ? dddirBackward : dddirForward, spac->ibuf.data(),
- spac->ibuf.size(), dd->globalAtomIndices.data() + nat_tot_specat, spas->nrecv);
+ ddSendrecv(dd,
+ d,
+ dir == 0 ? dddirBackward : dddirForward,
+ spac->ibuf.data(),
+ spac->ibuf.size(),
+ dd->globalAtomIndices.data() + nat_tot_specat,
+ spas->nrecv);
nat_tot_specat += spas->nrecv;
}
/* Increase the x/f communication buffer sizes, when necessary */
- ns = spac->spas[d][0].a.size();
- nr = spac->spas[d][0].nrecv;
+ int ns = spac->spas[d][0].a.size();
+ int nr = spac->spas[d][0].nrecv;
if (ndir == 2)
{
ns += spac->spas[d][1].a.size();
{
if (debug)
{
- fprintf(debug, "Requested %d, received %d (tot recv %d)\n", numRequested, nrecv_local,
+ fprintf(debug,
+ "Requested %d, received %d (tot recv %d)\n",
+ numRequested,
+ nrecv_local,
nat_tot_specat - at_start);
if (gmx_debug_at)
{
fprintf(debug, "\n");
}
}
- fprintf(stderr, "\nDD cell %d %d %d: Neighboring cells do not have atoms:", dd->ci[XX],
- dd->ci[YY], dd->ci[ZZ]);
+ fprintf(stderr,
+ "\nDD cell %d %d %d: Neighboring cells do not have atoms:",
+ dd->ci[XX],
+ dd->ci[YY],
+ dd->ci[ZZ]);
for (int i = 0; i < numRequested; i++)
{
if (!ga2la_specat->find((*ireq)[i]))
"%ss from the neighboring cells. This probably means your %s lengths are too "
"long compared to the domain decomposition cell size. Decrease the number of "
"domain decomposition grid cells%s%s.",
- dd->ci[XX], dd->ci[YY], dd->ci[ZZ], nrecv_local, numRequested, specat_type,
- specat_type, add_err, dd_dlb_is_on(dd) ? " or use the -rcon option of mdrun" : "");
+ dd->ci[XX],
+ dd->ci[YY],
+ dd->ci[ZZ],
+ nrecv_local,
+ numRequested,
+ specat_type,
+ specat_type,
+ add_err,
+ dd_dlb_is_on(dd) ? " or use the -rcon option of mdrun" : "");
}
spac->at_start = at_start;
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2006 - 2014, The GROMACS development team.
- * Copyright (c) 2015,2016,2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,2017,2018,2019,2020,2021, 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.
/*! \brief Returns the number of atom entries for il in gmx_reverse_top_t */
static int nral_rt(int ftype)
{
- int nral;
-
- nral = NRAL(ftype);
+ int nral = NRAL(ftype);
if (interaction_function[ftype].flags & IF_VSITE)
{
/* With vsites the reverse topology contains an extra entry
{
if (dd_check_ftype(ftype, rt.bBCheck, rt.bConstr, rt.bSettle))
{
- flagInteractionsForType(ftype, idef.il[ftype], ril, atomRange, numAtomsPerMolecule,
- cr->dd->globalAtomIndices, isAssigned);
+ flagInteractionsForType(
+ ftype, idef.il[ftype], ril, atomRange, numAtomsPerMolecule, cr->dd->globalAtomIndices, isAssigned);
}
}
numMissingToPrint);
}
log.writeStringFormatted("%20s atoms", interaction_function[ftype].longname);
- int a;
- for (a = 0; a < nral; a++)
+ int a = 0;
+ for (; a < nral; a++)
{
log.writeStringFormatted("%5d", ril.il[j_mol + 2 + a] + 1);
}
a++;
}
log.writeString(" global");
- for (a = 0; a < nral; a++)
+ for (int a = 0; a < nral; a++)
{
- log.writeStringFormatted("%6d", atomRange.begin() + mol * numAtomsPerMolecule
- + ril.il[j_mol + 2 + a] + 1);
+ log.writeStringFormatted("%6d",
+ atomRange.begin() + mol * numAtomsPerMolecule
+ + ril.il[j_mol + 2 + a] + 1);
}
log.ensureLineBreak();
}
a_end = a_start + molb.nmol * moltype.atoms.nr;
const gmx::Range<int> atomRange(a_start, a_end);
- auto warning = printMissingInteractionsMolblock(cr, rt, *(moltype.name), rt.ril_mt[molb.type],
- atomRange, moltype.atoms.nr, molb.nmol, idef);
+ auto warning = printMissingInteractionsMolblock(
+ cr, rt, *(moltype.name), rt.ril_mt[molb.type], atomRange, moltype.atoms.nr, molb.nmol, idef);
GMX_LOG(mdlog.warning).appendText(warning);
}
gmx::ArrayRef<const gmx::RVec> x,
const matrix box)
{
- int ndiff_tot, cl[F_NRE], n, ndiff, rest_global, rest_local;
- int ftype, nral;
- gmx_domdec_t* dd;
-
- dd = cr->dd;
+ int cl[F_NRE];
+ gmx_domdec_t* dd = cr->dd;
GMX_LOG(mdlog.warning)
.appendText(
"Not all bonded interactions have been properly assigned to the domain "
"decomposition cells");
- ndiff_tot = local_count - dd->nbonded_global;
+ const int ndiff_tot = local_count - dd->nbonded_global;
- for (ftype = 0; ftype < F_NRE; ftype++)
+ for (int ftype = 0; ftype < F_NRE; ftype++)
{
- nral = NRAL(ftype);
- cl[ftype] = top_local->idef.il[ftype].size() / (1 + nral);
+ const int nral = NRAL(ftype);
+ cl[ftype] = top_local->idef.il[ftype].size() / (1 + nral);
}
gmx_sumi(F_NRE, cl, cr);
if (DDMASTER(dd))
{
GMX_LOG(mdlog.warning).appendText("A list of missing interactions:");
- rest_global = dd->nbonded_global;
- rest_local = local_count;
- for (ftype = 0; ftype < F_NRE; ftype++)
+ int rest_global = dd->nbonded_global;
+ int rest_local = local_count;
+ for (int ftype = 0; ftype < F_NRE; ftype++)
{
/* In the reverse and local top all constraints are merged
* into F_CONSTR. So in the if statement we skip F_CONSTRNC
|| (dd->reverse_top->bConstr && ftype == F_CONSTR)
|| (dd->reverse_top->bSettle && ftype == F_SETTLE))
{
- n = gmx_mtop_ftype_count(top_global, ftype);
+ int n = gmx_mtop_ftype_count(top_global, ftype);
if (ftype == F_CONSTR)
{
n += gmx_mtop_ftype_count(top_global, F_CONSTRNC);
}
- ndiff = cl[ftype] - n;
+ int ndiff = cl[ftype] - n;
if (ndiff != 0)
{
GMX_LOG(mdlog.warning)
.appendTextFormatted("%20s of %6d missing %6d",
- interaction_function[ftype].longname, n, -ndiff);
+ interaction_function[ftype].longname,
+ n,
+ -ndiff);
}
rest_global -= n;
rest_local -= cl[ftype];
}
}
- ndiff = rest_local - rest_global;
+ int ndiff = rest_local - rest_global;
if (ndiff != 0)
{
GMX_LOG(mdlog.warning).appendTextFormatted("%20s of %6d missing %6d", "exclusions", rest_global, -ndiff);
"involved moved further apart than the multi-body cut-off distance (%g nm) or the "
"two-body cut-off distance (%g nm), see option -rdd, for pairs and tabulated bonds "
"also see option -ddcheck",
- -ndiff_tot, cr->dd->nbonded_global, dd_cutoff_multibody(dd), dd_cutoff_twobody(dd));
+ -ndiff_tot,
+ cr->dd->nbonded_global,
+ dd_cutoff_multibody(dd),
+ dd_cutoff_twobody(dd));
}
gmx_fatal_collective(FARGS, cr->mpi_comm_mygroup, MASTER(cr), "%s", errorMessage.c_str());
}
const MolblockIndices* mbi = rt->mbi.data();
int start = 0;
int end = rt->mbi.size(); /* exclusive */
- int mid;
+ int mid = 0;
/* binary search for molblock_ind */
while (TRUE)
gmx_bool bLinkToAllAtoms,
gmx_bool bAssign)
{
- int ftype, j, nlink, link;
- int a;
- int nint;
+ int nint = 0;
- nint = 0;
- for (ftype = 0; ftype < F_NRE; ftype++)
+ for (int ftype = 0; ftype < F_NRE; ftype++)
{
if ((interaction_function[ftype].flags & (IF_BOND | IF_VSITE))
|| (bConstr && (ftype == F_CONSTR || ftype == F_CONSTRNC)) || (bSettle && ftype == F_SETTLE))
const auto& il = il_mt[ftype];
for (int i = 0; i < il.size(); i += 1 + nral)
{
- const int* ia = il.iatoms.data() + i;
- if (bLinkToAllAtoms)
+ const int* ia = il.iatoms.data() + i;
+ const int nlink = bLinkToAllAtoms ? bVSite ? 0 : nral : 1;
+ for (int link = 0; link < nlink; link++)
{
- if (bVSite)
- {
- /* We don't need the virtual sites for the cg-links */
- nlink = 0;
- }
- else
- {
- nlink = nral;
- }
- }
- else
- {
- /* Couple to the first atom in the interaction */
- nlink = 1;
- }
- for (link = 0; link < nlink; link++)
- {
- a = ia[1 + link];
+ const int a = ia[1 + link];
if (bAssign)
{
GMX_ASSERT(!r_il.empty(), "with bAssign not allowed to be empty");
GMX_ASSERT(!r_index.empty(), "with bAssign not allowed to be empty");
r_il[r_index[a] + count[a]] = (ftype == F_CONSTRNC ? F_CONSTR : ftype);
r_il[r_index[a] + count[a] + 1] = ia[0];
- for (j = 1; j < 1 + nral; j++)
+ for (int j = 1; j < 1 + nral; j++)
{
/* Store the molecular atom number */
r_il[r_index[a] + count[a] + 1 + j] = ia[j];
* vsites again.
*/
r_il[r_index[a] + count[a] + 2 + nral] = 0;
- for (j = 2; j < 1 + nral; j++)
+ for (int j = 2; j < 1 + nral; j++)
{
if (atom[ia[j]].ptype == eptVSite)
{
gmx_bool bLinkToAllAtoms,
reverse_ilist_t* ril_mt)
{
- int nat_mt, *count, i, nint_mt;
-
/* Count the interactions */
- nat_mt = atoms->nr;
- snew(count, nat_mt);
- low_make_reverse_ilist(ilist, atoms->atom, count, bConstr, bSettle, bBCheck, {}, {},
- bLinkToAllAtoms, FALSE);
+ const int nat_mt = atoms->nr;
+ std::vector<int> count(nat_mt);
+ low_make_reverse_ilist(
+ ilist, atoms->atom, count.data(), bConstr, bSettle, bBCheck, {}, {}, bLinkToAllAtoms, FALSE);
ril_mt->index.push_back(0);
- for (i = 0; i < nat_mt; i++)
+ for (int i = 0; i < nat_mt; i++)
{
ril_mt->index.push_back(ril_mt->index[i] + count[i]);
count[i] = 0;
ril_mt->il.resize(ril_mt->index[nat_mt]);
/* Store the interactions */
- nint_mt = low_make_reverse_ilist(ilist, atoms->atom, count, bConstr, bSettle, bBCheck,
- ril_mt->index, ril_mt->il, bLinkToAllAtoms, TRUE);
-
- sfree(count);
+ int nint_mt = low_make_reverse_ilist(
+ ilist, atoms->atom, count.data(), bConstr, bSettle, bBCheck, ril_mt->index, ril_mt->il, bLinkToAllAtoms, TRUE);
ril_mt->numAtomsInMolecule = atoms->nr;
}
if (debug)
{
- fprintf(debug, "The total size of the atom to interaction index is %d integers\n",
- rt.ril_mt_tot_size);
+ fprintf(debug, "The total size of the atom to interaction index is %d integers\n", rt.ril_mt_tot_size);
}
*nint = 0;
GMX_RELEASE_ASSERT(mtop->intermolecular_ilist,
"We should have an ilist when intermolecular interactions are on");
- *nint += make_reverse_ilist(*mtop->intermolecular_ilist, &atoms_global, rt.bConstr,
- rt.bSettle, rt.bBCheck, FALSE, &rt.ril_intermol);
+ *nint += make_reverse_ilist(
+ *mtop->intermolecular_ilist, &atoms_global, rt.bConstr, rt.bSettle, rt.bBCheck, FALSE, &rt.ril_intermol);
}
if (bFE && gmx_mtop_bondeds_free_energy(mtop))
* the parallel version constraint algorithm(s).
*/
- dd->reverse_top = new gmx_reverse_top_t;
- *dd->reverse_top =
- make_reverse_top(mtop, ir->efep != efepNO, !dd->comm->systemInfo.haveSplitConstraints,
- !dd->comm->systemInfo.haveSplitSettles, bBCheck, &dd->nbonded_global);
+ dd->reverse_top = new gmx_reverse_top_t;
+ *dd->reverse_top = make_reverse_top(mtop,
+ ir->efep != efepNO,
+ !dd->comm->systemInfo.haveSplitConstraints,
+ !dd->comm->systemInfo.haveSplitSettles,
+ bBCheck,
+ &dd->nbonded_global);
dd->haveExclusions = false;
for (const gmx_molblock_t& molb : mtop->molblock)
const t_iatom* iatoms,
InteractionDefinitions* idef)
{
- int k;
t_iatom tiatoms[1 + MAXATOMLIST];
- int j, ftype_r, nral_r;
/* Add this interaction to the local topology */
add_ifunc_for_vsites(tiatoms, ga2la, nral, bHomeA, a, a_gl, a_mol, iatoms, &idef->il[ftype]);
if (iatoms[1 + nral])
{
/* Check for recursion */
- for (k = 2; k < 1 + nral; k++)
+ for (int k = 2; k < 1 + nral; k++)
{
if ((iatoms[1 + nral] & (2 << k)) && (tiatoms[k] < 0))
{
/* This construction atoms is a vsite and not a home atom */
if (gmx_debug_at)
{
- fprintf(debug, "Constructing atom %d of vsite atom %d is a vsite and non-home\n",
- iatoms[k] + 1, a_mol + 1);
+ fprintf(debug,
+ "Constructing atom %d of vsite atom %d is a vsite and non-home\n",
+ iatoms[k] + 1,
+ a_mol + 1);
}
/* Find the vsite construction */
/* Check all interactions assigned to this atom */
- j = index[iatoms[k]];
+ int j = index[iatoms[k]];
while (j < index[iatoms[k] + 1])
{
- ftype_r = rtil[j++];
- nral_r = NRAL(ftype_r);
+ int ftype_r = rtil[j++];
+ int nral_r = NRAL(ftype_r);
if (interaction_function[ftype_r].flags & IF_VSITE)
{
/* Add this vsite (recursion) */
- add_vsite(ga2la, index, rtil, ftype_r, nral_r, FALSE, -1,
- a_gl + iatoms[k] - iatoms[1], iatoms[k], rtil.data() + j, idef);
+ add_vsite(ga2la,
+ index,
+ rtil,
+ ftype_r,
+ nral_r,
+ FALSE,
+ -1,
+ a_gl + iatoms[k] - iatoms[1],
+ iatoms[k],
+ rtil.data() + j,
+ idef);
}
j += 1 + nral_rt(ftype_r);
}
/*! \brief Append t_idef structures 1 to nsrc in src to *dest */
static void combine_idef(InteractionDefinitions* dest, gmx::ArrayRef<const thread_work_t> src)
{
- int ftype;
-
- for (ftype = 0; ftype < F_NRE; ftype++)
+ for (int ftype = 0; ftype < F_NRE; ftype++)
{
int n = 0;
for (gmx::index s = 1; s < src.ssize(); s++)
}
else
{
- gmx_bool bUse;
+ bool bUse = false;
/* Copy the type */
tiatoms[0] = iatoms[0];
/* Assign single-body interactions to the home zone */
if (iz == 0)
{
- bUse = TRUE;
+ bUse = true;
tiatoms[1] = i;
if (ftype == F_POSRES)
{
{
add_fbposres(mol, i_mol, numAtomsInMolecule, molb, tiatoms, ip_in, idef);
}
- }
- else
- {
- bUse = FALSE;
+ else
+ {
+ bUse = false;
+ }
}
}
else if (nral == 2)
/* This is a two-body interaction, we can assign
* analogous to the non-bonded assignments.
*/
- int k_gl;
-
- if (!bInterMolInteractions)
- {
- /* Get the global index using the offset in the molecule */
- k_gl = i_gl + iatoms[2] - i_mol;
- }
- else
- {
- k_gl = iatoms[2];
- }
+ const int k_gl = (!bInterMolInteractions)
+ ?
+ /* Get the global index using the offset in the molecule */
+ (i_gl + iatoms[2] - i_mol)
+ : iatoms[2];
if (const auto* entry = dd->ga2la->find(k_gl))
{
int kz = entry->cell;
/* If necessary check the cgcm distance */
if (bRCheck2B && dd_dist2(pbc_null, cg_cm, tiatoms[1], tiatoms[2]) >= rc2)
{
- bUse = FALSE;
+ bUse = false;
}
}
}
* with 2 DD cells an extra check may be necessary.
*/
ivec k_zero, k_plus;
- int k;
-
- bUse = TRUE;
+ bUse = true;
clear_ivec(k_zero);
clear_ivec(k_plus);
- for (k = 1; k <= nral && bUse; k++)
+ for (int k = 1; k <= nral && bUse; k++)
{
- int k_gl;
- if (!bInterMolInteractions)
- {
- /* Get the global index using the offset in the molecule */
- k_gl = i_gl + iatoms[k] - i_mol;
- }
- else
- {
- k_gl = iatoms[k];
- }
+ const int k_gl = (!bInterMolInteractions)
+ ?
+ /* Get the global index using the offset in the molecule */
+ (i_gl + iatoms[k] - i_mol)
+ : iatoms[k];
const auto* entry = dd->ga2la->find(k_gl);
if (entry == nullptr || entry->cell >= zones->n)
{
}
else
{
- int d;
-
tiatoms[k] = entry->la;
- for (d = 0; d < DIM; d++)
+ for (int d = 0; d < DIM; d++)
{
if (zones->shift[entry->cell][d] == 0)
{
bUse = (bUse && (k_zero[XX] != 0) && (k_zero[YY] != 0) && (k_zero[ZZ] != 0));
if (bRCheckMB)
{
- int d;
-
- for (d = 0; (d < DIM && bUse); d++)
+ for (int d = 0; (d < DIM && bUse); d++)
{
/* Check if the cg_cm distance falls within
* the cut-off to avoid possible multiple
int izone,
const gmx::Range<int>& atomRange)
{
- int mb, mt, mol, i_mol;
- gmx_bool bBCheck;
- gmx_reverse_top_t* rt;
- int nbonded_local;
+ int mb = 0;
+ int mt = 0;
+ int mol = 0;
+ int i_mol = 0;
- rt = dd->reverse_top;
+ gmx_reverse_top_t* rt = dd->reverse_top;
- bBCheck = rt->bBCheck;
+ bool bBCheck = rt->bBCheck;
- nbonded_local = 0;
+ int nbonded_local = 0;
for (int i : atomRange)
{
gmx::ArrayRef<const int> index = rt->ril_mt[mt].index;
gmx::ArrayRef<const t_iatom> rtil = rt->ril_mt[mt].il;
- check_assign_interactions_atom(i, i_gl, mol, i_mol, rt->ril_mt[mt].numAtomsInMolecule,
- index, rtil, FALSE, index[i_mol], index[i_mol + 1], dd,
- zones, &molb[mb], bRCheckMB, rcheck, bRCheck2B, rc2,
- pbc_null, cg_cm, ip_in, idef, izone, bBCheck, &nbonded_local);
+ check_assign_interactions_atom(i,
+ i_gl,
+ mol,
+ i_mol,
+ rt->ril_mt[mt].numAtomsInMolecule,
+ index,
+ rtil,
+ FALSE,
+ index[i_mol],
+ index[i_mol + 1],
+ dd,
+ zones,
+ &molb[mb],
+ bRCheckMB,
+ rcheck,
+ bRCheck2B,
+ rc2,
+ pbc_null,
+ cg_cm,
+ ip_in,
+ idef,
+ izone,
+ bBCheck,
+ &nbonded_local);
if (rt->bIntermolecularInteractions)
index = rt->ril_intermol.index;
rtil = rt->ril_intermol.il;
- check_assign_interactions_atom(i, i_gl, mol, i_mol, rt->ril_mt[mt].numAtomsInMolecule,
- index, rtil, TRUE, index[i_gl], index[i_gl + 1], dd, zones,
- &molb[mb], bRCheckMB, rcheck, bRCheck2B, rc2, pbc_null,
- cg_cm, ip_in, idef, izone, bBCheck, &nbonded_local);
+ check_assign_interactions_atom(i,
+ i_gl,
+ mol,
+ i_mol,
+ rt->ril_mt[mt].numAtomsInMolecule,
+ index,
+ rtil,
+ TRUE,
+ index[i_gl],
+ index[i_gl + 1],
+ dd,
+ zones,
+ &molb[mb],
+ bRCheckMB,
+ rcheck,
+ bRCheck2B,
+ rc2,
+ pbc_null,
+ cg_cm,
+ ip_in,
+ idef,
+ izone,
+ bBCheck,
+ &nbonded_local);
}
}
if (GET_CGINFO_EXCL_INTER(cginfo[at]))
{
- int a_gl, mb, mt, mol, a_mol;
+ int mb = 0;
+ int mt = 0;
+ int mol = 0;
+ int a_mol = 0;
/* Copy the exclusions from the global top */
- a_gl = dd->globalAtomIndices[at];
+ int a_gl = dd->globalAtomIndices[at];
global_atomnr_to_moltype_ind(dd->reverse_top, a_gl, &mb, &mt, &mol, &a_mol);
const auto excls = moltype[mt].excls[a_mol];
for (const int aj_mol : excls)
bool isExcludedAtom = !intermolecularExclusionGroup.empty()
&& std::find(intermolecularExclusionGroup.begin(),
- intermolecularExclusionGroup.end(), dd->globalAtomIndices[at])
+ intermolecularExclusionGroup.end(),
+ dd->globalAtomIndices[at])
!= intermolecularExclusionGroup.end();
if (isExcludedAtom)
ListOfLists<int>* lexcls,
int* excl_count)
{
- int nzone_bondeds;
- int cg0, cg1;
- real rc2;
- int nbonded_local;
- gmx_reverse_top_t* rt;
+ int nzone_bondeds = 0;
if (dd->reverse_top->bInterAtomicInteractions)
{
/* We only use exclusions from i-zones to i- and j-zones */
const int numIZonesForExclusions = (dd->haveExclusions ? zones->iZones.size() : 0);
- rt = dd->reverse_top;
+ gmx_reverse_top_t* rt = dd->reverse_top;
- rc2 = rc * rc;
+ real rc2 = rc * rc;
/* Clear the counts */
idef->clear();
- nbonded_local = 0;
+ int nbonded_local = 0;
lexcls->clear();
*excl_count = 0;
for (int izone = 0; izone < nzone_bondeds; izone++)
{
- cg0 = zones->cg_range[izone];
- cg1 = zones->cg_range[izone + 1];
+ const int cg0 = zones->cg_range[izone];
+ const int cg1 = zones->cg_range[izone + 1];
const int numThreads = rt->th_work.size();
#pragma omp parallel for num_threads(numThreads) schedule(static)
{
try
{
- int cg0t, cg1t;
- InteractionDefinitions* idef_t;
+ InteractionDefinitions* idef_t = nullptr;
- cg0t = cg0 + ((cg1 - cg0) * thread) / numThreads;
- cg1t = cg0 + ((cg1 - cg0) * (thread + 1)) / numThreads;
+ int cg0t = cg0 + ((cg1 - cg0) * thread) / numThreads;
+ int cg1t = cg0 + ((cg1 - cg0) * (thread + 1)) / numThreads;
if (thread == 0)
{
idef_t->clear();
}
- rt->th_work[thread].nbonded = make_bondeds_zone(
- dd, zones, mtop->molblock, bRCheckMB, rcheck, bRCheck2B, rc2, pbc_null,
- cg_cm, idef->iparams.data(), idef_t, izone, gmx::Range<int>(cg0t, cg1t));
+ rt->th_work[thread].nbonded = make_bondeds_zone(dd,
+ zones,
+ mtop->molblock,
+ bRCheckMB,
+ rcheck,
+ bRCheck2B,
+ rc2,
+ pbc_null,
+ cg_cm,
+ idef->iparams.data(),
+ idef_t,
+ izone,
+ gmx::Range<int>(cg0t, cg1t));
if (izone < numIZonesForExclusions)
{
- ListOfLists<int>* excl_t;
+ ListOfLists<int>* excl_t = nullptr;
if (thread == 0)
{
// Thread 0 stores exclusions directly in the final storage
}
/* No charge groups and no distance check required */
- make_exclusions_zone(dd, zones, mtop->moltype, cginfo, excl_t, izone, cg0t,
- cg1t, mtop->intermolecularExclusionGroup);
+ make_exclusions_zone(
+ dd, zones, mtop->moltype, cginfo, excl_t, izone, cg0t, cg1t, mtop->intermolecularExclusionGroup);
}
}
GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
const gmx_mtop_t& mtop,
gmx_localtop_t* ltop)
{
- gmx_bool bRCheckMB, bRCheck2B;
- real rc = -1;
- ivec rcheck;
- int d, nexcl;
- t_pbc pbc, *pbc_null = nullptr;
+ real rc = -1;
+ ivec rcheck;
+ int nexcl = 0;
+ t_pbc pbc, *pbc_null = nullptr;
if (debug)
{
fprintf(debug, "Making local topology\n");
}
- bRCheckMB = FALSE;
- bRCheck2B = FALSE;
+ bool bRCheckMB = false;
+ bool bRCheck2B = false;
if (dd->reverse_top->bInterAtomicInteractions)
{
}
/* Should we check cg_cm distances when assigning bonded interactions? */
- for (d = 0; d < DIM; d++)
+ for (int d = 0; d < DIM; d++)
{
rcheck[d] = FALSE;
/* Only need to check for dimensions where the part of the box
}
if (debug)
{
- fprintf(debug, "dim %d cellmin %f bonded rcheck[%d] = %d, bRCheck2B = %s\n", d,
- cellsize_min[d], d, rcheck[d], gmx::boolToString(bRCheck2B));
+ fprintf(debug,
+ "dim %d cellmin %f bonded rcheck[%d] = %d, bRCheck2B = %s\n",
+ d,
+ cellsize_min[d],
+ d,
+ rcheck[d],
+ gmx::boolToString(bRCheck2B));
}
}
if (bRCheckMB || bRCheck2B)
}
}
- dd->nbonded_local = make_local_bondeds_excls(dd, zones, &mtop, fr->cginfo.data(), bRCheckMB,
- rcheck, bRCheck2B, rc, pbc_null, cgcm_or_x,
- <op->idef, <op->excls, &nexcl);
+ dd->nbonded_local = make_local_bondeds_excls(dd,
+ zones,
+ &mtop,
+ fr->cginfo.data(),
+ bRCheckMB,
+ rcheck,
+ bRCheck2B,
+ rc,
+ pbc_null,
+ cgcm_or_x,
+ <op->idef,
+ <op->excls,
+ &nexcl);
/* The ilist is not sorted yet,
* we can only do this when we have the charge arrays.
/*! \brief Check if a link is stored in \p link between charge groups \p cg_gl and \p cg_gl_j and if not so, store a link */
static void check_link(t_blocka* link, int cg_gl, int cg_gl_j)
{
- int k;
- gmx_bool bFound;
-
- bFound = FALSE;
- for (k = link->index[cg_gl]; k < link->index[cg_gl + 1]; k++)
+ bool bFound = false;
+ for (int k = link->index[cg_gl]; k < link->index[cg_gl + 1]; k++)
{
GMX_RELEASE_ASSERT(link->a, "Inconsistent NULL pointer while making charge-group links");
if (link->a[k] == cg_gl_j)
t_blocka* makeBondedLinks(const gmx_mtop_t& mtop, gmx::ArrayRef<cginfo_mb_t> cginfo_mb)
{
- t_blocka* link;
- cginfo_mb_t* cgi_mb;
+ t_blocka* link = nullptr;
/* For each atom make a list of other atoms in the system
* that a linked to it via bonded interactions
reverse_ilist_t ril;
make_reverse_ilist(molt.ilist, &molt.atoms, FALSE, FALSE, FALSE, TRUE, &ril);
- cgi_mb = &cginfo_mb[mb];
+ cginfo_mb_t* cgi_mb = &cginfo_mb[mb];
- int mol;
+ int mol = 0;
for (mol = 0; mol < (mtop.bIntermolecularInteractions ? molb.nmol : 1); mol++)
{
for (int a = 0; a < molt.atoms.nr; a++)
if (debug)
{
- fprintf(debug, "molecule type '%s' %d atoms has %d atom links through bonded interac.\n",
- *molt.name, molt.atoms.nr, nlink_mol);
+ fprintf(debug,
+ "molecule type '%s' %d atoms has %d atom links through bonded interac.\n",
+ *molt.name,
+ molt.atoms.nr,
+ nlink_mol);
}
if (molb.nmol > mol)
{
real rij2 = distance2(x[atomI], x[atomJ]);
- update_max_bonded_distance(rij2, ftype, atomI, atomJ,
- (nral == 2) ? bd_2b : bd_mb);
+ update_max_bonded_distance(
+ rij2, ftype, atomI, atomJ, (nral == 2) ? bd_2b : bd_mb);
}
}
}
for (int aj = ai + 1; aj < nral; aj++)
{
rvec dx;
- real rij2;
int atom_j = il.iatoms[i + 1 + aj];
pbc_dx(&pbc, x[atom_i], x[atom_j], dx);
- rij2 = norm2(dx);
+ const real rij2 = norm2(dx);
update_max_bonded_distance(rij2, ftype, atom_i, atom_j, (nral == 2) ? bd_2b : bd_mb);
}
ArrayRef<const RVec> x,
ArrayRef<RVec> xs)
{
- int n, i;
-
if (pbcType != PbcType::No)
{
mk_mshift(nullptr, graph, pbcType, box, as_rvec_array(x.data()));
* unchanged, just to be 100% sure that we do not affect
* binary reproducibility of simulations.
*/
- n = molt->atoms.nr;
- for (i = 0; i < n; i++)
+ for (int i = 0; i < molt->atoms.nr; i++)
{
copy_rvec(x[i], xs[i]);
}
real* r_2b,
real* r_mb)
{
- gmx_bool bExclRequired;
- int at_offset;
bonded_distance_t bd_2b = { 0, -1, -1, -1 };
bonded_distance_t bd_mb = { 0, -1, -1, -1 };
- bExclRequired = inputrecExclForces(ir);
+ bool bExclRequired = inputrecExclForces(ir);
- *r_2b = 0;
- *r_mb = 0;
- at_offset = 0;
+ *r_2b = 0;
+ *r_mb = 0;
+ int at_offset = 0;
for (const gmx_molblock_t& molb : mtop->molblock)
{
const gmx_moltype_t& molt = mtop->moltype[molb.type];
std::vector<RVec> xs(molt.atoms.nr);
for (int mol = 0; mol < molb.nmol; mol++)
{
- getWholeMoleculeCoordinates(&molt, &mtop->ffparams, ir->pbcType, &graph, box,
- x.subArray(at_offset, molt.atoms.nr), xs);
+ getWholeMoleculeCoordinates(&molt,
+ &mtop->ffparams,
+ ir->pbcType,
+ &graph,
+ box,
+ x.subArray(at_offset, molt.atoms.nr),
+ xs);
bonded_distance_t bd_mol_2b = { 0, -1, -1, -1 };
bonded_distance_t bd_mol_mb = { 0, -1, -1, -1 };
bonded_cg_distance_mol(&molt, bBCheck, bExclRequired, xs, &bd_mol_2b, &bd_mol_mb);
/* Process the mol data adding the atom index offset */
- update_max_bonded_distance(bd_mol_2b.r2, bd_mol_2b.ftype, at_offset + bd_mol_2b.a1,
- at_offset + bd_mol_2b.a2, &bd_2b);
- update_max_bonded_distance(bd_mol_mb.r2, bd_mol_mb.ftype, at_offset + bd_mol_mb.a1,
- at_offset + bd_mol_mb.a2, &bd_mb);
+ update_max_bonded_distance(bd_mol_2b.r2,
+ bd_mol_2b.ftype,
+ at_offset + bd_mol_2b.a1,
+ at_offset + bd_mol_2b.a2,
+ &bd_2b);
+ update_max_bonded_distance(bd_mol_mb.r2,
+ bd_mol_mb.ftype,
+ at_offset + bd_mol_mb.a1,
+ at_offset + bd_mol_mb.a2,
+ &bd_mb);
at_offset += molt.atoms.nr;
}
{
GMX_LOG(mdlog.info)
.appendTextFormatted(
- " two-body bonded interactions: %5.3f nm, %s, atoms %d %d", *r_2b,
+ " two-body bonded interactions: %5.3f nm, %s, atoms %d %d",
+ *r_2b,
(bd_2b.ftype >= 0) ? interaction_function[bd_2b.ftype].longname : "Exclusion",
- bd_2b.a1 + 1, bd_2b.a2 + 1);
+ bd_2b.a1 + 1,
+ bd_2b.a2 + 1);
}
if (*r_mb > 0)
{
GMX_LOG(mdlog.info)
.appendTextFormatted(
- " multi-body bonded interactions: %5.3f nm, %s, atoms %d %d", *r_mb,
- interaction_function[bd_mb.ftype].longname, bd_mb.a1 + 1, bd_mb.a2 + 1);
+ " multi-body bonded interactions: %5.3f nm, %s, atoms %d %d",
+ *r_mb,
+ interaction_function[bd_mb.ftype].longname,
+ bd_mb.a1 + 1,
+ bd_mb.a2 + 1);
}
}
}
}
}
- int at_end = setup_specat_communication(dd, &ireq, dd->vsite_comm, ga2la_specat, at_start, 1,
- "vsite", "");
+ int at_end = setup_specat_communication(
+ dd, &ireq, dd->vsite_comm, ga2la_specat, at_start, 1, "vsite", "");
/* Fill in the missing indices */
for (int ftype = 0; ftype < F_NRE; ftype++)
cx[YY] = grid_r[i * 2 + y][YY];
cx[ZZ] = grid_r[i * 2 + z][ZZ];
mvmul(tric, cx, r);
- gmx_fprintf_pdb_atomline(out, epdbATOM, a++, "CA", ' ', "GLY", ' ', i + 1, ' ',
- 10 * r[XX], 10 * r[YY], 10 * r[ZZ], 1.0, vol, "");
+ gmx_fprintf_pdb_atomline(out,
+ epdbATOM,
+ a++,
+ "CA",
+ ' ',
+ "GLY",
+ ' ',
+ i + 1,
+ ' ',
+ 10 * r[XX],
+ 10 * r[YY],
+ 10 * r[ZZ],
+ 1.0,
+ vol,
+ "");
}
}
}
{
b = dd->comm->zones.n + 1;
}
- gmx_fprintf_pdb_atomline(out, epdbATOM, ii + 1, atomname, ' ', resname, ' ', resnr, ' ',
- 10 * x[i][XX], 10 * x[i][YY], 10 * x[i][ZZ], 1.0, b, "");
+ gmx_fprintf_pdb_atomline(out,
+ epdbATOM,
+ ii + 1,
+ atomname,
+ ' ',
+ resname,
+ ' ',
+ resnr,
+ ' ',
+ 10 * x[i][XX],
+ 10 * x[i][YY],
+ 10 * x[i][ZZ],
+ 1.0,
+ b,
+ "");
}
fprintf(out, "TER\n");
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
#ifndef GMX_DOMDEC_GPUHALOEXCHANGE_H
#define GMX_DOMDEC_GPUHALOEXCHANGE_H
+#include <memory>
+
#include "gromacs/gpu_utils/devicebuffer_datatype.h"
#include "gromacs/math/vectypes.h"
#include "gromacs/utility/basedefinitions.h"
-#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/gmxmpi.h"
struct gmx_domdec_t;
private:
class Impl;
- gmx::PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
xSendSize_ = newSize;
#if GMX_MPI
- MPI_Sendrecv(&xSendSize_, sizeof(int), MPI_BYTE, sendRankX_, 0, &xRecvSize_, sizeof(int),
- MPI_BYTE, recvRankX_, 0, mpi_comm_mysim_, MPI_STATUS_IGNORE);
+ MPI_Sendrecv(&xSendSize_,
+ sizeof(int),
+ MPI_BYTE,
+ sendRankX_,
+ 0,
+ &xRecvSize_,
+ sizeof(int),
+ MPI_BYTE,
+ recvRankX_,
+ 0,
+ mpi_comm_mysim_,
+ MPI_STATUS_IGNORE);
#endif
fSendSize_ = xRecvSize_;
fRecvSize_ = xSendSize_;
"halo exchange index mapping array");
std::copy(ind.index.begin(), ind.index.end(), h_indexMap_.begin());
- copyToDeviceBuffer(&d_indexMap_, h_indexMap_.data(), 0, newSize, nonLocalStream_,
- GpuApiCallBehavior::Async, nullptr);
+ copyToDeviceBuffer(
+ &d_indexMap_, h_indexMap_.data(), 0, newSize, nonLocalStream_, GpuApiCallBehavior::Async, nullptr);
}
// This rank will push data to its neighbor, so needs to know
// the remote receive address and similarly send its receive
// Coordinates buffer:
void* recvPtr = static_cast<void*>(&d_x_[atomOffset_]);
#if GMX_MPI
- MPI_Sendrecv(&recvPtr, sizeof(void*), MPI_BYTE, recvRankX_, 0, &remoteXPtr_, sizeof(void*),
- MPI_BYTE, sendRankX_, 0, mpi_comm_mysim_, MPI_STATUS_IGNORE);
+ MPI_Sendrecv(&recvPtr,
+ sizeof(void*),
+ MPI_BYTE,
+ recvRankX_,
+ 0,
+ &remoteXPtr_,
+ sizeof(void*),
+ MPI_BYTE,
+ sendRankX_,
+ 0,
+ mpi_comm_mysim_,
+ MPI_STATUS_IGNORE);
// Force buffer:
recvPtr = static_cast<void*>(d_recvBuf_);
- MPI_Sendrecv(&recvPtr, sizeof(void*), MPI_BYTE, recvRankF_, 0, &remoteFPtr_, sizeof(void*),
- MPI_BYTE, sendRankF_, 0, mpi_comm_mysim_, MPI_STATUS_IGNORE);
+ MPI_Sendrecv(&recvPtr,
+ sizeof(void*),
+ MPI_BYTE,
+ recvRankF_,
+ 0,
+ &remoteFPtr_,
+ sizeof(void*),
+ MPI_BYTE,
+ sendRankF_,
+ 0,
+ mpi_comm_mysim_,
+ MPI_STATUS_IGNORE);
#endif
wallcycle_sub_stop(wcycle_, ewcsDD_GPU);
// is used every step to pass the shift vector as an argument of
// the packing kernel.
const int boxDimensionIndex = dd_->dim[dimIndex_];
- const float3 coordinateShift{ box[boxDimensionIndex][XX], box[boxDimensionIndex][YY],
+ const float3 coordinateShift{ box[boxDimensionIndex][XX],
+ box[boxDimensionIndex][YY],
box[boxDimensionIndex][ZZ] };
// Avoid launching kernel when there is no work to do
{
auto kernelFn = usePBC_ ? packSendBufKernel<true> : packSendBufKernel<false>;
- const auto kernelArgs = prepareGpuKernelArguments(kernelFn, config, &sendBuf, &d_x,
- &indexMap, &size, &coordinateShift);
+ const auto kernelArgs = prepareGpuKernelArguments(
+ kernelFn, config, &sendBuf, &d_x, &indexMap, &size, &coordinateShift);
- launchGpuKernel(kernelFn, config, nonLocalStream_, nullptr,
- "Domdec GPU Apply X Halo Exchange", kernelArgs);
+ launchGpuKernel(
+ kernelFn, config, nonLocalStream_, nullptr, "Domdec GPU Apply X Halo Exchange", kernelArgs);
}
wallcycle_sub_stop(wcycle_, ewcsLAUNCH_GPU_MOVEX);
const auto kernelArgs =
prepareGpuKernelArguments(kernelFn, config, &d_f, &recvBuf, &indexMap, &size);
- launchGpuKernel(kernelFn, config, nonLocalStream_, nullptr,
- "Domdec GPU Apply F Halo Exchange", kernelArgs);
+ launchGpuKernel(
+ kernelFn, config, nonLocalStream_, nullptr, "Domdec GPU Apply F Halo Exchange", kernelArgs);
}
if (pulse_ == 0)
// for subsequent data push. This avoids a race condition with the remote data being written in the previous timestep.
// Similarly send event to task that will push data to this task.
GpuEventSynchronizer* remoteCoordinatesReadyOnDeviceEvent;
- MPI_Sendrecv(&coordinatesReadyOnDeviceEvent, sizeof(GpuEventSynchronizer*), MPI_BYTE,
- recvRank, 0, &remoteCoordinatesReadyOnDeviceEvent, sizeof(GpuEventSynchronizer*),
- MPI_BYTE, sendRank, 0, mpi_comm_mysim_, MPI_STATUS_IGNORE);
+ MPI_Sendrecv(&coordinatesReadyOnDeviceEvent,
+ sizeof(GpuEventSynchronizer*),
+ MPI_BYTE,
+ recvRank,
+ 0,
+ &remoteCoordinatesReadyOnDeviceEvent,
+ sizeof(GpuEventSynchronizer*),
+ MPI_BYTE,
+ sendRank,
+ 0,
+ mpi_comm_mysim_,
+ MPI_STATUS_IGNORE);
remoteCoordinatesReadyOnDeviceEvent->enqueueWaitEvent(nonLocalStream_);
#else
GMX_UNUSED_VALUE(coordinatesReadyOnDeviceEvent);
// send data to neighbor, if any data exists to send
if (sendSize > 0)
{
- stat = cudaMemcpyAsync(remotePtr, sendPtr, sendSize * DIM * sizeof(float),
- cudaMemcpyDeviceToDevice, nonLocalStream_.stream());
+ stat = cudaMemcpyAsync(remotePtr,
+ sendPtr,
+ sendSize * DIM * sizeof(float),
+ cudaMemcpyDeviceToDevice,
+ nonLocalStream_.stream());
CU_RET_ERR(stat, "cudaMemcpyAsync on GPU Domdec CUDA direct data transfer failed");
}
haloDataTransferLaunched_->markEvent(nonLocalStream_);
- MPI_Sendrecv(&haloDataTransferLaunched_, sizeof(GpuEventSynchronizer*), MPI_BYTE, sendRank, 0,
- &haloDataTransferRemote, sizeof(GpuEventSynchronizer*), MPI_BYTE, recvRank, 0,
- mpi_comm_mysim_, MPI_STATUS_IGNORE);
+ MPI_Sendrecv(&haloDataTransferLaunched_,
+ sizeof(GpuEventSynchronizer*),
+ MPI_BYTE,
+ sendRank,
+ 0,
+ &haloDataTransferRemote,
+ sizeof(GpuEventSynchronizer*),
+ MPI_BYTE,
+ recvRank,
+ 0,
+ mpi_comm_mysim_,
+ MPI_STATUS_IGNORE);
haloDataTransferRemote->enqueueWaitEvent(nonLocalStream_);
#else
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <memory>
#include "gromacs/utility/basedefinitions.h"
-#include "gromacs/utility/classhelpers.h"
class gmx_ga2la_t;
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
force->resize(numTotalAtoms);
}
- atoms2md(&top_global, ir, numAtomIndex,
- usingDomDec ? cr->dd->globalAtomIndices : std::vector<int>(), numHomeAtoms, mdAtoms);
+ atoms2md(&top_global,
+ ir,
+ numAtomIndex,
+ usingDomDec ? cr->dd->globalAtomIndices : std::vector<int>(),
+ numHomeAtoms,
+ mdAtoms);
auto mdatoms = mdAtoms->mdatoms();
if (usingDomDec)
if (constr)
{
- constr->setConstraints(top, mdatoms->nr, mdatoms->homenr, mdatoms->massT, mdatoms->invmass,
- mdatoms->nMassPerturbed != 0, mdatoms->lambda, mdatoms->cFREEZE);
+ constr->setConstraints(top,
+ mdatoms->nr,
+ mdatoms->homenr,
+ mdatoms->massT,
+ mdatoms->invmass,
+ mdatoms->nMassPerturbed != 0,
+ mdatoms->lambda,
+ mdatoms->cFREEZE);
}
}
fprintf(fp,
"zone d0 %d d1 %d d2 %d min0 %6.3f max1 %6.3f mch0 %6.3f mch1 %6.3f p1_0 %6.3f p1_1 "
"%6.3f\n",
- d, i, j, zone->min0, zone->max1, zone->mch0, zone->mch0, zone->p1_0, zone->p1_1);
+ d,
+ i,
+ j,
+ zone->min0,
+ zone->max1,
+ zone->mch0,
+ zone->mch0,
+ zone->p1_0,
+ zone->p1_1);
}
/*! \brief Using the home grid size as input in cell_ns_x0 and cell_ns_x1
"Here we expect gmx_ddzone_t to consist of c_ddzoneNumReals reals (only)");
int numReals = numElementsInBuffer * c_ddzoneNumReals;
- ddSendrecv(dd, d, dddirBackward, gmx::arrayRefFromArray(&buf_s[0].min0, numReals),
+ ddSendrecv(dd,
+ d,
+ dddirBackward,
+ gmx::arrayRefFromArray(&buf_s[0].min0, numReals),
gmx::arrayRefFromArray(&buf_r[0].min0, numReals));
rvec dh = { 0 };
cellsizes[d].fracUpperMin = extr_s[d - 1][1];
if (debug)
{
- fprintf(debug, "Cell fraction d %d, max0 %f, min1 %f\n", d, cellsizes[d].fracLowerMax,
+ fprintf(debug,
+ "Cell fraction d %d, max0 %f, min1 %f\n",
+ d,
+ cellsizes[d].fracLowerMax,
cellsizes[d].fracUpperMin);
}
}
int globalAtomIndex = dd->globalAtomIndices[a];
if (have[globalAtomIndex] > 0)
{
- fprintf(stderr, "DD rank %d: global atom %d occurs twice: index %d and %d\n",
- dd->rank, globalAtomIndex + 1, have[globalAtomIndex], a + 1);
+ fprintf(stderr,
+ "DD rank %d: global atom %d occurs twice: index %d and %d\n",
+ dd->rank,
+ globalAtomIndex + 1,
+ have[globalAtomIndex],
+ a + 1);
}
else
{
fprintf(stderr,
"DD rank %d: global atom %d marked as local atom %d, which is larger than "
"nat_tot (%d)\n",
- dd->rank, i + 1, a + 1, numAtomsInZones);
+ dd->rank,
+ i + 1,
+ a + 1,
+ numAtomsInZones);
nerr++;
}
else
fprintf(stderr,
"DD rank %d: global atom %d marked as local atom %d, which has global "
"atom index %d\n",
- dd->rank, i + 1, a + 1, dd->globalAtomIndices[a] + 1);
+ dd->rank,
+ i + 1,
+ a + 1,
+ dd->globalAtomIndices[a] + 1);
nerr++;
}
}
}
if (ngl != numAtomsInZones)
{
- fprintf(stderr, "DD rank %d, %s: %d global atom indices, %d local atoms\n", dd->rank, where,
- ngl, numAtomsInZones);
+ fprintf(stderr, "DD rank %d, %s: %d global atom indices, %d local atoms\n", dd->rank, where, ngl, numAtomsInZones);
}
for (int a = 0; a < numAtomsInZones; a++)
{
if (have[a] == 0)
{
- fprintf(stderr, "DD rank %d, %s: local atom %d, global %d has no global index\n",
- dd->rank, where, a + 1, dd->globalAtomIndices[a] + 1);
+ fprintf(stderr,
+ "DD rank %d, %s: local atom %d, global %d has no global index\n",
+ dd->rank,
+ where,
+ a + 1,
+ dd->globalAtomIndices[a] + 1);
}
}
"step %s: The domain decomposition grid has shifted too much in the "
"%c-direction around cell %d %d %d. This should not have happened. "
"Running with fewer ranks might avoid this issue.",
- gmx_step_str(step, buf), dim2char(dim), dd->ci[XX], dd->ci[YY], dd->ci[ZZ]);
+ gmx_step_str(step, buf),
+ dim2char(dim),
+ dd->ci[XX],
+ dd->ci[YY],
+ dd->ci[ZZ]);
}
}
}
"step %s: The %c-size (%f) times the triclinic skew factor (%f) is smaller "
"than the smallest allowed cell size (%f) for domain decomposition grid cell "
"%d %d %d",
- gmx_step_str(step, buf), dim2char(dim),
- comm->cell_x1[dim] - comm->cell_x0[dim], ddbox->skew_fac[dim],
- dd->comm->cellsize_min[dim], dd->ci[XX], dd->ci[YY], dd->ci[ZZ]);
+ gmx_step_str(step, buf),
+ dim2char(dim),
+ comm->cell_x1[dim] - comm->cell_x0[dim],
+ ddbox->skew_fac[dim],
+ dd->comm->cellsize_min[dim],
+ dd->ci[XX],
+ dd->ci[YY],
+ dd->ci[ZZ]);
}
}
* The communicators are setup such that the root always has rank 0.
*/
#if GMX_MPI
- MPI_Gather(sbuf, load->nload * sizeof(float), MPI_BYTE, load->load,
- load->nload * sizeof(float), MPI_BYTE, 0, comm->mpi_comm_load[d]);
+ MPI_Gather(sbuf,
+ load->nload * sizeof(float),
+ MPI_BYTE,
+ load->load,
+ load->nload * sizeof(float),
+ MPI_BYTE,
+ 0,
+ comm->mpi_comm_load[d]);
#endif
if (dd->ci[dim] == dd->master_ci[dim])
{
sprintf(buf, " Average PME mesh/force load: %5.3f\n", pmeForceRatio);
fprintf(fplog, "%s", buf);
fprintf(stderr, "%s", buf);
- sprintf(buf, " Part of the total run time spent waiting due to PP/PME imbalance: %.1f %%\n",
+ sprintf(buf,
+ " Part of the total run time spent waiting due to PP/PME imbalance: %.1f %%\n",
std::fabs(lossFractionPme) * 100);
fprintf(fplog, "%s", buf);
fprintf(stderr, "%s", buf);
" had %s work to do than the PP ranks.\n"
" You might want to %s the number of PME ranks\n"
" or %s the cut-off and the grid spacing.\n",
- std::fabs(lossFractionPme * 100), (lossFractionPme < 0) ? "less" : "more",
+ std::fabs(lossFractionPme * 100),
+ (lossFractionPme < 0) ? "less" : "more",
(lossFractionPme < 0) ? "decrease" : "increase",
(lossFractionPme < 0) ? "decrease" : "increase");
fprintf(fplog, "%s\n", buf);
"step %s Measured %.1f %% performance loss due to load imbalance, "
"but the minimum cell size is smaller than 1.05 times the cell size limit. "
"Will no longer try dynamic load balancing.",
- gmx::toString(step).c_str(), dd_force_imb_perf_loss(dd) * 100);
+ gmx::toString(step).c_str(),
+ dd_force_imb_perf_loss(dd) * 100);
comm->dlbState = DlbState::offForever;
return;
.appendTextFormatted(
"step %s Turning on dynamic load balancing, because the performance loss due "
"to load imbalance is %.1f %%.",
- gmx::toString(step).c_str(), dd_force_imb_perf_loss(dd) * 100);
+ gmx::toString(step).c_str(),
+ dd_force_imb_perf_loss(dd) * 100);
comm->dlbState = DlbState::onCanTurnOff;
/* Store the non-DLB performance, so we can check if DLB actually
int cg1_th = cg0 + ((cg1 - cg0) * (th + 1)) / numThreads;
/* Get the cg's for this pulse in this zone */
- get_zone_pulse_cgs(dd, zonei, zone, cg0_th, cg1_th, dd->globalAtomGroupIndices,
- dim, dim_ind, dim0, dim1, dim2, r_comm2, r_bcomm2, box,
- distanceIsTriclinic, normal, skew_fac2_d, skew_fac_01,
- v_d, v_0, v_1, &corners, sf2_round, bDistBonded, bBondComm,
- bDist2B, bDistMB, state->x.rvec_array(), fr->cginfo,
- th == 0 ? &ind->index : &work.localAtomGroupBuffer, &work);
+ get_zone_pulse_cgs(dd,
+ zonei,
+ zone,
+ cg0_th,
+ cg1_th,
+ dd->globalAtomGroupIndices,
+ dim,
+ dim_ind,
+ dim0,
+ dim1,
+ dim2,
+ r_comm2,
+ r_bcomm2,
+ box,
+ distanceIsTriclinic,
+ normal,
+ skew_fac2_d,
+ skew_fac_01,
+ v_d,
+ v_0,
+ v_1,
+ &corners,
+ sf2_round,
+ bDistBonded,
+ bBondComm,
+ bDist2B,
+ bDistMB,
+ state->x.rvec_array(),
+ fr->cginfo,
+ th == 0 ? &ind->index : &work.localAtomGroupBuffer,
+ &work);
}
GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
} // END
{
const dd_comm_setup_work_t& dth = comm->dth[th];
- ind->index.insert(ind->index.end(), dth.localAtomGroupBuffer.begin(),
+ ind->index.insert(ind->index.end(),
+ dth.localAtomGroupBuffer.begin(),
dth.localAtomGroupBuffer.end());
- atomGroups.insert(atomGroups.end(), dth.atomGroupBuffer.begin(),
- dth.atomGroupBuffer.end());
- positions.insert(positions.end(), dth.positionBuffer.begin(),
- dth.positionBuffer.end());
+ atomGroups.insert(
+ atomGroups.end(), dth.atomGroupBuffer.begin(), dth.atomGroupBuffer.end());
+ positions.insert(
+ positions.end(), dth.positionBuffer.begin(), dth.positionBuffer.end());
comm->dth[0].nat += dth.nat;
ind->nsend[zone] += dth.nsend_zone;
}
else
{
/* This part of the code is never executed with bBondComm. */
- merge_cg_buffers(nzone, cd, p, zone_cg_range, dd->globalAtomGroupIndices,
- integerBufferRef.data(), state->x, rvecBufferRef, fr->cginfo_mb,
+ merge_cg_buffers(nzone,
+ cd,
+ p,
+ zone_cg_range,
+ dd->globalAtomGroupIndices,
+ integerBufferRef.data(),
+ state->x,
+ rvecBufferRef,
+ fr->cginfo_mb,
fr->cginfo);
pos_cg += ind->nrecv[nzone];
}
{
for (z = zone_start; z < zone_end; z++)
{
- fprintf(debug, "zone %d %6.3f - %6.3f %6.3f - %6.3f %6.3f - %6.3f\n", z,
- zones->size[z].x0[XX], zones->size[z].x1[XX], zones->size[z].x0[YY],
- zones->size[z].x1[YY], zones->size[z].x0[ZZ], zones->size[z].x1[ZZ]);
- fprintf(debug, "zone %d bb %6.3f - %6.3f %6.3f - %6.3f %6.3f - %6.3f\n", z,
- zones->size[z].bb_x0[XX], zones->size[z].bb_x1[XX], zones->size[z].bb_x0[YY],
- zones->size[z].bb_x1[YY], zones->size[z].bb_x0[ZZ], zones->size[z].bb_x1[ZZ]);
+ fprintf(debug,
+ "zone %d %6.3f - %6.3f %6.3f - %6.3f %6.3f - %6.3f\n",
+ z,
+ zones->size[z].x0[XX],
+ zones->size[z].x1[XX],
+ zones->size[z].x0[YY],
+ zones->size[z].x1[YY],
+ zones->size[z].x0[ZZ],
+ zones->size[z].x1[ZZ]);
+ fprintf(debug,
+ "zone %d bb %6.3f - %6.3f %6.3f - %6.3f %6.3f - %6.3f\n",
+ z,
+ zones->size[z].bb_x0[XX],
+ zones->size[z].bb_x1[XX],
+ zones->size[z].bb_x0[YY],
+ zones->size[z].bb_x1[YY],
+ zones->size[z].bb_x0[ZZ],
+ zones->size[z].bb_x1[ZZ]);
}
}
}
case DDAtomRanges::Type::Vsites:
if (cr->dd->vsite_comm)
{
- fprintf(fplog, " av. #atoms communicated per step for vsites: %d x %.1f\n",
- (EEL_PME(ir->coulombtype) || ir->coulombtype == eelEWALD) ? 3 : 2, av);
+ fprintf(fplog,
+ " av. #atoms communicated per step for vsites: %d x %.1f\n",
+ (EEL_PME(ir->coulombtype) || ir->coulombtype == eelEWALD) ? 3 : 2,
+ av);
}
break;
case DDAtomRanges::Type::Constraints:
if (cr->dd->constraint_comm)
{
- fprintf(fplog, " av. #atoms communicated per step for LINCS: %d x %.1f\n",
- 1 + ir->nLincsIter, av);
+ fprintf(fplog,
+ " av. #atoms communicated per step for LINCS: %d x %.1f\n",
+ 1 + ir->nLincsIter,
+ av);
}
break;
default: gmx_incons(" Unknown type for DD statistics");
// TODO if the update code becomes accessible here, use
// upd->deform for this logic.
bBoxChanged = (bMasterState || inputrecDeform(ir));
- if (ir->epc != epcNO)
+ if (ir->epc != PressureCoupling::No)
{
/* With nstpcouple > 1 pressure coupling happens.
* one step after calculating the pressure.
* Since it requires (possibly expensive) global communication,
* we might want to do DLB less frequently.
*/
- if (bBoxChanged || ir->epc != epcNO)
+ if (bBoxChanged || ir->epc != PressureCoupling::No)
{
bDoDLB = bBoxChanged;
}
gmx_fatal(FARGS,
"Internal inconsistency state_local->ddp_count (%d) > dd->ddp_count (%" PRId64
")",
- state_local->ddp_count, dd->ddp_count);
+ state_local->ddp_count,
+ dd->ddp_count);
}
if (state_local->ddp_count_cg_gl != state_local->ddp_count)
gmx_fatal(FARGS,
"Internal inconsistency state_local->ddp_count_cg_gl (%d) != "
"state_local->ddp_count (%d)",
- state_local->ddp_count_cg_gl, state_local->ddp_count);
+ state_local->ddp_count_cg_gl,
+ state_local->ddp_count);
}
/* Clear the old state */
}
// TODO: Integrate this code in the nbnxm module
- get_nsgrid_boundaries(ddbox.nboundeddim, state_local->box, dd, &ddbox, &comm->cell_x0,
- &comm->cell_x1, dd->ncg_home, as_rvec_array(state_local->x.data()),
- cell_ns_x0, cell_ns_x1, &grid_density);
+ get_nsgrid_boundaries(ddbox.nboundeddim,
+ state_local->box,
+ dd,
+ &ddbox,
+ &comm->cell_x0,
+ &comm->cell_x1,
+ dd->ncg_home,
+ as_rvec_array(state_local->x.data()),
+ cell_ns_x0,
+ cell_ns_x1,
+ &grid_density);
if (bBoxChanged)
{
set_zones_size(dd, state_local->box, &ddbox, 0, 1, ncg_moved);
- nbnxn_put_on_grid(fr->nbv.get(), state_local->box, 0, comm->zones.size[0].bb_x0,
- comm->zones.size[0].bb_x1, comm->updateGroupsCog.get(),
- { 0, dd->ncg_home }, comm->zones.dens_zone0, fr->cginfo, state_local->x,
- ncg_moved, bRedist ? comm->movedBuffer.data() : nullptr);
+ nbnxn_put_on_grid(fr->nbv.get(),
+ state_local->box,
+ 0,
+ comm->zones.size[0].bb_x0,
+ comm->zones.size[0].bb_x1,
+ comm->updateGroupsCog.get(),
+ { 0, dd->ncg_home },
+ comm->zones.dens_zone0,
+ fr->cginfo,
+ state_local->x,
+ ncg_moved,
+ bRedist ? comm->movedBuffer.data() : nullptr);
if (debug)
{
- fprintf(debug, "Step %s, sorting the %d home charge groups\n", gmx_step_str(step, sbuf),
- dd->ncg_home);
+ fprintf(debug, "Step %s, sorting the %d home charge groups\n", gmx_step_str(step, sbuf), dd->ncg_home);
}
dd_sort_state(dd, fr, state_local);
{
np[dd->dim[i]] = comm->cd[i].numPulses();
}
- dd_make_local_top(dd, &comm->zones, dd->unitCellInfo.npbcdim, state_local->box,
- comm->cellsize_min, np, fr, state_local->x.rvec_array(), top_global, top_local);
+ dd_make_local_top(dd,
+ &comm->zones,
+ dd->unitCellInfo.npbcdim,
+ state_local->box,
+ comm->cellsize_min,
+ np,
+ fr,
+ state_local->x.rvec_array(),
+ top_global,
+ top_local);
wallcycle_sub_stop(wcycle, ewcsDD_MAKETOP);
/* Set up the special atom communication */
int n = comm->atomRanges.end(DDAtomRanges::Type::Zones);
for (int i = static_cast<int>(DDAtomRanges::Type::Zones) + 1;
- i < static_cast<int>(DDAtomRanges::Type::Number); i++)
+ i < static_cast<int>(DDAtomRanges::Type::Number);
+ i++)
{
auto range = static_cast<DDAtomRanges::Type>(i);
switch (range)
if (dd->comm->systemInfo.haveSplitConstraints || dd->comm->systemInfo.haveSplitSettles)
{
/* Only for inter-cg constraints we need special code */
- n = dd_make_local_constraints(dd, n, &top_global, fr->cginfo.data(), constr,
- ir->nProjOrder, top_local->idef.il);
+ n = dd_make_local_constraints(dd,
+ n,
+ &top_global,
+ fr->cginfo.data(),
+ constr,
+ ir->nProjOrder,
+ top_local->idef.il);
}
break;
default: gmx_incons("Unknown special atom type setup");
* allocation, zeroing and copying, but this is probably not worth
* the complications and checking.
*/
- forcerec_set_ranges(fr, comm->atomRanges.end(DDAtomRanges::Type::Zones),
- comm->atomRanges.end(DDAtomRanges::Type::Constraints), nat_f_novirsum);
+ forcerec_set_ranges(fr,
+ comm->atomRanges.end(DDAtomRanges::Type::Zones),
+ comm->atomRanges.end(DDAtomRanges::Type::Constraints),
+ nat_f_novirsum);
/* Update atom data for mdatoms and several algorithms */
mdAlgorithmsSetupAtomData(cr, ir, top_global, top_local, fr, f, mdAtoms, constr, vsite, nullptr);
if (!thisRankHasDuty(cr, DUTY_PME))
{
/* Send the charges and/or c6/sigmas to our PME only node */
- gmx_pme_send_parameters(cr, fr->ic, mdatoms->nChargePerturbed != 0,
- mdatoms->nTypePerturbed != 0, mdatoms->chargeA, mdatoms->chargeB,
- mdatoms->sqrt_c6A, mdatoms->sqrt_c6B, mdatoms->sigmaA,
- mdatoms->sigmaB, dd_pme_maxshift_x(dd), dd_pme_maxshift_y(dd));
+ gmx_pme_send_parameters(cr,
+ fr->ic,
+ mdatoms->nChargePerturbed != 0,
+ mdatoms->nTypePerturbed != 0,
+ mdatoms->chargeA,
+ mdatoms->chargeB,
+ mdatoms->sqrt_c6A,
+ mdatoms->sqrt_c6B,
+ mdatoms->sigmaA,
+ mdatoms->sigmaB,
+ dd_pme_maxshift_x(dd),
+ dd_pme_maxshift_y(dd));
}
if (dd->atomSets != nullptr)
if (comm->ddSettings.nstDDDump > 0 && step % comm->ddSettings.nstDDDump == 0)
{
dd_move_x(dd, state_local->box, state_local->x, nullWallcycle);
- write_dd_pdb("dd_dump", step, "dump", &top_global, cr, -1, state_local->x.rvec_array(),
+ write_dd_pdb("dd_dump",
+ step,
+ "dump",
+ &top_global,
+ cr,
+ -1,
+ state_local->x.rvec_array(),
state_local->box);
}
{
if (totalNumberOfBondedInteractions != cr->dd->nbonded_global)
{
- dd_print_missing_interactions(mdlog, cr, totalNumberOfBondedInteractions, top_global,
- top_local, x, box); // Does not return
+ dd_print_missing_interactions(
+ mdlog, cr, totalNumberOfBondedInteractions, top_global, top_local, x, box); // Does not return
}
*shouldCheckNumberOfBondedInteractions = false;
}
mesg += gmx::formatString(" in direction %c\n", dim2char(dim));
fprintf(fplog, "%s", mesg.c_str());
- fprintf(fplog, "distance out of cell %f\n",
+ fprintf(fplog,
+ "distance out of cell %f\n",
dir == 1 ? pos_d - comm->cell_x1[dim] : pos_d - comm->cell_x0[dim]);
if (bHaveCgcmOld)
{
fprintf(fplog, "Old coordinates: %8.3f %8.3f %8.3f\n", cm_old[XX], cm_old[YY], cm_old[ZZ]);
}
fprintf(fplog, "New coordinates: %8.3f %8.3f %8.3f\n", cm_new[XX], cm_new[YY], cm_new[ZZ]);
- fprintf(fplog, "Old cell boundaries in direction %c: %8.3f %8.3f\n", dim2char(dim),
- comm->old_cell_x0[dim], comm->old_cell_x1[dim]);
- fprintf(fplog, "New cell boundaries in direction %c: %8.3f %8.3f\n", dim2char(dim),
- comm->cell_x0[dim], comm->cell_x1[dim]);
+ fprintf(fplog,
+ "Old cell boundaries in direction %c: %8.3f %8.3f\n",
+ dim2char(dim),
+ comm->old_cell_x0[dim],
+ comm->old_cell_x1[dim]);
+ fprintf(fplog,
+ "New cell boundaries in direction %c: %8.3f %8.3f\n",
+ dim2char(dim),
+ comm->cell_x0[dim],
+ comm->cell_x1[dim]);
}
[[noreturn]] static void cg_move_error(FILE* fplog,
{
if (pos_d >= moveLimits.upper[d])
{
- cg_move_error(fplog, dd, step, a, d, 1, false, moveLimits.distance[d],
- cm_new, cm_new, pos_d);
+ cg_move_error(
+ fplog, dd, step, a, d, 1, false, moveLimits.distance[d], cm_new, cm_new, pos_d);
}
dev[d] = 1;
if (dd->ci[d] == dd->numCells[d] - 1)
{
if (pos_d < moveLimits.lower[d])
{
- cg_move_error(fplog, dd, step, a, d, -1, false, moveLimits.distance[d],
- cm_new, cm_new, pos_d);
+ cg_move_error(
+ fplog, dd, step, a, d, -1, false, moveLimits.distance[d], cm_new, cm_new, pos_d);
}
dev[d] = -1;
if (dd->ci[d] == 0)
{
if (pos_d >= moveLimits.upper[d])
{
- cg_move_error(fplog, dd, step, g, d, 1, true, moveLimits.distance[d],
- cogOld, cog, pos_d);
+ cg_move_error(
+ fplog, dd, step, g, d, 1, true, moveLimits.distance[d], cogOld, cog, pos_d);
}
dev[d] = 1;
if (dd->ci[d] == dd->numCells[d] - 1)
{
if (pos_d < moveLimits.lower[d])
{
- cg_move_error(fplog, dd, step, g, d, -1, true, moveLimits.distance[d],
- cogOld, cog, pos_d);
+ cg_move_error(
+ fplog, dd, step, g, d, -1, true, moveLimits.distance[d], cogOld, cog, pos_d);
}
dev[d] = -1;
if (dd->ci[d] == 0)
{
const auto& updateGroupsCog = *comm->updateGroupsCog;
const int numGroups = updateGroupsCog.numCogs();
- calcGroupMove(fplog, step, dd, state, tric_dir, tcm, cell_x0, cell_x1, moveLimits,
- (thread * numGroups) / nthread, ((thread + 1) * numGroups) / nthread,
+ calcGroupMove(fplog,
+ step,
+ dd,
+ state,
+ tric_dir,
+ tcm,
+ cell_x0,
+ cell_x1,
+ moveLimits,
+ (thread * numGroups) / nthread,
+ ((thread + 1) * numGroups) / nthread,
pbcAndFlags);
/* We need a barrier as atoms below can be in a COG of a different thread */
#pragma omp barrier
const int numHomeAtoms = comm->atomRanges.numHomeAtoms();
- applyPbcAndSetMoveFlags(updateGroupsCog, pbcAndFlags, (thread * numHomeAtoms) / nthread,
- ((thread + 1) * numHomeAtoms) / nthread, state->x, move);
+ applyPbcAndSetMoveFlags(updateGroupsCog,
+ pbcAndFlags,
+ (thread * numHomeAtoms) / nthread,
+ ((thread + 1) * numHomeAtoms) / nthread,
+ state->x,
+ move);
}
else
{
/* Here we handle single atoms or charge groups */
- calc_cg_move(fplog, step, dd, state, tric_dir, tcm, cell_x0, cell_x1, moveLimits,
+ calc_cg_move(fplog,
+ step,
+ dd,
+ state,
+ tric_dir,
+ tcm,
+ cell_x0,
+ cell_x1,
+ moveLimits,
(thread * dd->ncg_home) / nthread,
- ((thread + 1) * dd->ncg_home) / nthread, move);
+ ((thread + 1) * dd->ncg_home) / nthread,
+ move);
}
}
GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
flagBuffer.resize((ncg_recv + rbuf[0]) * DD_CGIBS);
/* Communicate the charge group indices, sizes and flags */
- ddSendrecv(dd, d, dir, comm->cggl_flag[cdd].data(), sbuf[0] * DD_CGIBS,
- flagBuffer.buffer.data() + ncg_recv * DD_CGIBS, rbuf[0] * DD_CGIBS);
+ ddSendrecv(dd,
+ d,
+ dir,
+ comm->cggl_flag[cdd].data(),
+ sbuf[0] * DD_CGIBS,
+ flagBuffer.buffer.data() + ncg_recv * DD_CGIBS,
+ rbuf[0] * DD_CGIBS);
const int nvs = ncg[cdd] + nat[cdd] * nvec;
const int i = rbuf[0] + rbuf[1] * nvec;
rvecBuffer.resize(nvr + i);
/* Communicate cgcm and state */
- ddSendrecv(dd, d, dir, as_rvec_array(comm->cgcm_state[cdd].data()), nvs,
- as_rvec_array(rvecBuffer.buffer.data()) + nvr, i);
+ ddSendrecv(dd,
+ d,
+ dir,
+ as_rvec_array(comm->cgcm_state[cdd].data()),
+ nvs,
+ as_rvec_array(rvecBuffer.buffer.data()) + nvr,
+ i);
ncg_recv += rbuf[0];
nvr += i;
}
|| ((flag & DD_FLAG_BW(d)) && cog[dim] < cell_x0[dim]))
{
rvec pos = { cog[0], cog[1], cog[2] };
- cg_move_error(fplog, dd, step, cg, dim, (flag & DD_FLAG_FW(d)) ? 1 : 0, false,
- 0, pos, pos, pos[dim]);
+ cg_move_error(
+ fplog, dd, step, cg, dim, (flag & DD_FLAG_FW(d)) ? 1 : 0, false, 0, pos, pos, pos[dim]);
}
}
}
/* Copy from the receive to the send buffers */
memcpy(comm->cggl_flag[mc].data() + ncg[mc] * DD_CGIBS,
- flagBuffer.buffer.data() + cg * DD_CGIBS, DD_CGIBS * sizeof(int));
- memcpy(comm->cgcm_state[mc][nvr], rvecBuffer.buffer.data() + buf_pos,
+ flagBuffer.buffer.data() + cg * DD_CGIBS,
+ DD_CGIBS * sizeof(int));
+ memcpy(comm->cgcm_state[mc][nvr],
+ rvecBuffer.buffer.data() + buf_pos,
(1 + nrcg * nvec) * sizeof(rvec));
buf_pos += 1 + nrcg * nvec;
ncg[mc] += 1;
if (debug)
{
- fprintf(debug, "Finished repartitioning: cgs moved out %d, new home %d\n", *ncg_moved,
+ fprintf(debug,
+ "Finished repartitioning: cgs moved out %d, new home %d\n",
+ *ncg_moved,
dd->ncg_home - *ncg_moved);
}
}
{
for (int pulse = 0; pulse < dd->comm->cd[d].numPulses(); pulse++)
{
- gpuHaloExchange[d].push_back(GpuHaloExchange(dd, d, MPI_COMM_WORLD, deviceContext,
- deviceStream, deviceStream, pulse, nullptr));
+ gpuHaloExchange[d].push_back(GpuHaloExchange(
+ dd, d, MPI_COMM_WORLD, deviceContext, deviceStream, deviceStream, pulse, nullptr));
}
}
haloCompletedEvent.waitForEvent();
// Copy results back to host
- copyFromDeviceBuffer(h_x->data(), &d_x, 0, numAtomsTotal, deviceStream,
- GpuApiCallBehavior::Sync, nullptr);
+ copyFromDeviceBuffer(
+ h_x->data(), &d_x, 0, numAtomsTotal, deviceStream, GpuApiCallBehavior::Sync, nullptr);
freeDeviceBuffer(d_x);
#else
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2014,2015, by the GROMACS development team, led by
+# Copyright (c) 2014,2015,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.
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+add_library(essentialdynamics INTERFACE)
+
file(GLOB ESSENTIALDYNAMICS_SOURCES *.cpp)
+
+# Source files have the following private module dependencies.
+target_link_libraries(essentialdynamics PRIVATE
+ # gmxlib
+ # math
+ # mdtypes
+ # tng_io
+ )
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(essentialdynamics PUBLIC
+target_include_directories(essentialdynamics INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(essentialdynamics PUBLIC
+target_link_libraries(essentialdynamics INTERFACE
+ legacy_api
+ )
+
+# TODO: when fileio is an OBJECT target
+#target_link_libraries(fileio PUBLIC legacy_api)
+#target_link_libraries(fileio PRIVATE common)
+
+# Module dependencies
+# fileio interfaces convey transitive dependence on these modules.
+#target_link_libraries(essentialdynamics PUBLIC
+target_link_libraries(essentialdynamics INTERFACE
+ utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(essentialdynamics PRIVATE tng_io)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(essentialdynamics PRIVATE legacy_modules)
+
set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${ESSENTIALDYNAMICS_SOURCES} PARENT_SCOPE)
if (BUILD_TESTING)
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
rad += gmx::square((vec.refproj[i] - vec.xproj[i]));
}
- return rad = sqrt(rad);
+ return sqrt(rad);
}
} // namespace
/* Broadcast the positions of the AVERAGE structure such that they are known on
* every processor. Each node contributes its local positions x and stores them in
* the collective ED array buf->xcoll */
- communicate_group_positions(cr, buf->xcoll, buf->shifts_xcoll, buf->extra_shifts_xcoll, bNS, x,
- edi->sav.nr, edi->sav.nr_loc, edi->sav.anrs_loc, edi->sav.c_ind,
- edi->sav.x_old, box);
+ communicate_group_positions(cr,
+ buf->xcoll,
+ buf->shifts_xcoll,
+ buf->extra_shifts_xcoll,
+ bNS,
+ x,
+ edi->sav.nr,
+ edi->sav.nr_loc,
+ edi->sav.anrs_loc,
+ edi->sav.c_ind,
+ edi->sav.x_old,
+ box);
/* Only assembly REFERENCE positions if their indices differ from the average ones */
if (!edi->bRefEqAv)
{
- communicate_group_positions(cr, buf->xc_ref, buf->shifts_xc_ref, buf->extra_shifts_xc_ref,
- bNS, x, edi->sref.nr, edi->sref.nr_loc, edi->sref.anrs_loc,
- edi->sref.c_ind, edi->sref.x_old, box);
+ communicate_group_positions(cr,
+ buf->xc_ref,
+ buf->shifts_xc_ref,
+ buf->extra_shifts_xc_ref,
+ bNS,
+ x,
+ edi->sref.nr,
+ edi->sref.nr_loc,
+ edi->sref.anrs_loc,
+ edi->sref.c_ind,
+ edi->sref.x_old,
+ box);
}
/* If bUpdateShifts was TRUE, the shifts have just been updated in get_positions.
/* If in any of the ED groups we find a flooding vector, flooding is turned on */
ed->eEDtype = EssentialDynamicsType::Flooding;
- fprintf(stderr, "ED: Flooding %d eigenvector%s.\n", edi->flood.vecs.neig,
+ fprintf(stderr,
+ "ED: Flooding %d eigenvector%s.\n",
+ edi->flood.vecs.neig,
edi->flood.vecs.neig > 1 ? "s" : "");
if (edi->flood.bConstForce)
{
edi->flood.vecs.fproj[i] = edi->flood.vecs.stpsz[i];
- fprintf(stderr, "ED: applying on eigenvector %d a constant force of %g\n",
- edi->flood.vecs.ieig[i], edi->flood.vecs.fproj[i]);
+ fprintf(stderr,
+ "ED: applying on eigenvector %d a constant force of %g\n",
+ edi->flood.vecs.ieig[i],
+ edi->flood.vecs.fproj[i]);
}
}
}
}
else
{
- ed->edo = xvgropen(edoFileName, "Essential dynamics / flooding output", "Time (ps)",
- "RMSDs (nm), projections on EVs (nm), ...", oenv);
+ ed->edo = xvgropen(edoFileName,
+ "Essential dynamics / flooding output",
+ "Time (ps)",
+ "RMSDs (nm), projections on EVs (nm), ...",
+ oenv);
/* Make a descriptive legend */
write_edo_legend(ed, EDstate->nED, oenv);
* There, also memory is allocated */
s->nalloc_loc = 0; /* allocation size of s->anrs_loc */
snew_bc(MASTER(cr), s->x_old, s->nr); /* To be able to always make the ED molecule whole, ... */
- nblock_bc(cr->mpi_comm_mygroup, s->nr,
- s->x_old); /* ... keep track of shift changes with the help of old coords */
+ nblock_bc(cr->mpi_comm_mygroup, s->nr, s->x_old); /* ... keep track of shift changes with the help of old coords */
}
/* broadcast masses for the reference structure (for mass-weighted fitting) */
block_bc(cr->mpi_comm_mygroup, edi);
/* Broadcast positions */
- bc_ed_positions(cr, &(edi.sref),
- EssentialDynamicsStructure::Reference); /* reference positions (don't broadcast masses) */
- bc_ed_positions(cr, &(edi.sav),
- EssentialDynamicsStructure::Average); /* average positions (do broadcast masses as well) */
+ bc_ed_positions(cr, &(edi.sref), EssentialDynamicsStructure::Reference); /* reference positions (don't broadcast masses) */
+ bc_ed_positions(cr, &(edi.sav), EssentialDynamicsStructure::Average); /* average positions (do broadcast masses as well) */
bc_ed_positions(cr, &(edi.star), EssentialDynamicsStructure::Target); /* target positions */
bc_ed_positions(cr, &(edi.sori), EssentialDynamicsStructure::Origin); /* origin positions */
">0.\n"
"Either make the covariance analysis non-mass-weighted, or exclude massless\n"
"atoms from the reference structure by creating a proper index group.\n",
- i, edi->sref.anrs[i] + 1, edi->sref.m[i]);
+ i,
+ edi->sref.anrs[i] + 1,
+ edi->sref.m[i]);
}
totalmass += edi->sref.m[i];
">0.\n"
"Either make the covariance analysis non-mass-weighted, or exclude massless\n"
"atoms from the average structure by creating a proper index group.\n",
- i, edi->sav.anrs[i] + 1, edi->sav.m[i]);
+ i,
+ edi->sav.anrs[i] + 1,
+ edi->sav.m[i]);
}
}
gmx_fatal(FARGS,
"Could not find input parameter %s at expected position in edsam input-file "
"(.edi)\nline read instead is %s",
- label, line);
+ label,
+ line);
}
}
double stepSize = 0.;
double referenceProjection = 0.;
double referenceSlope = 0.;
- const int nscan = sscanf(line, max_ev_fmt_dlflflf, &numEigenVectors, &stepSize,
- &referenceProjection, &referenceSlope);
+ const int nscan = sscanf(
+ line, max_ev_fmt_dlflflf, &numEigenVectors, &stepSize, &referenceProjection, &referenceSlope);
/* Zero out values which were not scanned */
switch (nscan)
{
edi.nini = read_edint(in, &bEOF);
if (edi.nini != nr_mdatoms)
{
- gmx_fatal(FARGS, "Nr of atoms in %s (%d) does not match nr of md atoms (%d)", fn, edi.nini,
- nr_mdatoms);
+ gmx_fatal(FARGS, "Nr of atoms in %s (%d) does not match nr of md atoms (%d)", fn, edi.nini, nr_mdatoms);
}
/* Done checking. For the rest we blindly trust the input */
bool bHaveReference = false;
if (edi.flood.bHarmonic)
{
- bHaveReference = readEdVecWithReferenceProjection(in, edi.sav.nr, &edi.flood.vecs,
+ bHaveReference = readEdVecWithReferenceProjection(in,
+ edi.sav.nr,
+ &edi.flood.vecs,
&edi.flood.initialReferenceProjection,
&edi.flood.referenceProjectionSlope);
}
gmx_fatal(FARGS, "No complete ED data set found in edi file %s.", fn);
}
- fprintf(stderr, "ED: Found %zu ED group%s.\n", essentialDynamicsParameters.size(),
+ fprintf(stderr,
+ "ED: Found %zu ED group%s.\n",
+ essentialDynamicsParameters.size(),
essentialDynamicsParameters.size() > 1 ? "s" : "");
/* Close the .edi file again */
* if their indices differ from the average ones */
if (!edi.bRefEqAv)
{
- dd_make_local_group_indices(dd->ga2la, edi.sref.nr, edi.sref.anrs, &edi.sref.nr_loc,
- &edi.sref.anrs_loc, &edi.sref.nalloc_loc, edi.sref.c_ind);
+ dd_make_local_group_indices(dd->ga2la,
+ edi.sref.nr,
+ edi.sref.anrs,
+ &edi.sref.nr_loc,
+ &edi.sref.anrs_loc,
+ &edi.sref.nalloc_loc,
+ edi.sref.c_ind);
}
/* Local atoms of the average structure (on these ED will be performed) */
- dd_make_local_group_indices(dd->ga2la, edi.sav.nr, edi.sav.anrs, &edi.sav.nr_loc,
- &edi.sav.anrs_loc, &edi.sav.nalloc_loc, edi.sav.c_ind);
+ dd_make_local_group_indices(dd->ga2la,
+ edi.sav.nr,
+ edi.sav.anrs,
+ &edi.sav.nr_loc,
+ &edi.sav.anrs_loc,
+ &edi.sav.nalloc_loc,
+ edi.sav.c_ind);
/* Indicate that the ED shift vectors for this structure need to be updated
* at the next call to communicate_group_positions, since obviously we are in a NS step */
gmx_fatal(FARGS,
"The number of reference structure atoms in ED group %c is\n"
"not the same in .cpt (NREF=%d) and .edi (NREF=%d) files!\n",
- get_EDgroupChar(edinum + 1, 0), EDstate->nref[edinum], ed.edpar[edinum].sref.nr);
+ get_EDgroupChar(edinum + 1, 0),
+ EDstate->nref[edinum],
+ ed.edpar[edinum].sref.nr);
}
if (EDstate->nav[edinum] != ed.edpar[edinum].sav.nr)
{
gmx_fatal(FARGS,
"The number of average structure atoms in ED group %c is\n"
"not the same in .cpt (NREF=%d) and .edi (NREF=%d) files!\n",
- get_EDgroupChar(edinum + 1, 0), EDstate->nav[edinum], ed.edpar[edinum].sav.nr);
+ get_EDgroupChar(edinum + 1, 0),
+ EDstate->nav[edinum],
+ ed.edpar[edinum].sav.nr);
}
}
"The number of essential dynamics / flooding groups is not consistent.\n"
"There are %d ED groups in the .cpt file, but %zu in the .edi file!\n"
"Are you sure this is the correct .edi file?\n",
- EDstate->nED, ed.edpar.size());
+ EDstate->nED,
+ ed.edpar.size());
}
}
auto edi = ed->edpar.begin();
- fprintf(ed->edo, "# Output will be written every %d step%s\n", edi->outfrq,
- edi->outfrq != 1 ? "s" : "");
+ fprintf(ed->edo, "# Output will be written every %d step%s\n", edi->outfrq, edi->outfrq != 1 ? "s" : "");
for (nr_edi = 1; nr_edi <= nED; nr_edi++)
{
fprintf(ed->edo, "#\n");
- fprintf(ed->edo, "# Summary of applied con/restraints for the ED group %c\n",
+ fprintf(ed->edo,
+ "# Summary of applied con/restraints for the ED group %c\n",
get_EDgroupChar(nr_edi, nED));
fprintf(ed->edo, "# Atoms in average structure: %d\n", edi->sav.nr);
- fprintf(ed->edo, "# monitor : %d vec%s\n", edi->vecs.mon.neig,
- edi->vecs.mon.neig != 1 ? "s" : "");
- fprintf(ed->edo, "# LINFIX : %d vec%s\n", edi->vecs.linfix.neig,
+ fprintf(ed->edo, "# monitor : %d vec%s\n", edi->vecs.mon.neig, edi->vecs.mon.neig != 1 ? "s" : "");
+ fprintf(ed->edo,
+ "# LINFIX : %d vec%s\n",
+ edi->vecs.linfix.neig,
edi->vecs.linfix.neig != 1 ? "s" : "");
- fprintf(ed->edo, "# LINACC : %d vec%s\n", edi->vecs.linacc.neig,
+ fprintf(ed->edo,
+ "# LINACC : %d vec%s\n",
+ edi->vecs.linacc.neig,
edi->vecs.linacc.neig != 1 ? "s" : "");
- fprintf(ed->edo, "# RADFIX : %d vec%s\n", edi->vecs.radfix.neig,
+ fprintf(ed->edo,
+ "# RADFIX : %d vec%s\n",
+ edi->vecs.radfix.neig,
edi->vecs.radfix.neig != 1 ? "s" : "");
- fprintf(ed->edo, "# RADACC : %d vec%s\n", edi->vecs.radacc.neig,
+ fprintf(ed->edo,
+ "# RADACC : %d vec%s\n",
+ edi->vecs.radacc.neig,
edi->vecs.radacc.neig != 1 ? "s" : "");
- fprintf(ed->edo, "# RADCON : %d vec%s\n", edi->vecs.radcon.neig,
+ fprintf(ed->edo,
+ "# RADCON : %d vec%s\n",
+ edi->vecs.radcon.neig,
edi->vecs.radcon.neig != 1 ? "s" : "");
- fprintf(ed->edo, "# FLOODING : %d vec%s ", edi->flood.vecs.neig,
- edi->flood.vecs.neig != 1 ? "s" : "");
+ fprintf(ed->edo, "# FLOODING : %d vec%s ", edi->flood.vecs.neig, edi->flood.vecs.neig != 1 ? "s" : "");
if (edi->flood.vecs.neig)
{
nice_legend(&setname, &nsets, &LegendStr, "RMSD to ref", "nm", get_EDgroupChar(nr_edi, nED));
/* Essential dynamics, projections on eigenvectors */
- nice_legend_evec(&setname, &nsets, &LegendStr, &edi->vecs.mon,
- get_EDgroupChar(nr_edi, nED), "MON");
- nice_legend_evec(&setname, &nsets, &LegendStr, &edi->vecs.linfix,
- get_EDgroupChar(nr_edi, nED), "LINFIX");
- nice_legend_evec(&setname, &nsets, &LegendStr, &edi->vecs.linacc,
- get_EDgroupChar(nr_edi, nED), "LINACC");
- nice_legend_evec(&setname, &nsets, &LegendStr, &edi->vecs.radfix,
- get_EDgroupChar(nr_edi, nED), "RADFIX");
+ nice_legend_evec(&setname,
+ &nsets,
+ &LegendStr,
+ &edi->vecs.mon,
+ get_EDgroupChar(nr_edi, nED),
+ "MON");
+ nice_legend_evec(&setname,
+ &nsets,
+ &LegendStr,
+ &edi->vecs.linfix,
+ get_EDgroupChar(nr_edi, nED),
+ "LINFIX");
+ nice_legend_evec(&setname,
+ &nsets,
+ &LegendStr,
+ &edi->vecs.linacc,
+ get_EDgroupChar(nr_edi, nED),
+ "LINACC");
+ nice_legend_evec(&setname,
+ &nsets,
+ &LegendStr,
+ &edi->vecs.radfix,
+ get_EDgroupChar(nr_edi, nED),
+ "RADFIX");
if (edi->vecs.radfix.neig)
{
- nice_legend(&setname, &nsets, &LegendStr, "RADFIX radius", "nm",
- get_EDgroupChar(nr_edi, nED));
+ nice_legend(&setname, &nsets, &LegendStr, "RADFIX radius", "nm", get_EDgroupChar(nr_edi, nED));
}
- nice_legend_evec(&setname, &nsets, &LegendStr, &edi->vecs.radacc,
- get_EDgroupChar(nr_edi, nED), "RADACC");
+ nice_legend_evec(&setname,
+ &nsets,
+ &LegendStr,
+ &edi->vecs.radacc,
+ get_EDgroupChar(nr_edi, nED),
+ "RADACC");
if (edi->vecs.radacc.neig)
{
- nice_legend(&setname, &nsets, &LegendStr, "RADACC radius", "nm",
- get_EDgroupChar(nr_edi, nED));
+ nice_legend(&setname, &nsets, &LegendStr, "RADACC radius", "nm", get_EDgroupChar(nr_edi, nED));
}
- nice_legend_evec(&setname, &nsets, &LegendStr, &edi->vecs.radcon,
- get_EDgroupChar(nr_edi, nED), "RADCON");
+ nice_legend_evec(&setname,
+ &nsets,
+ &LegendStr,
+ &edi->vecs.radcon,
+ get_EDgroupChar(nr_edi, nED),
+ "RADCON");
if (edi->vecs.radcon.neig)
{
- nice_legend(&setname, &nsets, &LegendStr, "RADCON radius", "nm",
- get_EDgroupChar(nr_edi, nED));
+ nice_legend(&setname, &nsets, &LegendStr, "RADCON radius", "nm", get_EDgroupChar(nr_edi, nED));
}
}
++edi;
fprintf(ed->edo,
"#\n"
"# Legend for %d column%s of flooding plus %d column%s of essential dynamics data:\n",
- n_flood, 1 == n_flood ? "" : "s", n_edsam, 1 == n_edsam ? "" : "s");
+ n_flood,
+ 1 == n_flood ? "" : "s",
+ n_edsam,
+ 1 == n_edsam ? "" : "s");
fprintf(ed->edo, "%s", LegendStr);
sfree(LegendStr);
/* Output how well we fit to the reference at the start */
translate_and_rotate(xfit, edi->sref.nr, fit_transvec, fit_rotmat);
- fprintf(stderr, "ED: Initial RMSD from reference after fit = %f nm",
+ fprintf(stderr,
+ "ED: Initial RMSD from reference after fit = %f nm",
rmsd_from_structure(xfit, &edi->sref));
if (EDstate->nED > 1)
{
{
for (i = 0; i < edi->flood.vecs.neig; i++)
{
- fprintf(stdout, "ED: EV %d flooding potential center: %11.4e",
- edi->flood.vecs.ieig[i], edi->flood.vecs.refproj[i]);
+ fprintf(stdout,
+ "ED: EV %d flooding potential center: %11.4e",
+ edi->flood.vecs.ieig[i],
+ edi->flood.vecs.refproj[i]);
if (edi->flood.bHarmonic)
{
- fprintf(stdout, " (adding %11.4e/timestep)",
- edi->flood.referenceProjectionSlope[i]);
+ fprintf(stdout, " (adding %11.4e/timestep)", edi->flood.referenceProjectionSlope[i]);
}
fprintf(stdout, "\n");
}
* the collective buf->xcoll array. Note that for edinr > 1
* xs could already have been modified by an earlier ED */
- communicate_group_positions(cr, buf->xcoll, buf->shifts_xcoll, buf->extra_shifts_xcoll,
- PAR(cr) ? buf->bUpdateShifts : TRUE, xs, edi.sav.nr, edi.sav.nr_loc,
- edi.sav.anrs_loc, edi.sav.c_ind, edi.sav.x_old, box);
+ communicate_group_positions(cr,
+ buf->xcoll,
+ buf->shifts_xcoll,
+ buf->extra_shifts_xcoll,
+ PAR(cr) ? buf->bUpdateShifts : TRUE,
+ xs,
+ edi.sav.nr,
+ edi.sav.nr_loc,
+ edi.sav.anrs_loc,
+ edi.sav.c_ind,
+ edi.sav.x_old,
+ box);
/* Only assembly reference positions if their indices differ from the average ones */
if (!edi.bRefEqAv)
{
- communicate_group_positions(
- cr, buf->xc_ref, buf->shifts_xc_ref, buf->extra_shifts_xc_ref,
- PAR(cr) ? buf->bUpdateShifts : TRUE, xs, edi.sref.nr, edi.sref.nr_loc,
- edi.sref.anrs_loc, edi.sref.c_ind, edi.sref.x_old, box);
+ communicate_group_positions(cr,
+ buf->xc_ref,
+ buf->shifts_xc_ref,
+ buf->extra_shifts_xc_ref,
+ PAR(cr) ? buf->bUpdateShifts : TRUE,
+ xs,
+ edi.sref.nr,
+ edi.sref.nr_loc,
+ edi.sref.anrs_loc,
+ edi.sref.c_ind,
+ edi.sref.x_old,
+ box);
}
/* If bUpdateShifts was TRUE then the shifts have just been updated in communicate_group_positions.
for (i = 0; i < edi.sav.nr_loc; i++)
{
/* Unshift local ED coordinate and store in x_unsh */
- ed_unshift_single_coord(box, buf->xcoll[edi.sav.c_ind[i]],
- buf->shifts_xcoll[edi.sav.c_ind[i]], x_unsh);
+ ed_unshift_single_coord(
+ box, buf->xcoll[edi.sav.c_ind[i]], buf->shifts_xcoll[edi.sav.c_ind[i]], x_unsh);
/* dx is the ED correction to the positions: */
rvec_sub(x_unsh, xs[edi.sav.anrs_loc[i]], dx);
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/math/vectypes.h"
#include "gromacs/utility/basedefinitions.h"
-#include "gromacs/utility/classhelpers.h"
/*! \brief Abstract type for essential dynamics
*
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
class MDLogger;
} // namespace gmx
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+# Set up the module library
+add_library(ewald INTERFACE)
gmx_add_libgromacs_sources(
calculate_spline_moduli.cpp
ewald.cpp
)
endif()
+# Source files have the following private module dependencies.
+target_link_libraries(ewald PRIVATE
+ # gmxlib
+ # math
+ # mdtypes
+ # tng_io
+ )
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(ewald PUBLIC
+target_include_directories(ewald INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(ewald PUBLIC
+target_link_libraries(ewald INTERFACE
+ legacy_api
+ )
+
+# TODO: when fileio is an OBJECT target
+#target_link_libraries(ewald PUBLIC legacy_api)
+#target_link_libraries(ewald PRIVATE common)
+
+# Module dependencies
+# This module convey transitive dependence on these modules.
+#target_link_libraries(ewald PUBLIC
+target_link_libraries(ewald INTERFACE
+ # utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(ewald PRIVATE tng_io)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(ewald PRIVATE legacy_modules)
+
if (BUILD_TESTING)
add_subdirectory(tests)
endif()
if (debug)
{
fprintf(debug, "Long Range corrections for Ewald interactions:\n");
- fprintf(debug, "q2sum = %g, Vself_q=%g\n", L1_q * fr.q2sum[0] + lambda_q * fr.q2sum[1],
+ fprintf(debug,
+ "q2sum = %g, Vself_q=%g\n",
+ L1_q * fr.q2sum[0] + lambda_q * fr.q2sum[1],
L1_q * Vself_q[0] + lambda_q * Vself_q[1]);
fprintf(debug, "Electrostatic Long Range correction: Vexcl=%g\n", Vexcl_q);
if (MASTER(cr) && thread == 0)
{
if (ir.epsilon_surface > 0 || ir.ewald_geometry == eewg3DC)
{
- fprintf(debug, "Total dipole correction: Vdipole=%g\n",
+ fprintf(debug,
+ "Total dipole correction: Vdipole=%g\n",
L1_q * Vdipole[0] + lambda_q * Vdipole[1]);
}
}
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 The GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
MPI_Status stat;
for (size_t b = 0; b < ol->comm_data.size(); b++)
{
- MPI_Sendrecv(&ol->send_size, 1, MPI_INT, ol->comm_data[b].send_id, b, &ol->comm_data[b].recv_size,
- 1, MPI_INT, ol->comm_data[b].recv_id, b, ol->mpi_comm, &stat);
+ MPI_Sendrecv(&ol->send_size,
+ 1,
+ MPI_INT,
+ ol->comm_data[b].send_id,
+ b,
+ &ol->comm_data[b].recv_size,
+ 1,
+ MPI_INT,
+ ol->comm_data[b].recv_id,
+ b,
+ ol->mpi_comm,
+ &stat);
}
#endif
std::string message = gmx::formatString(
"pme_order (%d) is larger than the maximum allowed value (%d). Modify and "
"recompile the code if you really need such a high order.",
- pme_order, PME_ORDER_MAX);
+ pme_order,
+ PME_ORDER_MAX);
GMX_THROW(gmx::InconsistentInputError(message));
}
"threads, the number of grid lines per rank along x should be >= pme_order (%d) "
"or = pmeorder-1. To resolve this issue, use fewer ranks along x (and possibly "
"more along y and/or z) by specifying -dd manually.",
- nkx / static_cast<double>(numPmeDomainsAlongX), pme_order);
+ nkx / static_cast<double>(numPmeDomainsAlongX),
+ pme_order);
}
return true;
pme->ndecompdim = 2;
#if GMX_MPI
- MPI_Comm_split(pme->mpi_comm, pme->nodeid % numPmeDomains.y, pme->nodeid,
+ MPI_Comm_split(pme->mpi_comm,
+ pme->nodeid % numPmeDomains.y,
+ pme->nodeid,
&pme->mpi_comm_d[0]); /* My communicator along major dimension */
- MPI_Comm_split(pme->mpi_comm, pme->nodeid / numPmeDomains.y, pme->nodeid,
+ MPI_Comm_split(pme->mpi_comm,
+ pme->nodeid / numPmeDomains.y,
+ pme->nodeid,
&pme->mpi_comm_d[1]); /* My communicator along minor dimension */
MPI_Comm_rank(pme->mpi_comm_d[0], &pme->nodeid_major);
pme->boxScaler = new EwaldBoxZScaler(*ir);
/* If we violate restrictions, generate a fatal error here */
- gmx_pme_check_restrictions(pme->pme_order, pme->nkx, pme->nky, pme->nkz, pme->nnodes_major,
- pme->bUseThreads, true);
+ gmx_pme_check_restrictions(
+ pme->pme_order, pme->nkx, pme->nky, pme->nkz, pme->nnodes_major, pme->bUseThreads, true);
if (pme->nnodes > 1)
{
" and PME grid_y (%d) and grid_z (%d) should be divisible by "
"#PME_ranks_y "
"(%d)",
- gmx::roundToInt((imbal - 1) * 100), pme->nkx, pme->nky,
- pme->nnodes_major, pme->nky, pme->nkz, pme->nnodes_minor);
+ gmx::roundToInt((imbal - 1) * 100),
+ pme->nkx,
+ pme->nky,
+ pme->nnodes_major,
+ pme->nky,
+ pme->nkz,
+ pme->nnodes_minor);
}
}
* y is always copied through a buffer: we don't need padding in z,
* but we do need the overlap in x because of the communication order.
*/
- init_overlap_comm(&pme->overlap[0], pme->pme_order, pme->mpi_comm_d[0], pme->nnodes_major,
- pme->nodeid_major, pme->nkx,
+ init_overlap_comm(&pme->overlap[0],
+ pme->pme_order,
+ pme->mpi_comm_d[0],
+ pme->nnodes_major,
+ pme->nodeid_major,
+ pme->nkx,
(div_round_up(pme->nky, pme->nnodes_minor) + pme->pme_order)
* (pme->nkz + pme->pme_order - 1));
* We do this with an offset buffer of equal size, so we need to allocate
* extra for the offset. That's what the (+1)*pme->nkz is for.
*/
- init_overlap_comm(&pme->overlap[1], pme->pme_order, pme->mpi_comm_d[1], pme->nnodes_minor,
- pme->nodeid_minor, pme->nky,
+ init_overlap_comm(&pme->overlap[1],
+ pme->pme_order,
+ pme->mpi_comm_d[1],
+ pme->nnodes_minor,
+ pme->nodeid_minor,
+ pme->nky,
(div_round_up(pme->nkx, pme->nnodes_major) + pme->pme_order + 1) * pme->nkz);
/* Double-check for a limitation of the (current) sum_fftgrid_dd code.
pme->pmegrid_start_iy = pme->overlap[1].s2g0[pme->nodeid_minor];
pme->pmegrid_start_iz = 0;
- make_gridindex_to_localindex(pme->nkx, pme->pmegrid_start_ix,
- pme->pmegrid_nx - (pme->pme_order - 1), &pme->nnx, &pme->fshx);
- make_gridindex_to_localindex(pme->nky, pme->pmegrid_start_iy,
- pme->pmegrid_ny - (pme->pme_order - 1), &pme->nny, &pme->fshy);
- make_gridindex_to_localindex(pme->nkz, pme->pmegrid_start_iz, pme->pmegrid_nz_base, &pme->nnz,
- &pme->fshz);
+ make_gridindex_to_localindex(
+ pme->nkx, pme->pmegrid_start_ix, pme->pmegrid_nx - (pme->pme_order - 1), &pme->nnx, &pme->fshx);
+ make_gridindex_to_localindex(
+ pme->nky, pme->pmegrid_start_iy, pme->pmegrid_ny - (pme->pme_order - 1), &pme->nny, &pme->fshy);
+ make_gridindex_to_localindex(
+ pme->nkz, pme->pmegrid_start_iz, pme->pmegrid_nz_base, &pme->nnz, &pme->fshz);
pme->spline_work = make_pme_spline_work(pme->pme_order);
|| (i >= DO_Q && pme->doLJ
&& (i == 2 || bFreeEnergy_lj || ir->ljpme_combination_rule == eljpmeLB)))
{
- pmegrids_init(&pme->pmegrid[i], pme->pmegrid_nx, pme->pmegrid_ny, pme->pmegrid_nz,
- pme->pmegrid_nz_base, pme->pme_order, pme->bUseThreads, pme->nthread,
+ pmegrids_init(&pme->pmegrid[i],
+ pme->pmegrid_nx,
+ pme->pmegrid_ny,
+ pme->pmegrid_nz,
+ pme->pmegrid_nz_base,
+ pme->pme_order,
+ pme->bUseThreads,
+ pme->nthread,
pme->overlap[0].s2g1[pme->nodeid_major]
- pme->overlap[0].s2g0[pme->nodeid_major + 1],
pme->overlap[1].s2g1[pme->nodeid_minor]
const auto allocateRealGridForGpu = (pme->runMode == PmeRunMode::Mixed)
? gmx::PinningPolicy::PinnedIfSupported
: gmx::PinningPolicy::CannotBePinned;
- gmx_parallel_3dfft_init(&pme->pfft_setup[i], ndata, &pme->fftgrid[i], &pme->cfftgrid[i],
- pme->mpi_comm_d, bReproducible, pme->nthread, allocateRealGridForGpu);
+ gmx_parallel_3dfft_init(&pme->pfft_setup[i],
+ ndata,
+ &pme->fftgrid[i],
+ &pme->cfftgrid[i],
+ pme->mpi_comm_d,
+ bReproducible,
+ pme->nthread,
+ allocateRealGridForGpu);
}
}
const gmx::MDLogger dummyLogger;
GMX_ASSERT(pmedata, "Invalid PME pointer");
NumPmeDomains numPmeDomains = { pme_src->nnodes_major, pme_src->nnodes_minor };
- *pmedata = gmx_pme_init(cr, numPmeDomains, &irc, pme_src->bFEP_q, pme_src->bFEP_lj, FALSE,
- ewaldcoeff_q, ewaldcoeff_lj, pme_src->nthread, pme_src->runMode,
- pme_src->gpu, nullptr, nullptr, nullptr, dummyLogger);
+ *pmedata = gmx_pme_init(cr,
+ numPmeDomains,
+ &irc,
+ pme_src->bFEP_q,
+ pme_src->bFEP_lj,
+ FALSE,
+ ewaldcoeff_q,
+ ewaldcoeff_lj,
+ pme_src->nthread,
+ pme_src->runMode,
+ pme_src->gpu,
+ nullptr,
+ nullptr,
+ nullptr,
+ dummyLogger);
/* When running PME on the CPU not using domain decomposition,
* the atom data is allocated once only in gmx_pme_(re)init().
*/
}
if (grid_index < DO_Q)
{
- loop_count = solve_pme_yzx(
- pme, cfftgrid, scaledBox[XX][XX] * scaledBox[YY][YY] * scaledBox[ZZ][ZZ],
- computeEnergyAndVirial, pme->nthread, thread);
+ loop_count = solve_pme_yzx(pme,
+ cfftgrid,
+ scaledBox[XX][XX] * scaledBox[YY][YY] * scaledBox[ZZ][ZZ],
+ computeEnergyAndVirial,
+ pme->nthread,
+ thread);
}
else
{
loop_count =
- solve_pme_lj_yzx(pme, &cfftgrid, FALSE,
+ solve_pme_lj_yzx(pme,
+ &cfftgrid,
+ FALSE,
scaledBox[XX][XX] * scaledBox[YY][YY] * scaledBox[ZZ][ZZ],
- computeEnergyAndVirial, pme->nthread, thread);
+ computeEnergyAndVirial,
+ pme->nthread,
+ thread);
}
if (thread == 0)
{
try
{
- gather_f_bsplines(pme, grid, bClearF, &atc, &atc.spline[thread],
+ gather_f_bsplines(pme,
+ grid,
+ bClearF,
+ &atc,
+ &atc.spline[thread],
pme->bFEP ? (grid_index % 2 == 0 ? 1.0 - lambda : lambda) : 1.0);
}
GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
}
- inc_nrnb(nrnb, eNR_GATHERFBSP,
- pme->pme_order * pme->pme_order * pme->pme_order * atc.numAtoms());
+ inc_nrnb(nrnb, eNR_GATHERFBSP, pme->pme_order * pme->pme_order * pme->pme_order * atc.numAtoms());
/* Note: this wallcycle region is opened above inside an OpenMP
region, so take care if refactoring code here. */
wallcycle_stop(wcycle, ewcPME_GATHER);
inc_nrnb(nrnb, eNR_WEIGHTS, DIM * atc.numAtoms());
}
- inc_nrnb(nrnb, eNR_SPREADBSP,
+ inc_nrnb(nrnb,
+ eNR_SPREADBSP,
pme->pme_order * pme->pme_order * pme->pme_order * atc.numAtoms());
if (pme->nthread == 1)
{
}
loop_count =
- solve_pme_lj_yzx(pme, &pme->cfftgrid[2], TRUE,
+ solve_pme_lj_yzx(pme,
+ &pme->cfftgrid[2],
+ TRUE,
scaledBox[XX][XX] * scaledBox[YY][YY] * scaledBox[ZZ][ZZ],
- computeEnergyAndVirial, pme->nthread, thread);
+ computeEnergyAndVirial,
+ pme->nthread,
+ thread);
if (thread == 0)
{
wallcycle_stop(wcycle, ewcLJPME);
{
try
{
- gather_f_bsplines(pme, grid, bClearF, &pme->atc[0],
- &pme->atc[0].spline[thread], scale);
+ gather_f_bsplines(
+ pme, grid, bClearF, &pme->atc[0], &pme->atc[0].spline[thread], scale);
}
GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
}
- inc_nrnb(nrnb, eNR_GATHERFBSP,
+ inc_nrnb(nrnb,
+ eNR_GATHERFBSP,
pme->pme_order * pme->pme_order * pme->pme_order * pme->atc[0].numAtoms());
}
wallcycle_stop(wcycle, ewcPME_GATHER);
{
return (pme.nkx == grid_size[XX] && pme.nky == grid_size[YY] && pme.nkz == grid_size[ZZ]);
}
+
+void gmx::SeparatePmeRanksPermitted::disablePmeRanks(const std::string& reason)
+{
+ permitSeparatePmeRanks_ = false;
+
+ if (!reason.empty())
+ {
+ reasons_.push_back(reason);
+ }
+}
+
+bool gmx::SeparatePmeRanksPermitted::permitSeparatePmeRanks() const
+{
+ return permitSeparatePmeRanks_;
+}
+
+std::string gmx::SeparatePmeRanksPermitted::reasonsWhyDisabled() const
+{
+ return joinStrings(reasons_, "; ");
+}
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#define GMX_EWALD_PME_H
#include <string>
+#include <vector>
#include "gromacs/gpu_utils/devicebuffer_datatype.h"
#include "gromacs/gpu_utils/gpu_macros.h"
class MDLogger;
enum class PinningPolicy : int;
class StepWorkload;
+
+/*! \libinternal \brief Class for managing usage of separate PME-only ranks
+ *
+ * Used for checking if some parts of the code could not use PME-only ranks
+ *
+ */
+class SeparatePmeRanksPermitted
+{
+public:
+ //! Disables PME ranks permitted flag with a reason
+ void disablePmeRanks(const std::string& reason);
+ //! Return status of PME ranks usage
+ bool permitSeparatePmeRanks() const;
+ //! Returns all reasons, for not using PME ranks
+ std::string reasonsWhyDisabled() const;
+
+private:
+ //! Flag that informs whether simualtion could use dedicated PME ranks
+ bool permitSeparatePmeRanks_ = true;
+ //! Storage for all reasons, why PME ranks could not be used
+ std::vector<std::string> reasons_;
+};
+
} // namespace gmx
enum
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
#ifndef GMX_PMECOORDINATERECEIVERGPU_H
#define GMX_PMECOORDINATERECEIVERGPU_H
+#include <memory>
+
#include "gromacs/gpu_utils/devicebuffer_datatype.h"
#include "gromacs/math/vectypes.h"
-#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/gmxmpi.h"
class DeviceStream;
private:
class Impl;
- gmx::PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
#if GMX_MPI
// Receive event from PP task
- MPI_Irecv(&ppSync_[recvCount_], sizeof(GpuEventSynchronizer*), MPI_BYTE, ppRank, 0, comm_,
- &request_[recvCount_]);
+ MPI_Irecv(&ppSync_[recvCount_], sizeof(GpuEventSynchronizer*), MPI_BYTE, ppRank, 0, comm_, &request_[recvCount_]);
recvCount_++;
#else
GMX_UNUSED_VALUE(ppRank);
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
#ifndef GMX_PMEFORCESENDERGPU_H
#define GMX_PMEFORCESENDERGPU_H
+#include <memory>
+
#include "gromacs/math/vectypes.h"
-#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/gmxmpi.h"
class DeviceStream;
private:
class Impl;
- gmx::PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
if (chargeCheck)
{
- sumForceComponents(&fx, &fy, &fz, ixBase, nx, pny, pnz, constOffset, splineIndexBase, tdy,
- tdz, sm_splineParams, gm_gridA);
+ sumForceComponents(
+ &fx, &fy, &fz, ixBase, nx, pny, pnz, constOffset, splineIndexBase, tdy, tdz, sm_splineParams, gm_gridA);
}
// Reduction of partial force contributions
__local float sm_forceReduction[totalSharedMemory];
__local float* sm_forceTemp[DIM];
- reduce_atom_forces(sm_forces, atomIndexLocal, splineIndex, lineIndex,
- kernelParams.grid.realGridSizeFP, fx, fy, fz, sm_forceReduction, sm_forceTemp);
+ reduce_atom_forces(sm_forces,
+ atomIndexLocal,
+ splineIndex,
+ lineIndex,
+ kernelParams.grid.realGridSizeFP,
+ fx,
+ fy,
+ fz,
+ sm_forceReduction,
+ sm_forceTemp);
barrier(CLK_LOCAL_MEM_FENCE);
/* Calculating the final forces with no component branching, atomsPerBlock threads */
const float scale = kernelParams.current.scale;
if (forceIndexLocal < atomsPerBlock)
{
- calculateAndStoreGridForces(sm_forces, forceIndexLocal, forceIndexGlobal,
- kernelParams.current.recipBox, scale, gm_coefficientsA);
+ calculateAndStoreGridForces(
+ sm_forces, forceIndexLocal, forceIndexGlobal, kernelParams.current.recipBox, scale, gm_coefficientsA);
}
#if !defined(_AMD_SOURCE_) && !defined(_NVIDIA_SOURCE_)
chargeCheck = pme_gpu_check_atom_charge(gm_coefficientsB[atomIndexGlobal]);
if (chargeCheck)
{
- sumForceComponents(&fx, &fy, &fz, ixBase, nx, pny, pnz, constOffset, splineIndexBase,
- tdy, tdz, sm_splineParams, gm_gridB);
+ sumForceComponents(
+ &fx, &fy, &fz, ixBase, nx, pny, pnz, constOffset, splineIndexBase, tdy, tdz, sm_splineParams, gm_gridB);
}
- reduce_atom_forces(sm_forces, atomIndexLocal, splineIndex, lineIndex,
- kernelParams.grid.realGridSizeFP, fx, fy, fz, sm_forceReduction, sm_forceTemp);
+ reduce_atom_forces(sm_forces,
+ atomIndexLocal,
+ splineIndex,
+ lineIndex,
+ kernelParams.grid.realGridSizeFP,
+ fx,
+ fy,
+ fz,
+ sm_forceReduction,
+ sm_forceTemp);
barrier(CLK_LOCAL_MEM_FENCE);
if (forceIndexLocal < atomsPerBlock)
{
- calculateAndStoreGridForces(sm_forces, forceIndexLocal, forceIndexGlobal,
- kernelParams.current.recipBox, 1.0F - scale, gm_coefficientsB);
+ calculateAndStoreGridForces(sm_forces,
+ forceIndexLocal,
+ forceIndexGlobal,
+ kernelParams.current.recipBox,
+ 1.0F - scale,
+ gm_coefficientsB);
}
#if !defined(_AMD_SOURCE_) && !defined(_NVIDIA_SOURCE_)
const int ithyMax = (threadsPerAtom == ThreadsPerAtom::Order) ? order : threadIdx.y + 1;
if (chargeCheck)
{
- sumForceComponents<order, atomsPerWarp, wrapX, wrapY>(
- &fx, &fy, &fz, ithyMin, ithyMax, ixBase, iz, nx, ny, pny, pnz, atomIndexLocal,
- splineIndexBase, tdz, sm_gridlineIndices, sm_theta, sm_dtheta, gm_gridA);
+ sumForceComponents<order, atomsPerWarp, wrapX, wrapY>(&fx,
+ &fy,
+ &fz,
+ ithyMin,
+ ithyMax,
+ ixBase,
+ iz,
+ nx,
+ ny,
+ pny,
+ pnz,
+ atomIndexLocal,
+ splineIndexBase,
+ tdz,
+ sm_gridlineIndices,
+ sm_theta,
+ sm_dtheta,
+ gm_gridA);
}
// Reduction of partial force contributions
__shared__ float3 sm_forces[atomsPerBlock];
- reduce_atom_forces<order, atomDataSize, blockSize>(sm_forces, atomIndexLocal, splineIndex, lineIndex,
- kernelParams.grid.realGridSizeFP, fx, fy, fz);
+ reduce_atom_forces<order, atomDataSize, blockSize>(
+ sm_forces, atomIndexLocal, splineIndex, lineIndex, kernelParams.grid.realGridSizeFP, fx, fy, fz);
__syncthreads();
/* Calculating the final forces with no component branching, atomsPerBlock threads */
const float scale = kernelParams.current.scale;
if (forceIndexLocal < atomsPerBlock)
{
- calculateAndStoreGridForces(sm_forces, forceIndexLocal, forceIndexGlobal,
- kernelParams.current.recipBox, scale, gm_coefficientsA);
+ calculateAndStoreGridForces(
+ sm_forces, forceIndexLocal, forceIndexGlobal, kernelParams.current.recipBox, scale, gm_coefficientsA);
}
__syncwarp();
const int chargeCheck = pme_gpu_check_atom_charge(gm_coefficientsB[atomIndexGlobal]);
if (chargeCheck)
{
- sumForceComponents<order, atomsPerWarp, wrapX, wrapY>(
- &fx, &fy, &fz, ithyMin, ithyMax, ixBase, iz, nx, ny, pny, pnz, atomIndexLocal,
- splineIndexBase, tdz, sm_gridlineIndices, sm_theta, sm_dtheta, gm_gridB);
+ sumForceComponents<order, atomsPerWarp, wrapX, wrapY>(&fx,
+ &fy,
+ &fz,
+ ithyMin,
+ ithyMax,
+ ixBase,
+ iz,
+ nx,
+ ny,
+ pny,
+ pnz,
+ atomIndexLocal,
+ splineIndexBase,
+ tdz,
+ sm_gridlineIndices,
+ sm_theta,
+ sm_dtheta,
+ gm_gridB);
}
// Reduction of partial force contributions
- reduce_atom_forces<order, atomDataSize, blockSize>(sm_forces, atomIndexLocal, splineIndex,
- lineIndex, kernelParams.grid.realGridSizeFP,
- fx, fy, fz);
+ reduce_atom_forces<order, atomDataSize, blockSize>(
+ sm_forces, atomIndexLocal, splineIndex, lineIndex, kernelParams.grid.realGridSizeFP, fx, fy, fz);
__syncthreads();
/* Calculating the final forces with no component branching, atomsPerBlock threads */
if (forceIndexLocal < atomsPerBlock)
{
- calculateAndStoreGridForces(sm_forces, forceIndexLocal, forceIndexGlobal,
- kernelParams.current.recipBox, 1.0F - scale, gm_coefficientsB);
+ calculateAndStoreGridForces(sm_forces,
+ forceIndexLocal,
+ forceIndexGlobal,
+ kernelParams.current.recipBox,
+ 1.0F - scale,
+ gm_coefficientsB);
}
__syncwarp();
#pragma omp parallel for num_threads(pme->nthread) schedule(static)
for (int thread = 0; thread < pme->nthread; thread++)
{
- solve_pme_yzx(pme, cfftgrid, pme->boxVolume, computeEnergyAndVirial,
- pme->nthread, thread);
+ solve_pme_yzx(pme, cfftgrid, pme->boxVolume, computeEnergyAndVirial, pme->nthread, thread);
}
wallcycle_stop(wcycle, ewcPME_SOLVE_MIXED_MODE);
}
pme_gpu_update_timings(pme->gpu);
// There's no support for computing energy without virial, or vice versa
const bool computeEnergyAndVirial = stepWork.computeEnergy || stepWork.computeVirial;
- PmeOutput output = pme_gpu_getOutput(*pme, computeEnergyAndVirial,
- pme->gpu->common->ngrids > 1 ? lambdaQ : 1.0);
+ PmeOutput output = pme_gpu_getOutput(
+ *pme, computeEnergyAndVirial, pme->gpu->common->ngrids > 1 ? lambdaQ : 1.0);
wallcycle_stop(wcycle, ewcWAIT_GPU_PME_GATHER);
GMX_ASSERT(pme->gpu->settings.useGpuForceReduction == !output.haveForceOutput_,
pme_gpu_synchronize(pme->gpu);
}
- PmeOutput output = pme_gpu_getOutput(*pme, computeEnergyAndVirial,
- pme->gpu->common->ngrids > 1 ? lambdaQ : 1.0);
+ PmeOutput output = pme_gpu_getOutput(
+ *pme, computeEnergyAndVirial, pme->gpu->common->ngrids > 1 ? lambdaQ : 1.0);
wallcycle_stop(wcycle, ewcWAIT_GPU_PME_GATHER);
return output;
}
*/
const int rank = 3, batch = 1;
- result = cufftPlanMany(&planR2C_, rank, realGridSize, realGridSizePadded, 1, realGridSizePaddedTotal,
- complexGridSizePadded, 1, complexGridSizePaddedTotal, CUFFT_R2C, batch);
+ result = cufftPlanMany(&planR2C_,
+ rank,
+ realGridSize,
+ realGridSizePadded,
+ 1,
+ realGridSizePaddedTotal,
+ complexGridSizePadded,
+ 1,
+ complexGridSizePaddedTotal,
+ CUFFT_R2C,
+ batch);
handleCufftError(result, "cufftPlanMany R2C plan failure");
- result = cufftPlanMany(&planC2R_, rank, realGridSize, complexGridSizePadded, 1,
- complexGridSizePaddedTotal, realGridSizePadded, 1,
- realGridSizePaddedTotal, CUFFT_C2R, batch);
+ result = cufftPlanMany(&planC2R_,
+ rank,
+ realGridSize,
+ complexGridSizePadded,
+ 1,
+ complexGridSizePaddedTotal,
+ realGridSizePadded,
+ 1,
+ realGridSizePaddedTotal,
+ CUFFT_C2R,
+ batch);
handleCufftError(result, "cufftPlanMany C2R plan failure");
cudaStream_t stream = pmeGpu->archSpecific->pmeStream_.stream();
// clFFT expects row-major, so dimensions/strides are reversed (ZYX instead of XYZ)
std::array<size_t, DIM> realGridDimensions = { realGridSize[ZZ], realGridSize[YY], realGridSize[XX] };
- std::array<size_t, DIM> realGridStrides = { 1, realGridSizePadded[ZZ],
+ std::array<size_t, DIM> realGridStrides = { 1,
+ realGridSizePadded[ZZ],
realGridSizePadded[YY] * realGridSizePadded[ZZ] };
- std::array<size_t, DIM> complexGridStrides = { 1, complexGridSizePadded[ZZ],
- complexGridSizePadded[YY] * complexGridSizePadded[ZZ] };
+ std::array<size_t, DIM> complexGridStrides = {
+ 1, complexGridSizePadded[ZZ], complexGridSizePadded[YY] * complexGridSizePadded[ZZ]
+ };
constexpr clfftDim dims = CLFFT_3D;
handleClfftError(clfftCreateDefaultPlan(&planR2C_, context, dims, realGridDimensions.data()),
GMX_THROW(
gmx::NotImplementedError("The chosen 3D-FFT case is not implemented on GPUs"));
}
- handleClfftError(clfftEnqueueTransform(plan, direction, deviceStreams_.size(),
- deviceStreams_.data(), waitEvents.size(), waitEvents.data(),
- timingEvent, inputGrids, outputGrids, tempBuffer),
+ handleClfftError(clfftEnqueueTransform(plan,
+ direction,
+ deviceStreams_.size(),
+ deviceStreams_.data(),
+ waitEvents.size(),
+ waitEvents.data(),
+ timingEvent,
+ inputGrids,
+ outputGrids,
+ tempBuffer),
"clFFT execution failure");
}
// TODO have shared table for both parameters to share the fetch, as index is always same?
// TODO compare texture/LDG performance
- sm_fractCoords[sharedMemoryIndex] +=
- fetchFromParamLookupTable(kernelParams.grid.d_fractShiftsTable,
- kernelParams.fractShiftsTableTexture, tableIndex);
+ sm_fractCoords[sharedMemoryIndex] += fetchFromParamLookupTable(
+ kernelParams.grid.d_fractShiftsTable, kernelParams.fractShiftsTableTexture, tableIndex);
sm_gridlineIndices[sharedMemoryIndex] =
fetchFromParamLookupTable(kernelParams.grid.d_gridlineIndicesTable,
- kernelParams.gridlineIndicesTableTexture, tableIndex);
+ kernelParams.gridlineIndicesTableTexture,
+ tableIndex);
if (writeGlobal)
{
gm_gridlineIndices[atomIndexOffset * DIM + sharedMemoryIndex] =
for (int gridIndex = 0; gridIndex < pmeGpu->common->ngrids; gridIndex++)
{
allocateDeviceBuffer(&pmeGpu->kernelParams->constants.d_virialAndEnergy[gridIndex],
- c_virialAndEnergyCount, pmeGpu->archSpecific->deviceContext_);
+ c_virialAndEnergyCount,
+ pmeGpu->archSpecific->deviceContext_);
pmalloc(reinterpret_cast<void**>(&pmeGpu->staging.h_virialAndEnergy[gridIndex]), energyAndVirialSize);
}
}
{
for (int gridIndex = 0; gridIndex < pmeGpu->common->ngrids; gridIndex++)
{
- clearDeviceBufferAsync(&pmeGpu->kernelParams->constants.d_virialAndEnergy[gridIndex], 0,
- c_virialAndEnergyCount, pmeGpu->archSpecific->pmeStream_);
+ clearDeviceBufferAsync(&pmeGpu->kernelParams->constants.d_virialAndEnergy[gridIndex],
+ 0,
+ c_virialAndEnergyCount,
+ pmeGpu->archSpecific->pmeStream_);
}
}
GMX_ASSERT(gridIndex < pmeGpu->common->ngrids,
"Invalid combination of gridIndex and number of grids");
- const int splineValuesOffset[DIM] = { 0, pmeGpu->kernelParams->grid.realGridSize[XX],
+ const int splineValuesOffset[DIM] = { 0,
+ pmeGpu->kernelParams->grid.realGridSize[XX],
pmeGpu->kernelParams->grid.realGridSize[XX]
+ pmeGpu->kernelParams->grid.realGridSize[YY] };
memcpy(&pmeGpu->kernelParams->grid.splineValuesOffset, &splineValuesOffset, sizeof(splineValuesOffset));
+ pmeGpu->kernelParams->grid.realGridSize[ZZ];
const bool shouldRealloc = (newSplineValuesSize > pmeGpu->archSpecific->splineValuesSize[gridIndex]);
reallocateDeviceBuffer(&pmeGpu->kernelParams->grid.d_splineModuli[gridIndex],
- newSplineValuesSize, &pmeGpu->archSpecific->splineValuesSize[gridIndex],
+ newSplineValuesSize,
+ &pmeGpu->archSpecific->splineValuesSize[gridIndex],
&pmeGpu->archSpecific->splineValuesCapacity[gridIndex],
pmeGpu->archSpecific->deviceContext_);
if (shouldRealloc)
for (int i = 0; i < DIM; i++)
{
memcpy(pmeGpu->staging.h_splineModuli[gridIndex] + splineValuesOffset[i],
- pmeGpu->common->bsp_mod[i].data(), pmeGpu->common->bsp_mod[i].size() * sizeof(float));
+ pmeGpu->common->bsp_mod[i].data(),
+ pmeGpu->common->bsp_mod[i].size() * sizeof(float));
}
/* TODO: pin original buffer instead! */
copyToDeviceBuffer(&pmeGpu->kernelParams->grid.d_splineModuli[gridIndex],
- pmeGpu->staging.h_splineModuli[gridIndex], 0, newSplineValuesSize,
- pmeGpu->archSpecific->pmeStream_, pmeGpu->settings.transferKind, nullptr);
+ pmeGpu->staging.h_splineModuli[gridIndex],
+ 0,
+ newSplineValuesSize,
+ pmeGpu->archSpecific->pmeStream_,
+ pmeGpu->settings.transferKind,
+ nullptr);
}
void pme_gpu_free_bspline_values(const PmeGpu* pmeGpu)
{
const size_t newForcesSize = pmeGpu->nAtomsAlloc * DIM;
GMX_ASSERT(newForcesSize > 0, "Bad number of atoms in PME GPU");
- reallocateDeviceBuffer(&pmeGpu->kernelParams->atoms.d_forces, newForcesSize,
- &pmeGpu->archSpecific->forcesSize, &pmeGpu->archSpecific->forcesSizeAlloc,
+ reallocateDeviceBuffer(&pmeGpu->kernelParams->atoms.d_forces,
+ newForcesSize,
+ &pmeGpu->archSpecific->forcesSize,
+ &pmeGpu->archSpecific->forcesSizeAlloc,
pmeGpu->archSpecific->deviceContext_);
pmeGpu->staging.h_forces.reserveWithPadding(pmeGpu->nAtomsAlloc);
pmeGpu->staging.h_forces.resizeWithPadding(pmeGpu->kernelParams->atoms.nAtoms);
{
GMX_ASSERT(pmeGpu->kernelParams->atoms.nAtoms > 0, "Bad number of atoms in PME GPU");
float* h_forcesFloat = reinterpret_cast<float*>(pmeGpu->staging.h_forces.data());
- copyToDeviceBuffer(&pmeGpu->kernelParams->atoms.d_forces, h_forcesFloat, 0,
- DIM * pmeGpu->kernelParams->atoms.nAtoms, pmeGpu->archSpecific->pmeStream_,
- pmeGpu->settings.transferKind, nullptr);
+ copyToDeviceBuffer(&pmeGpu->kernelParams->atoms.d_forces,
+ h_forcesFloat,
+ 0,
+ DIM * pmeGpu->kernelParams->atoms.nAtoms,
+ pmeGpu->archSpecific->pmeStream_,
+ pmeGpu->settings.transferKind,
+ nullptr);
}
void pme_gpu_copy_output_forces(PmeGpu* pmeGpu)
{
GMX_ASSERT(pmeGpu->kernelParams->atoms.nAtoms > 0, "Bad number of atoms in PME GPU");
float* h_forcesFloat = reinterpret_cast<float*>(pmeGpu->staging.h_forces.data());
- copyFromDeviceBuffer(h_forcesFloat, &pmeGpu->kernelParams->atoms.d_forces, 0,
- DIM * pmeGpu->kernelParams->atoms.nAtoms, pmeGpu->archSpecific->pmeStream_,
- pmeGpu->settings.transferKind, nullptr);
+ copyFromDeviceBuffer(h_forcesFloat,
+ &pmeGpu->kernelParams->atoms.d_forces,
+ 0,
+ DIM * pmeGpu->kernelParams->atoms.nAtoms,
+ pmeGpu->archSpecific->pmeStream_,
+ pmeGpu->settings.transferKind,
+ nullptr);
}
void pme_gpu_realloc_and_copy_input_coefficients(const PmeGpu* pmeGpu,
const size_t newCoefficientsSize = pmeGpu->nAtomsAlloc;
GMX_ASSERT(newCoefficientsSize > 0, "Bad number of atoms in PME GPU");
reallocateDeviceBuffer(&pmeGpu->kernelParams->atoms.d_coefficients[gridIndex],
- newCoefficientsSize, &pmeGpu->archSpecific->coefficientsSize[gridIndex],
+ newCoefficientsSize,
+ &pmeGpu->archSpecific->coefficientsSize[gridIndex],
&pmeGpu->archSpecific->coefficientsCapacity[gridIndex],
pmeGpu->archSpecific->deviceContext_);
copyToDeviceBuffer(&pmeGpu->kernelParams->atoms.d_coefficients[gridIndex],
- const_cast<float*>(h_coefficients), 0, pmeGpu->kernelParams->atoms.nAtoms,
- pmeGpu->archSpecific->pmeStream_, pmeGpu->settings.transferKind, nullptr);
+ const_cast<float*>(h_coefficients),
+ 0,
+ pmeGpu->kernelParams->atoms.nAtoms,
+ pmeGpu->archSpecific->pmeStream_,
+ pmeGpu->settings.transferKind,
+ nullptr);
const size_t paddingIndex = pmeGpu->kernelParams->atoms.nAtoms;
const size_t paddingCount = pmeGpu->nAtomsAlloc - paddingIndex;
if (paddingCount > 0)
{
- clearDeviceBufferAsync(&pmeGpu->kernelParams->atoms.d_coefficients[gridIndex], paddingIndex,
- paddingCount, pmeGpu->archSpecific->pmeStream_);
+ clearDeviceBufferAsync(&pmeGpu->kernelParams->atoms.d_coefficients[gridIndex],
+ paddingIndex,
+ paddingCount,
+ pmeGpu->archSpecific->pmeStream_);
}
}
const bool shouldRealloc = (newSplineDataSize > pmeGpu->archSpecific->splineDataSize);
int currentSizeTemp = pmeGpu->archSpecific->splineDataSize;
int currentSizeTempAlloc = pmeGpu->archSpecific->splineDataSizeAlloc;
- reallocateDeviceBuffer(&pmeGpu->kernelParams->atoms.d_theta, newSplineDataSize, ¤tSizeTemp,
- ¤tSizeTempAlloc, pmeGpu->archSpecific->deviceContext_);
- reallocateDeviceBuffer(&pmeGpu->kernelParams->atoms.d_dtheta, newSplineDataSize,
- &pmeGpu->archSpecific->splineDataSize, &pmeGpu->archSpecific->splineDataSizeAlloc,
+ reallocateDeviceBuffer(&pmeGpu->kernelParams->atoms.d_theta,
+ newSplineDataSize,
+ ¤tSizeTemp,
+ ¤tSizeTempAlloc,
+ pmeGpu->archSpecific->deviceContext_);
+ reallocateDeviceBuffer(&pmeGpu->kernelParams->atoms.d_dtheta,
+ newSplineDataSize,
+ &pmeGpu->archSpecific->splineDataSize,
+ &pmeGpu->archSpecific->splineDataSizeAlloc,
pmeGpu->archSpecific->deviceContext_);
// the host side reallocation
if (shouldRealloc)
{
const size_t newIndicesSize = DIM * pmeGpu->nAtomsAlloc;
GMX_ASSERT(newIndicesSize > 0, "Bad number of atoms in PME GPU");
- reallocateDeviceBuffer(&pmeGpu->kernelParams->atoms.d_gridlineIndices, newIndicesSize,
+ reallocateDeviceBuffer(&pmeGpu->kernelParams->atoms.d_gridlineIndices,
+ newIndicesSize,
&pmeGpu->archSpecific->gridlineIndicesSize,
&pmeGpu->archSpecific->gridlineIndicesSizeAlloc,
pmeGpu->archSpecific->deviceContext_);
if (pmeGpu->archSpecific->performOutOfPlaceFFT)
{
/* 2 separate grids */
- reallocateDeviceBuffer(&kernelParamsPtr->grid.d_fourierGrid[gridIndex], newComplexGridSize,
+ reallocateDeviceBuffer(&kernelParamsPtr->grid.d_fourierGrid[gridIndex],
+ newComplexGridSize,
&pmeGpu->archSpecific->complexGridSize[gridIndex],
&pmeGpu->archSpecific->complexGridCapacity[gridIndex],
pmeGpu->archSpecific->deviceContext_);
- reallocateDeviceBuffer(&kernelParamsPtr->grid.d_realGrid[gridIndex], newRealGridSize,
+ reallocateDeviceBuffer(&kernelParamsPtr->grid.d_realGrid[gridIndex],
+ newRealGridSize,
&pmeGpu->archSpecific->realGridSize[gridIndex],
&pmeGpu->archSpecific->realGridCapacity[gridIndex],
pmeGpu->archSpecific->deviceContext_);
{
/* A single buffer so that any grid will fit */
const int newGridsSize = std::max(newRealGridSize, newComplexGridSize);
- reallocateDeviceBuffer(&kernelParamsPtr->grid.d_realGrid[gridIndex], newGridsSize,
+ reallocateDeviceBuffer(&kernelParamsPtr->grid.d_realGrid[gridIndex],
+ newGridsSize,
&pmeGpu->archSpecific->realGridSize[gridIndex],
&pmeGpu->archSpecific->realGridCapacity[gridIndex],
pmeGpu->archSpecific->deviceContext_);
{
for (int gridIndex = 0; gridIndex < pmeGpu->common->ngrids; gridIndex++)
{
- clearDeviceBufferAsync(&pmeGpu->kernelParams->grid.d_realGrid[gridIndex], 0,
+ clearDeviceBufferAsync(&pmeGpu->kernelParams->grid.d_realGrid[gridIndex],
+ 0,
pmeGpu->archSpecific->realGridSize[gridIndex],
pmeGpu->archSpecific->pmeStream_);
}
const int newFractShiftsSize = cellCount * (nx + ny + nz);
initParamLookupTable(&kernelParamsPtr->grid.d_fractShiftsTable,
- &kernelParamsPtr->fractShiftsTableTexture, pmeGpu->common->fsh.data(),
- newFractShiftsSize, pmeGpu->archSpecific->deviceContext_);
+ &kernelParamsPtr->fractShiftsTableTexture,
+ pmeGpu->common->fsh.data(),
+ newFractShiftsSize,
+ pmeGpu->archSpecific->deviceContext_);
initParamLookupTable(&kernelParamsPtr->grid.d_gridlineIndicesTable,
- &kernelParamsPtr->gridlineIndicesTableTexture, pmeGpu->common->nn.data(),
- newFractShiftsSize, pmeGpu->archSpecific->deviceContext_);
+ &kernelParamsPtr->gridlineIndicesTableTexture,
+ pmeGpu->common->nn.data(),
+ newFractShiftsSize,
+ pmeGpu->archSpecific->deviceContext_);
}
void pme_gpu_free_fract_shifts(const PmeGpu* pmeGpu)
void pme_gpu_copy_input_gather_grid(const PmeGpu* pmeGpu, const float* h_grid, const int gridIndex)
{
- copyToDeviceBuffer(&pmeGpu->kernelParams->grid.d_realGrid[gridIndex], h_grid, 0,
+ copyToDeviceBuffer(&pmeGpu->kernelParams->grid.d_realGrid[gridIndex],
+ h_grid,
+ 0,
pmeGpu->archSpecific->realGridSize[gridIndex],
- pmeGpu->archSpecific->pmeStream_, pmeGpu->settings.transferKind, nullptr);
+ pmeGpu->archSpecific->pmeStream_,
+ pmeGpu->settings.transferKind,
+ nullptr);
}
void pme_gpu_copy_output_spread_grid(const PmeGpu* pmeGpu, float* h_grid, const int gridIndex)
{
- copyFromDeviceBuffer(h_grid, &pmeGpu->kernelParams->grid.d_realGrid[gridIndex], 0,
+ copyFromDeviceBuffer(h_grid,
+ &pmeGpu->kernelParams->grid.d_realGrid[gridIndex],
+ 0,
pmeGpu->archSpecific->realGridSize[gridIndex],
- pmeGpu->archSpecific->pmeStream_, pmeGpu->settings.transferKind, nullptr);
+ pmeGpu->archSpecific->pmeStream_,
+ pmeGpu->settings.transferKind,
+ nullptr);
pmeGpu->archSpecific->syncSpreadGridD2H.markEvent(pmeGpu->archSpecific->pmeStream_);
}
{
const size_t splinesCount = DIM * pmeGpu->nAtomsAlloc * pmeGpu->common->pme_order;
auto* kernelParamsPtr = pmeGpu->kernelParams.get();
- copyFromDeviceBuffer(pmeGpu->staging.h_dtheta, &kernelParamsPtr->atoms.d_dtheta, 0, splinesCount,
- pmeGpu->archSpecific->pmeStream_, pmeGpu->settings.transferKind, nullptr);
- copyFromDeviceBuffer(pmeGpu->staging.h_theta, &kernelParamsPtr->atoms.d_theta, 0, splinesCount,
- pmeGpu->archSpecific->pmeStream_, pmeGpu->settings.transferKind, nullptr);
- copyFromDeviceBuffer(pmeGpu->staging.h_gridlineIndices, &kernelParamsPtr->atoms.d_gridlineIndices,
- 0, kernelParamsPtr->atoms.nAtoms * DIM, pmeGpu->archSpecific->pmeStream_,
- pmeGpu->settings.transferKind, nullptr);
+ copyFromDeviceBuffer(pmeGpu->staging.h_dtheta,
+ &kernelParamsPtr->atoms.d_dtheta,
+ 0,
+ splinesCount,
+ pmeGpu->archSpecific->pmeStream_,
+ pmeGpu->settings.transferKind,
+ nullptr);
+ copyFromDeviceBuffer(pmeGpu->staging.h_theta,
+ &kernelParamsPtr->atoms.d_theta,
+ 0,
+ splinesCount,
+ pmeGpu->archSpecific->pmeStream_,
+ pmeGpu->settings.transferKind,
+ nullptr);
+ copyFromDeviceBuffer(pmeGpu->staging.h_gridlineIndices,
+ &kernelParamsPtr->atoms.d_gridlineIndices,
+ 0,
+ kernelParamsPtr->atoms.nAtoms * DIM,
+ pmeGpu->archSpecific->pmeStream_,
+ pmeGpu->settings.transferKind,
+ nullptr);
}
void pme_gpu_copy_input_gather_atom_data(const PmeGpu* pmeGpu)
auto* kernelParamsPtr = pmeGpu->kernelParams.get();
// TODO: could clear only the padding and not the whole thing, but this is a test-exclusive code anyway
- clearDeviceBufferAsync(&kernelParamsPtr->atoms.d_gridlineIndices, 0, pmeGpu->nAtomsAlloc * DIM,
+ clearDeviceBufferAsync(&kernelParamsPtr->atoms.d_gridlineIndices,
+ 0,
+ pmeGpu->nAtomsAlloc * DIM,
pmeGpu->archSpecific->pmeStream_);
- clearDeviceBufferAsync(&kernelParamsPtr->atoms.d_dtheta, 0,
+ clearDeviceBufferAsync(&kernelParamsPtr->atoms.d_dtheta,
+ 0,
pmeGpu->nAtomsAlloc * pmeGpu->common->pme_order * DIM,
pmeGpu->archSpecific->pmeStream_);
- clearDeviceBufferAsync(&kernelParamsPtr->atoms.d_theta, 0,
+ clearDeviceBufferAsync(&kernelParamsPtr->atoms.d_theta,
+ 0,
pmeGpu->nAtomsAlloc * pmeGpu->common->pme_order * DIM,
pmeGpu->archSpecific->pmeStream_);
- copyToDeviceBuffer(&kernelParamsPtr->atoms.d_dtheta, pmeGpu->staging.h_dtheta, 0, splinesCount,
- pmeGpu->archSpecific->pmeStream_, pmeGpu->settings.transferKind, nullptr);
- copyToDeviceBuffer(&kernelParamsPtr->atoms.d_theta, pmeGpu->staging.h_theta, 0, splinesCount,
- pmeGpu->archSpecific->pmeStream_, pmeGpu->settings.transferKind, nullptr);
- copyToDeviceBuffer(&kernelParamsPtr->atoms.d_gridlineIndices, pmeGpu->staging.h_gridlineIndices,
- 0, kernelParamsPtr->atoms.nAtoms * DIM, pmeGpu->archSpecific->pmeStream_,
- pmeGpu->settings.transferKind, nullptr);
+ copyToDeviceBuffer(&kernelParamsPtr->atoms.d_dtheta,
+ pmeGpu->staging.h_dtheta,
+ 0,
+ splinesCount,
+ pmeGpu->archSpecific->pmeStream_,
+ pmeGpu->settings.transferKind,
+ nullptr);
+ copyToDeviceBuffer(&kernelParamsPtr->atoms.d_theta,
+ pmeGpu->staging.h_theta,
+ 0,
+ splinesCount,
+ pmeGpu->archSpecific->pmeStream_,
+ pmeGpu->settings.transferKind,
+ nullptr);
+ copyToDeviceBuffer(&kernelParamsPtr->atoms.d_gridlineIndices,
+ pmeGpu->staging.h_gridlineIndices,
+ 0,
+ kernelParamsPtr->atoms.nAtoms * DIM,
+ pmeGpu->archSpecific->pmeStream_,
+ pmeGpu->settings.transferKind,
+ nullptr);
}
void pme_gpu_sync_spread_grid(const PmeGpu* pmeGpu)
if (spreadCharges)
{
timingId = gtPME_SPLINEANDSPREAD;
- kernelPtr = selectSplineAndSpreadKernelPtr(pmeGpu, pmeGpu->settings.threadsPerAtom,
+ kernelPtr = selectSplineAndSpreadKernelPtr(pmeGpu,
+ pmeGpu->settings.threadsPerAtom,
writeGlobal || (!recalculateSplines),
pmeGpu->common->ngrids);
}
else
{
timingId = gtPME_SPLINE;
- kernelPtr = selectSplineKernelPtr(pmeGpu, pmeGpu->settings.threadsPerAtom,
+ kernelPtr = selectSplineKernelPtr(pmeGpu,
+ pmeGpu->settings.threadsPerAtom,
writeGlobal || (!recalculateSplines),
pmeGpu->common->ngrids);
}
else
{
timingId = gtPME_SPREAD;
- kernelPtr = selectSpreadKernelPtr(pmeGpu, pmeGpu->settings.threadsPerAtom,
- writeGlobal || (!recalculateSplines), pmeGpu->common->ngrids);
+ kernelPtr = selectSpreadKernelPtr(pmeGpu,
+ pmeGpu->settings.threadsPerAtom,
+ writeGlobal || (!recalculateSplines),
+ pmeGpu->common->ngrids);
}
#if c_canEmbedBuffers
const auto kernelArgs = prepareGpuKernelArguments(kernelPtr, config, kernelParamsPtr);
#else
- const auto kernelArgs = prepareGpuKernelArguments(
- kernelPtr, config, kernelParamsPtr, &kernelParamsPtr->atoms.d_theta,
- &kernelParamsPtr->atoms.d_dtheta, &kernelParamsPtr->atoms.d_gridlineIndices,
- &kernelParamsPtr->grid.d_realGrid[FEP_STATE_A], &kernelParamsPtr->grid.d_realGrid[FEP_STATE_B],
- &kernelParamsPtr->grid.d_fractShiftsTable, &kernelParamsPtr->grid.d_gridlineIndicesTable,
- &kernelParamsPtr->atoms.d_coefficients[FEP_STATE_A],
- &kernelParamsPtr->atoms.d_coefficients[FEP_STATE_B], &kernelParamsPtr->atoms.d_coordinates);
+ const auto kernelArgs =
+ prepareGpuKernelArguments(kernelPtr,
+ config,
+ kernelParamsPtr,
+ &kernelParamsPtr->atoms.d_theta,
+ &kernelParamsPtr->atoms.d_dtheta,
+ &kernelParamsPtr->atoms.d_gridlineIndices,
+ &kernelParamsPtr->grid.d_realGrid[FEP_STATE_A],
+ &kernelParamsPtr->grid.d_realGrid[FEP_STATE_B],
+ &kernelParamsPtr->grid.d_fractShiftsTable,
+ &kernelParamsPtr->grid.d_gridlineIndicesTable,
+ &kernelParamsPtr->atoms.d_coefficients[FEP_STATE_A],
+ &kernelParamsPtr->atoms.d_coefficients[FEP_STATE_B],
+ &kernelParamsPtr->atoms.d_coordinates);
#endif
- launchGpuKernel(kernelPtr, config, pmeGpu->archSpecific->pmeStream_, timingEvent,
- "PME spline/spread", kernelArgs);
+ launchGpuKernel(
+ kernelPtr, config, pmeGpu->archSpecific->pmeStream_, timingEvent, "PME spline/spread", kernelArgs);
pme_gpu_stop_timing(pmeGpu, timingId);
const auto& settings = pmeGpu->settings;
float* h_gridFloat = reinterpret_cast<float*>(h_grid);
if (copyInputAndOutputGrid)
{
- copyToDeviceBuffer(&kernelParamsPtr->grid.d_fourierGrid[gridIndex], h_gridFloat, 0,
+ copyToDeviceBuffer(&kernelParamsPtr->grid.d_fourierGrid[gridIndex],
+ h_gridFloat,
+ 0,
pmeGpu->archSpecific->complexGridSize[gridIndex],
- pmeGpu->archSpecific->pmeStream_, pmeGpu->settings.transferKind, nullptr);
+ pmeGpu->archSpecific->pmeStream_,
+ pmeGpu->settings.transferKind,
+ nullptr);
}
int majorDim = -1, middleDim = -1, minorDim = -1;
#if c_canEmbedBuffers
const auto kernelArgs = prepareGpuKernelArguments(kernelPtr, config, kernelParamsPtr);
#else
- const auto kernelArgs = prepareGpuKernelArguments(
- kernelPtr, config, kernelParamsPtr, &kernelParamsPtr->grid.d_splineModuli[gridIndex],
- &kernelParamsPtr->constants.d_virialAndEnergy[gridIndex],
- &kernelParamsPtr->grid.d_fourierGrid[gridIndex]);
+ const auto kernelArgs =
+ prepareGpuKernelArguments(kernelPtr,
+ config,
+ kernelParamsPtr,
+ &kernelParamsPtr->grid.d_splineModuli[gridIndex],
+ &kernelParamsPtr->constants.d_virialAndEnergy[gridIndex],
+ &kernelParamsPtr->grid.d_fourierGrid[gridIndex]);
#endif
- launchGpuKernel(kernelPtr, config, pmeGpu->archSpecific->pmeStream_, timingEvent, "PME solve",
- kernelArgs);
+ launchGpuKernel(kernelPtr, config, pmeGpu->archSpecific->pmeStream_, timingEvent, "PME solve", kernelArgs);
pme_gpu_stop_timing(pmeGpu, timingId);
if (computeEnergyAndVirial)
{
copyFromDeviceBuffer(pmeGpu->staging.h_virialAndEnergy[gridIndex],
- &kernelParamsPtr->constants.d_virialAndEnergy[gridIndex], 0,
- c_virialAndEnergyCount, pmeGpu->archSpecific->pmeStream_,
- pmeGpu->settings.transferKind, nullptr);
+ &kernelParamsPtr->constants.d_virialAndEnergy[gridIndex],
+ 0,
+ c_virialAndEnergyCount,
+ pmeGpu->archSpecific->pmeStream_,
+ pmeGpu->settings.transferKind,
+ nullptr);
}
if (copyInputAndOutputGrid)
{
- copyFromDeviceBuffer(h_gridFloat, &kernelParamsPtr->grid.d_fourierGrid[gridIndex], 0,
+ copyFromDeviceBuffer(h_gridFloat,
+ &kernelParamsPtr->grid.d_fourierGrid[gridIndex],
+ 0,
pmeGpu->archSpecific->complexGridSize[gridIndex],
- pmeGpu->archSpecific->pmeStream_, pmeGpu->settings.transferKind, nullptr);
+ pmeGpu->archSpecific->pmeStream_,
+ pmeGpu->settings.transferKind,
+ nullptr);
}
}
int timingId = gtPME_GATHER;
PmeGpuProgramImpl::PmeKernelHandle kernelPtr =
- selectGatherKernelPtr(pmeGpu, pmeGpu->settings.threadsPerAtom,
- readGlobal || (!recalculateSplines), pmeGpu->common->ngrids);
+ selectGatherKernelPtr(pmeGpu,
+ pmeGpu->settings.threadsPerAtom,
+ readGlobal || (!recalculateSplines),
+ pmeGpu->common->ngrids);
// TODO design kernel selection getters and make PmeGpu a friend of PmeGpuProgramImpl
pme_gpu_start_timing(pmeGpu, timingId);
#if c_canEmbedBuffers
const auto kernelArgs = prepareGpuKernelArguments(kernelPtr, config, kernelParamsPtr);
#else
- const auto kernelArgs = prepareGpuKernelArguments(
- kernelPtr, config, kernelParamsPtr, &kernelParamsPtr->atoms.d_coefficients[FEP_STATE_A],
- &kernelParamsPtr->atoms.d_coefficients[FEP_STATE_B],
- &kernelParamsPtr->grid.d_realGrid[FEP_STATE_A], &kernelParamsPtr->grid.d_realGrid[FEP_STATE_B],
- &kernelParamsPtr->atoms.d_theta, &kernelParamsPtr->atoms.d_dtheta,
- &kernelParamsPtr->atoms.d_gridlineIndices, &kernelParamsPtr->atoms.d_forces);
+ const auto kernelArgs =
+ prepareGpuKernelArguments(kernelPtr,
+ config,
+ kernelParamsPtr,
+ &kernelParamsPtr->atoms.d_coefficients[FEP_STATE_A],
+ &kernelParamsPtr->atoms.d_coefficients[FEP_STATE_B],
+ &kernelParamsPtr->grid.d_realGrid[FEP_STATE_A],
+ &kernelParamsPtr->grid.d_realGrid[FEP_STATE_B],
+ &kernelParamsPtr->atoms.d_theta,
+ &kernelParamsPtr->atoms.d_dtheta,
+ &kernelParamsPtr->atoms.d_gridlineIndices,
+ &kernelParamsPtr->atoms.d_forces);
#endif
- launchGpuKernel(kernelPtr, config, pmeGpu->archSpecific->pmeStream_, timingEvent, "PME gather",
- kernelArgs);
+ launchGpuKernel(kernelPtr, config, pmeGpu->archSpecific->pmeStream_, timingEvent, "PME gather", kernelArgs);
pme_gpu_stop_timing(pmeGpu, timingId);
if (pmeGpu->settings.useGpuForceReduction)
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "config.h"
+#include <memory>
+
#include "gromacs/gpu_utils/device_context.h"
#include "gromacs/utility/classhelpers.h"
stat |= clReleaseKernel(solveYZXKernelB);
stat |= clReleaseKernel(solveYZXEnergyKernelB);
GMX_ASSERT(stat == CL_SUCCESS,
- gmx::formatString("Failed to release PME OpenCL resources %d: %s", stat,
+ gmx::formatString("Failed to release PME OpenCL resources %d: %s",
+ stat,
ocl_get_error_string(stat).c_str())
.c_str());
}
"PME OpenCL kernels require >=%d execution width, but the %s kernel "
"has been compiled for the device %s to a %d width and therefore it can not "
"execute correctly.",
- minKernelWarpSize, kernelName, deviceInfo.device_name, kernelWarpSize);
+ minKernelWarpSize,
+ kernelName,
+ deviceInfo.device_name,
+ kernelWarpSize);
GMX_THROW(gmx::InternalError(errorString));
}
}
"-DDIM=%d -DXX=%d -DYY=%d -DZZ=%d "
// decomposition parameter placeholders
"-DwrapX=true -DwrapY=true ",
- warpSize_, c_pmeGpuOrder, c_pmeGpuOrder * c_pmeGpuOrder,
- static_cast<float>(c_pmeMaxUnitcellShift), static_cast<int>(c_skipNeutralAtoms),
- c_virialAndEnergyCount, spreadWorkGroupSize, solveMaxWorkGroupSize,
- gatherWorkGroupSize, DIM, XX, YY, ZZ);
+ warpSize_,
+ c_pmeGpuOrder,
+ c_pmeGpuOrder * c_pmeGpuOrder,
+ static_cast<float>(c_pmeMaxUnitcellShift),
+ static_cast<int>(c_skipNeutralAtoms),
+ c_virialAndEnergyCount,
+ spreadWorkGroupSize,
+ solveMaxWorkGroupSize,
+ gatherWorkGroupSize,
+ DIM,
+ XX,
+ YY,
+ ZZ);
try
{
/* TODO when we have a proper MPI-aware logging module,
the log output here should be written there */
- program = gmx::ocl::compileProgram(stderr, "gromacs/ewald", "pme_program.cl",
- commonDefines, deviceContext_.context(),
- deviceInfo.oclDeviceId, deviceInfo.deviceVendor);
+ program = gmx::ocl::compileProgram(stderr,
+ "gromacs/ewald",
+ "pme_program.cl",
+ commonDefines,
+ deviceContext_.context(),
+ deviceInfo.oclDeviceId,
+ deviceInfo.deviceVendor);
}
catch (gmx::GromacsException& e)
{
{
const std::string errorString = gmx::formatString(
"Failed to create kernels for PME on GPU #%s:\n OpenCL error %d: %s",
- deviceInfo.device_name, clError, ocl_get_error_string(clError).c_str());
+ deviceInfo.device_name,
+ clError,
+ ocl_get_error_string(clError).c_str());
GMX_THROW(gmx::InternalError(errorString));
}
kernels.resize(actualKernelCount);
std::array<char, 100> kernelNamesBuffer;
for (const auto& kernel : kernels)
{
- clError = clGetKernelInfo(kernel, CL_KERNEL_FUNCTION_NAME, kernelNamesBuffer.size(),
- kernelNamesBuffer.data(), nullptr);
+ clError = clGetKernelInfo(
+ kernel, CL_KERNEL_FUNCTION_NAME, kernelNamesBuffer.size(), kernelNamesBuffer.data(), nullptr);
if (clError != CL_SUCCESS)
{
const std::string errorString = gmx::formatString(
"Failed to parse kernels for PME on GPU #%s:\n OpenCL error %d: %s",
- deviceInfo.device_name, clError, ocl_get_error_string(clError).c_str());
+ deviceInfo.device_name,
+ clError,
+ ocl_get_error_string(clError).c_str());
GMX_THROW(gmx::InternalError(errorString));
}
/* Copy data to contiguous send buffer */
if (debug)
{
- fprintf(debug, "PME send rank %d %d -> %d grid start %d Communicating %d to %d\n",
- pme->nodeid, overlap->nodeid, send_id, pme->pmegrid_start_iy,
+ fprintf(debug,
+ "PME send rank %d %d -> %d grid start %d Communicating %d to %d\n",
+ pme->nodeid,
+ overlap->nodeid,
+ send_id,
+ pme->pmegrid_start_iy,
send_index0 - pme->pmegrid_start_iy,
send_index0 - pme->pmegrid_start_iy + send_nindex);
}
datasize = pme->pmegrid_nx * pme->nkz;
- MPI_Sendrecv(overlap->sendbuf.data(), send_nindex * datasize, GMX_MPI_REAL, send_id, ipulse,
- overlap->recvbuf.data(), recv_nindex * datasize, GMX_MPI_REAL, recv_id, ipulse,
- overlap->mpi_comm, &stat);
+ MPI_Sendrecv(overlap->sendbuf.data(),
+ send_nindex * datasize,
+ GMX_MPI_REAL,
+ send_id,
+ ipulse,
+ overlap->recvbuf.data(),
+ recv_nindex * datasize,
+ GMX_MPI_REAL,
+ recv_id,
+ ipulse,
+ overlap->mpi_comm,
+ &stat);
/* Get data from contiguous recv buffer */
if (debug)
{
- fprintf(debug, "PME recv rank %d %d <- %d grid start %d Communicating %d to %d\n",
- pme->nodeid, overlap->nodeid, recv_id, pme->pmegrid_start_iy,
+ fprintf(debug,
+ "PME recv rank %d %d <- %d grid start %d Communicating %d to %d\n",
+ pme->nodeid,
+ overlap->nodeid,
+ recv_id,
+ pme->pmegrid_start_iy,
recv_index0 - pme->pmegrid_start_iy,
recv_index0 - pme->pmegrid_start_iy + recv_nindex);
}
if (debug)
{
- fprintf(debug, "PME send rank %d %d -> %d grid start %d Communicating %d to %d\n",
- pme->nodeid, overlap->nodeid, send_id, pme->pmegrid_start_ix,
+ fprintf(debug,
+ "PME send rank %d %d -> %d grid start %d Communicating %d to %d\n",
+ pme->nodeid,
+ overlap->nodeid,
+ send_id,
+ pme->pmegrid_start_ix,
send_index0 - pme->pmegrid_start_ix,
send_index0 - pme->pmegrid_start_ix + send_nindex);
- fprintf(debug, "PME recv rank %d %d <- %d grid start %d Communicating %d to %d\n",
- pme->nodeid, overlap->nodeid, recv_id, pme->pmegrid_start_ix,
+ fprintf(debug,
+ "PME recv rank %d %d <- %d grid start %d Communicating %d to %d\n",
+ pme->nodeid,
+ overlap->nodeid,
+ recv_id,
+ pme->pmegrid_start_ix,
recv_index0 - pme->pmegrid_start_ix,
recv_index0 - pme->pmegrid_start_ix + recv_nindex);
}
- MPI_Sendrecv(sendptr, send_nindex * datasize, GMX_MPI_REAL, send_id, ipulse, recvptr,
- recv_nindex * datasize, GMX_MPI_REAL, recv_id, ipulse, overlap->mpi_comm, &stat);
+ MPI_Sendrecv(sendptr,
+ send_nindex * datasize,
+ GMX_MPI_REAL,
+ send_id,
+ ipulse,
+ recvptr,
+ recv_nindex * datasize,
+ GMX_MPI_REAL,
+ recv_id,
+ ipulse,
+ overlap->mpi_comm,
+ &stat);
/* ADD data from contiguous recv buffer */
if (direction == GMX_SUM_GRID_FORWARD)
int pmeidx, fftidx;
/* Dimensions should be identical for A/B grid, so we just use A here */
- gmx_parallel_3dfft_real_limits(pme->pfft_setup[grid_index], local_fft_ndata, local_fft_offset,
- local_fft_size);
+ gmx_parallel_3dfft_real_limits(
+ pme->pfft_setup[grid_index], local_fft_ndata, local_fft_offset, local_fft_size);
local_pme_size[0] = pme->pmegrid_nx;
local_pme_size[1] = pme->pmegrid_ny;
val = 100 * pmegrid[pmeidx];
if (pmegrid[pmeidx] != 0)
{
- gmx_fprintf_pdb_atomline(fp, epdbATOM, pmeidx, "CA", ' ', "GLY", ' ', pmeidx,
- ' ', 5.0 * ix, 5.0 * iy, 5.0 * iz, 1.0, val, "");
+ gmx_fprintf_pdb_atomline(fp,
+ epdbATOM,
+ pmeidx,
+ "CA",
+ ' ',
+ "GLY",
+ ' ',
+ pmeidx,
+ ' ',
+ 5.0 * ix,
+ 5.0 * iy,
+ 5.0 * iz,
+ 1.0,
+ val,
+ "");
}
if (pmegrid[pmeidx] != 0)
{
- fprintf(fp2, "%-12s %5d %5d %5d %12.5e\n", "qgrid",
- pme->pmegrid_start_ix + ix, pme->pmegrid_start_iy + iy,
- pme->pmegrid_start_iz + iz, pmegrid[pmeidx]);
+ fprintf(fp2,
+ "%-12s %5d %5d %5d %12.5e\n",
+ "qgrid",
+ pme->pmegrid_start_ix + ix,
+ pme->pmegrid_start_iy + iy,
+ pme->pmegrid_start_iz + iz,
+ pmegrid[pmeidx]);
}
#endif
}
c1 = omp_cyc_start();
#endif
/* Dimensions should be identical for A/B grid, so we just use A here */
- gmx_parallel_3dfft_real_limits(pme->pfft_setup[grid_index], local_fft_ndata, local_fft_offset,
- local_fft_size);
+ gmx_parallel_3dfft_real_limits(
+ pme->pfft_setup[grid_index], local_fft_ndata, local_fft_offset, local_fft_size);
local_pme_size[0] = pme->pmegrid_nx;
local_pme_size[1] = pme->pmegrid_ny;
gmx_fatal(FARGS,
"PME grid thread division (%d x %d x %d) does not match the total number of "
"threads (%d)",
- nsub[XX], nsub[YY], nsub[ZZ], nthread);
+ nsub[XX],
+ nsub[YY],
+ nsub[ZZ],
+ nthread);
}
}
if (debug)
{
- fprintf(debug, "pmegrid thread local division: %d x %d x %d\n", grids->nc[XX],
- grids->nc[YY], grids->nc[ZZ]);
- fprintf(debug, "pmegrid %d %d %d max thread pmegrid %d %d %d\n", nx, ny, nz, nst[XX],
- nst[YY], nst[ZZ]);
+ fprintf(debug,
+ "pmegrid thread local division: %d x %d x %d\n",
+ grids->nc[XX],
+ grids->nc[YY],
+ grids->nc[ZZ]);
+ fprintf(debug, "pmegrid %d %d %d max thread pmegrid %d %d %d\n", nx, ny, nz, nst[XX], nst[YY], nst[ZZ]);
}
snew(grids->grid_th, grids->nthread);
t = 0;
gridsize = nst[XX] * nst[YY] * nst[ZZ];
set_gridsize_alignment(&gridsize, pme_order);
- snew_aligned(grids->grid_all, grids->nthread * gridsize + (grids->nthread + 1) * GMX_CACHE_SEP,
+ snew_aligned(grids->grid_all,
+ grids->nthread * gridsize + (grids->nthread + 1) * GMX_CACHE_SEP,
SIMD4_ALIGNMENT);
for (x = 0; x < grids->nc[XX]; x++)
{
for (z = 0; z < grids->nc[ZZ]; z++)
{
- pmegrid_init(&grids->grid_th[t], x, y, z, (n[XX] * (x)) / grids->nc[XX],
- (n[YY] * (y)) / grids->nc[YY], (n[ZZ] * (z)) / grids->nc[ZZ],
- (n[XX] * (x + 1)) / grids->nc[XX], (n[YY] * (y + 1)) / grids->nc[YY],
- (n[ZZ] * (z + 1)) / grids->nc[ZZ], TRUE, pme_order,
+ pmegrid_init(&grids->grid_th[t],
+ x,
+ y,
+ z,
+ (n[XX] * (x)) / grids->nc[XX],
+ (n[YY] * (y)) / grids->nc[YY],
+ (n[ZZ] * (z)) / grids->nc[ZZ],
+ (n[XX] * (x + 1)) / grids->nc[XX],
+ (n[YY] * (y + 1)) / grids->nc[YY],
+ (n[ZZ] * (z + 1)) / grids->nc[ZZ],
+ TRUE,
+ pme_order,
grids->grid_all + GMX_CACHE_SEP + t * (gridsize + GMX_CACHE_SEP));
t++;
}
}
if (debug != nullptr)
{
- fprintf(debug, "pmegrid thread grid communication range in %c: %d\n", 'x' + d,
+ fprintf(debug,
+ "pmegrid thread grid communication range in %c: %d\n",
+ 'x' + d,
grids->nthread_comm[d]);
}
/* It should be possible to make grids->nthread_comm[d]==grids->nc[d]
};
/*! \brief Descriptive strings matching ::epmelb */
-static const char* pmelblim_str[epmelblimNR] = { "no", "box size", "domain decompostion",
+static const char* pmelblim_str[epmelblimNR] = { "no",
+ "box size",
+ "domain decompostion",
"PME grid restriction",
"maximum allowed grid scaling" };
if (!pme_lb->bSepPMERanks)
{
- GMX_RELEASE_ASSERT(pmedata,
- "On ranks doing both PP and PME we need a valid pmedata object");
+ GMX_RELEASE_ASSERT(pmedata, "On ranks doing both PP and PME we need a valid pmedata object");
pme_lb->setup[0].pmedata = pmedata;
}
fac *= 1.01;
clear_ivec(set.grid);
- sp = calcFftGrid(nullptr, pme_lb->box_start, fac * pme_lb->setup[pme_lb->cur].spacing,
- minimalPmeGridSize(pme_order), &set.grid[XX], &set.grid[YY], &set.grid[ZZ]);
+ sp = calcFftGrid(nullptr,
+ pme_lb->box_start,
+ fac * pme_lb->setup[pme_lb->cur].spacing,
+ minimalPmeGridSize(pme_order),
+ &set.grid[XX],
+ &set.grid[YY],
+ &set.grid[ZZ]);
/* As here we can't easily check if one of the PME ranks
* uses threading, we do a conservative grid check.
* This means we can't use pme_order or less grid lines
* per PME rank along x, which is not a strong restriction.
*/
- grid_ok = gmx_pme_check_restrictions(pme_order, set.grid[XX], set.grid[YY], set.grid[ZZ],
- numPmeDomains.x, true, false);
+ grid_ok = gmx_pme_check_restrictions(
+ pme_order, set.grid[XX], set.grid[YY], set.grid[ZZ], numPmeDomains.x, true, false);
} while (sp <= 1.001 * pme_lb->setup[pme_lb->cur].spacing || !grid_ok);
set.rcut_coulomb = pme_lb->cut_spacing * sp;
if (debug)
{
- fprintf(debug, "PME loadbal: grid %d %d %d, coulomb cutoff %f\n", set.grid[XX],
- set.grid[YY], set.grid[ZZ], set.rcut_coulomb);
+ fprintf(debug,
+ "PME loadbal: grid %d %d %d, coulomb cutoff %f\n",
+ set.grid[XX],
+ set.grid[YY],
+ set.grid[ZZ],
+ set.rcut_coulomb);
}
pme_lb->setup.push_back(set);
return TRUE;
/*! \brief Print the PME grid */
static void print_grid(FILE* fp_err, FILE* fp_log, const char* pre, const char* desc, const pme_setup_t* set, double cycles)
{
- auto buf = gmx::formatString("%-11s%10s pme grid %d %d %d, coulomb cutoff %.3f", pre, desc,
- set->grid[XX], set->grid[YY], set->grid[ZZ], set->rcut_coulomb);
+ auto buf = gmx::formatString("%-11s%10s pme grid %d %d %d, coulomb cutoff %.3f",
+ pre,
+ desc,
+ set->grid[XX],
+ set->grid[YY],
+ set->grid[ZZ],
+ set->rcut_coulomb);
if (cycles >= 0)
{
buf += gmx::formatString(": %.1f M-cycles", cycles * 1e-6);
{
auto buf = gmx::formatString(
"step %4s: the %s limits the PME load balancing to a coulomb cut-off of %.3f",
- gmx::int64ToString(step).c_str(), pmelblim_str[pme_lb->elimited],
+ gmx::int64ToString(step).c_str(),
+ pmelblim_str[pme_lb->elimited],
pme_lb->setup[pme_loadbal_end(pme_lb) - 1].rcut_coulomb);
if (fp_err != nullptr)
{
"is more than %f\n"
"Increased the number stages to %d"
" and ignoring the previous performance\n",
- set->grid[XX], set->grid[YY], set->grid[ZZ], set->cycles * 1e-6,
- cycles * 1e-6, maxFluctuationAccepted, pme_lb->nstage);
+ set->grid[XX],
+ set->grid[YY],
+ set->grid[ZZ],
+ set->cycles * 1e-6,
+ cycles * 1e-6,
+ maxFluctuationAccepted,
+ pme_lb->nstage);
}
}
set->cycles = std::min(set->cycles, cycles);
/* Generate a new PME data structure,
* copying part of the old pointers.
*/
- gmx_pme_reinit(&set->pmedata, cr, pme_lb->setup[0].pmedata, &ir, set->grid,
- set->ewaldcoeff_q, set->ewaldcoeff_lj);
+ gmx_pme_reinit(
+ &set->pmedata, cr, pme_lb->setup[0].pmedata, &ir, set->grid, set->ewaldcoeff_q, set->ewaldcoeff_lj);
}
*pmedata = set->pmedata;
}
* since init_step might not be a multiple of nstlist,
* but the first data collected is skipped anyhow.
*/
- pme_load_balance(pme_lb, cr, fp_err, fp_log, mdlog, ir, box, x,
- pme_lb->cycles_c - cycles_prev, fr->ic, fr->nbv.get(), &fr->pmedata, step);
+ pme_load_balance(pme_lb,
+ cr,
+ fp_err,
+ fp_log,
+ mdlog,
+ ir,
+ box,
+ x,
+ pme_lb->cycles_c - cycles_prev,
+ fr->ic,
+ fr->nbv.get(),
+ &fr->pmedata,
+ step);
/* Update deprecated rlist in forcerec to stay in sync with fr->nbv */
fr->rlist = fr->nbv->pairlistOuterRadius();
/*! \brief Print one load-balancing setting */
static void print_pme_loadbal_setting(FILE* fplog, const char* name, const pme_setup_t* setup)
{
- fprintf(fplog, " %-7s %6.3f nm %6.3f nm %3d %3d %3d %5.3f nm %5.3f nm\n", name,
- setup->rcut_coulomb, setup->rlistInner, setup->grid[XX], setup->grid[YY],
- setup->grid[ZZ], setup->spacing, 1 / setup->ewaldcoeff_q);
+ fprintf(fplog,
+ " %-7s %6.3f nm %6.3f nm %3d %3d %3d %5.3f nm %5.3f nm\n",
+ name,
+ setup->rcut_coulomb,
+ setup->rlistInner,
+ setup->grid[XX],
+ setup->grid[YY],
+ setup->grid[ZZ],
+ setup->spacing,
+ 1 / setup->ewaldcoeff_q);
}
/*! \brief Print all load-balancing settings */
/* Here we only warn when the optimal setting is the last one */
if (pme_lb->elimited != epmelblimNO && pme_lb->cur == pme_loadbal_end(pme_lb) - 1)
{
- fprintf(fplog, " NOTE: The PP/PME load balancing was limited by the %s,\n",
+ fprintf(fplog,
+ " NOTE: The PP/PME load balancing was limited by the %s,\n",
pmelblim_str[pme_lb->elimited]);
fprintf(fplog, " you might not have reached a good load balance.\n");
if (pme_lb->elimited == epmelblimDD)
cnb.flags = 0;
/* Receive the send count, box and time step from the peer PP node */
- MPI_Recv(&cnb, sizeof(cnb), MPI_BYTE, pme_pp->peerRankId, eCommType_CNB,
- pme_pp->mpi_comm_mysim, MPI_STATUS_IGNORE);
+ MPI_Recv(&cnb, sizeof(cnb), MPI_BYTE, pme_pp->peerRankId, eCommType_CNB, pme_pp->mpi_comm_mysim, MPI_STATUS_IGNORE);
/* We accumulate all received flags */
flags |= cnb.flags;
if (debug)
{
- fprintf(debug, "PME only rank receiving:%s%s%s%s%s\n",
+ fprintf(debug,
+ "PME only rank receiving:%s%s%s%s%s\n",
(cnb.flags & PP_PME_CHARGE) ? " charges" : "",
(cnb.flags & PP_PME_COORD) ? " coordinates" : "",
(cnb.flags & PP_PME_FINISH) ? " finish" : "",
}
else
{
- MPI_Irecv(&sender.numAtoms, sizeof(sender.numAtoms), MPI_BYTE, sender.rankId,
- eCommType_CNB, pme_pp->mpi_comm_mysim, &pme_pp->req[messages++]);
+ MPI_Irecv(&sender.numAtoms,
+ sizeof(sender.numAtoms),
+ MPI_BYTE,
+ sender.rankId,
+ eCommType_CNB,
+ pme_pp->mpi_comm_mysim,
+ &pme_pp->req[messages++]);
}
}
MPI_Waitall(messages, pme_pp->req.data(), pme_pp->stat.data());
{
if (sender.numAtoms > 0)
{
- MPI_Irecv(bufferPtr + nat, sender.numAtoms * sizeof(real), MPI_BYTE,
- sender.rankId, q, pme_pp->mpi_comm_mysim, &pme_pp->req[messages++]);
+ MPI_Irecv(bufferPtr + nat,
+ sender.numAtoms * sizeof(real),
+ MPI_BYTE,
+ sender.rankId,
+ q,
+ pme_pp->mpi_comm_mysim,
+ &pme_pp->req[messages++]);
nat += sender.numAtoms;
if (debug)
{
- fprintf(debug, "Received from PP rank %d: %d %s\n", sender.rankId,
+ fprintf(debug,
+ "Received from PP rank %d: %d %s\n",
+ sender.rankId,
sender.numAtoms,
(q == eCommType_ChargeA || q == eCommType_ChargeB) ? "charges"
: "params");
}
else
{
- MPI_Irecv(pme_pp->x[nat], sender.numAtoms * sizeof(rvec), MPI_BYTE, sender.rankId,
- eCommType_COORD, pme_pp->mpi_comm_mysim, &pme_pp->req[messages++]);
+ MPI_Irecv(pme_pp->x[nat],
+ sender.numAtoms * sizeof(rvec),
+ MPI_BYTE,
+ sender.rankId,
+ eCommType_COORD,
+ pme_pp->mpi_comm_mysim,
+ &pme_pp->req[messages++]);
}
nat += sender.numAtoms;
if (debug)
fprintf(debug,
"Received from PP rank %d: %d "
"coordinates\n",
- sender.rankId, sender.numAtoms);
+ sender.rankId,
+ sender.numAtoms);
}
}
}
else
{
// Send using MPI
- MPI_Isend(sendbuf, receiver.numAtoms * sizeof(rvec), MPI_BYTE, receiver.rankId, 0,
- pme_pp->mpi_comm_mysim, &pme_pp->req[*messages]);
+ MPI_Isend(sendbuf,
+ receiver.numAtoms * sizeof(rvec),
+ MPI_BYTE,
+ receiver.rankId,
+ 0,
+ pme_pp->mpi_comm_mysim,
+ &pme_pp->req[*messages]);
*messages = *messages + 1;
}
}
{
fprintf(debug, "PME rank sending to PP rank %d: virial and energy\n", pme_pp->peerRankId);
}
- MPI_Isend(&cve, sizeof(cve), MPI_BYTE, pme_pp->peerRankId, 1, pme_pp->mpi_comm_mysim,
- &pme_pp->req[messages++]);
+ MPI_Isend(&cve, sizeof(cve), MPI_BYTE, pme_pp->peerRankId, 1, pme_pp->mpi_comm_mysim, &pme_pp->req[messages++]);
/* Wait for the forces to arrive */
MPI_Waitall(messages, pme_pp->req.data(), pme_pp->stat.data());
if (c_enableGpuPmePpComms)
{
pme_pp->pmeCoordinateReceiverGpu = std::make_unique<gmx::PmeCoordinateReceiverGpu>(
- deviceStreamManager->stream(gmx::DeviceStreamType::Pme), pme_pp->mpi_comm_mysim,
+ deviceStreamManager->stream(gmx::DeviceStreamType::Pme),
+ pme_pp->mpi_comm_mysim,
pme_pp->ppRanks);
pme_pp->pmeForceSenderGpu = std::make_unique<gmx::PmeForceSenderGpu>(
- deviceStreamManager->stream(gmx::DeviceStreamType::Pme), pme_pp->mpi_comm_mysim,
+ deviceStreamManager->stream(gmx::DeviceStreamType::Pme),
+ pme_pp->mpi_comm_mysim,
pme_pp->ppRanks);
}
// TODO: Special PME-only constructor is used here. There is no mechanism to prevent from using the other constructor here.
// This should be made safer.
stateGpu = std::make_unique<gmx::StatePropagatorDataGpu>(
- &deviceStreamManager->stream(gmx::DeviceStreamType::Pme), deviceStreamManager->context(),
- GpuApiCallBehavior::Async, pme_gpu_get_block_size(pme), wcycle);
+ &deviceStreamManager->stream(gmx::DeviceStreamType::Pme),
+ deviceStreamManager->context(),
+ GpuApiCallBehavior::Async,
+ pme_gpu_get_block_size(pme),
+ wcycle);
}
clear_nrnb(mynrnb);
/* Domain decomposition */
ivec newGridSize;
real ewaldcoeff_q = 0, ewaldcoeff_lj = 0;
- ret = gmx_pme_recv_coeffs_coords(pme, pme_pp.get(), &natoms, box, &maxshift_x, &maxshift_y,
- &lambda_q, &lambda_lj, &computeEnergyAndVirial, &step,
- &newGridSize, &ewaldcoeff_q, &ewaldcoeff_lj,
- useGpuForPme, stateGpu.get(), runMode);
+ ret = gmx_pme_recv_coeffs_coords(pme,
+ pme_pp.get(),
+ &natoms,
+ box,
+ &maxshift_x,
+ &maxshift_y,
+ &lambda_q,
+ &lambda_lj,
+ &computeEnergyAndVirial,
+ &step,
+ &newGridSize,
+ &ewaldcoeff_q,
+ &ewaldcoeff_lj,
+ useGpuForPme,
+ stateGpu.get(),
+ runMode);
if (ret == pmerecvqxSWITCHGRID)
{
GMX_ASSERT(pme_pp->x.size() == static_cast<size_t>(natoms),
"The coordinate buffer should have size natoms");
- gmx_pme_do(pme, pme_pp->x, pme_pp->f, pme_pp->chargeA.data(), pme_pp->chargeB.data(),
- pme_pp->sqrt_c6A.data(), pme_pp->sqrt_c6B.data(), pme_pp->sigmaA.data(),
- pme_pp->sigmaB.data(), box, cr, maxshift_x, maxshift_y, mynrnb, wcycle,
- output.coulombVirial_, output.lennardJonesVirial_, &output.coulombEnergy_,
- &output.lennardJonesEnergy_, lambda_q, lambda_lj, &dvdlambda_q,
- &dvdlambda_lj, stepWork);
+ gmx_pme_do(pme,
+ pme_pp->x,
+ pme_pp->f,
+ pme_pp->chargeA.data(),
+ pme_pp->chargeB.data(),
+ pme_pp->sqrt_c6A.data(),
+ pme_pp->sqrt_c6B.data(),
+ pme_pp->sigmaA.data(),
+ pme_pp->sigmaB.data(),
+ box,
+ cr,
+ maxshift_x,
+ maxshift_y,
+ mynrnb,
+ wcycle,
+ output.coulombVirial_,
+ output.lennardJonesVirial_,
+ &output.coulombEnergy_,
+ &output.lennardJonesEnergy_,
+ lambda_q,
+ lambda_lj,
+ &dvdlambda_q,
+ &dvdlambda_lj,
+ stepWork);
output.forces_ = pme_pp->f;
}
if (debug)
{
- fprintf(debug, "PP rank %d sending to PME rank %d: %d%s%s%s%s\n", cr->sim_nodeid, dd->pme_nodeid,
- n, (flags & PP_PME_CHARGE) ? " charges" : "", (flags & PP_PME_SQRTC6) ? " sqrtC6" : "",
- (flags & PP_PME_SIGMA) ? " sigma" : "", (flags & PP_PME_COORD) ? " coordinates" : "");
+ fprintf(debug,
+ "PP rank %d sending to PME rank %d: %d%s%s%s%s\n",
+ cr->sim_nodeid,
+ dd->pme_nodeid,
+ n,
+ (flags & PP_PME_CHARGE) ? " charges" : "",
+ (flags & PP_PME_SQRTC6) ? " sqrtC6" : "",
+ (flags & PP_PME_SIGMA) ? " sigma" : "",
+ (flags & PP_PME_COORD) ? " coordinates" : "");
}
if (useGpuPmePpComms)
copy_mat(box, cnb->box);
}
#if GMX_MPI
- MPI_Isend(cnb, sizeof(*cnb), MPI_BYTE, dd->pme_nodeid, eCommType_CNB, cr->mpi_comm_mysim,
+ MPI_Isend(cnb,
+ sizeof(*cnb),
+ MPI_BYTE,
+ dd->pme_nodeid,
+ eCommType_CNB,
+ cr->mpi_comm_mysim,
&dd->req_pme[dd->nreq_pme++]);
#endif
}
{
#if GMX_MPI
/* Communicate only the number of atoms */
- MPI_Isend(&n, sizeof(n), MPI_BYTE, dd->pme_nodeid, eCommType_CNB, cr->mpi_comm_mysim,
+ MPI_Isend(&n,
+ sizeof(n),
+ MPI_BYTE,
+ dd->pme_nodeid,
+ eCommType_CNB,
+ cr->mpi_comm_mysim,
&dd->req_pme[dd->nreq_pme++]);
#endif
}
{
if (flags & PP_PME_CHARGE)
{
- MPI_Isend(chargeA, n * sizeof(real), MPI_BYTE, dd->pme_nodeid, eCommType_ChargeA,
- cr->mpi_comm_mysim, &dd->req_pme[dd->nreq_pme++]);
+ MPI_Isend(chargeA,
+ n * sizeof(real),
+ MPI_BYTE,
+ dd->pme_nodeid,
+ eCommType_ChargeA,
+ cr->mpi_comm_mysim,
+ &dd->req_pme[dd->nreq_pme++]);
}
if (flags & PP_PME_CHARGEB)
{
- MPI_Isend(chargeB, n * sizeof(real), MPI_BYTE, dd->pme_nodeid, eCommType_ChargeB,
- cr->mpi_comm_mysim, &dd->req_pme[dd->nreq_pme++]);
+ MPI_Isend(chargeB,
+ n * sizeof(real),
+ MPI_BYTE,
+ dd->pme_nodeid,
+ eCommType_ChargeB,
+ cr->mpi_comm_mysim,
+ &dd->req_pme[dd->nreq_pme++]);
}
if (flags & PP_PME_SQRTC6)
{
- MPI_Isend(c6A, n * sizeof(real), MPI_BYTE, dd->pme_nodeid, eCommType_SQRTC6A,
- cr->mpi_comm_mysim, &dd->req_pme[dd->nreq_pme++]);
+ MPI_Isend(c6A,
+ n * sizeof(real),
+ MPI_BYTE,
+ dd->pme_nodeid,
+ eCommType_SQRTC6A,
+ cr->mpi_comm_mysim,
+ &dd->req_pme[dd->nreq_pme++]);
}
if (flags & PP_PME_SQRTC6B)
{
- MPI_Isend(c6B, n * sizeof(real), MPI_BYTE, dd->pme_nodeid, eCommType_SQRTC6B,
- cr->mpi_comm_mysim, &dd->req_pme[dd->nreq_pme++]);
+ MPI_Isend(c6B,
+ n * sizeof(real),
+ MPI_BYTE,
+ dd->pme_nodeid,
+ eCommType_SQRTC6B,
+ cr->mpi_comm_mysim,
+ &dd->req_pme[dd->nreq_pme++]);
}
if (flags & PP_PME_SIGMA)
{
- MPI_Isend(sigmaA, n * sizeof(real), MPI_BYTE, dd->pme_nodeid, eCommType_SigmaA,
- cr->mpi_comm_mysim, &dd->req_pme[dd->nreq_pme++]);
+ MPI_Isend(sigmaA,
+ n * sizeof(real),
+ MPI_BYTE,
+ dd->pme_nodeid,
+ eCommType_SigmaA,
+ cr->mpi_comm_mysim,
+ &dd->req_pme[dd->nreq_pme++]);
}
if (flags & PP_PME_SIGMAB)
{
- MPI_Isend(sigmaB, n * sizeof(real), MPI_BYTE, dd->pme_nodeid, eCommType_SigmaB,
- cr->mpi_comm_mysim, &dd->req_pme[dd->nreq_pme++]);
+ MPI_Isend(sigmaB,
+ n * sizeof(real),
+ MPI_BYTE,
+ dd->pme_nodeid,
+ eCommType_SigmaB,
+ cr->mpi_comm_mysim,
+ &dd->req_pme[dd->nreq_pme++]);
}
if (flags & PP_PME_COORD)
{
void* sendPtr = sendCoordinatesFromGpu
? static_cast<void*>(fr->stateGpu->getCoordinates())
: static_cast<void*>(xRealPtr);
- fr->pmePpCommGpu->sendCoordinatesToPmeCudaDirect(sendPtr, n, sendCoordinatesFromGpu,
- coordinatesReadyOnDeviceEvent);
+ fr->pmePpCommGpu->sendCoordinatesToPmeCudaDirect(
+ sendPtr, n, sendCoordinatesFromGpu, coordinatesReadyOnDeviceEvent);
}
else
{
- MPI_Isend(xRealPtr, n * sizeof(rvec), MPI_BYTE, dd->pme_nodeid, eCommType_COORD,
- cr->mpi_comm_mysim, &dd->req_pme[dd->nreq_pme++]);
+ MPI_Isend(xRealPtr,
+ n * sizeof(rvec),
+ MPI_BYTE,
+ dd->pme_nodeid,
+ eCommType_COORD,
+ cr->mpi_comm_mysim,
+ &dd->req_pme[dd->nreq_pme++]);
}
}
}
flags |= (flags << 1);
}
- gmx_pme_send_coeffs_coords(nullptr, cr, flags, chargeA, chargeB, sqrt_c6A, sqrt_c6B, sigmaA,
- sigmaB, nullptr, nullptr, 0, 0, maxshift_x, maxshift_y, -1, false,
- false, false, nullptr);
+ gmx_pme_send_coeffs_coords(nullptr,
+ cr,
+ flags,
+ chargeA,
+ chargeB,
+ sqrt_c6A,
+ sqrt_c6B,
+ sigmaA,
+ sigmaB,
+ nullptr,
+ nullptr,
+ 0,
+ 0,
+ maxshift_x,
+ maxshift_y,
+ -1,
+ false,
+ false,
+ false,
+ nullptr);
}
void gmx_pme_send_coordinates(t_forcerec* fr,
{
flags |= PP_PME_ENER_VIR;
}
- gmx_pme_send_coeffs_coords(fr, cr, flags, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
- box, x, lambda_q, lambda_lj, 0, 0, step, useGpuPmePpComms,
- receiveCoordinateAddressFromPme, sendCoordinatesFromGpu,
+ gmx_pme_send_coeffs_coords(fr,
+ cr,
+ flags,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ box,
+ x,
+ lambda_q,
+ lambda_lj,
+ 0,
+ 0,
+ step,
+ useGpuPmePpComms,
+ receiveCoordinateAddressFromPme,
+ sendCoordinatesFromGpu,
coordinatesReadyOnDeviceEvent);
wallcycle_stop(wcycle, ewcPP_PMESENDX);
{
unsigned int flags = PP_PME_FINISH;
- gmx_pme_send_coeffs_coords(nullptr, cr, flags, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
- nullptr, nullptr, 0, 0, 0, 0, -1, false, false, false, nullptr);
+ gmx_pme_send_coeffs_coords(nullptr,
+ cr,
+ flags,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ 0,
+ 0,
+ 0,
+ 0,
+ -1,
+ false,
+ false,
+ false,
+ nullptr);
}
void gmx_pme_send_switchgrid(const t_commrec* cr, ivec grid_size, real ewaldcoeff_q, real ewaldcoeff_lj)
{
if (debug)
{
- fprintf(debug, "PP rank %d receiving from PME rank %d: virial and energy\n",
- cr->sim_nodeid, cr->dd->pme_nodeid);
+ fprintf(debug,
+ "PP rank %d receiving from PME rank %d: virial and energy\n",
+ cr->sim_nodeid,
+ cr->dd->pme_nodeid);
}
#if GMX_MPI
MPI_Recv(&cve, sizeof(cve), MPI_BYTE, cr->dd->pme_nodeid, 1, cr->mpi_comm_mysim, MPI_STATUS_IGNORE);
{
// Receive data using MPI
#if GMX_MPI
- MPI_Recv(recvptr, n * sizeof(rvec), MPI_BYTE, cr->dd->pme_nodeid, 0, cr->mpi_comm_mysim,
- MPI_STATUS_IGNORE);
+ MPI_Recv(recvptr, n * sizeof(rvec), MPI_BYTE, cr->dd->pme_nodeid, 0, cr->mpi_comm_mysim, MPI_STATUS_IGNORE);
#else
GMX_UNUSED_VALUE(cr);
#endif
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
#ifndef GMX_PME_PP_COMM_GPU_H
#define GMX_PME_PP_COMM_GPU_H
-#include "gromacs/utility/classhelpers.h"
+#include <memory>
+
#include "gromacs/utility/gmxmpi.h"
class DeviceContext;
private:
class Impl;
- gmx::PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
// Pull force data from remote GPU
void* pmeForcePtr = receivePmeForceToGpu ? static_cast<void*>(d_pmeForces_) : recvPtr;
- cudaError_t stat = cudaMemcpyAsync(pmeForcePtr, remotePmeFBuffer_, recvSize * DIM * sizeof(float),
- cudaMemcpyDefault, pmePpCommStream_.stream());
+ cudaError_t stat = cudaMemcpyAsync(pmeForcePtr,
+ remotePmeFBuffer_,
+ recvSize * DIM * sizeof(float),
+ cudaMemcpyDefault,
+ pmePpCommStream_.stream());
CU_RET_ERR(stat, "cudaMemcpyAsync on Recv from PME CUDA direct data transfer failed");
if (receivePmeForceToGpu)
// ensure stream waits until coordinate data is available on device
coordinatesReadyOnDeviceEvent->enqueueWaitEvent(pmePpCommStream_);
- cudaError_t stat = cudaMemcpyAsync(remotePmeXBuffer_, sendPtr, sendSize * DIM * sizeof(float),
- cudaMemcpyDefault, pmePpCommStream_.stream());
+ cudaError_t stat = cudaMemcpyAsync(remotePmeXBuffer_,
+ sendPtr,
+ sendSize * DIM * sizeof(float),
+ cudaMemcpyDefault,
+ pmePpCommStream_.stream());
CU_RET_ERR(stat, "cudaMemcpyAsync on Send to PME CUDA direct data transfer failed");
// Record and send event to allow PME task to sync to above transfer before commencing force calculations
bool sendPmeCoordinatesFromGpu,
GpuEventSynchronizer* coordinatesReadyOnDeviceEvent)
{
- impl_->sendCoordinatesToPmeCudaDirect(sendPtr, sendSize, sendPmeCoordinatesFromGpu,
- coordinatesReadyOnDeviceEvent);
+ impl_->sendCoordinatesToPmeCudaDirect(
+ sendPtr, sendSize, sendPmeCoordinatesFromGpu, coordinatesReadyOnDeviceEvent);
}
void* PmePpCommGpu::getGpuForceStagingPtr()
try
{
const int natoms = x.ssize();
- pme_calc_pidx(natoms * thread / nthread, natoms * (thread + 1) / nthread, recipbox, x,
- atc, atc->count_thread[thread].data());
+ pme_calc_pidx(natoms * thread / nthread,
+ natoms * (thread + 1) / nthread,
+ recipbox,
+ x,
+ atc,
+ atc->count_thread[thread].data());
}
GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
}
if (nbyte_s > 0 && nbyte_r > 0)
{
- MPI_Sendrecv(buf_s, nbyte_s, MPI_BYTE, dest, shift, buf_r, nbyte_r, MPI_BYTE, src, shift,
- atc->mpi_comm, &stat);
+ MPI_Sendrecv(
+ buf_s, nbyte_s, MPI_BYTE, dest, shift, buf_r, nbyte_r, MPI_BYTE, src, shift, atc->mpi_comm, &stat);
}
else if (nbyte_s > 0)
{
"%zd particles communicated to PME rank %d are more than 2/3 times the cut-off "
"out of the domain decomposition cell of their charge group in dimension %c.\n"
"This usually means that your system is not well equilibrated.",
- x.ssize() - (sendCount[atc->nodeid] + nsend), pme->nodeid, 'x' + atc->dimind);
+ x.ssize() - (sendCount[atc->nodeid] + nsend),
+ pme->nodeid,
+ 'x' + atc->dimind);
}
if (nsend > pme->buf_nalloc)
/* Communicate the count */
if (debug)
{
- fprintf(debug, "dimind %d PME rank %d send to rank %d: %d\n", atc->dimind,
- atc->nodeid, commnode, scount);
+ fprintf(debug, "dimind %d PME rank %d send to rank %d: %d\n", atc->dimind, atc->nodeid, commnode, scount);
}
- pme_dd_sendrecv(atc, FALSE, i, &scount, sizeof(int), &atc->slabCommSetup[i].rcount,
- sizeof(int));
+ pme_dd_sendrecv(
+ atc, FALSE, i, &scount, sizeof(int), &atc->slabCommSetup[i].rcount, sizeof(int));
numAtoms += atc->slabCommSetup[i].rcount;
}
if (bX)
{
/* Communicate the coordinates */
- pme_dd_sendrecv(atc, FALSE, i, pme->bufv + buf_pos, scount * sizeof(rvec),
- atc->xBuffer.data() + local_pos, rcount * sizeof(rvec));
+ pme_dd_sendrecv(atc,
+ FALSE,
+ i,
+ pme->bufv + buf_pos,
+ scount * sizeof(rvec),
+ atc->xBuffer.data() + local_pos,
+ rcount * sizeof(rvec));
}
/* Communicate the coefficients */
- pme_dd_sendrecv(atc, FALSE, i, pme->bufr + buf_pos, scount * sizeof(real),
- atc->coefficientBuffer.data() + local_pos, rcount * sizeof(real));
+ pme_dd_sendrecv(atc,
+ FALSE,
+ i,
+ pme->bufr + buf_pos,
+ scount * sizeof(real),
+ atc->coefficientBuffer.data() + local_pos,
+ rcount * sizeof(real));
buf_pos += scount;
local_pos += atc->slabCommSetup[i].rcount;
}
if (scount > 0 || rcount > 0)
{
/* Communicate the forces */
- pme_dd_sendrecv(atc, TRUE, i, atc->f.data() + local_pos, scount * sizeof(rvec),
- pme->bufv + buf_pos, rcount * sizeof(rvec));
+ pme_dd_sendrecv(atc,
+ TRUE,
+ i,
+ atc->f.data() + local_pos,
+ scount * sizeof(rvec),
+ pme->bufv + buf_pos,
+ rcount * sizeof(rvec));
local_pos += scount;
}
atc->slabCommSetup[commnode].buf_index = buf_pos;
static void reallocSimdAlignedAndPadded(real** ptr, int unpaddedNumElements)
{
sfree_aligned(*ptr);
- snew_aligned(*ptr, roundUpToMultipleOfFactor<c_simdWidth>(unpaddedNumElements),
+ snew_aligned(*ptr,
+ roundUpToMultipleOfFactor<c_simdWidth>(unpaddedNumElements),
c_simdWidth * sizeof(real));
}
nz = pme->nkz;
/* Dimensions should be identical for A/B grid, so we just use A here */
- gmx_parallel_3dfft_complex_limits(pme->pfft_setup[PME_GRID_QA], complex_order, local_ndata,
- local_offset, local_size);
+ gmx_parallel_3dfft_complex_limits(
+ pme->pfft_setup[PME_GRID_QA], complex_order, local_ndata, local_offset, local_size);
rxx = pme->recipbox[XX][XX];
ryx = pme->recipbox[YY][XX];
}
calc_exponentials_q(
- kxstart, kxend, elfac,
+ kxstart,
+ kxend,
+ elfac,
ArrayRef<PME_T>(denom, denom + roundUpToMultipleOfFactor<c_simdWidth>(kxend)),
ArrayRef<PME_T>(tmp1, tmp1 + roundUpToMultipleOfFactor<c_simdWidth>(kxend)),
ArrayRef<PME_T>(eterm, eterm + roundUpToMultipleOfFactor<c_simdWidth>(kxend)));
}
calc_exponentials_q(
- kxstart, kxend, elfac,
+ kxstart,
+ kxend,
+ elfac,
ArrayRef<PME_T>(denom, denom + roundUpToMultipleOfFactor<c_simdWidth>(kxend)),
ArrayRef<PME_T>(tmp1, tmp1 + roundUpToMultipleOfFactor<c_simdWidth>(kxend)),
ArrayRef<PME_T>(eterm, eterm + roundUpToMultipleOfFactor<c_simdWidth>(kxend)));
nz = pme->nkz;
/* Dimensions should be identical for A/B grid, so we just use A here */
- gmx_parallel_3dfft_complex_limits(pme->pfft_setup[PME_GRID_C6A], complex_order, local_ndata,
- local_offset, local_size);
+ gmx_parallel_3dfft_complex_limits(
+ pme->pfft_setup[PME_GRID_C6A], complex_order, local_ndata, local_offset, local_size);
rxx = pme->recipbox[XX][XX];
ryx = pme->recipbox[YY][XX];
ryy = pme->recipbox[YY][YY];
}
calc_exponentials_lj(
- kxstart, kxend,
+ kxstart,
+ kxend,
ArrayRef<PME_T>(tmp1, tmp1 + roundUpToMultipleOfFactor<c_simdWidth>(kxend)),
ArrayRef<PME_T>(tmp2, tmp2 + roundUpToMultipleOfFactor<c_simdWidth>(kxend)),
ArrayRef<PME_T>(denom, denom + roundUpToMultipleOfFactor<c_simdWidth>(kxend)));
}
calc_exponentials_lj(
- kxstart, kxend,
+ kxstart,
+ kxend,
ArrayRef<PME_T>(tmp1, tmp1 + roundUpToMultipleOfFactor<c_simdWidth>(kxend)),
ArrayRef<PME_T>(tmp2, tmp2 + roundUpToMultipleOfFactor<c_simdWidth>(kxend)),
ArrayRef<PME_T>(denom, denom + roundUpToMultipleOfFactor<c_simdWidth>(kxend)));
pme_gpu_stage_atom_data(sm_coordinates, gm_coordinates, DIM);
barrier(CLK_LOCAL_MEM_FENCE);
- calculate_splines(kernelParams, atomIndexOffset, sm_coordinates, sm_coefficients, sm_theta,
- sm_gridlineIndices, sm_fractCoords, gm_theta, gm_dtheta,
- gm_gridlineIndices, gm_fractShiftsTable, gm_gridlineIndicesTable);
+ calculate_splines(kernelParams,
+ atomIndexOffset,
+ sm_coordinates,
+ sm_coefficients,
+ sm_theta,
+ sm_gridlineIndices,
+ sm_fractCoords,
+ gm_theta,
+ gm_dtheta,
+ gm_gridlineIndices,
+ gm_fractShiftsTable,
+ gm_gridlineIndicesTable);
#if !defined(_AMD_SOURCE_) && !defined(_NVIDIA_SOURCE_)
/* This is only here for execution of e.g. 32-sized warps on 16-wide hardware; this was
* __syncwarp() in CUDA. #2519
/* Spline data - only thetas (dthetas will only be needed in gather) */
pme_gpu_stage_atom_data(sm_theta, gm_theta, DIM * order);
/* Gridline indices - they're actually int and not float, but C99 is angry about overloads */
- pme_gpu_stage_atom_data((__local float*)sm_gridlineIndices,
- (__global const float*)gm_gridlineIndices, DIM);
+ pme_gpu_stage_atom_data(
+ (__local float*)sm_gridlineIndices, (__global const float*)gm_gridlineIndices, DIM);
barrier(CLK_LOCAL_MEM_FENCE);
}
int d;
real* grid_th;
- gmx_parallel_3dfft_real_limits(pme->pfft_setup[grid_index], local_fft_ndata, local_fft_offset,
- local_fft_size);
+ gmx_parallel_3dfft_real_limits(
+ pme->pfft_setup[grid_index], local_fft_ndata, local_fft_offset, local_fft_size);
fft_my = local_fft_size[YY];
fft_mz = local_fft_size[ZZ];
const real* grid_th;
real* commbuf = nullptr;
- gmx_parallel_3dfft_real_limits(pme->pfft_setup[grid_index], local_fft_ndata, local_fft_offset,
- local_fft_size);
+ gmx_parallel_3dfft_real_limits(
+ pme->pfft_setup[grid_index], local_fft_ndata, local_fft_offset, local_fft_size);
fft_nx = local_fft_ndata[XX];
fft_ny = local_fft_ndata[YY];
fft_nz = local_fft_ndata[ZZ];
#ifdef DEBUG_PME_REDUCE
printf("n%d t%d add %d %2d %2d %2d %2d %2d %2d %2d-%2d %2d-%2d, %2d-%2d "
"%2d-%2d, %2d-%2d %2d-%2d\n",
- pme->nodeid, thread, thread_f, pme->pmegrid_start_ix, pme->pmegrid_start_iy,
- pme->pmegrid_start_iz, sx, sy, sz, offx - ox, tx1 - ox, offx, tx1, offy - oy,
- ty1 - oy, offy, ty1, offz - oz, tz1 - oz, offz, tz1);
+ pme->nodeid,
+ thread,
+ thread_f,
+ pme->pmegrid_start_ix,
+ pme->pmegrid_start_iy,
+ pme->pmegrid_start_iz,
+ sx,
+ sy,
+ sz,
+ offx - ox,
+ tx1 - ox,
+ offx,
+ tx1,
+ offy - oy,
+ ty1 - oy,
+ offy,
+ ty1,
+ offz - oz,
+ tz1 - oz,
+ offz,
+ tz1);
#endif
if (!(bCommX || bCommY))
* communication setup.
*/
- gmx_parallel_3dfft_real_limits(pme->pfft_setup[grid_index], local_fft_ndata, local_fft_offset,
- local_fft_size);
+ gmx_parallel_3dfft_real_limits(
+ pme->pfft_setup[grid_index], local_fft_ndata, local_fft_offset, local_fft_size);
if (pme->nnodes_minor > 1)
{
if (debug != nullptr)
{
- fprintf(debug, "PME fftgrid comm y %2d x %2d x %2d\n", local_fft_ndata[XX],
- send_nindex, local_fft_ndata[ZZ]);
+ fprintf(debug,
+ "PME fftgrid comm y %2d x %2d x %2d\n",
+ local_fft_ndata[XX],
+ send_nindex,
+ local_fft_ndata[ZZ]);
}
#if GMX_MPI
int send_id = overlap->comm_data[ipulse].send_id;
int recv_id = overlap->comm_data[ipulse].recv_id;
- MPI_Sendrecv(sendptr, send_size_y * datasize, GMX_MPI_REAL, send_id, ipulse, recvptr,
- recv_size_y * datasize, GMX_MPI_REAL, recv_id, ipulse, overlap->mpi_comm, &stat);
+ MPI_Sendrecv(sendptr,
+ send_size_y * datasize,
+ GMX_MPI_REAL,
+ send_id,
+ ipulse,
+ recvptr,
+ recv_size_y * datasize,
+ GMX_MPI_REAL,
+ recv_id,
+ ipulse,
+ overlap->mpi_comm,
+ &stat);
#endif
for (x = 0; x < local_fft_ndata[XX]; x++)
if (debug != nullptr)
{
- fprintf(debug, "PME fftgrid comm x %2d x %2d x %2d\n", send_nindex, local_fft_ndata[YY],
+ fprintf(debug,
+ "PME fftgrid comm x %2d x %2d x %2d\n",
+ send_nindex,
+ local_fft_ndata[YY],
local_fft_ndata[ZZ]);
}
int recv_id = overlap->comm_data[ipulse].recv_id;
auto* sendptr = const_cast<real*>(overlap->sendbuf.data());
auto* recvptr = const_cast<real*>(overlap->recvbuf.data());
- MPI_Sendrecv(sendptr, send_nindex * datasize, GMX_MPI_REAL, send_id, ipulse, recvptr,
- recv_nindex * datasize, GMX_MPI_REAL, recv_id, ipulse, overlap->mpi_comm, &stat);
+ MPI_Sendrecv(sendptr,
+ send_nindex * datasize,
+ GMX_MPI_REAL,
+ send_id,
+ ipulse,
+ recvptr,
+ recv_nindex * datasize,
+ GMX_MPI_REAL,
+ recv_id,
+ ipulse,
+ overlap->mpi_comm,
+ &stat);
#endif
for (x = 0; x < recv_nindex; x++)
if (bCalcSplines)
{
- make_bsplines(spline->theta.coefficients, spline->dtheta.coefficients,
- pme->pme_order, as_rvec_array(atc->fractx.data()), spline->n,
- spline->ind.data(), atc->coefficient.data(), bDoSplines);
+ make_bsplines(spline->theta.coefficients,
+ spline->dtheta.coefficients,
+ pme->pme_order,
+ as_rvec_array(atc->fractx.data()),
+ spline->n,
+ spline->ind.data(),
+ atc->coefficient.data(),
+ bDoSplines);
}
if (bSpread)
{
try
{
- reduce_threadgrid_overlap(pme, grids, thread, fftgrid,
+ reduce_threadgrid_overlap(pme,
+ grids,
+ thread,
+ fftgrid,
const_cast<real*>(pme->overlap[0].sendbuf.data()),
- const_cast<real*>(pme->overlap[1].sendbuf.data()), grid_index);
+ const_cast<real*>(pme->overlap[1].sendbuf.data()),
+ grid_index);
}
GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
}
/* Spreading */
if (spreadCharges)
{
- spread_charges<order, wrapX, wrapY, 0, threadsPerAtom>(kernelParams, &atomCharge,
- sm_gridlineIndices, sm_theta);
+ spread_charges<order, wrapX, wrapY, 0, threadsPerAtom>(
+ kernelParams, &atomCharge, sm_gridlineIndices, sm_theta);
}
if (numGrids == 2)
{
}
if (spreadCharges)
{
- spread_charges<order, wrapX, wrapY, 1, threadsPerAtom>(kernelParams, &atomCharge,
- sm_gridlineIndices, sm_theta);
+ spread_charges<order, wrapX, wrapY, 1, threadsPerAtom>(
+ kernelParams, &atomCharge, sm_gridlineIndices, sm_theta);
}
}
}
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2016,2017,2020, by the GROMACS development team, led by
+# Copyright (c) 2016,2017,2020,2021, 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.
pmesolvetest.cpp
pmesplinespreadtest.cpp
pmetestcommon.cpp
+ pme.cpp
)
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2021, 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 functionality of the pme related classes:
+ * class SeparatePmeRanksPermitted
+ *
+ * \author Dmitry Morozov <dmitry.morozov@jyu.fi>
+ * \ingroup module_ewald
+ */
+#include "gmxpre.h"
+
+#include <gtest/gtest.h>
+
+#include "gromacs/utility/real.h"
+#include "gromacs/utility/smalloc.h"
+#include "gromacs/utility/stringcompare.h"
+
+#include "testutils/testasserts.h"
+#include "testutils/testmatchers.h"
+
+#include "pmetestcommon.h"
+
+namespace gmx
+{
+
+namespace test
+{
+
+class SeparatePmeRanksPermittedTest : public ::testing::Test
+{
+public:
+ void disableFirstReason() { separatePmeRanksPermitted_.disablePmeRanks("First reason"); }
+
+ void disableSecondReason() { separatePmeRanksPermitted_.disablePmeRanks("Second reason"); }
+
+ void disableEmptyReason() { separatePmeRanksPermitted_.disablePmeRanks(""); }
+
+protected:
+ SeparatePmeRanksPermitted separatePmeRanksPermitted_;
+};
+
+TEST_F(SeparatePmeRanksPermittedTest, ZeroPmeDisableReasons)
+{
+ // Expect that SeparatePmeRanksPermitted is enabled by default
+ EXPECT_TRUE(separatePmeRanksPermitted_.permitSeparatePmeRanks());
+}
+
+TEST_F(SeparatePmeRanksPermittedTest, CanBeDisabled)
+{
+ // Test if disablePmeRanks works
+ EXPECT_NO_THROW(disableFirstReason(););
+}
+
+TEST_F(SeparatePmeRanksPermittedTest, OneDisableReasonFlag)
+{
+ disableFirstReason();
+
+ // Expect that SeparatePmeRanksPermitted is disabled now
+ EXPECT_FALSE(separatePmeRanksPermitted_.permitSeparatePmeRanks());
+}
+
+TEST_F(SeparatePmeRanksPermittedTest, OneDisableReasonText)
+{
+ disableFirstReason();
+
+ // Expect that reasonsWhyDisabled works with one reason
+ EXPECT_TRUE(separatePmeRanksPermitted_.reasonsWhyDisabled() == "First reason");
+}
+
+TEST_F(SeparatePmeRanksPermittedTest, TwoDisableReasonText)
+{
+ disableFirstReason();
+ disableSecondReason();
+
+ // Expect that reasonsWhyDisabled works with two reasons
+ EXPECT_TRUE(separatePmeRanksPermitted_.reasonsWhyDisabled() == "First reason; Second reason");
+}
+
+TEST_F(SeparatePmeRanksPermittedTest, EmptyDisableReasonText)
+{
+ disableEmptyReason();
+
+ // Expect that reasonsWhyDisabled works with empty reason
+ EXPECT_TRUE(separatePmeRanksPermitted_.reasonsWhyDisabled().empty());
+}
+
+} // namespace test
+
+} // namespace gmx
/* Describing the test in case it fails */
SCOPED_TRACE(formatString(
"Testing B-spline moduli creation (%s) for PME order %d, grid size %d %d %d",
- (moduliType == ModuliType::P3M) ? "P3M" : "plain", pmeOrder, gridSize[XX],
- gridSize[YY], gridSize[ZZ]));
+ (moduliType == ModuliType::P3M) ? "P3M" : "plain",
+ pmeOrder,
+ gridSize[XX],
+ gridSize[YY],
+ gridSize[ZZ]));
/* Storing the input where it's needed */
t_inputrec inputRec;
BSplineModuliInputParameters{ IVec{ 64, 2, 64 }, sanePmeOrder, ModuliType::PME },
/* Invalid interpolation orders */
BSplineModuliInputParameters{
- saneGridSize, 8 + 1, ModuliType::P3M // P3M only supports orders up to 8
+ saneGridSize,
+ 8 + 1,
+ ModuliType::P3M // P3M only supports orders up to 8
},
BSplineModuliInputParameters{ saneGridSize, PME_ORDER_MAX + 1, ModuliType::PME },
};
SCOPED_TRACE(
formatString("Testing force gathering on %s for PME grid size %d %d %d"
", order %d, %zu atoms",
- pmeTestHardwareContext->description().c_str(), gridSize[XX],
- gridSize[YY], gridSize[ZZ], pmeOrder, atomCount));
-
- PmeSafePointer pmeSafe =
- pmeInitWrapper(&inputRec, codePath, pmeTestHardwareContext->deviceContext(),
- pmeTestHardwareContext->deviceStream(),
- pmeTestHardwareContext->pmeGpuProgram(), box);
+ pmeTestHardwareContext->description().c_str(),
+ gridSize[XX],
+ gridSize[YY],
+ gridSize[ZZ],
+ pmeOrder,
+ atomCount));
+
+ PmeSafePointer pmeSafe = pmeInitWrapper(&inputRec,
+ codePath,
+ pmeTestHardwareContext->deviceContext(),
+ pmeTestHardwareContext->deviceStream(),
+ pmeTestHardwareContext->pmeGpuProgram(),
+ box);
std::unique_ptr<StatePropagatorDataGpu> stateGpu =
(codePath == CodePath::GPU)
? makeStatePropagatorDataGpu(*pmeSafe.get(),
pmeTestHardwareContext->deviceStream())
: nullptr;
- pmeInitAtoms(pmeSafe.get(), stateGpu.get(), codePath, inputAtomData.coordinates,
+ pmeInitAtoms(pmeSafe.get(),
+ stateGpu.get(),
+ codePath,
+ inputAtomData.coordinates,
inputAtomData.charges);
/* Setting some more inputs */
pmeSetGridLineIndices(pmeSafe.get(), codePath, inputAtomData.gridLineIndices);
for (int dimIndex = 0; dimIndex < DIM; dimIndex++)
{
- pmeSetSplineData(pmeSafe.get(), codePath, inputAtomSplineData.splineValues[dimIndex],
- PmeSplineDataType::Values, dimIndex);
- pmeSetSplineData(pmeSafe.get(), codePath, inputAtomSplineData.splineDerivatives[dimIndex],
- PmeSplineDataType::Derivatives, dimIndex);
+ pmeSetSplineData(pmeSafe.get(),
+ codePath,
+ inputAtomSplineData.splineValues[dimIndex],
+ PmeSplineDataType::Values,
+ dimIndex);
+ pmeSetSplineData(pmeSafe.get(),
+ codePath,
+ inputAtomSplineData.splineDerivatives[dimIndex],
+ PmeSplineDataType::Derivatives,
+ dimIndex);
}
/* Explicitly copying the sample forces to be able to modify them */
if (!supportedInput)
{
/* Testing the failure for the unsupported input */
- EXPECT_THROW_GMX(pmeInitWrapper(&inputRec, codePath, nullptr, nullptr, nullptr, box,
- ewaldCoeff_q, ewaldCoeff_lj),
- NotImplementedError);
+ EXPECT_THROW_GMX(
+ pmeInitWrapper(&inputRec, codePath, nullptr, nullptr, nullptr, box, ewaldCoeff_q, ewaldCoeff_lj),
+ NotImplementedError);
continue;
}
"Testing solving (%s, %s, %s energy/virial) on %s for PME grid "
"size %d %d %d, Ewald coefficients %g %g",
(method == PmeSolveAlgorithm::LennardJones) ? "Lennard-Jones" : "Coulomb",
- gridOrdering.second.c_str(), computeEnergyAndVirial ? "with" : "without",
- pmeTestHardwareContext->description().c_str(), gridSize[XX],
- gridSize[YY], gridSize[ZZ], ewaldCoeff_q, ewaldCoeff_lj));
+ gridOrdering.second.c_str(),
+ computeEnergyAndVirial ? "with" : "without",
+ pmeTestHardwareContext->description().c_str(),
+ gridSize[XX],
+ gridSize[YY],
+ gridSize[ZZ],
+ ewaldCoeff_q,
+ ewaldCoeff_lj));
/* Running the test */
- PmeSafePointer pmeSafe = pmeInitWrapper(
- &inputRec, codePath, pmeTestHardwareContext->deviceContext(),
- pmeTestHardwareContext->deviceStream(),
- pmeTestHardwareContext->pmeGpuProgram(), box, ewaldCoeff_q, ewaldCoeff_lj);
+ PmeSafePointer pmeSafe = pmeInitWrapper(&inputRec,
+ codePath,
+ pmeTestHardwareContext->deviceContext(),
+ pmeTestHardwareContext->deviceStream(),
+ pmeTestHardwareContext->pmeGpuProgram(),
+ box,
+ ewaldCoeff_q,
+ ewaldCoeff_lj);
pmeSetComplexGrid(pmeSafe.get(), codePath, gridOrdering.first, nonZeroGridValues);
const real cellVolume = box[0] * box[4] * box[8];
// FIXME - this is box[XX][XX] * box[YY][YY] * box[ZZ][ZZ], should be stored in the PME structure
- pmePerformSolve(pmeSafe.get(), codePath, method, cellVolume, gridOrdering.first,
- computeEnergyAndVirial);
+ pmePerformSolve(pmeSafe.get(), codePath, method, cellVolume, gridOrdering.first, computeEnergyAndVirial);
pmeFinalizeTest(pmeSafe.get(), codePath);
/* Check the outputs */
const uint64_t splineModuliDoublePrecisionUlps =
getSplineModuliDoublePrecisionUlps(inputRec.pme_order + 1);
auto gridTolerance = relativeToleranceAsPrecisionDependentUlp(
- gridValuesMagnitude, gridUlpToleranceFactor * c_splineModuliSinglePrecisionUlps,
+ gridValuesMagnitude,
+ gridUlpToleranceFactor * c_splineModuliSinglePrecisionUlps,
gridUlpToleranceFactor * splineModuliDoublePrecisionUlps);
gridValuesChecker.setDefaultTolerance(gridTolerance);
// TODO This factor is arbitrary, do a proper error-propagation analysis
uint64_t energyUlpToleranceFactor = gridUlpToleranceFactor * 2;
auto energyTolerance = relativeToleranceAsPrecisionDependentUlp(
- energyMagnitude, energyUlpToleranceFactor * c_splineModuliSinglePrecisionUlps,
+ energyMagnitude,
+ energyUlpToleranceFactor * c_splineModuliSinglePrecisionUlps,
energyUlpToleranceFactor * splineModuliDoublePrecisionUlps);
TestReferenceChecker energyChecker(checker);
energyChecker.setDefaultTolerance(energyTolerance);
// TODO This factor is arbitrary, do a proper error-propagation analysis
uint64_t virialUlpToleranceFactor = energyUlpToleranceFactor * 2;
auto virialTolerance = relativeToleranceAsPrecisionDependentUlp(
- virialMagnitude, virialUlpToleranceFactor * c_splineModuliSinglePrecisionUlps,
+ virialMagnitude,
+ virialUlpToleranceFactor * c_splineModuliSinglePrecisionUlps,
virialUlpToleranceFactor * splineModuliDoublePrecisionUlps);
TestReferenceChecker virialChecker(
checker.checkCompound("Matrix", "Virial"));
{
/* Describing the test uniquely in case it fails */
- SCOPED_TRACE(formatString(
- "Testing %s on %s for PME grid size %d %d %d"
- ", order %d, %zu atoms",
- option.second.c_str(), pmeTestHardwareContext->description().c_str(),
- gridSize[XX], gridSize[YY], gridSize[ZZ], pmeOrder, atomCount));
+ SCOPED_TRACE(
+ formatString("Testing %s on %s for PME grid size %d %d %d"
+ ", order %d, %zu atoms",
+ option.second.c_str(),
+ pmeTestHardwareContext->description().c_str(),
+ gridSize[XX],
+ gridSize[YY],
+ gridSize[ZZ],
+ pmeOrder,
+ atomCount));
/* Running the test */
- PmeSafePointer pmeSafe =
- pmeInitWrapper(&inputRec, codePath, pmeTestHardwareContext->deviceContext(),
- pmeTestHardwareContext->deviceStream(),
- pmeTestHardwareContext->pmeGpuProgram(), box);
+ PmeSafePointer pmeSafe = pmeInitWrapper(&inputRec,
+ codePath,
+ pmeTestHardwareContext->deviceContext(),
+ pmeTestHardwareContext->deviceStream(),
+ pmeTestHardwareContext->pmeGpuProgram(),
+ box);
std::unique_ptr<StatePropagatorDataGpu> stateGpu =
(codePath == CodePath::GPU)
? makeStatePropagatorDataGpu(*pmeSafe.get(),
{
auto splineValuesDim =
pmeGetSplineData(pmeSafe.get(), codePath, PmeSplineDataType::Values, i);
- splineValuesChecker.checkSequence(splineValuesDim.begin(),
- splineValuesDim.end(), dimString[i]);
+ splineValuesChecker.checkSequence(
+ splineValuesDim.begin(), splineValuesDim.end(), dimString[i]);
}
/* Spline derivatives */
/* Particle gridline indices */
auto gridLineIndices = pmeGetGridlineIndices(pmeSafe.get(), codePath);
- rootChecker.checkSequence(gridLineIndices.begin(), gridLineIndices.end(),
- "Gridline indices");
+ rootChecker.checkSequence(
+ gridLineIndices.begin(), gridLineIndices.end(), "Gridline indices");
}
if (spreadCharges)
//! Random coordinate vectors
CoordinatesVector const c_sampleCoordinatesFull{ { 5.59F, 1.37F, 0.95F },
{
- 16.0F, 1.02F, 0.22F // 2 box lengths in x
+ 16.0F,
+ 1.02F,
+ 0.22F // 2 box lengths in x
},
{ 0.034F, 1.65F, 0.22F },
{ 0.33F, 0.92F, 1.56F },
{ 1.16F, 0.75F, 0.39F },
{ 0.5F, 1.63F, 1.14F },
{
- 16.0001F, 1.52F, 1.19F // > 2 box lengths in x
+ 16.0001F,
+ 1.52F,
+ 1.19F // > 2 box lengths in x
},
{
- 1.43F, 1.1F, 4.1F // > 2 box lengths in z
+ 1.43F,
+ 1.1F,
+ 4.1F // > 2 box lengths in z
},
{
- -1.08F, 1.19F, 0.08F // negative x
+ -1.08F,
+ 1.19F,
+ 0.08F // negative x
},
{ 1.6F, 0.93F, 0.53F },
{
- 1.32F, -1.48F, 0.16F // negative y
+ 1.32F,
+ -1.48F,
+ 0.16F // negative y
},
{ 0.87F, 0.0F, 0.33F },
{
- 0.95F, 7.7F, -0.48F // > 2 box lengths in y, negative z
+ 0.95F,
+ 7.7F,
+ -0.48F // > 2 box lengths in y, negative z
},
{ 1.23F, 0.91F, 0.68F },
{ 0.19F, 1.45F, 0.94F },
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2016,2017,2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
const auto runMode = (mode == CodePath::CPU) ? PmeRunMode::CPU : PmeRunMode::Mixed;
t_commrec dummyCommrec = { 0 };
NumPmeDomains numPmeDomains = { 1, 1 };
- gmx_pme_t* pmeDataRaw = gmx_pme_init(&dummyCommrec, numPmeDomains, inputRec, false, false, true,
- ewaldCoeff_q, ewaldCoeff_lj, 1, runMode, nullptr,
- deviceContext, deviceStream, pmeGpuProgram, dummyLogger);
+ gmx_pme_t* pmeDataRaw = gmx_pme_init(&dummyCommrec,
+ numPmeDomains,
+ inputRec,
+ false,
+ false,
+ true,
+ ewaldCoeff_q,
+ ewaldCoeff_lj,
+ 1,
+ runMode,
+ nullptr,
+ deviceContext,
+ deviceStream,
+ pmeGpuProgram,
+ dummyLogger);
PmeSafePointer pme(pmeDataRaw); // taking ownership
// TODO get rid of this with proper matrix type
// TODO: Pin the host buffer and use async memory copies
// TODO: Special constructor for PME-only rank / PME-tests is used here. There should be a mechanism to
// restrict one from using other constructor here.
- return std::make_unique<StatePropagatorDataGpu>(deviceStream, *deviceContext, GpuApiCallBehavior::Sync,
- pme_gpu_get_block_size(&pme), nullptr);
+ return std::make_unique<StatePropagatorDataGpu>(
+ deviceStream, *deviceContext, GpuApiCallBehavior::Sync, pme_gpu_get_block_size(&pme), nullptr);
}
//! PME initialization with atom data
switch (mode)
{
case CodePath::CPU:
- gmx_parallel_3dfft_real_limits(pme->pfft_setup[gridIndex], gridSize, gridOffsetUnused,
- paddedGridSize);
+ gmx_parallel_3dfft_real_limits(
+ pme->pfft_setup[gridIndex], gridSize, gridOffsetUnused, paddedGridSize);
break;
case CodePath::GPU:
{
const size_t gridIndex = 0;
IVec gridOffsetUnused, complexOrderUnused;
- gmx_parallel_3dfft_complex_limits(pme->pfft_setup[gridIndex], complexOrderUnused, gridSize,
- gridOffsetUnused, paddedGridSize); // TODO: what about YZX ordering?
+ gmx_parallel_3dfft_complex_limits(
+ pme->pfft_setup[gridIndex], complexOrderUnused, gridSize, gridOffsetUnused, paddedGridSize); // TODO: what about YZX ordering?
}
//! Getting the PME grid memory buffer and its sizes - template definition
IVec& /*unused*/) //NOLINT(google-runtime-references)
{
GMX_THROW(InternalError("Deleted function call"));
- // explicitly deleting general template does not compile in clang/icc, see https://llvm.org/bugs/show_bug.cgi?id=17537
+ // explicitly deleting general template does not compile in clang, see https://llvm.org/bugs/show_bug.cgi?id=17537
}
//! Getting the PME real grid memory buffer and its sizes
switch (mode)
{
case CodePath::CPU:
- spread_on_grid(pme, atc, &pme->pmegrid[gridIndex], computeSplines, spreadCharges,
+ spread_on_grid(pme,
+ atc,
+ &pme->pmegrid[gridIndex],
+ computeSplines,
+ spreadCharges,
fftgrid != nullptr ? fftgrid[gridIndex] : nullptr,
- computeSplinesForZeroCharges, gridIndex);
+ computeSplinesForZeroCharges,
+ gridIndex);
if (spreadCharges && !pme->bUseThreads)
{
wrap_periodic_pmegrid(pme, pmegrid);
break;
case PmeSolveAlgorithm::LennardJones:
- solve_pme_lj_yzx(pme, &h_grid, useLorentzBerthelot, cellVolume,
- computeEnergyAndVirial, pme->nthread, threadIndex);
+ solve_pme_lj_yzx(pme,
+ &h_grid,
+ useLorentzBerthelot,
+ cellVolume,
+ computeEnergyAndVirial,
+ pme->nthread,
+ threadIndex);
break;
default: GMX_THROW(InternalError("Test not implemented for this mode"));
switch (mode)
{
case CodePath::GPU:
- memcpy(pme_gpu_staging(pme->gpu).h_gridlineIndices, gridLineIndices.data(),
+ memcpy(pme_gpu_staging(pme->gpu).h_gridlineIndices,
+ gridLineIndices.data(),
atomCount * sizeof(gridLineIndices[0]));
break;
{
case CodePath::GPU: // intentional absence of break, the grid will be copied from the host buffer in testing mode
case CodePath::CPU:
- std::memset(grid, 0,
- paddedGridSize[XX] * paddedGridSize[YY] * paddedGridSize[ZZ] * sizeof(ValueType));
+ std::memset(grid, 0, paddedGridSize[XX] * paddedGridSize[YY] * paddedGridSize[ZZ] * sizeof(ValueType));
for (const auto& gridValue : gridValues)
{
for (int i = 0; i < DIM; i++)
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2013,2014,2015,2018,2019, by the GROMACS development team, led by
+# Copyright (c) 2013,2014,2015,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.
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+# Set up the module library
+add_library(fft INTERFACE)
+
gmx_add_libgromacs_sources(
calcgrid.cpp
fft.cpp
gmx_add_libgromacs_sources(fft_mkl.cpp)
endif()
+# Source files have the following private module dependencies.
+target_link_libraries(fft PRIVATE
+ # gmxlib
+ # math
+ # mdtypes
+ # tng_io
+ )
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(fft PUBLIC
+target_include_directories(fft INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(fft PUBLIC
+target_link_libraries(fft INTERFACE
+ legacy_api
+ )
+
+# TODO: when fft is an OBJECT target
+#target_link_libraries(fft PUBLIC legacy_api)
+#target_link_libraries(fft PRIVATE common)
+
+# Module dependencies
+# This module convey transitive dependence on these modules.
+#target_link_libraries(fft PUBLIC
+target_link_libraries(fft INTERFACE
+ # utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(fft PRIVATE tng_io)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(fft PRIVATE legacy_modules)
+
if (BUILD_TESTING)
add_subdirectory(tests)
endif()
{
if (nullptr != fp)
{
- fprintf(fp, "Calculating fourier grid dimensions for%s%s%s\n", *nx > 0 ? "" : " X",
- *ny > 0 ? "" : " Y", *nz > 0 ? "" : " Z");
+ fprintf(fp,
+ "Calculating fourier grid dimensions for%s%s%s\n",
+ *nx > 0 ? "" : " X",
+ *ny > 0 ? "" : " Y",
+ *nz > 0 ? "" : " Z");
}
}
*nz = n[ZZ];
if (nullptr != fp)
{
- fprintf(fp, "Using a fourier grid of %dx%dx%d, spacing %.3f %.3f %.3f\n", *nx, *ny, *nz,
- spacing[XX], spacing[YY], spacing[ZZ]);
+ fprintf(fp,
+ "Using a fourier grid of %dx%dx%d, spacing %.3f %.3f %.3f\n",
+ *nx,
+ *ny,
+ *nz,
+ spacing[XX],
+ spacing[YY],
+ spacing[ZZ]);
}
return max_spacing;
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2009-2018, The GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#if GMX_FFT_FFTW3
+# include <mutex>
+
# include "gromacs/utility/exceptions.h"
-# include "gromacs/utility/mutex.h"
+
/* none of the fftw3 calls, except execute(), are thread-safe, so
we need to serialize them with this mutex. */
-static gmx::Mutex big_fftw_mutex;
+static std::mutex big_fftw_mutex;
# define FFTW_LOCK \
try \
{ \
fprintf(debug,
"FFT5D: N: %d, M: %d, K: %d, P: %dx%d, real2complex: %d, backward: %d, order "
"yz: %d, debug %d\n",
- NG, MG, KG, P[0], P[1], int((flags & FFT5D_REALCOMPLEX) > 0),
- int((flags & FFT5D_BACKWARD) > 0), int((flags & FFT5D_ORDER_YZ) > 0),
+ NG,
+ MG,
+ KG,
+ P[0],
+ P[1],
+ int((flags & FFT5D_REALCOMPLEX) > 0),
+ int((flags & FFT5D_BACKWARD) > 0),
+ int((flags & FFT5D_ORDER_YZ) > 0),
int((flags & FFT5D_DEBUG) > 0));
}
/* The check below is not correct, one prime factor 11 or 13 is ok.
# endif
if ((flags & FFT5D_REALCOMPLEX) && !(flags & FFT5D_BACKWARD))
{
- plan->p3d = FFTW(plan_guru_dft_r2c)(/*rank*/ 3, dims,
- /*howmany*/ 0, /*howmany_dims*/ nullptr,
+ plan->p3d = FFTW(plan_guru_dft_r2c)(/*rank*/ 3,
+ dims,
+ /*howmany*/ 0,
+ /*howmany_dims*/ nullptr,
reinterpret_cast<real*>(lin),
reinterpret_cast<FFTW(complex)*>(lout),
/*flags*/ fftwflags);
}
else if ((flags & FFT5D_REALCOMPLEX) && (flags & FFT5D_BACKWARD))
{
- plan->p3d = FFTW(plan_guru_dft_c2r)(/*rank*/ 3, dims,
- /*howmany*/ 0, /*howmany_dims*/ nullptr,
+ plan->p3d = FFTW(plan_guru_dft_c2r)(/*rank*/ 3,
+ dims,
+ /*howmany*/ 0,
+ /*howmany_dims*/ nullptr,
reinterpret_cast<FFTW(complex)*>(lin),
reinterpret_cast<real*>(lout),
/*flags*/ fftwflags);
else
{
plan->p3d = FFTW(plan_guru_dft)(
- /*rank*/ 3, dims,
- /*howmany*/ 0, /*howmany_dims*/ nullptr, reinterpret_cast<FFTW(complex)*>(lin),
+ /*rank*/ 3,
+ dims,
+ /*howmany*/ 0,
+ /*howmany_dims*/ nullptr,
+ reinterpret_cast<FFTW(complex)*>(lin),
reinterpret_cast<FFTW(complex)*>(lout),
- /*sign*/ (flags & FFT5D_BACKWARD) ? 1 : -1, /*flags*/ fftwflags);
+ /*sign*/ (flags & FFT5D_BACKWARD) ? 1 : -1,
+ /*flags*/ fftwflags);
}
# ifdef FFT5D_THREADS
# ifdef FFT5D_FFTW_THREADS
{
if (debug)
{
- fprintf(debug, "FFT5D: Plan s %d rC %d M %d pK %d C %d lsize %d\n", s, rC[s], M[s],
- pK[s], C[s], lsize);
+ fprintf(debug, "FFT5D: Plan s %d rC %d M %d pK %d C %d lsize %d\n", s, rC[s], M[s], pK[s], C[s], lsize);
}
plan->p1d[s] = static_cast<gmx_fft_t*>(malloc(sizeof(gmx_fft_t) * nthreads));
|| ((flags & FFT5D_BACKWARD) && s == 2)))
{
gmx_fft_init_many_1d_real(
- &plan->p1d[s][t], rC[s], tsize,
+ &plan->p1d[s][t],
+ rC[s],
+ tsize,
(flags & FFT5D_NOMEASURE) ? GMX_FFT_FLAG_CONSERVATIVE : 0);
}
else
{
- gmx_fft_init_many_1d(&plan->p1d[s][t], C[s], tsize,
+ gmx_fft_init_many_1d(&plan->p1d[s][t],
+ C[s],
+ tsize,
(flags & FFT5D_NOMEASURE) ? GMX_FFT_FLAG_CONSERVATIVE : 0);
}
}
{
if ((s == 0 && !(flags & FFT5D_ORDER_YZ)) || (s == 1 && (flags & FFT5D_ORDER_YZ)))
{
- plan->mpip[s] = FFTW(mpi_plan_many_transpose)(nP[s], nP[s], N[s] * K[s] * pM[s] * 2, 1,
- 1, (real*)lout2, (real*)lout3,
- plan->cart[s], FFTW_PATIENT);
+ plan->mpip[s] = FFTW(mpi_plan_many_transpose)(
+ nP[s], nP[s], N[s] * K[s] * pM[s] * 2, 1, 1, (real*)lout2, (real*)lout3, plan->cart[s], FFTW_PATIENT);
}
else
{
- plan->mpip[s] = FFTW(mpi_plan_many_transpose)(nP[s], nP[s], N[s] * pK[s] * M[s] * 2, 1,
- 1, (real*)lout2, (real*)lout3,
- plan->cart[s], FFTW_PATIENT);
+ plan->mpip[s] = FFTW(mpi_plan_many_transpose)(
+ nP[s], nP[s], N[s] * pK[s] * M[s] * 2, 1, 1, (real*)lout2, (real*)lout3, plan->cart[s], FFTW_PATIENT);
}
}
FFTW_UNLOCK;
{
for (l = 0; l < ll; l++)
{
- fprintf(debug, "%f ",
+ fprintf(debug,
+ "%f ",
reinterpret_cast<const real*>(
lin)[(z * xs[2] + y * xs[1]) * 2 + (x * xs[0]) * ll + l]);
}
gmx_fft_many_1d_real(p1d[s][thread],
(plan->flags & FFT5D_BACKWARD) ? GMX_FFT_COMPLEX_TO_REAL
: GMX_FFT_REAL_TO_COMPLEX,
- lin + tstart, fftout + tstart);
+ lin + tstart,
+ fftout + tstart);
}
else
{
gmx_fft_many_1d(p1d[s][thread],
(plan->flags & FFT5D_BACKWARD) ? GMX_FFT_BACKWARD : GMX_FFT_FORWARD,
- lin + tstart, fftout + tstart);
+ lin + tstart,
+ fftout + tstart);
}
#ifdef NOGMX
{
tend = ((thread + 1) * pM[s] * pK[s] / plan->nthreads);
tstart /= C[s];
- splitaxes(lout2, lout, N[s], M[s], K[s], pM[s], P[s], C[s], iNout[s], oNout[s],
- tstart % pM[s], tstart / pM[s], tend % pM[s], tend / pM[s]);
+ splitaxes(lout2,
+ lout,
+ N[s],
+ M[s],
+ K[s],
+ pM[s],
+ P[s],
+ C[s],
+ iNout[s],
+ oNout[s],
+ tstart % pM[s],
+ tstart / pM[s],
+ tend % pM[s],
+ tend / pM[s]);
}
#pragma omp barrier /*barrier required before AllToAll (all input has to be their) - before timing to make timing more acurate*/
#ifdef NOGMX
{
MPI_Alltoall(reinterpret_cast<real*>(lout2),
N[s] * pM[s] * K[s] * sizeof(t_complex) / sizeof(real),
- GMX_MPI_REAL, reinterpret_cast<real*>(lout3),
+ GMX_MPI_REAL,
+ reinterpret_cast<real*>(lout3),
N[s] * pM[s] * K[s] * sizeof(t_complex) / sizeof(real),
- GMX_MPI_REAL, cart[s]);
+ GMX_MPI_REAL,
+ cart[s]);
}
else
{
MPI_Alltoall(reinterpret_cast<real*>(lout2),
N[s] * M[s] * pK[s] * sizeof(t_complex) / sizeof(real),
- GMX_MPI_REAL, reinterpret_cast<real*>(lout3),
+ GMX_MPI_REAL,
+ reinterpret_cast<real*>(lout3),
N[s] * M[s] * pK[s] * sizeof(t_complex) / sizeof(real),
- GMX_MPI_REAL, cart[s]);
+ GMX_MPI_REAL,
+ cart[s]);
}
# else
GMX_RELEASE_ASSERT(false, "Invalid call to fft5d_execute");
{
tstart = (thread * pM[s] * pN[s] / plan->nthreads);
tend = ((thread + 1) * pM[s] * pN[s] / plan->nthreads);
- joinAxesTrans13(lin, joinin, N[s], pM[s], K[s], pM[s], P[s], C[s + 1], iNin[s + 1],
- oNin[s + 1], tstart % pM[s], tstart / pM[s], tend % pM[s], tend / pM[s]);
+ joinAxesTrans13(lin,
+ joinin,
+ N[s],
+ pM[s],
+ K[s],
+ pM[s],
+ P[s],
+ C[s + 1],
+ iNin[s + 1],
+ oNin[s + 1],
+ tstart % pM[s],
+ tstart / pM[s],
+ tend % pM[s],
+ tend / pM[s]);
}
}
else
{
tstart = (thread * pK[s] * pN[s] / plan->nthreads);
tend = ((thread + 1) * pK[s] * pN[s] / plan->nthreads);
- joinAxesTrans12(lin, joinin, N[s], M[s], pK[s], pN[s], P[s], C[s + 1], iNin[s + 1],
- oNin[s + 1], tstart % pN[s], tstart / pN[s], tend % pN[s], tend / pN[s]);
+ joinAxesTrans12(lin,
+ joinin,
+ N[s],
+ M[s],
+ pK[s],
+ pN[s],
+ P[s],
+ C[s + 1],
+ iNin[s + 1],
+ oNin[s + 1],
+ tstart % pN[s],
+ tstart / pN[s],
+ tend % pN[s],
+ tend / pN[s]);
}
}
{
gmx_fft_many_1d_real(p1d[s][thread],
(plan->flags & FFT5D_BACKWARD) ? GMX_FFT_COMPLEX_TO_REAL : GMX_FFT_REAL_TO_COMPLEX,
- lin + tstart, lout + tstart);
+ lin + tstart,
+ lout + tstart);
}
else
{
- gmx_fft_many_1d(p1d[s][thread], (plan->flags & FFT5D_BACKWARD) ? GMX_FFT_BACKWARD : GMX_FFT_FORWARD,
- lin + tstart, lout + tstart);
+ gmx_fft_many_1d(p1d[s][thread],
+ (plan->flags & FFT5D_BACKWARD) ? GMX_FFT_BACKWARD : GMX_FFT_FORWARD,
+ lin + tstart,
+ lout + tstart);
}
/* ------------ END FFT ---------*/
if (std::fabs(a - b) > 2 * NG[0] * NG[1] * NG[2] * GMX_REAL_EPS)
{
printf("result incorrect on %d,%d at %d,%d,%d: FFT5D:%f reference:%f\n",
- coor[0], coor[1], x, y, z, a, b);
+ coor[0],
+ coor[1],
+ x,
+ y,
+ z,
+ a,
+ b);
}
/* assert(fabs(a-b)<2*NG[0]*NG[1]*NG[2]*GMX_REAL_EPS);*/
}
*
* Copyright (c) 1991-2003 David van der Spoel, Erik Lindahl, University of Groningen.
* Copyright (c) 2013,2014,2015,2017,2018 by the GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <cerrno>
#include <cstdlib>
+#include <mutex>
+
#include <fftw3.h>
#include "gromacs/fft/fft.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/fatalerror.h"
-#include "gromacs/utility/mutex.h"
#if GMX_DOUBLE
# define FFTWPREFIX(name) fftw_##name
/* none of the fftw3 calls, except execute(), are thread-safe, so
we need to serialize them with this mutex. */
-static gmx::Mutex big_fftw_mutex;
+static std::mutex big_fftw_mutex;
#define FFTW_LOCK \
try \
{ \
fftw_complex *out, const int *onembed,
int ostride, int odist,
int sign, unsigned flags */
- fft->plan[0][0][0] = FFTWPREFIX(plan_many_dft)(1, &nx, howmany, up1, &nx, 1, nx, up2, &nx, 1,
- nx, FFTW_BACKWARD, fftw_flags);
- fft->plan[0][0][1] = FFTWPREFIX(plan_many_dft)(1, &nx, howmany, up1, &nx, 1, nx, up2, &nx, 1,
- nx, FFTW_FORWARD, fftw_flags);
- fft->plan[0][1][0] = FFTWPREFIX(plan_many_dft)(1, &nx, howmany, up1, &nx, 1, nx, up1, &nx, 1,
- nx, FFTW_BACKWARD, fftw_flags);
- fft->plan[0][1][1] = FFTWPREFIX(plan_many_dft)(1, &nx, howmany, up1, &nx, 1, nx, up1, &nx, 1,
- nx, FFTW_FORWARD, fftw_flags);
- fft->plan[1][0][0] = FFTWPREFIX(plan_many_dft)(1, &nx, howmany, p1, &nx, 1, nx, p2, &nx, 1, nx,
- FFTW_BACKWARD, fftw_flags);
- fft->plan[1][0][1] = FFTWPREFIX(plan_many_dft)(1, &nx, howmany, p1, &nx, 1, nx, p2, &nx, 1, nx,
- FFTW_FORWARD, fftw_flags);
- fft->plan[1][1][0] = FFTWPREFIX(plan_many_dft)(1, &nx, howmany, p1, &nx, 1, nx, p1, &nx, 1, nx,
- FFTW_BACKWARD, fftw_flags);
- fft->plan[1][1][1] = FFTWPREFIX(plan_many_dft)(1, &nx, howmany, p1, &nx, 1, nx, p1, &nx, 1, nx,
- FFTW_FORWARD, fftw_flags);
+ fft->plan[0][0][0] = FFTWPREFIX(plan_many_dft)(
+ 1, &nx, howmany, up1, &nx, 1, nx, up2, &nx, 1, nx, FFTW_BACKWARD, fftw_flags);
+ fft->plan[0][0][1] = FFTWPREFIX(plan_many_dft)(
+ 1, &nx, howmany, up1, &nx, 1, nx, up2, &nx, 1, nx, FFTW_FORWARD, fftw_flags);
+ fft->plan[0][1][0] = FFTWPREFIX(plan_many_dft)(
+ 1, &nx, howmany, up1, &nx, 1, nx, up1, &nx, 1, nx, FFTW_BACKWARD, fftw_flags);
+ fft->plan[0][1][1] = FFTWPREFIX(plan_many_dft)(
+ 1, &nx, howmany, up1, &nx, 1, nx, up1, &nx, 1, nx, FFTW_FORWARD, fftw_flags);
+ fft->plan[1][0][0] = FFTWPREFIX(plan_many_dft)(
+ 1, &nx, howmany, p1, &nx, 1, nx, p2, &nx, 1, nx, FFTW_BACKWARD, fftw_flags);
+ fft->plan[1][0][1] = FFTWPREFIX(plan_many_dft)(
+ 1, &nx, howmany, p1, &nx, 1, nx, p2, &nx, 1, nx, FFTW_FORWARD, fftw_flags);
+ fft->plan[1][1][0] = FFTWPREFIX(plan_many_dft)(
+ 1, &nx, howmany, p1, &nx, 1, nx, p1, &nx, 1, nx, FFTW_BACKWARD, fftw_flags);
+ fft->plan[1][1][1] = FFTWPREFIX(plan_many_dft)(
+ 1, &nx, howmany, p1, &nx, 1, nx, p1, &nx, 1, nx, FFTW_FORWARD, fftw_flags);
for (i = 0; i < 2; i++)
{
fftw_complex *out, const int *onembed,
int ostride, int odist,
unsigned flag */
- fft->plan[0][0][1] = FFTWPREFIX(plan_many_dft_r2c)(
- 1, &nx, howmany, up1, nullptr, 1, (nx / 2 + 1) * 2,
- reinterpret_cast<FFTWPREFIX(complex)*>(up2), nullptr, 1, (nx / 2 + 1), fftw_flags);
- fft->plan[0][1][1] = FFTWPREFIX(plan_many_dft_r2c)(
- 1, &nx, howmany, up1, nullptr, 1, (nx / 2 + 1) * 2,
- reinterpret_cast<FFTWPREFIX(complex)*>(up1), nullptr, 1, (nx / 2 + 1), fftw_flags);
- fft->plan[1][0][1] = FFTWPREFIX(plan_many_dft_r2c)(
- 1, &nx, howmany, p1, nullptr, 1, (nx / 2 + 1) * 2,
- reinterpret_cast<FFTWPREFIX(complex)*>(p2), nullptr, 1, (nx / 2 + 1), fftw_flags);
- fft->plan[1][1][1] = FFTWPREFIX(plan_many_dft_r2c)(
- 1, &nx, howmany, p1, nullptr, 1, (nx / 2 + 1) * 2,
- reinterpret_cast<FFTWPREFIX(complex)*>(p1), nullptr, 1, (nx / 2 + 1), fftw_flags);
-
- fft->plan[0][0][0] = FFTWPREFIX(plan_many_dft_c2r)(
- 1, &nx, howmany, reinterpret_cast<FFTWPREFIX(complex)*>(up1), nullptr, 1, (nx / 2 + 1),
- up2, nullptr, 1, (nx / 2 + 1) * 2, fftw_flags);
- fft->plan[0][1][0] = FFTWPREFIX(plan_many_dft_c2r)(
- 1, &nx, howmany, reinterpret_cast<FFTWPREFIX(complex)*>(up1), nullptr, 1, (nx / 2 + 1),
- up1, nullptr, 1, (nx / 2 + 1) * 2, fftw_flags);
- fft->plan[1][0][0] = FFTWPREFIX(plan_many_dft_c2r)(
- 1, &nx, howmany, reinterpret_cast<FFTWPREFIX(complex)*>(p1), nullptr, 1, (nx / 2 + 1),
- p2, nullptr, 1, (nx / 2 + 1) * 2, fftw_flags);
- fft->plan[1][1][0] = FFTWPREFIX(plan_many_dft_c2r)(
- 1, &nx, howmany, reinterpret_cast<FFTWPREFIX(complex)*>(p1), nullptr, 1, (nx / 2 + 1),
- p1, nullptr, 1, (nx / 2 + 1) * 2, fftw_flags);
+ fft->plan[0][0][1] = FFTWPREFIX(plan_many_dft_r2c)(1,
+ &nx,
+ howmany,
+ up1,
+ nullptr,
+ 1,
+ (nx / 2 + 1) * 2,
+ reinterpret_cast<FFTWPREFIX(complex)*>(up2),
+ nullptr,
+ 1,
+ (nx / 2 + 1),
+ fftw_flags);
+ fft->plan[0][1][1] = FFTWPREFIX(plan_many_dft_r2c)(1,
+ &nx,
+ howmany,
+ up1,
+ nullptr,
+ 1,
+ (nx / 2 + 1) * 2,
+ reinterpret_cast<FFTWPREFIX(complex)*>(up1),
+ nullptr,
+ 1,
+ (nx / 2 + 1),
+ fftw_flags);
+ fft->plan[1][0][1] = FFTWPREFIX(plan_many_dft_r2c)(1,
+ &nx,
+ howmany,
+ p1,
+ nullptr,
+ 1,
+ (nx / 2 + 1) * 2,
+ reinterpret_cast<FFTWPREFIX(complex)*>(p2),
+ nullptr,
+ 1,
+ (nx / 2 + 1),
+ fftw_flags);
+ fft->plan[1][1][1] = FFTWPREFIX(plan_many_dft_r2c)(1,
+ &nx,
+ howmany,
+ p1,
+ nullptr,
+ 1,
+ (nx / 2 + 1) * 2,
+ reinterpret_cast<FFTWPREFIX(complex)*>(p1),
+ nullptr,
+ 1,
+ (nx / 2 + 1),
+ fftw_flags);
+
+ fft->plan[0][0][0] = FFTWPREFIX(plan_many_dft_c2r)(1,
+ &nx,
+ howmany,
+ reinterpret_cast<FFTWPREFIX(complex)*>(up1),
+ nullptr,
+ 1,
+ (nx / 2 + 1),
+ up2,
+ nullptr,
+ 1,
+ (nx / 2 + 1) * 2,
+ fftw_flags);
+ fft->plan[0][1][0] = FFTWPREFIX(plan_many_dft_c2r)(1,
+ &nx,
+ howmany,
+ reinterpret_cast<FFTWPREFIX(complex)*>(up1),
+ nullptr,
+ 1,
+ (nx / 2 + 1),
+ up1,
+ nullptr,
+ 1,
+ (nx / 2 + 1) * 2,
+ fftw_flags);
+ fft->plan[1][0][0] = FFTWPREFIX(plan_many_dft_c2r)(1,
+ &nx,
+ howmany,
+ reinterpret_cast<FFTWPREFIX(complex)*>(p1),
+ nullptr,
+ 1,
+ (nx / 2 + 1),
+ p2,
+ nullptr,
+ 1,
+ (nx / 2 + 1) * 2,
+ fftw_flags);
+ fft->plan[1][1][0] = FFTWPREFIX(plan_many_dft_c2r)(1,
+ &nx,
+ howmany,
+ reinterpret_cast<FFTWPREFIX(complex)*>(p1),
+ nullptr,
+ 1,
+ (nx / 2 + 1),
+ p1,
+ nullptr,
+ 1,
+ (nx / 2 + 1) * 2,
+ fftw_flags);
for (i = 0; i < 2; i++)
{
}
FFTWPREFIX(execute_dft)
- (fft->plan[aligned][inplace][isforward], static_cast<FFTWPREFIX(complex)*>(in_data),
+ (fft->plan[aligned][inplace][isforward],
+ static_cast<FFTWPREFIX(complex)*>(in_data),
static_cast<FFTWPREFIX(complex)*>(out_data));
return 0;
if (isforward)
{
FFTWPREFIX(execute_dft_r2c)
- (fft->plan[aligned][inplace][isforward], static_cast<real*>(in_data),
+ (fft->plan[aligned][inplace][isforward],
+ static_cast<real*>(in_data),
static_cast<FFTWPREFIX(complex)*>(out_data));
}
else
{
FFTWPREFIX(execute_dft_c2r)
- (fft->plan[aligned][inplace][isforward], static_cast<FFTWPREFIX(complex)*>(in_data),
+ (fft->plan[aligned][inplace][isforward],
+ static_cast<FFTWPREFIX(complex)*>(in_data),
static_cast<real*>(out_data));
}
if (isforward)
{
FFTWPREFIX(execute_dft_r2c)
- (fft->plan[aligned][inplace][isforward], static_cast<real*>(in_data),
+ (fft->plan[aligned][inplace][isforward],
+ static_cast<real*>(in_data),
static_cast<FFTWPREFIX(complex)*>(out_data));
}
else
{
FFTWPREFIX(execute_dft_c2r)
- (fft->plan[aligned][inplace][isforward], static_cast<FFTWPREFIX(complex)*>(in_data),
+ (fft->plan[aligned][inplace][isforward],
+ static_cast<FFTWPREFIX(complex)*>(in_data),
static_cast<real*>(out_data));
}
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 1991-2005 David van der Spoel, Erik Lindahl, University of Groningen.
- * Copyright (c) 2013,2014,2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2017,2018,2019,2020, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
Kb = M; /* currently always true because ORDER_YZ always set */
}
- (*pfft_setup)->p1 = fft5d_plan_3d(rN, M, K, rcomm, flags, reinterpret_cast<t_complex**>(real_data),
- complex_data, &buf1, &buf2, nthreads, realGridAllocation);
+ (*pfft_setup)->p1 = fft5d_plan_3d(
+ rN, M, K, rcomm, flags, reinterpret_cast<t_complex**>(real_data), complex_data, &buf1, &buf2, nthreads, realGridAllocation);
- (*pfft_setup)->p2 = fft5d_plan_3d(
- Nb, Mb, Kb, rcomm, (flags | FFT5D_BACKWARD | FFT5D_NOMALLOC) ^ FFT5D_ORDER_YZ,
- complex_data, reinterpret_cast<t_complex**>(real_data), &buf1, &buf2, nthreads);
+ (*pfft_setup)->p2 = fft5d_plan_3d(Nb,
+ Mb,
+ Kb,
+ rcomm,
+ (flags | FFT5D_BACKWARD | FFT5D_NOMALLOC) ^ FFT5D_ORDER_YZ,
+ complex_data,
+ reinterpret_cast<t_complex**>(real_data),
+ &buf1,
+ &buf2,
+ nthreads);
return static_cast<int>((*pfft_setup)->p1 != nullptr && (*pfft_setup)->p2 != nullptr);
}
if (((pfft_setup->p1->flags & FFT5D_REALCOMPLEX) == 0)
^ (dir == GMX_FFT_FORWARD || dir == GMX_FFT_BACKWARD))
{
- gmx_fatal(FARGS,
- "Invalid transform. Plan and execution don't match regarding reel/complex");
+ gmx_fatal(FARGS, "Invalid transform. Plan and execution don't match regarding reel/complex");
}
if (dir == GMX_FFT_FORWARD || dir == GMX_FFT_REAL_TO_COMPLEX)
{
gmx_parallel_3dfft_execute(fft_, GMX_FFT_COMPLEX_TO_REAL, 0, nullptr);
for (int i = 0; i < ndata[0] * ndata[1]; i++) // check sequence but skip unused data
{
- checker_.checkSequenceArray(ndata[2], rdata + i * rsize[2],
- gmx::formatString("backward %d", i).c_str());
+ checker_.checkSequenceArray(
+ ndata[2], rdata + i * rsize[2], gmx::formatString("backward %d", i).c_str());
}
}
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+# Set up the module library
+add_library(fileio INTERFACE)
file(GLOB FILEIO_SOURCES *.cpp)
if(GMX_USE_PLUGINS)
list(FILTER FILEIO_SOURCES EXCLUDE REGEX ".*vmdio.cpp$")
endif()
-target_sources(libgromacs PRIVATE ${FILEIO_SOURCES})
+# Source files have the following private module dependencies.
+target_link_libraries(fileio PRIVATE
+# gmxlib
+# math
+# mdtypes
+# tng_io
+ )
-if(GMX_INSTALL_LEGACY_API)
- install(FILES
- oenv.h
- confio.h
- pdbio.h
- tpxio.h
- trxio.h
- filetypes.h
- DESTINATION include/gromacs/fileio)
-endif()
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(fileio PUBLIC
+target_include_directories(fileio INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(fileio PUBLIC
+target_link_libraries(fileio INTERFACE
+ legacy_api
+ )
+
+# TODO: when fileio is an OBJECT target
+#target_link_libraries(fileio PUBLIC legacy_api)
+#target_link_libraries(fileio PRIVATE common)
+
+# Module dependencies
+# fileio interfaces convey transitive dependence on these modules.
+#target_link_libraries(fileio PUBLIC
+target_link_libraries(fileio INTERFACE
+ utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(fileio PRIVATE tng_io)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(fileio PRIVATE legacy_modules)
+
+target_sources(libgromacs PRIVATE ${FILEIO_SOURCES})
if (BUILD_TESTING)
add_subdirectory(tests)
"energy_delta_h_start_time",
"energy_delta_h_start_lambda" };
-static const char* ePullhNames[epullhNR] = { "pullhistory_numcoordinates", "pullhistory_numgroups",
+static const char* ePullhNames[epullhNR] = { "pullhistory_numcoordinates",
+ "pullhistory_numgroups",
"pullhistory_numvaluesinxsum",
"pullhistory_numvaluesinfsum" };
#if !GMX_DOUBLE
if (cptElementType == CptElementType::real3)
{
- pr_rvecs(list, 0, entryName(part, ecpt),
- reinterpret_cast<const rvec*>(data.data()), nf / 3);
+ pr_rvecs(list, 0, entryName(part, ecpt), reinterpret_cast<const rvec*>(data.data()), nf / 3);
}
else
#endif
{
/* Note: With double precision code dumping a single precision rvec will produce float iso rvec print, but that's a minor annoyance */
- pr_fvec(list, 0, entryName(part, ecpt),
- reinterpret_cast<const float*>(data.data()), nf, TRUE);
+ pr_fvec(list, 0, entryName(part, ecpt), reinterpret_cast<const float*>(data.data()), nf, TRUE);
}
break;
case xdr_datatype_double:
#if GMX_DOUBLE
if (cptElementType == CptElementType::real3)
{
- pr_rvecs(list, 0, entryName(part, ecpt),
- reinterpret_cast<const rvec*>(data.data()), nf / 3);
+ pr_rvecs(list, 0, entryName(part, ecpt), reinterpret_cast<const rvec*>(data.data()), nf / 3);
}
else
#endif
{
/* Note: With single precision code dumping a double precision rvec will produce float iso rvec print, but that's a minor annoyance */
- pr_dvec(list, 0, entryName(part, ecpt),
- reinterpret_cast<const double*>(data.data()), nf, TRUE);
+ pr_dvec(list, 0, entryName(part, ecpt), reinterpret_cast<const double*>(data.data()), nf, TRUE);
}
break;
default: GMX_RELEASE_ASSERT(false, "Data type not implemented for listing");
{
gmx_fatal(FARGS,
"Count mismatch for state entry %s, code count is %d, file count is %d\n",
- entryName(part, ecpt), nval, numElemInTheFile);
+ entryName(part, ecpt),
+ nval,
+ numElemInTheFile);
}
}
else if (nptr != nullptr)
if (!typesMatch)
{
char buf[STRLEN];
- sprintf(buf, "mismatch for state entry %s, code precision is %s, file precision is %s",
- entryName(part, ecpt), xdr_datatype_names[xdrTypeInTheCode],
+ sprintf(buf,
+ "mismatch for state entry %s, code precision is %s, file precision is %s",
+ entryName(part, ecpt),
+ xdr_datatype_names[xdrTypeInTheCode],
xdr_datatype_names[xdrTypeInTheFile]);
/* Matching int and real should never occur, but check anyhow */
if (xdrTypeInTheFile == xdr_datatype_int || xdrTypeInTheCode == xdr_datatype_int)
{
gmx_fatal(FARGS,
- "Type %s: incompatible checkpoint formats or corrupted checkpoint file.", buf);
+ "Type %s: incompatible checkpoint formats or corrupted checkpoint file.",
+ buf);
}
}
{
snew(vChar, numElemInTheFile * sizeOfXdrType(xdrTypeInTheFile));
}
- res = xdr_vector(xd, vChar, numElemInTheFile, sizeOfXdrType(xdrTypeInTheFile),
- xdrProc(xdrTypeInTheFile));
+ res = xdr_vector(
+ xd, vChar, numElemInTheFile, sizeOfXdrType(xdrTypeInTheFile), xdrProc(xdrTypeInTheFile));
if (res == 0)
{
return -1;
static int
doVector(XDR* xd, StatePart part, int ecpt, int sflags, std::vector<T>* vector, FILE* list, int numElements = -1)
{
- return doVectorLow<T>(xd, part, ecpt, sflags, numElements, nullptr, nullptr, vector, list,
- CptElementType::real);
+ return doVectorLow<T>(
+ xd, part, ecpt, sflags, numElements, nullptr, nullptr, vector, list, CptElementType::real);
}
//! \brief Read/Write an ArrayRef<real>.
static int doRealArrayRef(XDR* xd, StatePart part, int ecpt, int sflags, gmx::ArrayRef<real> vector, FILE* list)
{
real* v_real = vector.data();
- return doVectorLow<real, std::allocator<real>>(xd, part, ecpt, sflags, vector.size(), nullptr,
- &v_real, nullptr, list, CptElementType::real);
+ return doVectorLow<real, std::allocator<real>>(
+ xd, part, ecpt, sflags, vector.size(), nullptr, &v_real, nullptr, list, CptElementType::real);
}
//! Convert from view of RVec to view of real.
// allocator from RVec to real.
using realAllocator =
typename std::allocator_traits<typename PaddedVectorOfRVecType::allocator_type>::template rebind_alloc<real>;
- return doVectorLow<real, realAllocator>(xd, part, ecpt, sflags, numReals, nullptr, nullptr,
- nullptr, list, CptElementType::real);
+ return doVectorLow<real, realAllocator>(
+ xd, part, ecpt, sflags, numReals, nullptr, nullptr, nullptr, list, CptElementType::real);
}
}
*/
static int do_cpte_reals(XDR* xd, StatePart part, int ecpt, int sflags, int n, real** v, FILE* list)
{
- return doVectorLow<real, std::allocator<real>>(xd, part, ecpt, sflags, n, nullptr, v, nullptr,
- list, CptElementType::real);
+ return doVectorLow<real, std::allocator<real>>(
+ xd, part, ecpt, sflags, n, nullptr, v, nullptr, list, CptElementType::real);
}
/* This function does the same as do_cpte_reals,
*/
static int do_cpte_n_reals(XDR* xd, StatePart part, int ecpt, int sflags, int* n, real** v, FILE* list)
{
- return doVectorLow<real, std::allocator<real>>(xd, part, ecpt, sflags, -1, n, v, nullptr, list,
- CptElementType::real);
+ return doVectorLow<real, std::allocator<real>>(
+ xd, part, ecpt, sflags, -1, n, v, nullptr, list, CptElementType::real);
}
static int do_cpte_real(XDR* xd, StatePart part, int ecpt, int sflags, real* r, FILE* list)
{
- return doVectorLow<real, std::allocator<real>>(xd, part, ecpt, sflags, 1, nullptr, &r, nullptr,
- list, CptElementType::real);
+ return doVectorLow<real, std::allocator<real>>(
+ xd, part, ecpt, sflags, 1, nullptr, &r, nullptr, list, CptElementType::real);
}
static int do_cpte_ints(XDR* xd, StatePart part, int ecpt, int sflags, int n, int** v, FILE* list)
{
- return doVectorLow<int, std::allocator<int>>(xd, part, ecpt, sflags, n, nullptr, v, nullptr,
- list, CptElementType::integer);
+ return doVectorLow<int, std::allocator<int>>(
+ xd, part, ecpt, sflags, n, nullptr, v, nullptr, list, CptElementType::integer);
}
static int do_cpte_int(XDR* xd, StatePart part, int ecpt, int sflags, int* i, FILE* list)
static int do_cpte_doubles(XDR* xd, StatePart part, int ecpt, int sflags, int n, double** v, FILE* list)
{
- return doVectorLow<double, std::allocator<double>>(xd, part, ecpt, sflags, n, nullptr, v,
- nullptr, list, CptElementType::real);
+ return doVectorLow<double, std::allocator<double>>(
+ xd, part, ecpt, sflags, n, nullptr, v, nullptr, list, CptElementType::real);
}
static int do_cpte_double(XDR* xd, StatePart part, int ecpt, int sflags, double* r, FILE* list)
int ret;
vr = &(v[0][0]);
- ret = doVectorLow<real, std::allocator<real>>(xd, part, ecpt, sflags, DIM * DIM, nullptr, &vr,
- nullptr, nullptr, CptElementType::matrix3x3);
+ ret = doVectorLow<real, std::allocator<real>>(
+ xd, part, ecpt, sflags, DIM * DIM, nullptr, &vr, nullptr, nullptr, CptElementType::matrix3x3);
if (list && ret == 0)
{
}
for (i = 0; i < n; i++)
{
- reti = doVectorLow<real, std::allocator<real>>(xd, part, ecpt, sflags, n, nullptr, &(v[i]),
- nullptr, nullptr, CptElementType::matrix3x3);
+ reti = doVectorLow<real, std::allocator<real>>(
+ xd, part, ecpt, sflags, n, nullptr, &(v[i]), nullptr, nullptr, CptElementType::matrix3x3);
if (list && reti == 0)
{
sprintf(name, "%s[%d]", entryName(part, ecpt), i);
}
if (list == nullptr && nf != n)
{
- gmx_fatal(FARGS, "Count mismatch for state entry %s, code count is %d, file count is %d\n",
- entryName(part, ecpt), n, nf);
+ gmx_fatal(FARGS,
+ "Count mismatch for state entry %s, code count is %d, file count is %d\n",
+ entryName(part, ecpt),
+ n,
+ nf);
}
if (list || !(sflags & (1 << ecpt)))
{
}
}
}
- ret = doVectorLow<real, std::allocator<real>>(xd, part, ecpt, sflags, nf * DIM * DIM, nullptr,
- &vr, nullptr, nullptr, CptElementType::matrix3x3);
+ ret = doVectorLow<real, std::allocator<real>>(
+ xd, part, ecpt, sflags, nf * DIM * DIM, nullptr, &vr, nullptr, nullptr, CptElementType::matrix3x3);
for (i = 0; i < nf; i++)
{
for (j = 0; j < DIM; j++)
gmx_fatal(FARGS,
"Start of file magic number mismatch, checkpoint file has %d, should be %d\n"
"The checkpoint file is corrupted or not a checkpoint file",
- magic, CPT_MAGIC1);
+ magic,
+ CPT_MAGIC1);
}
char fhost[255];
if (!bRead)
{
gmx_fatal(FARGS,
"Attempting to read a checkpoint file of version %d with code of version %d\n",
- contents->file_version, cpt_version);
+ contents->file_version,
+ cpt_version);
}
if (contents->file_version >= 13)
{
if (contents->file_version >= cptv_ModularSimulator)
{
- do_cpt_bool_err(xd, "Is modular simulator checkpoint",
- &contents->isModularSimulatorCheckpoint, list);
+ do_cpt_bool_err(
+ xd, "Is modular simulator checkpoint", &contents->isModularSimulatorCheckpoint, list);
}
else
{
{
case estLAMBDA:
ret = doRealArrayRef(
- xd, part, i, sflags,
+ xd,
+ part,
+ i,
+ sflags,
gmx::arrayRefFromArray<real>(state->lambda.data(), state->lambda.size()),
list);
break;
ret = do_cpte_real(xd, part, i, sflags, &state->hist.disre_initf, list);
break;
case estDISRE_RM3TAV:
- ret = do_cpte_n_reals(xd, part, i, sflags, &state->hist.ndisrepairs,
- &state->hist.disre_rm3tav, list);
+ ret = do_cpte_n_reals(
+ xd, part, i, sflags, &state->hist.ndisrepairs, &state->hist.disre_rm3tav, list);
break;
case estORIRE_INITF:
ret = do_cpte_real(xd, part, i, sflags, &state->hist.orire_initf, list);
break;
case estORIRE_DTAV:
- ret = do_cpte_n_reals(xd, part, i, sflags, &state->hist.norire_Dtav,
- &state->hist.orire_Dtav, list);
+ ret = do_cpte_n_reals(
+ xd, part, i, sflags, &state->hist.norire_Dtav, &state->hist.orire_Dtav, list);
break;
case estPULLCOMPREVSTEP:
ret = doVector<double>(xd, part, i, sflags, &state->pull_com_prev_step, list);
}
else
{
- do_cpt_n_rvecs_err(xd, "Ch0 whole x", swapstate->nat[eChan0],
- *swapstate->xc_old_whole_p[eChan0], list);
- do_cpt_n_rvecs_err(xd, "Ch1 whole x", swapstate->nat[eChan1],
- *swapstate->xc_old_whole_p[eChan1], list);
+ do_cpt_n_rvecs_err(
+ xd, "Ch0 whole x", swapstate->nat[eChan0], *swapstate->xc_old_whole_p[eChan0], list);
+ do_cpt_n_rvecs_err(
+ xd, "Ch1 whole x", swapstate->nat[eChan1], *swapstate->xc_old_whole_p[eChan1], list);
}
return 0;
return ret;
}
- GMX_RELEASE_ASSERT(enerhist != nullptr,
- "With energy history, we need a valid enerhist pointer");
+ GMX_RELEASE_ASSERT(enerhist != nullptr, "With energy history, we need a valid enerhist pointer");
/* This is stored/read for backward compatibility */
int energyHistoryNumEnergies = 0;
if (bRead)
{
- initCorrelationGridHistory(corrGrid, corrGrid->numCorrelationTensors, corrGrid->tensorSize,
- corrGrid->blockDataListSize);
+ initCorrelationGridHistory(
+ corrGrid, corrGrid->numCorrelationTensors, corrGrid->tensorSize, corrGrid->blockDataListSize);
}
for (gmx::CorrelationBlockDataHistory& blockData : corrGrid->blockDataBuffer)
do_cpt_step_err(xd, eawhh_names[i], &(state->numUpdates), list);
break;
case eawhhFORCECORRELATIONGRID:
- ret = do_cpt_correlation_grid(xd, bRead, fflags,
- &biasHistory->forceCorrelationGrid, list, i);
+ ret = do_cpt_correlation_grid(
+ xd, bRead, fflags, &biasHistory->forceCorrelationGrid, list, i);
break;
default: gmx_fatal(FARGS, "Unknown awh history entry %d\n", i);
}
{
return -1;
}
- if (do_cpt_u_chars(xd, "file_checksum", outputfile.checksum.size(),
- outputfile.checksum.data(), list)
+ if (do_cpt_u_chars(xd, "file_checksum", outputfile.checksum.size(), outputfile.checksum.data(), list)
!= 0)
{
return -1;
if ((do_cpt_state(gmx_fio_getxdr(fp), state->flags, state, nullptr) < 0)
|| (do_cpt_ekinstate(gmx_fio_getxdr(fp), headerContents.flags_eks, &state->ekinstate, nullptr) < 0)
|| (do_cpt_enerhist(gmx_fio_getxdr(fp), FALSE, headerContents.flags_enh, enerhist, nullptr) < 0)
- || (doCptPullHist(gmx_fio_getxdr(fp), FALSE, headerContents.flagsPullHistory, pullHist,
- StatePart::pullHistory, nullptr)
+ || (doCptPullHist(gmx_fio_getxdr(fp), FALSE, headerContents.flagsPullHistory, pullHist, StatePart::pullHistory, nullptr)
< 0)
- || (do_cpt_df_hist(gmx_fio_getxdr(fp), headerContents.flags_dfh, headerContents.nlambda,
- &state->dfhist, nullptr)
+ || (do_cpt_df_hist(gmx_fio_getxdr(fp), headerContents.flags_dfh, headerContents.nlambda, &state->dfhist, nullptr)
< 0)
- || (do_cpt_EDstate(gmx_fio_getxdr(fp), FALSE, headerContents.nED,
- observablesHistory->edsamHistory.get(), nullptr)
+ || (do_cpt_EDstate(
+ gmx_fio_getxdr(fp), FALSE, headerContents.nED, observablesHistory->edsamHistory.get(), nullptr)
< 0)
|| (do_cpt_awh(gmx_fio_getxdr(fp), FALSE, headerContents.flags_awhh, state->awhHistory.get(), nullptr) < 0)
- || (do_cpt_swapstate(gmx_fio_getxdr(fp), FALSE, headerContents.eSwapCoords,
- observablesHistory->swapHistory.get(), nullptr)
+ || (do_cpt_swapstate(gmx_fio_getxdr(fp),
+ FALSE,
+ headerContents.eSwapCoords,
+ observablesHistory->swapHistory.get(),
+ nullptr)
< 0)
|| (do_cpt_files(gmx_fio_getxdr(fp), FALSE, outputfiles, nullptr, headerContents.file_version) < 0))
{
if (reproducibilityRequested)
{
- check_string(fplog, "Program name", gmx::getProgramContext().fullBinaryPath(),
- headerContents.fprog, &mm);
+ check_string(
+ fplog, "Program name", gmx::getProgramContext().fullBinaryPath(), headerContents.fprog, &mm);
check_int(fplog, "#ranks", cr->nnodes, headerContents.nnodes, &mm);
}
gmx_fatal(FARGS,
"Checkpoint file is for a system of %d atoms, while the current system consists "
"of %d atoms",
- headerContents->natoms, state->natoms);
+ headerContents->natoms,
+ state->natoms);
}
if (headerContents->ngtc != state->ngtc)
{
gmx_fatal(FARGS,
"Checkpoint file is for a system of %d T-coupling groups, while the current "
"system consists of %d T-coupling groups",
- headerContents->ngtc, state->ngtc);
+ headerContents->ngtc,
+ state->ngtc);
}
if (headerContents->nnhpres != state->nnhpres)
{
gmx_fatal(FARGS,
"Checkpoint file is for a system of %d NH-pressure-coupling variables, while the "
"current system consists of %d NH-pressure-coupling variables",
- headerContents->nnhpres, state->nnhpres);
+ headerContents->nnhpres,
+ state->nnhpres);
}
int nlambdaHistory = (state->dfhist ? state->dfhist->nlambda : 0);
gmx_fatal(FARGS,
"Checkpoint file is for a system with %d lambda states, while the current system "
"consists of %d lambda states",
- headerContents->nlambda, nlambdaHistory);
+ headerContents->nlambda,
+ nlambdaHistory);
}
- init_gtc_state(state, state->ngtc, state->nnhpres,
+ init_gtc_state(state,
+ state->ngtc,
+ state->nnhpres,
headerContents->nhchainlength); /* need to keep this here to keep the tpr format working */
/* write over whatever was read; we use the number of Nose-Hoover chains from the checkpoint */
{
observablesHistory->energyHistory = std::make_unique<energyhistory_t>();
}
- ret = do_cpt_enerhist(gmx_fio_getxdr(fp), TRUE, headerContents->flags_enh,
- observablesHistory->energyHistory.get(), nullptr);
+ ret = do_cpt_enerhist(
+ gmx_fio_getxdr(fp), TRUE, headerContents->flags_enh, observablesHistory->energyHistory.get(), nullptr);
if (ret)
{
cp_error();
{
observablesHistory->pullHistory = std::make_unique<PullHistory>();
}
- ret = doCptPullHist(gmx_fio_getxdr(fp), TRUE, headerContents->flagsPullHistory,
- observablesHistory->pullHistory.get(), StatePart::pullHistory, nullptr);
+ ret = doCptPullHist(gmx_fio_getxdr(fp),
+ TRUE,
+ headerContents->flagsPullHistory,
+ observablesHistory->pullHistory.get(),
+ StatePart::pullHistory,
+ nullptr);
if (ret)
{
cp_error();
"Continuing from checkpoint files written before GROMACS 4.5 is not supported");
}
- ret = do_cpt_df_hist(gmx_fio_getxdr(fp), headerContents->flags_dfh, headerContents->nlambda,
- &state->dfhist, nullptr);
+ ret = do_cpt_df_hist(
+ gmx_fio_getxdr(fp), headerContents->flags_dfh, headerContents->nlambda, &state->dfhist, nullptr);
if (ret)
{
cp_error();
{
observablesHistory->edsamHistory = std::make_unique<edsamhistory_t>(edsamhistory_t{});
}
- ret = do_cpt_EDstate(gmx_fio_getxdr(fp), TRUE, headerContents->nED,
- observablesHistory->edsamHistory.get(), nullptr);
+ ret = do_cpt_EDstate(
+ gmx_fio_getxdr(fp), TRUE, headerContents->nED, observablesHistory->edsamHistory.get(), nullptr);
if (ret)
{
cp_error();
{
observablesHistory->swapHistory = std::make_unique<swaphistory_t>(swaphistory_t{});
}
- ret = do_cpt_swapstate(gmx_fio_getxdr(fp), TRUE, headerContents->eSwapCoords,
- observablesHistory->swapHistory.get(), nullptr);
+ ret = do_cpt_swapstate(
+ gmx_fio_getxdr(fp), TRUE, headerContents->eSwapCoords, observablesHistory->swapHistory.get(), nullptr);
if (ret)
{
cp_error();
if (SIMMASTER(cr))
{
/* Read the state from the checkpoint file */
- read_checkpoint(fn, logfio, cr, dd_nc, ir->eI, &(ir->fepvals->init_fep_state),
- &headerContents, state, observablesHistory, reproducibilityRequested,
- mdModulesNotifier, modularSimulatorCheckpointData, useModularSimulator);
+ read_checkpoint(fn,
+ logfio,
+ cr,
+ dd_nc,
+ ir->eI,
+ &(ir->fepvals->init_fep_state),
+ &headerContents,
+ state,
+ observablesHistory,
+ reproducibilityRequested,
+ mdModulesNotifier,
+ modularSimulatorCheckpointData,
+ useModularSimulator);
}
if (PAR(cr))
{
cp_error();
}
PullHistory pullHist = {};
- ret = doCptPullHist(gmx_fio_getxdr(fp), TRUE, headerContents.flagsPullHistory, &pullHist,
- StatePart::pullHistory, nullptr);
+ ret = doCptPullHist(
+ gmx_fio_getxdr(fp), TRUE, headerContents.flagsPullHistory, &pullHist, StatePart::pullHistory, nullptr);
if (ret)
{
cp_error();
}
- ret = do_cpt_df_hist(gmx_fio_getxdr(fp), headerContents.flags_dfh, headerContents.nlambda,
- &state->dfhist, nullptr);
+ ret = do_cpt_df_hist(
+ gmx_fio_getxdr(fp), headerContents.flags_dfh, headerContents.nlambda, &state->dfhist, nullptr);
if (ret)
{
cp_error();
if (ret == 0)
{
PullHistory pullHist = {};
- ret = doCptPullHist(gmx_fio_getxdr(fp), TRUE, headerContents.flagsPullHistory, &pullHist,
- StatePart::pullHistory, out);
+ ret = doCptPullHist(
+ gmx_fio_getxdr(fp), TRUE, headerContents.flagsPullHistory, &pullHist, StatePart::pullHistory, out);
}
if (ret == 0)
{
- ret = do_cpt_df_hist(gmx_fio_getxdr(fp), headerContents.flags_dfh, headerContents.nlambda,
- &state.dfhist, out);
+ ret = do_cpt_df_hist(
+ gmx_fio_getxdr(fp), headerContents.flags_dfh, headerContents.nlambda, &state.dfhist, out);
}
if (ret == 0)
*/
#include "gmxpre.h"
-#include "confio.h"
+#include "gromacs/fileio/confio.h"
#include <cstdio>
#include <cstring>
case efENT:
case efPQR:
out = gmx_fio_fopen(outfile, "w");
- write_pdbfile_indexed(out, title, atoms, x, pbcType, box, ' ', -1, nindex, index,
- nullptr, ftp == efPQR);
+ write_pdbfile_indexed(
+ out, title, atoms, x, pbcType, box, ' ', -1, nindex, index, nullptr, ftp == efPQR);
gmx_fio_fclose(out);
break;
case efESP:
snew(*v, header.natoms);
}
int natoms;
- PbcType pbcType_tmp = read_tpx(infile, nullptr, box, &natoms, (x == nullptr) ? nullptr : *x,
- (v == nullptr) ? nullptr : *v, mtop);
+ PbcType pbcType_tmp = read_tpx(
+ infile, nullptr, box, &natoms, (x == nullptr) ? nullptr : *x, (v == nullptr) ? nullptr : *v, mtop);
if (pbcType != nullptr)
{
*pbcType = pbcType_tmp;
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
}
else
{
- gmx_fatal(FARGS, "%s\n%s", msg,
+ gmx_fatal(FARGS,
+ "%s\n%s",
+ msg,
"If you want to use the correct frames before the corrupted frame and avoid this "
"fatal error set the env.var. GMX_ENX_NO_FATAL");
}
xdr_int(xdr, &file_version);
if (file_version > enx_version)
{
- gmx_fatal(FARGS, "reading tpx file (%s) version %d with version %d program",
- gmx_fio_getname(ef->fio), file_version, enx_version);
+ gmx_fatal(FARGS,
+ "reading tpx file (%s) version %d with version %d program",
+ gmx_fio_getname(ef->fio),
+ file_version,
+ enx_version);
}
xdr_int(xdr, nre);
}
}
if (*bOK && *file_version > enx_version)
{
- gmx_fatal(FARGS, "reading tpx file (%s) version %d with version %d program",
- gmx_fio_getname(ef->fio), *file_version, enx_version);
+ gmx_fatal(FARGS,
+ "reading tpx file (%s) version %d with version %d program",
+ gmx_fio_getname(ef->fio),
+ *file_version,
+ enx_version);
}
if (!gmx_fio_do_double(ef->fio, fr->t))
{
{
if (bRead)
{
- fprintf(stderr, "\rLast energy frame read %d time %8.3f ", ef->framenr - 1,
- ef->frametime);
+ fprintf(stderr, "\rLast energy frame read %d time %8.3f ", ef->framenr - 1, ef->frametime);
fflush(stderr);
if (!bOK)
{
- fprintf(stderr, "\nWARNING: Incomplete energy frame: nr %d time %8.3f\n",
- ef->framenr, fr->t);
+ fprintf(stderr, "\nWARNING: Incomplete energy frame: nr %d time %8.3f\n", ef->framenr, fr->t);
}
}
else
}
if (!((fr->step >= 0) && bSane) && bRead)
{
- fprintf(stderr, "\nWARNING: there may be something wrong with energy file %s\n",
+ fprintf(stderr,
+ "\nWARNING: there may be something wrong with energy file %s\n",
gmx_fio_getname(ef->fio));
- fprintf(stderr, "Found: step=%" PRId64 ", nre=%d, nblock=%d, time=%g.\n", fr->step, fr->nre,
- fr->nblock, fr->t);
+ fprintf(stderr,
+ "Found: step=%" PRId64 ", nre=%d, nblock=%d, time=%g.\n",
+ fr->step,
+ fr->nre,
+ fr->nblock,
+ fr->t);
}
if (bRead && fr->nre > fr->e_alloc)
{
}
npcoupl = TRICLINIC(ir->compress) ? 6 : 3;
- if (ir->epc == epcPARRINELLORAHMAN)
+ if (ir->epc == PressureCoupling::ParrinelloRahman)
{
clear_mat(state->boxv);
for (i = 0; i < npcoupl; i++)
fprintf(stderr, "\nREAD %d BOX VELOCITIES FROM %s\n\n", npcoupl, fn);
}
- if (ir->etc == etcNOSEHOOVER)
+ if (ir->etc == TemperatureCoupling::NoseHoover)
{
char cns[20];
}
if (!equal_real(e1[ind1[i]].e, e2[ind2[i]].e, ftol_i, abstol_i))
{
- fprintf(fp, "%-15s step %3d: %12g, step %3d: %12g\n", enm1[ind1[i]].name, step1,
- e1[ind1[i]].e, step2, e2[ind2[i]].e);
+ fprintf(fp,
+ "%-15s step %3d: %12g, step %3d: %12g\n",
+ enm1[ind1[i]].name,
+ step1,
+ e1[ind1[i]].e,
+ step2,
+ e2[ind2[i]].e);
}
}
/* cmp_int(stdout,"nre",-1,fr1->nre,fr2->nre); */
if ((fr1->nre >= nre) && (fr2->nre >= nre))
{
- cmp_energies(stdout, fr1->step, fr1->step, fr1->ener, fr2->ener, enm1, ftol, abstol,
- nre, ind1, ind2, maxener);
+ cmp_energies(
+ stdout, fr1->step, fr1->step, fr1->ener, fr2->ener, enm1, ftol, abstol, nre, ind1, ind2, maxener);
}
/*cmp_disres(fr1,fr2,ftol,abstol);*/
cmp_eblocks(fr1, fr2, ftol, abstol);
}
else
{
- sprintf(buf, "T%c%c", 'A' + atoms->atom[i].type / 26,
- 'A' + atoms->atom[i].type % 26);
+ sprintf(buf, "T%c%c", 'A' + atoms->atom[i].type / 26, 'A' + atoms->atom[i].type % 26);
}
t_atoms_set_resinfo(atoms, i, symtab, buf, i, ' ', 0, ' ');
}
gmx_fatal(FARGS,
"Internal inconsistency in Espresso routines, read %d atoms, expected %d "
"atoms",
- i, atoms->nr);
+ i,
+ atoms->nr);
}
}
else if (level == 1 && std::strcmp(word, "variable") == 0 && !bFoundVariable)
{
j = i;
}
- fprintf(out, "\t{%d %f %f %f %hu %g", j, x[j][XX], x[j][YY], x[j][ZZ], atoms->atom[j].type,
+ fprintf(out,
+ "\t{%d %f %f %f %hu %g",
+ j,
+ x[j][XX],
+ x[j][YY],
+ x[j][ZZ],
+ atoms->atom[j].type,
atoms->atom[j].q);
if (v)
{
*/
#include "gmxpre.h"
-#include "filetypes.h"
+#include "gromacs/fileio/filetypes.h"
#include <cstring>
{ eftGEN, ".???", "trajout", "-f", "Trajectory", NTROS, tros },
{ eftGEN, ".???", "traj", nullptr, "Full precision trajectory", NTRNS, trns },
{ eftXDR, ".trr", "traj", nullptr, "Trajectory in portable xdr format" },
- { eftGEN, ".???", "traj_comp", nullptr,
- "Compressed trajectory (tng format or portable xdr format)", NTRCOMPRESSED, trcompressed },
+ { eftGEN,
+ ".???",
+ "traj_comp",
+ nullptr,
+ "Compressed trajectory (tng format or portable xdr format)",
+ NTRCOMPRESSED,
+ trcompressed },
{ eftXDR, ".xtc", "traj", nullptr, "Compressed trajectory (portable xdr format): xtc" },
{ eftTNG, ".tng", "traj", nullptr, "Trajectory file (tng format)" },
{ eftXDR, ".edr", "ener", nullptr, "Energy file" },
}
if ((nwanted != -1) && (natoms >= nwanted))
{
- gmx_fatal(FARGS, "Found more coordinates (%d) in %s than expected %d\n", natoms,
- infile, nwanted);
+ gmx_fatal(FARGS, "Found more coordinates (%d) in %s than expected %d\n", natoms, infile, nwanted);
}
if (atoms)
{
newres++;
if (newres >= atoms->nr)
{
- gmx_fatal(FARGS, "More residues than atoms in %s (natoms = %d)", infile,
- atoms->nr);
+ gmx_fatal(FARGS, "More residues than atoms in %s (natoms = %d)", infile, atoms->nr);
}
atoms->atom[natoms].resind = newres;
if (newres + 1 > atoms->nres)
}
if ((nwanted != -1) && natoms != nwanted)
{
- fprintf(stderr, "Warning: found less coordinates (%d) in %s than expected %d\n", natoms,
- infile, nwanted);
+ fprintf(stderr, "Warning: found less coordinates (%d) in %s than expected %d\n", natoms, infile, nwanted);
}
}
}
if ((nwanted != -1) && (natoms >= nwanted))
{
- gmx_fatal(FARGS, "Found more velocities (%d) in %s than expected %d\n", natoms,
- infile, nwanted);
+ gmx_fatal(FARGS, "Found more velocities (%d) in %s than expected %d\n", natoms, infile, nwanted);
}
if (fr->v)
{
}
if ((nwanted != -1) && (natoms != nwanted))
{
- fprintf(stderr, "Warning: found less velocities (%d) in %s than expected %d\n", natoms,
- infile, nwanted);
+ fprintf(stderr, "Warning: found less velocities (%d) in %s than expected %d\n", natoms, infile, nwanted);
}
}
bEnd = (strncmp(line, "END", 3) == 0);
if (!bEnd && (line[0] != '#'))
{
- nbp = sscanf(line, "%15lf%15lf%15lf%15lf%15lf%15lf%15lf%15lf%15lf", &db1, &db2,
- &db3, &db4, &db5, &db6, &db7, &db8, &db9);
+ nbp = sscanf(line,
+ "%15lf%15lf%15lf%15lf%15lf%15lf%15lf%15lf%15lf",
+ &db1,
+ &db2,
+ &db3,
+ &db4,
+ &db5,
+ &db6,
+ &db7,
+ &db8,
+ &db9);
if (nbp < 3)
{
gmx_fatal(FARGS, "Found a BOX line, but no box in %s", infile);
{
a = i;
}
- fprintf(out, "%5d %-5s %-5s%7d%15.9f%15.9f%15.9f\n",
+ fprintf(out,
+ "%5d %-5s %-5s%7d%15.9f%15.9f%15.9f\n",
(atoms->resinfo[atoms->atom[a].resind].nr) % 100000,
- *atoms->resinfo[atoms->atom[a].resind].name, *atoms->atomname[a],
- (i + 1) % 10000000, fr->x[a][XX], fr->x[a][YY], fr->x[a][ZZ]);
+ *atoms->resinfo[atoms->atom[a].resind].name,
+ *atoms->atomname[a],
+ (i + 1) % 10000000,
+ fr->x[a][XX],
+ fr->x[a][YY],
+ fr->x[a][ZZ]);
}
}
else
{
a = i;
}
- fprintf(out, "%5d %-5s %-5s%7d%15.9f%15.9f%15.9f\n",
+ fprintf(out,
+ "%5d %-5s %-5s%7d%15.9f%15.9f%15.9f\n",
(atoms->resinfo[atoms->atom[a].resind].nr) % 100000,
- *atoms->resinfo[atoms->atom[a].resind].name, *atoms->atomname[a],
- (i + 1) % 10000000, fr->v[a][XX], fr->v[a][YY], fr->v[a][ZZ]);
+ *atoms->resinfo[atoms->atom[a].resind].name,
+ *atoms->atomname[a],
+ (i + 1) % 10000000,
+ fr->v[a][XX],
+ fr->v[a][YY],
+ fr->v[a][ZZ]);
}
}
else
if ((fr->box[XX][YY] != 0.0F) || (fr->box[XX][ZZ] != 0.0F) || (fr->box[YY][XX] != 0.0F)
|| (fr->box[YY][ZZ] != 0.0F) || (fr->box[ZZ][XX] != 0.0F) || (fr->box[ZZ][YY] != 0.0F))
{
- fprintf(out, "%15.9f%15.9f%15.9f%15.9f%15.9f%15.9f", fr->box[XX][YY], fr->box[XX][ZZ],
- fr->box[YY][XX], fr->box[YY][ZZ], fr->box[ZZ][XX], fr->box[ZZ][YY]);
+ fprintf(out,
+ "%15.9f%15.9f%15.9f%15.9f%15.9f%15.9f",
+ fr->box[XX][YY],
+ fr->box[XX][ZZ],
+ fr->box[YY][XX],
+ fr->box[YY][ZZ],
+ fr->box[ZZ][XX],
+ fr->box[ZZ][YY]);
}
fprintf(out, "\n");
fprintf(out, "END\n");
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <cstdio>
#include <cstring>
+#include <mutex>
#include <vector>
#if HAVE_IO_H
#include "gromacs/fileio/md5.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
-#include "gromacs/utility/mutex.h"
#include "gromacs/utility/smalloc.h"
#include "gmxfio_impl.h"
opening and closing of files, or during global operations like
iterating along all open files. All these cases should be rare
during the simulation. */
-static gmx::Mutex open_file_mutex;
+static std::mutex open_file_mutex;
-using Lock = gmx::lock_guard<gmx::Mutex>;
+using Lock = std::lock_guard<std::mutex>;
/******************************************************************
*
gmx_fatal(FARGS,
"nitem may differ from 1 only for %s, %s, %s or %s, not for %s"
"(%s, %d)",
- eioNames[eioNUCHAR], eioNames[eioNRVEC], eioNames[eioNCHAR], eioNames[eioOPAQUE],
- eioNames[eio], file, line);
+ eioNames[eioNUCHAR],
+ eioNames[eioNRVEC],
+ eioNames[eioNCHAR],
+ eioNames[eioOPAQUE],
+ eioNames[eio],
+ file,
+ line);
}
}
/* output a data type error. */
[[noreturn]] static void gmx_fio_fe(t_fileio* fio, int eio, const char* desc, const char* srcfile, int line)
{
- gmx_fatal(FARGS, "Trying to %s %s type %d (%s), src %s, line %d", fio->bRead ? "read" : "write",
- desc, eio, ((eio >= 0) && (eio < eioNR)) ? eioNames[eio] : "unknown", srcfile, line);
+ gmx_fatal(FARGS,
+ "Trying to %s %s type %d (%s), src %s, line %d",
+ fio->bRead ? "read" : "write",
+ desc,
+ eio,
+ ((eio >= 0) && (eio < eioNR)) ? eioNames[eio] : "unknown",
+ srcfile,
+ line);
}
/* This is the part that reads xdr files. */
cptr = static_cast<char*>(item);
GMX_RELEASE_ASSERT(nitem < static_cast<std::size_t>(std::numeric_limits<int>::max()),
"The XDR interface cannot handle array lengths > 2^31");
- res = xdr_vector(fio->xdr, cptr, static_cast<int>(nitem),
+ res = xdr_vector(fio->xdr,
+ cptr,
+ static_cast<int>(nitem),
static_cast<unsigned int>(sizeof(char)),
reinterpret_cast<xdrproc_t>(xdr_char));
break;
ucptr = static_cast<unsigned char*>(item);
GMX_RELEASE_ASSERT(nitem < static_cast<std::size_t>(std::numeric_limits<int>::max()),
"The XDR interface cannot handle array lengths > 2^31");
- res = xdr_vector(fio->xdr, reinterpret_cast<char*>(ucptr), static_cast<int>(nitem),
+ res = xdr_vector(fio->xdr,
+ reinterpret_cast<char*>(ucptr),
+ static_cast<int>(nitem),
static_cast<unsigned int>(sizeof(unsigned char)),
reinterpret_cast<xdrproc_t>(xdr_u_char));
break;
dvec[m] = (static_cast<real*>(item))[m];
}
}
- res = xdr_vector(fio->xdr, reinterpret_cast<char*>(dvec), DIM,
+ res = xdr_vector(fio->xdr,
+ reinterpret_cast<char*>(dvec),
+ DIM,
static_cast<unsigned int>(sizeof(double)),
reinterpret_cast<xdrproc_t>(xdr_double));
if (item)
fvec[m] = (static_cast<real*>(item))[m];
}
}
- res = xdr_vector(fio->xdr, reinterpret_cast<char*>(fvec), DIM,
+ res = xdr_vector(fio->xdr,
+ reinterpret_cast<char*>(fvec),
+ DIM,
static_cast<unsigned int>(sizeof(float)),
reinterpret_cast<xdrproc_t>(xdr_float));
if (item)
gmx_fatal(FARGS,
"wrong string length %d for string %s"
" (source %s, line %d)",
- slen, desc, srcfile, line);
+ slen,
+ desc,
+ srcfile,
+ line);
}
if (!item && fio->bRead)
{
fprintf(stderr,
"Warning: gro file contains less atoms (%d) than expected"
" (%d)\n",
- natoms, atoms->nr);
+ natoms,
+ atoms->nr);
}
atoms->haveMass = FALSE;
{
box[m][m] = (xmax[m] - xmin[m]);
}
- fprintf(stderr, "Generated a cubic box %8.3f x %8.3f x %8.3f\n", box[XX][XX], box[YY][YY],
- box[ZZ][ZZ]);
+ fprintf(stderr, "Generated a cubic box %8.3f x %8.3f x %8.3f\n", box[XX][XX], box[YY][YY], box[ZZ][ZZ]);
}
else
{
gmx_fatal(FARGS,
"Number of atoms in gro frame (%d) doesn't match the number in the previous "
"frame (%d)",
- atoms.nr, fr->natoms);
+ atoms.nr,
+ fr->natoms);
}
return TRUE;
if ((box[XX][YY] != 0.0F) || (box[XX][ZZ] != 0.0F) || (box[YY][XX] != 0.0F)
|| (box[YY][ZZ] != 0.0F) || (box[ZZ][XX] != 0.0F) || (box[ZZ][YY] != 0.0F))
{
- fprintf(out, "%10.5f %9.5f %9.5f %9.5f %9.5f %9.5f %9.5f %9.5f %9.5f\n", box[XX][XX],
- box[YY][YY], box[ZZ][ZZ], box[XX][YY], box[XX][ZZ], box[YY][XX], box[YY][ZZ],
- box[ZZ][XX], box[ZZ][YY]);
+ fprintf(out,
+ "%10.5f %9.5f %9.5f %9.5f %9.5f %9.5f %9.5f %9.5f %9.5f\n",
+ box[XX][XX],
+ box[YY][YY],
+ box[ZZ][ZZ],
+ box[XX][YY],
+ box[XX][ZZ],
+ box[YY][XX],
+ box[YY][ZZ],
+ box[ZZ][XX],
+ box[ZZ][YY]);
}
else
{
fprintf(stderr,
"major breakdown in sendints num %u doesn't "
"match size %u\n",
- nums[i], sizes[i]);
+ nums[i],
+ sizes[i]);
exit(1);
}
/* use one step multiply */
*/
if (*size <= 9)
{
- return (xdr_vector(xdrs, reinterpret_cast<char*>(fp), static_cast<unsigned int>(size3),
+ return (xdr_vector(xdrs,
+ reinterpret_cast<char*>(fp),
+ static_cast<unsigned int>(size3),
static_cast<unsigned int>(sizeof(*fp)),
reinterpret_cast<xdrproc_t>(xdr_float)));
}
fprintf(stderr,
"wrong number of coordinates in xdr3dfcoord; "
"%d arg vs %d in file",
- *size, lsize);
+ *size,
+ lsize);
}
*size = lsize;
size3 = *size * 3;
if (*size <= 9)
{
*precision = -1;
- return (xdr_vector(xdrs, reinterpret_cast<char*>(fp), static_cast<unsigned int>(size3),
+ return (xdr_vector(xdrs,
+ reinterpret_cast<char*>(fp),
+ static_cast<unsigned int>(size3),
static_cast<unsigned int>(sizeof(*fp)),
reinterpret_cast<xdrproc_t>(xdr_float)));
}
gmx_fatal(FARGS,
"Not enough lines in colormap file %s"
"(should be %d, found only %d)",
- fn, n + 1, i);
+ fn,
+ n + 1,
+ i);
}
sscanf(line, "%s%s%lf%lf%lf", code, desc, &r, &g, &b);
m[i].code.c1 = code[0];
fprintf(out, "%d\n", n);
for (i = 0; (i < n); i++)
{
- fprintf(out, "%c%c %20s %10g %10g %10g\n", map[i].code.c1 ? map[i].code.c1 : ' ',
- map[i].code.c2 ? map[i].code.c2 : ' ', map[i].desc, map[i].rgb.r, map[i].rgb.g,
+ fprintf(out,
+ "%c%c %20s %10g %10g %10g\n",
+ map[i].code.c1 ? map[i].code.c1 : ' ',
+ map[i].code.c2 ? map[i].code.c2 : ' ',
+ map[i].desc,
+ map[i].rgb.r,
+ map[i].rgb.g,
map[i].rgb.b);
}
}
if (debug)
{
- fprintf(debug, "%s %s %s %s\n", mm.title.c_str(), mm.legend.c_str(), mm.label_x.c_str(),
+ fprintf(debug,
+ "%s %s %s %s\n",
+ mm.title.c_str(),
+ mm.legend.c_str(),
+ mm.label_x.c_str(),
mm.label_y.c_str());
}
gmx_fatal(FARGS,
"Number of read colors map entries (%d) does not match the number in the header "
"(%d)",
- m, nmap);
+ m,
+ nmap);
}
/* Read axes, if there are any */
fprintf(stderr,
"Could not convert matrix to reals,\n"
"color map entry %zd has a non-real description: \"%s\"\n",
- i, in->map[i].desc);
+ i,
+ in->map[i].desc);
return nullptr;
}
rmap[i] = tmp;
if (*nlevels > NMAP * NMAP)
{
- fprintf(stderr, "Warning, too many levels (%d) in matrix, using %d only\n", *nlevels,
+ fprintf(stderr,
+ "Warning, too many levels (%d) in matrix, using %d only\n",
+ *nlevels,
static_cast<int>(NMAP * NMAP));
*nlevels = NMAP * NMAP;
}
r = rlo.r + (i * (rmid.r - rlo.r) / clev_lo);
g = rlo.g + (i * (rmid.g - rlo.g) / clev_lo);
b = rlo.b + (i * (rmid.b - rlo.b) / clev_lo);
- fprintf(out, "\"%c%c c #%02X%02X%02X \" /* \"%.3g\" */,\n", mapper[i % NMAP],
+ fprintf(out,
+ "\"%c%c c #%02X%02X%02X \" /* \"%.3g\" */,\n",
+ mapper[i % NMAP],
(*nlevels <= NMAP) ? ' ' : mapper[i / NMAP],
static_cast<unsigned int>(std::round(255 * r)),
static_cast<unsigned int>(std::round(255 * g)),
- static_cast<unsigned int>(std::round(255 * b)), ((nmid - i) * lo + i * mid) / clev_lo);
+ static_cast<unsigned int>(std::round(255 * b)),
+ ((nmid - i) * lo + i * mid) / clev_lo);
}
for (i = 0; (i < (*nlevels - nmid)); i++)
{
r = rmid.r + (i * (rhi.r - rmid.r) / clev_hi);
g = rmid.g + (i * (rhi.g - rmid.g) / clev_hi);
b = rmid.b + (i * (rhi.b - rmid.b) / clev_hi);
- fprintf(out, "\"%c%c c #%02X%02X%02X \" /* \"%.3g\" */,\n", mapper[(i + nmid) % NMAP],
+ fprintf(out,
+ "\"%c%c c #%02X%02X%02X \" /* \"%.3g\" */,\n",
+ mapper[(i + nmid) % NMAP],
(*nlevels <= NMAP) ? ' ' : mapper[(i + nmid) / NMAP],
static_cast<unsigned int>(std::round(255 * r)),
static_cast<unsigned int>(std::round(255 * g)),
r = rlo.r + fac * (rhi.r - rlo.r);
g = rlo.g + fac * (rhi.g - rlo.g);
b = rlo.b + fac * (rhi.b - rlo.b);
- fprintf(out, "\"%c%c c #%02X%02X%02X \" /* \"%.3g\" */,\n", mapper[(i + i0) % NMAP],
+ fprintf(out,
+ "\"%c%c c #%02X%02X%02X \" /* \"%.3g\" */,\n",
+ mapper[(i + i0) % NMAP],
(nlevel <= NMAP) ? ' ' : mapper[(i + i0) / NMAP],
static_cast<unsigned int>(std::round(255 * r)),
static_cast<unsigned int>(std::round(255 * g)),
- static_cast<unsigned int>(std::round(255 * b)), lo + fac * (hi - lo));
+ static_cast<unsigned int>(std::round(255 * b)),
+ lo + fac * (hi - lo));
}
}
n = *nlevel;
for (i = 0; (i < n); i++)
{
- fprintf(out, "\"%c%c c #%02X%02X%02X \" /* \"%3d\" */,\n", mapper[(i + i0) % NMAP],
+ fprintf(out,
+ "\"%c%c c #%02X%02X%02X \" /* \"%3d\" */,\n",
+ mapper[(i + i0) % NMAP],
(n <= NMAP) ? ' ' : mapper[(i + i0) / NMAP],
static_cast<unsigned int>(round(255 * rgbd[i].r)),
static_cast<unsigned int>(round(255 * rgbd[i].g)),
- static_cast<unsigned int>(round(255 * rgbd[i].b)), i);
+ static_cast<unsigned int>(round(255 * rgbd[i].b)),
+ i);
}
}
if (*nlevels > NMAP * NMAP)
{
- fprintf(stderr, "Warning, too many levels (%d) in matrix, using %d only\n", *nlevels,
+ fprintf(stderr,
+ "Warning, too many levels (%d) in matrix, using %d only\n",
+ *nlevels,
static_cast<int>(NMAP * NMAP));
*nlevels = NMAP * NMAP;
}
r = (nlo * rlo.r + i * rhi.r) * invlevel;
g = (nlo * rlo.g + i * rhi.g) * invlevel;
b = (nlo * rlo.b + i * rhi.b) * invlevel;
- fprintf(out, "\"%c%c c #%02X%02X%02X \" /* \"%.3g\" */,\n", mapper[i % NMAP],
+ fprintf(out,
+ "\"%c%c c #%02X%02X%02X \" /* \"%.3g\" */,\n",
+ mapper[i % NMAP],
(*nlevels <= NMAP) ? ' ' : mapper[i / NMAP],
static_cast<unsigned int>(std::round(255 * r)),
static_cast<unsigned int>(std::round(255 * g)),
- static_cast<unsigned int>(std::round(255 * b)), (nlo * lo + i * hi) * invlevel);
+ static_cast<unsigned int>(std::round(255 * b)),
+ (nlo * lo + i * hi) * invlevel);
}
}
gmx_fatal(FARGS,
"Range checking i = %d, j = %d, c = %d, bot = %d, top = %d "
"matrix[i,j] = %f",
- i, j, c, nlevel_bot, nlevel_top, mat[i][j]);
+ i,
+ j,
+ c,
+ nlevel_bot,
+ nlevel_top,
+ mat[i][j]);
}
}
else if (i > j)
gmx_fatal(FARGS,
"Range checking i = %d, j = %d, c = %d, bot = %d, top = %d "
"matrix[i,j] = %f",
- i, j, c, nlevel_bot, nlevel_top, mat[i][j]);
+ i,
+ j,
+ c,
+ nlevel_bot,
+ nlevel_top,
+ mat[i][j]);
}
}
else
fprintf(out, "\"%d %d %zu %d\",\n", m.nx, m.ny, m.map.size(), bOneChar ? 1 : 2);
for (const auto& map : m.map)
{
- fprintf(out, "\"%c%c c #%02X%02X%02X \" /* \"%s\" */,\n", map.code.c1,
- bOneChar ? ' ' : map.code.c2, static_cast<unsigned int>(round(map.rgb.r * 255)),
+ fprintf(out,
+ "\"%c%c c #%02X%02X%02X \" /* \"%s\" */,\n",
+ map.code.c1,
+ bOneChar ? ' ' : map.code.c2,
+ static_cast<unsigned int>(round(map.rgb.r * 255)),
static_cast<unsigned int>(round(map.rgb.g * 255)),
- static_cast<unsigned int>(round(map.rgb.b * 255)), map.desc);
+ static_cast<unsigned int>(round(map.rgb.b * 255)),
+ map.desc);
}
writeXpmAxis(out, "x", m.axis_x);
writeXpmAxis(out, "y", m.axis_y);
}
write_xpm_header(out, title, legend, label_x, label_y, FALSE);
- write_xpm_map_split(out, n_x, n_y, nlevel_top, lo_top, hi_top, rlo_top, rhi_top, bDiscreteColor,
- nlevel_bot, lo_bot, hi_bot, rlo_bot, rhi_bot);
+ write_xpm_map_split(
+ out, n_x, n_y, nlevel_top, lo_top, hi_top, rlo_top, rhi_top, bDiscreteColor, nlevel_bot, lo_bot, hi_bot, rlo_bot, rhi_bot);
writeXpmAxis(out, "x", ArrayRef<real>(axis_x, axis_x + n_x + ((flags & MAT_SPATIAL_X) != 0U ? 1 : 0)));
writeXpmAxis(out, "y", ArrayRef<real>(axis_y, axis_y + n_y + ((flags & MAT_SPATIAL_Y) != 0U ? 1 : 0)));
write_xpm_data_split(out, n_x, n_y, mat, lo_top, hi_top, *nlevel_top, lo_bot, hi_bot, *nlevel_bot);
gmx_fseek(gmx_fio_getfp(mrcFile), 0, SEEK_SET);
// Read whole file into buffer the size of the file
std::vector<char> fileContentBuffer(fileSize);
- size_t readSize = fread(fileContentBuffer.data(), sizeof(char), fileContentBuffer.size(),
- gmx_fio_getfp(mrcFile));
+ size_t readSize = fread(
+ fileContentBuffer.data(), sizeof(char), fileContentBuffer.size(), gmx_fio_getfp(mrcFile));
gmx_fio_close(mrcFile);
if (fileContentBuffer.size() != readSize)
{
MultiDimArray<std::vector<float>, dynamicExtents3D> result(
getDynamicExtents3D(impl_->reader().header()));
- std::copy(std::begin(impl_->reader().constView()), std::end(impl_->reader().constView()),
+ std::copy(std::begin(impl_->reader().constView()),
+ std::end(impl_->reader().constView()),
begin(result.asView()));
return result;
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
* \inlibraryapi
* \ingroup module_fileio
*/
+#include <memory>
#include <string>
#include <vector>
#include "gromacs/math/multidimarray.h"
#include "gromacs/mdspan/extensions.h"
-#include "gromacs/utility/classhelpers.h"
namespace gmx
{
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
/*! \libinternal \brief Read an mrc density map from a given file.
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
/*! \libinternal \brief Write an mrc/ccp4 file that contains float values.
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
template<typename Container>
bool anyLargerThanValue(Container values, typename Container::value_type boundaryValue)
{
- return std::any_of(std::begin(values), std::end(values),
- [boundaryValue](auto v) { return v > boundaryValue; });
+ return std::any_of(std::begin(values), std::end(values), [boundaryValue](auto v) {
+ return v > boundaryValue;
+ });
}
} // namespace
RVec scale = { header.extent_[XX] / (header.cellLength_[XX] * c_AAtoNmConversion),
header.extent_[YY] / (header.cellLength_[YY] * c_AAtoNmConversion),
header.extent_[ZZ] / (header.cellLength_[ZZ] * c_AAtoNmConversion) };
- const RVec emdbOrigin{ header.userDefinedFloat_[12], header.userDefinedFloat_[13],
+ const RVec emdbOrigin{ header.userDefinedFloat_[12],
+ header.userDefinedFloat_[13],
header.userDefinedFloat_[14] };
RVec translation;
if (emdbOrigin[XX] == 0. && emdbOrigin[YY] == 0. && emdbOrigin[ZZ] == 0.)
}
else
{
- translation = { -emdbOrigin[XX] * c_AAtoNmConversion, -emdbOrigin[YY] * c_AAtoNmConversion,
+ translation = { -emdbOrigin[XX] * c_AAtoNmConversion,
+ -emdbOrigin[YY] * c_AAtoNmConversion,
-emdbOrigin[ZZ] * c_AAtoNmConversion };
}
return { scale, translation };
dynamicExtents3D getDynamicExtents3D(const MrcDensityMapHeader& header)
{
- return { header.numColumnRowSection_[ZZ], header.numColumnRowSection_[YY],
+ return { header.numColumnRowSection_[ZZ],
+ header.numColumnRowSection_[YY],
header.numColumnRowSection_[XX] };
};
}
gmx_fio_do_int(fio, prec);
- fprintf(stderr, "Reading %s precision matrix generated by GROMACS %s\n",
- (prec == 1) ? "double" : "single", gmxver);
+ fprintf(stderr,
+ "Reading %s precision matrix generated by GROMACS %s\n",
+ (prec == 1) ? "double" : "single",
+ gmxver);
gmx_fio_do_int(fio, i);
*nrow = i;
*/
#include "gmxpre.h"
-#include "oenv.h"
+#include "gromacs/fileio/oenv.h"
#include "gromacs/utility/enumerationhelpers.h"
#include "gromacs/utility/exceptions.h"
*/
#include "gmxpre.h"
-#include "pdbio.h"
+#include "gromacs/fileio/pdbio.h"
#include <cctype>
#include <cmath>
fprintf(out, "REMARK THIS IS A SIMULATION BOX\n");
if (pbcType != PbcType::Screw)
{
- fprintf(out, "CRYST1%9.3f%9.3f%9.3f%7.2f%7.2f%7.2f %-11s%4d\n", 10 * norm(box[XX]),
- 10 * norm(box[YY]), 10 * norm(box[ZZ]), alpha, beta, gamma, "P 1", 1);
+ fprintf(out,
+ "CRYST1%9.3f%9.3f%9.3f%7.2f%7.2f%7.2f %-11s%4d\n",
+ 10 * norm(box[XX]),
+ 10 * norm(box[YY]),
+ 10 * norm(box[ZZ]),
+ alpha,
+ beta,
+ gamma,
+ "P 1",
+ 1);
}
else
{
/* Double the a-vector length and write the correct space group */
- fprintf(out, "CRYST1%9.3f%9.3f%9.3f%7.2f%7.2f%7.2f %-11s%4d\n", 20 * norm(box[XX]),
- 10 * norm(box[YY]), 10 * norm(box[ZZ]), alpha, beta, gamma, "P 21 1 1", 1);
+ fprintf(out,
+ "CRYST1%9.3f%9.3f%9.3f%7.2f%7.2f%7.2f %-11s%4d\n",
+ 20 * norm(box[XX]),
+ 10 * norm(box[YY]),
+ 10 * norm(box[ZZ]),
+ alpha,
+ beta,
+ gamma,
+ "P 21 1 1",
+ 1);
}
}
atom_seq_number = atom_seq_number % 100000;
res_seq_number = res_seq_number % 10000;
- int n = fprintf(fp, "%-6s%5d %-4.4s%4.4s%c%4d %8.3f %8.3f %8.3f %6.2f %6.2f\n", pdbtp[record],
- atom_seq_number, atom_name, res_name, chain_id, res_seq_number, x, y, z,
- occupancy, b_factor);
+ int n = fprintf(fp,
+ "%-6s%5d %-4.4s%4.4s%c%4d %8.3f %8.3f %8.3f %6.2f %6.2f\n",
+ pdbtp[record],
+ atom_seq_number,
+ atom_name,
+ res_name,
+ chain_id,
+ res_seq_number,
+ x,
+ y,
+ z,
+ occupancy,
+ b_factor);
return n;
}
bfac = pdbinfo.bfac;
if (!usePqrFormat)
{
- gmx_fprintf_pdb_atomline(out, type, i + 1, nm.c_str(), altloc, resnm.c_str(), ch, resnr,
- resic, 10 * x[i][XX], 10 * x[i][YY], 10 * x[i][ZZ], occup,
- bfac, atoms->atom[i].elem);
+ gmx_fprintf_pdb_atomline(out,
+ type,
+ i + 1,
+ nm.c_str(),
+ altloc,
+ resnm.c_str(),
+ ch,
+ resnr,
+ resic,
+ 10 * x[i][XX],
+ 10 * x[i][YY],
+ 10 * x[i][ZZ],
+ occup,
+ bfac,
+ atoms->atom[i].elem);
if (atoms->pdbinfo && atoms->pdbinfo[i].bAnisotropic)
{
- fprintf(out, "ANISOU%5d %-4.4s%4.4s%c%4d%c %7d%7d%7d%7d%7d%7d\n", (i + 1) % 100000,
- nm.c_str(), resnm.c_str(), ch, resnr, (resic == '\0') ? ' ' : resic,
- atoms->pdbinfo[i].uij[0], atoms->pdbinfo[i].uij[1], atoms->pdbinfo[i].uij[2],
- atoms->pdbinfo[i].uij[3], atoms->pdbinfo[i].uij[4], atoms->pdbinfo[i].uij[5]);
+ fprintf(out,
+ "ANISOU%5d %-4.4s%4.4s%c%4d%c %7d%7d%7d%7d%7d%7d\n",
+ (i + 1) % 100000,
+ nm.c_str(),
+ resnm.c_str(),
+ ch,
+ resnr,
+ (resic == '\0') ? ' ' : resic,
+ atoms->pdbinfo[i].uij[0],
+ atoms->pdbinfo[i].uij[1],
+ atoms->pdbinfo[i].uij[2],
+ atoms->pdbinfo[i].uij[3],
+ atoms->pdbinfo[i].uij[4],
+ atoms->pdbinfo[i].uij[5]);
}
}
else
{
- gmx_fprintf_pqr_atomline(out, type, i + 1, nm.c_str(), resnm.c_str(), ch, resnr,
- 10 * x[i][XX], 10 * x[i][YY], 10 * x[i][ZZ], occup, bfac);
+ gmx_fprintf_pqr_atomline(out,
+ type,
+ i + 1,
+ nm.c_str(),
+ resnm.c_str(),
+ ch,
+ resnr,
+ 10 * x[i][XX],
+ 10 * x[i][YY],
+ 10 * x[i][ZZ],
+ occup,
+ bfac);
}
}
{
index[i] = i;
}
- write_pdbfile_indexed(out, title, atoms, x, pbcType, box, chainid, model_nr, atoms->nr, index,
- conect, false);
+ write_pdbfile_indexed(
+ out, title, atoms, x, pbcType, box, chainid, model_nr, atoms->nr, index, conect, false);
sfree(index);
}
}
else
{
- if (sscanf(line + 29, "%d%d%d%d%d%d", &atoms->pdbinfo[i].uij[U11], &atoms->pdbinfo[i].uij[U22],
- &atoms->pdbinfo[i].uij[U33], &atoms->pdbinfo[i].uij[U12],
- &atoms->pdbinfo[i].uij[U13], &atoms->pdbinfo[i].uij[U23])
+ if (sscanf(line + 29,
+ "%d%d%d%d%d%d",
+ &atoms->pdbinfo[i].uij[U11],
+ &atoms->pdbinfo[i].uij[U22],
+ &atoms->pdbinfo[i].uij[U33],
+ &atoms->pdbinfo[i].uij[U12],
+ &atoms->pdbinfo[i].uij[U13],
+ &atoms->pdbinfo[i].uij[U23])
== 6)
{
atoms->pdbinfo[i].bAnisotropic = TRUE;
atom_seq_number = atom_seq_number % 100000;
res_seq_number = res_seq_number % 10000;
- n = fprintf(fp, "%-6s%5d %-4.4s%c%4.4s%c%4d%c %8.3f%8.3f%8.3f%6.2f%6.2f %2s\n",
- pdbtp[record], atom_seq_number, tmp_atomname, alternate_location, tmp_resname,
- chain_id, res_seq_number, res_insertion_code, x, y, z, occupancy, b_factor,
+ n = fprintf(fp,
+ "%-6s%5d %-4.4s%c%4.4s%c%4d%c %8.3f%8.3f%8.3f%6.2f%6.2f %2s\n",
+ pdbtp[record],
+ atom_seq_number,
+ tmp_atomname,
+ alternate_location,
+ tmp_resname,
+ chain_id,
+ res_seq_number,
+ res_insertion_code,
+ x,
+ y,
+ z,
+ occupancy,
+ b_factor,
(element != nullptr) ? element : "");
return n;
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
}
else
{
- writer.writeLine(formatString("%-24s = %s", local.name_.c_str(),
+ writer.writeLine(formatString("%-24s = %s",
+ local.name_.c_str(),
!local.value_.empty() ? local.value_.c_str() : ""));
}
}
gmx_fatal(FARGS,
"A parameter is present with both the old name '%s' and the new name "
"'%s'.",
- local.name_.c_str(), inp[foundIndex].name_.c_str());
+ local.name_.c_str(),
+ inp[foundIndex].name_.c_str());
}
local.name_.assign(new_entry);
}
}
-static int get_einp(std::vector<t_inpfile>* inp, const char* name)
+int get_einp(std::vector<t_inpfile>* inp, const char* name)
{
std::vector<t_inpfile>& inpRef = *inp;
bool notfound = false;
sprintf(warn_buf,
"Right hand side '%s' for parameter '%s' in parameter file is not an integer "
"value\n",
- inpRef[ii].value_.c_str(), inpRef[ii].name_.c_str());
+ inpRef[ii].value_.c_str(),
+ inpRef[ii].name_.c_str());
warning_error(wi, warn_buf);
}
sprintf(warn_buf,
"Right hand side '%s' for parameter '%s' in parameter file is not an integer "
"value\n",
- inpRef[ii].value_.c_str(), inpRef[ii].name_.c_str());
+ inpRef[ii].value_.c_str(),
+ inpRef[ii].name_.c_str());
warning_error(wi, warn_buf);
}
sprintf(warn_buf,
"Right hand side '%s' for parameter '%s' in parameter file is not a real "
"value\n",
- inpRef[ii].value_.c_str(), inpRef[ii].name_.c_str());
+ inpRef[ii].value_.c_str(),
+ inpRef[ii].name_.c_str());
warning_error(wi, warn_buf);
}
if (defs[i] == nullptr)
{
- n += sprintf(buf, "Invalid enum '%s' for variable %s, using '%s'\n",
- inpRef[ii].value_.c_str(), name, defs[0]);
+ n += sprintf(buf,
+ "Invalid enum '%s' for variable %s, using '%s'\n",
+ inpRef[ii].value_.c_str(),
+ name,
+ defs[0]);
n += sprintf(buf + n, "Next time use one of:");
int j = 0;
while (defs[j])
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
int get_eenum(std::vector<t_inpfile>* inp, const char* name, const char** defs);
/* defs must be NULL terminated */
+//! Get index of option `name`. Exposed here so that `getEnum` can access it.
+int get_einp(std::vector<t_inpfile>* inp, const char* name);
+
+/*! \brief Read option from input and return corresponding enum value
+ *
+ * If the option is not set, return the first value of the enum as default.
+ *
+ * \tparam EnumType The type of enum to be returned
+ * \param[in] inp The input file vector
+ * \param[in] name The name of the option to be read
+ * \param[out] wi Handler for context-sensitive warnings.
+ * \return Enum value corresponding to read input
+ */
+template<typename EnumType>
+EnumType getEnum(std::vector<t_inpfile>* inp, const char* name, warninp* wi);
+
//! Replace for macro CCTYPE, prints comment string after newline
void printStringNewline(std::vector<t_inpfile>* inp, const char* line);
//! Replace for macro CTYPE, prints comment string
${tng_sources}
xvgio.cpp
)
+target_link_libraries(fileio-test PRIVATE legacy_api)
void writeReferenceFile()
{
- write_sto_conf(referenceFilename_.c_str(), *refTop_->name, &refTop_->atoms,
- as_rvec_array(refX_.data()), nullptr, PbcType::Unset, refBox_);
+ write_sto_conf(referenceFilename_.c_str(),
+ *refTop_->name,
+ &refTop_->atoms,
+ as_rvec_array(refX_.data()),
+ nullptr,
+ PbcType::Unset,
+ refBox_);
}
void readReferenceFileTps()
void writeTestFileAndTest()
{
- write_sto_conf(testFilename_.c_str(), *testTop_->name, &testTop_->atoms, testX_, nullptr,
- PbcType::Unset, testBox_);
+ write_sto_conf(
+ testFilename_.c_str(), *testTop_->name, &testTop_->atoms, testX_, nullptr, PbcType::Unset, testBox_);
testFilesEqual(referenceFilename_, testFilename_);
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
TestReferenceData refData;
TestReferenceChecker checker(refData.rootChecker());
- checker.checkSequence(begin(densityData.asConstView()), end(densityData.asConstView()),
+ checker.checkSequence(begin(densityData.asConstView()),
+ end(densityData.asConstView()),
"data ellipsoid density");
}
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2018,2019,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "timecontrol.h"
-#include "thread_mpi/threads.h"
+#include <mutex>
#include "gromacs/utility/basedefinitions.h"
#include "gromacs/utility/fatalerror.h"
static t_timecontrol timecontrol[TNR] = { { 0, FALSE }, { 0, FALSE }, { 0, FALSE } };
-static tMPI_Thread_mutex_t tc_mutex = TMPI_THREAD_MUTEX_INITIALIZER;
+static std::mutex g_timeControlMutex;
gmx_bool bTimeSet(int tcontrol)
{
gmx_bool ret;
- tMPI_Thread_mutex_lock(&tc_mutex);
+ const std::lock_guard<std::mutex> lock(g_timeControlMutex);
range_check(tcontrol, 0, TNR);
ret = timecontrol[tcontrol].bSet;
- tMPI_Thread_mutex_unlock(&tc_mutex);
return ret;
}
{
real ret;
- tMPI_Thread_mutex_lock(&tc_mutex);
+ const std::lock_guard<std::mutex> lock(g_timeControlMutex);
range_check(tcontrol, 0, TNR);
ret = timecontrol[tcontrol].t;
- tMPI_Thread_mutex_unlock(&tc_mutex);
return ret;
}
void setTimeValue(int tcontrol, real value)
{
- tMPI_Thread_mutex_lock(&tc_mutex);
+ const std::lock_guard<std::mutex> lock(g_timeControlMutex);
range_check(tcontrol, 0, TNR);
timecontrol[tcontrol].t = value;
timecontrol[tcontrol].bSet = TRUE;
- tMPI_Thread_mutex_unlock(&tc_mutex);
}
# if GMX_DOUBLE
precisionString = " (double precision)";
# endif
- sprintf(programInfo, "%.100s %.128s%.24s", gmx::getProgramContext().displayName(),
- gmx_version(), precisionString);
+ sprintf(programInfo, "%.100s %.128s%.24s", gmx::getProgramContext().displayName(), gmx_version(), precisionString);
if (mode == 'w')
{
tng_first_program_name_set(*tng, programInfo);
* number the latter should be used. Wait for TNG 2.0*/
tng_chain_residue_add(tng, tngChain, *resInfo->name, &tngRes);
}
- tng_residue_atom_add(tng, tngRes, *(atoms->atomname[atomIndex]),
- *(atoms->atomtype[atomIndex]), &tngAtom);
+ tng_residue_atom_add(
+ tng, tngRes, *(atoms->atomname[atomIndex]), *(atoms->atomtype[atomIndex]), &tngAtom);
}
}
tng_molecule_cnt_set(tng, *tngMol, numMolecules);
}
for (int molCounter = 1; molCounter < molBlock.nmol; molCounter++)
{
- std::copy_n(atomCharges.end() - molType->atoms.nr, molType->atoms.nr,
+ std::copy_n(atomCharges.end() - molType->atoms.nr,
+ molType->atoms.nr,
std::back_inserter(atomCharges));
- std::copy_n(atomMasses.end() - molType->atoms.nr, molType->atoms.nr,
- std::back_inserter(atomMasses));
+ std::copy_n(atomMasses.end() - molType->atoms.nr, molType->atoms.nr, std::back_inserter(atomMasses));
}
}
/* Write the TNG data blocks. */
- tng_particle_data_block_add(tng, TNG_TRAJ_PARTIAL_CHARGES, "PARTIAL CHARGES", datatype,
- TNG_NON_TRAJECTORY_BLOCK, 1, 1, 1, 0, mtop->natoms,
- TNG_GZIP_COMPRESSION, atomCharges.data());
- tng_particle_data_block_add(tng, TNG_TRAJ_MASSES, "ATOM MASSES", datatype, TNG_NON_TRAJECTORY_BLOCK,
- 1, 1, 1, 0, mtop->natoms, TNG_GZIP_COMPRESSION, atomMasses.data());
+ tng_particle_data_block_add(tng,
+ TNG_TRAJ_PARTIAL_CHARGES,
+ "PARTIAL CHARGES",
+ datatype,
+ TNG_NON_TRAJECTORY_BLOCK,
+ 1,
+ 1,
+ 1,
+ 0,
+ mtop->natoms,
+ TNG_GZIP_COMPRESSION,
+ atomCharges.data());
+ tng_particle_data_block_add(tng,
+ TNG_TRAJ_MASSES,
+ "ATOM MASSES",
+ datatype,
+ TNG_NON_TRAJECTORY_BLOCK,
+ 1,
+ 1,
+ 1,
+ 0,
+ mtop->natoms,
+ TNG_GZIP_COMPRESSION,
+ atomMasses.data());
}
/*! \libinternal \brief Compute greatest common divisor of n1 and n2
/* Define pointers to specific writing functions depending on if we
* write float or double data */
typedef tng_function_status (*set_writing_interval_func_pointer)(
- tng_trajectory_t, const int64_t, const int64_t, const int64_t, const char*, const char,
- const char);
+ tng_trajectory_t, const int64_t, const int64_t, const int64_t, const char*, const char, const char);
# if GMX_DOUBLE
set_writing_interval_func_pointer set_writing_interval = tng_util_generic_write_interval_double_set;
# else
}
if (xout)
{
- set_writing_interval(tng, xout, 3, TNG_TRAJ_POSITIONS, "POSITIONS", TNG_PARTICLE_BLOCK_DATA,
- compression);
+ set_writing_interval(
+ tng, xout, 3, TNG_TRAJ_POSITIONS, "POSITIONS", TNG_PARTICLE_BLOCK_DATA, compression);
/* TODO: if/when we write energies to TNG also, reconsider how
* and when box information is written, because GROMACS
* behaviour pre-5.0 was to write the box with every
}
if (vout)
{
- set_writing_interval(tng, vout, 3, TNG_TRAJ_VELOCITIES, "VELOCITIES",
- TNG_PARTICLE_BLOCK_DATA, compression);
+ set_writing_interval(
+ tng, vout, 3, TNG_TRAJ_VELOCITIES, "VELOCITIES", TNG_PARTICLE_BLOCK_DATA, compression);
gcd = greatest_common_divisor_if_positive(gcd, vout);
if (lowest < 0 || vout < lowest)
}
if (fout)
{
- set_writing_interval(tng, fout, 3, TNG_TRAJ_FORCES, "FORCES", TNG_PARTICLE_BLOCK_DATA,
- TNG_GZIP_COMPRESSION);
+ set_writing_interval(
+ tng, fout, 3, TNG_TRAJ_FORCES, "FORCES", TNG_PARTICLE_BLOCK_DATA, TNG_GZIP_COMPRESSION);
gcd = greatest_common_divisor_if_positive(gcd, fout);
if (lowest < 0 || fout < lowest)
{
/* Lambdas and box shape written at an interval of the lowest common
denominator of other output */
- set_writing_interval(tng, gcd, 1, TNG_GMX_LAMBDA, "LAMBDAS", TNG_NON_PARTICLE_BLOCK_DATA,
- TNG_GZIP_COMPRESSION);
+ set_writing_interval(
+ tng, gcd, 1, TNG_GMX_LAMBDA, "LAMBDAS", TNG_NON_PARTICLE_BLOCK_DATA, TNG_GZIP_COMPRESSION);
- set_writing_interval(tng, gcd, 9, TNG_TRAJ_BOX_SHAPE, "BOX SHAPE",
- TNG_NON_PARTICLE_BLOCK_DATA, TNG_GZIP_COMPRESSION);
+ set_writing_interval(
+ tng, gcd, 9, TNG_TRAJ_BOX_SHAPE, "BOX SHAPE", TNG_NON_PARTICLE_BLOCK_DATA, TNG_GZIP_COMPRESSION);
gmx_tng->lambdaOutputInterval = gcd;
gmx_tng->boxOutputInterval = gcd;
if (gcd < lowest / 10)
"The lowest common denominator of trajectory output is "
"every %d step(s), whereas the shortest output interval "
"is every %d steps.",
- gcd, lowest);
+ gcd,
+ lowest);
}
}
}
* original residue IDs - otherwise there might be conflicts. */
tng_chain_residue_add(tng, chain, res_name, &res);
}
- tng_residue_atom_w_id_add(tng, res, *(atoms->atomname[atomIndex]),
- *(atoms->atomtype[atomIndex]), atom_offset + atomIndex, &atom);
+ tng_residue_atom_w_id_add(tng,
+ res,
+ *(atoms->atomname[atomIndex]),
+ *(atoms->atomtype[atomIndex]),
+ atom_offset + atomIndex,
+ &atom);
bAtomsAdded = TRUE;
}
/* Add bonds. */
int atom1, atom2;
atom1 = ilist.iatoms[l] + atom_offset;
atom2 = ilist.iatoms[l + 1] + atom_offset;
- if (getGroupType(mtop->groups,
- SimulationAtomGroupType::CompressedPositionOutput, atom1)
+ if (getGroupType(mtop->groups, SimulationAtomGroupType::CompressedPositionOutput, atom1)
== 0
- && getGroupType(mtop->groups,
- SimulationAtomGroupType::CompressedPositionOutput, atom2)
+ && getGroupType(mtop->groups, SimulationAtomGroupType::CompressedPositionOutput, atom2)
== 0)
{
- tng_molecule_bond_add(tng, mol, ilist.iatoms[l],
- ilist.iatoms[l + 1], &tngBond);
+ tng_molecule_bond_add(
+ tng, mol, ilist.iatoms[l], ilist.iatoms[l + 1], &tngBond);
}
}
}
const rvec* f)
{
#if GMX_USE_TNG
- typedef tng_function_status (*write_data_func_pointer)(
- tng_trajectory_t, const int64_t, const double, const real*, const int64_t,
- const int64_t, const char*, const char, const char);
+ typedef tng_function_status (*write_data_func_pointer)(tng_trajectory_t,
+ const int64_t,
+ const double,
+ const real*,
+ const int64_t,
+ const int64_t,
+ const char*,
+ const char,
+ const char);
# if GMX_DOUBLE
static write_data_func_pointer write_data = tng_util_generic_with_time_double_write;
# else
{
GMX_ASSERT(box, "Need a non-NULL box if positions are written");
- if (write_data(tng, step, elapsedSeconds, reinterpret_cast<const real*>(x), 3,
- TNG_TRAJ_POSITIONS, "POSITIONS", TNG_PARTICLE_BLOCK_DATA, compression)
+ if (write_data(tng,
+ step,
+ elapsedSeconds,
+ reinterpret_cast<const real*>(x),
+ 3,
+ TNG_TRAJ_POSITIONS,
+ "POSITIONS",
+ TNG_PARTICLE_BLOCK_DATA,
+ compression)
!= TNG_SUCCESS)
{
gmx_file("Cannot write TNG trajectory frame; maybe you are out of disk space?");
if (v)
{
- if (write_data(tng, step, elapsedSeconds, reinterpret_cast<const real*>(v), 3,
- TNG_TRAJ_VELOCITIES, "VELOCITIES", TNG_PARTICLE_BLOCK_DATA, compression)
+ if (write_data(tng,
+ step,
+ elapsedSeconds,
+ reinterpret_cast<const real*>(v),
+ 3,
+ TNG_TRAJ_VELOCITIES,
+ "VELOCITIES",
+ TNG_PARTICLE_BLOCK_DATA,
+ compression)
!= TNG_SUCCESS)
{
gmx_file("Cannot write TNG trajectory frame; maybe you are out of disk space?");
{
/* TNG-MF1 compression only compresses positions and velocities. Use lossless
* compression for forces regardless of output mode */
- if (write_data(tng, step, elapsedSeconds, reinterpret_cast<const real*>(f), 3,
- TNG_TRAJ_FORCES, "FORCES", TNG_PARTICLE_BLOCK_DATA, TNG_GZIP_COMPRESSION)
+ if (write_data(tng,
+ step,
+ elapsedSeconds,
+ reinterpret_cast<const real*>(f),
+ 3,
+ TNG_TRAJ_FORCES,
+ "FORCES",
+ TNG_PARTICLE_BLOCK_DATA,
+ TNG_GZIP_COMPRESSION)
!= TNG_SUCCESS)
{
gmx_file("Cannot write TNG trajectory frame; maybe you are out of disk space?");
{
/* TNG-MF1 compression only compresses positions and velocities. Use lossless
* compression for box shape regardless of output mode */
- if (write_data(tng, step, elapsedSeconds, reinterpret_cast<const real*>(box), 9,
- TNG_TRAJ_BOX_SHAPE, "BOX SHAPE", TNG_NON_PARTICLE_BLOCK_DATA, TNG_GZIP_COMPRESSION)
+ if (write_data(tng,
+ step,
+ elapsedSeconds,
+ reinterpret_cast<const real*>(box),
+ 9,
+ TNG_TRAJ_BOX_SHAPE,
+ "BOX SHAPE",
+ TNG_NON_PARTICLE_BLOCK_DATA,
+ TNG_GZIP_COMPRESSION)
!= TNG_SUCCESS)
{
gmx_file("Cannot write TNG trajectory frame; maybe you are out of disk space?");
{
/* TNG-MF1 compression only compresses positions and velocities. Use lossless
* compression for lambda regardless of output mode */
- if (write_data(tng, step, elapsedSeconds, reinterpret_cast<const real*>(&lambda), 1,
- TNG_GMX_LAMBDA, "LAMBDAS", TNG_NON_PARTICLE_BLOCK_DATA, TNG_GZIP_COMPRESSION)
+ if (write_data(tng,
+ step,
+ elapsedSeconds,
+ reinterpret_cast<const real*>(&lambda),
+ 1,
+ TNG_GMX_LAMBDA,
+ "LAMBDAS",
+ TNG_NON_PARTICLE_BLOCK_DATA,
+ TNG_GZIP_COMPRESSION)
!= TNG_SUCCESS)
{
gmx_file("Cannot write TNG trajectory frame; maybe you are out of disk space?");
#if GMX_USE_TNG
tng_trajectory_t* input = (gmx_tng_input && *gmx_tng_input) ? &(*gmx_tng_input)->tng : nullptr;
/* FIXME after 5.0: Currently only standard block types are read */
- const int defaultNumIds = 5;
- static int64_t fallbackIds[defaultNumIds] = { TNG_TRAJ_BOX_SHAPE, TNG_TRAJ_POSITIONS,
- TNG_TRAJ_VELOCITIES, TNG_TRAJ_FORCES, TNG_GMX_LAMBDA };
- static char fallbackNames[defaultNumIds][32] = { "BOX SHAPE", "POSITIONS", "VELOCITIES",
- "FORCES", "LAMBDAS" };
+ const int defaultNumIds = 5;
+ static int64_t fallbackIds[defaultNumIds] = {
+ TNG_TRAJ_BOX_SHAPE, TNG_TRAJ_POSITIONS, TNG_TRAJ_VELOCITIES, TNG_TRAJ_FORCES, TNG_GMX_LAMBDA
+ };
+ static char fallbackNames[defaultNumIds][32] = {
+ "BOX SHAPE", "POSITIONS", "VELOCITIES", "FORCES", "LAMBDAS"
+ };
typedef tng_function_status (*set_writing_interval_func_pointer)(
- tng_trajectory_t, const int64_t, const int64_t, const int64_t, const char*, const char,
- const char);
+ tng_trajectory_t, const int64_t, const int64_t, const int64_t, const char*, const char, const char);
# if GMX_DOUBLE
set_writing_interval_func_pointer set_writing_interval = tng_util_generic_write_interval_double_set;
# else
{
case TNG_TRAJ_POSITIONS:
case TNG_TRAJ_VELOCITIES:
- set_writing_interval(*output, interval, 3, fallbackIds[i], fallbackNames[i],
- TNG_PARTICLE_BLOCK_DATA, compression_type);
+ set_writing_interval(*output,
+ interval,
+ 3,
+ fallbackIds[i],
+ fallbackNames[i],
+ TNG_PARTICLE_BLOCK_DATA,
+ compression_type);
break;
case TNG_TRAJ_FORCES:
- set_writing_interval(*output, interval, 3, fallbackIds[i], fallbackNames[i],
- TNG_PARTICLE_BLOCK_DATA, TNG_GZIP_COMPRESSION);
+ set_writing_interval(*output,
+ interval,
+ 3,
+ fallbackIds[i],
+ fallbackNames[i],
+ TNG_PARTICLE_BLOCK_DATA,
+ TNG_GZIP_COMPRESSION);
break;
case TNG_TRAJ_BOX_SHAPE:
- set_writing_interval(*output, interval, 9, fallbackIds[i], fallbackNames[i],
- TNG_NON_PARTICLE_BLOCK_DATA, TNG_GZIP_COMPRESSION);
+ set_writing_interval(*output,
+ interval,
+ 9,
+ fallbackIds[i],
+ fallbackNames[i],
+ TNG_NON_PARTICLE_BLOCK_DATA,
+ TNG_GZIP_COMPRESSION);
(*gmx_tng_output)->boxOutputInterval = interval;
break;
case TNG_GMX_LAMBDA:
- set_writing_interval(*output, interval, 1, fallbackIds[i], fallbackNames[i],
- TNG_NON_PARTICLE_BLOCK_DATA, TNG_GZIP_COMPRESSION);
+ set_writing_interval(*output,
+ interval,
+ 1,
+ fallbackIds[i],
+ fallbackNames[i],
+ TNG_NON_PARTICLE_BLOCK_DATA,
+ TNG_GZIP_COMPRESSION);
(*gmx_tng_output)->lambdaOutputInterval = interval;
break;
default: continue;
{
natoms = frame->natoms;
}
- gmx_fwrite_tng(gmx_tng_output, TRUE, frame->step, frame->time, 0, frame->box, natoms, frame->x,
- frame->v, frame->f);
+ gmx_fwrite_tng(
+ gmx_tng_output, TRUE, frame->step, frame->time, 0, frame->box, natoms, frame->x, frame->v, frame->f);
#else
GMX_UNUSED_VALUE(gmx_tng_output);
GMX_UNUSED_VALUE(frame);
double frameTime = -1.0;
int size, blockDependency;
double prec;
- const int defaultNumIds = 5;
- static int64_t fallbackRequestedIds[defaultNumIds] = { TNG_TRAJ_BOX_SHAPE, TNG_TRAJ_POSITIONS,
- TNG_TRAJ_VELOCITIES, TNG_TRAJ_FORCES,
- TNG_GMX_LAMBDA };
+ const int defaultNumIds = 5;
+ static int64_t fallbackRequestedIds[defaultNumIds] = {
+ TNG_TRAJ_BOX_SHAPE, TNG_TRAJ_POSITIONS, TNG_TRAJ_VELOCITIES, TNG_TRAJ_FORCES, TNG_GMX_LAMBDA
+ };
fr->bStep = FALSE;
tng_data_block_dependency_get(input, blockId, &blockDependency);
if (blockDependency & TNG_PARTICLE_DEPENDENT)
{
- stat = tng_util_particle_data_next_frame_read(input, blockId, &values, &datatype,
- &frameNumber, &frameTime);
+ stat = tng_util_particle_data_next_frame_read(
+ input, blockId, &values, &datatype, &frameNumber, &frameTime);
}
else
{
- stat = tng_util_non_particle_data_next_frame_read(input, blockId, &values, &datatype,
- &frameNumber, &frameTime);
+ stat = tng_util_non_particle_data_next_frame_read(
+ input, blockId, &values, &datatype, &frameNumber, &frameTime);
}
if (stat == TNG_CRITICAL)
{
{
convert_array_to_real_array(reinterpret_cast<char*>(values) + size * i * DIM,
reinterpret_cast<real*>(fr->box[i]),
- getDistanceScaleFactor(gmx_tng_input), 1, DIM, datatype);
+ getDistanceScaleFactor(gmx_tng_input),
+ 1,
+ DIM,
+ datatype);
}
fr->bBox = TRUE;
break;
case TNG_TRAJ_POSITIONS:
srenew(fr->x, fr->natoms);
- convert_array_to_real_array(values, reinterpret_cast<real*>(fr->x),
- getDistanceScaleFactor(gmx_tng_input), fr->natoms, DIM,
+ convert_array_to_real_array(values,
+ reinterpret_cast<real*>(fr->x),
+ getDistanceScaleFactor(gmx_tng_input),
+ fr->natoms,
+ DIM,
datatype);
fr->bX = TRUE;
tng_util_frame_current_compression_get(input, blockId, &codecId, &prec);
break;
case TNG_TRAJ_VELOCITIES:
srenew(fr->v, fr->natoms);
- convert_array_to_real_array(values, reinterpret_cast<real*>(fr->v),
- getDistanceScaleFactor(gmx_tng_input), fr->natoms, DIM,
+ convert_array_to_real_array(values,
+ reinterpret_cast<real*>(fr->v),
+ getDistanceScaleFactor(gmx_tng_input),
+ fr->natoms,
+ DIM,
datatype);
fr->bV = TRUE;
tng_util_frame_current_compression_get(input, blockId, &codecId, &prec);
break;
case TNG_TRAJ_FORCES:
srenew(fr->f, fr->natoms);
- convert_array_to_real_array(values, reinterpret_cast<real*>(fr->f),
- getDistanceScaleFactor(gmx_tng_input), fr->natoms, DIM,
+ convert_array_to_real_array(values,
+ reinterpret_cast<real*>(fr->f),
+ getDistanceScaleFactor(gmx_tng_input),
+ fr->natoms,
+ DIM,
datatype);
fr->bF = TRUE;
break;
}
tng_num_particles_get(input, &nAtoms);
- stat = tng_particle_data_vector_get(input, TNG_TRAJ_PARTIAL_CHARGES, &data, &nFramesRead,
- &strideLength, &nParticlesRead, &nValuesPerFrameRead, &datatype);
+ stat = tng_particle_data_vector_get(input,
+ TNG_TRAJ_PARTIAL_CHARGES,
+ &data,
+ &nFramesRead,
+ &strideLength,
+ &nParticlesRead,
+ &nValuesPerFrameRead,
+ &datatype);
if (stat == TNG_SUCCESS)
{
atomCharges.resize(nAtoms);
}
}
- stat = tng_particle_data_vector_get(input, TNG_TRAJ_MASSES, &data, &nFramesRead, &strideLength,
- &nParticlesRead, &nValuesPerFrameRead, &datatype);
+ stat = tng_particle_data_vector_get(
+ input, TNG_TRAJ_MASSES, &data, &nFramesRead, &strideLength, &nParticlesRead, &nValuesPerFrameRead, &datatype);
if (stat == TNG_SUCCESS)
{
atomMasses.resize(nAtoms);
if (blockDependency & TNG_PARTICLE_DEPENDENT)
{
tng_num_particles_get(input, nAtoms);
- stat = tng_util_particle_data_next_frame_read(input, blockId, &data, &datatype, frameNumber,
- frameTime);
+ stat = tng_util_particle_data_next_frame_read(
+ input, blockId, &data, &datatype, frameNumber, frameTime);
}
else
{
*nAtoms = 1; /* There are not actually any atoms, but it is used for
allocating memory */
- stat = tng_util_non_particle_data_next_frame_read(input, blockId, &data, &datatype,
- frameNumber, frameTime);
+ stat = tng_util_non_particle_data_next_frame_read(
+ input, blockId, &data, &datatype, frameNumber, frameTime);
}
if (stat == TNG_CRITICAL)
{
gmx_file("Cannot read next frame of TNG file");
}
srenew(*values, sizeof(real) * *nValuesPerFrame * *nAtoms);
- convert_array_to_real_array(data, *values, getDistanceScaleFactor(gmx_tng_input), *nAtoms,
- *nValuesPerFrame, datatype);
+ convert_array_to_real_array(
+ data, *values, getDistanceScaleFactor(gmx_tng_input), *nAtoms, *nValuesPerFrame, datatype);
tng_util_frame_current_compression_get(input, blockId, &codecId, &localPrec);
/* This file is completely threadsafe - keep it that way! */
-#include "tpxio.h"
+#include "gromacs/fileio/tpxio.h"
#include <cstdio>
#include <cstdlib>
tpxv_StoreNonBondedInteractionExclusionGroup, /**< Store the non bonded interaction exclusion group in the topology */
tpxv_VSite1, /**< Added 1 type virtual site */
tpxv_MTS, /**< Added multiple time stepping */
- tpxv_Count /**< the total number of tpxv versions */
+ tpxv_RemovedConstantAcceleration, /**< Removed support for constant acceleration NEMD. */
+ tpxv_Count /**< the total number of tpxv versions */
};
/*! \brief Version number of the file format written to run input
serializer->doInt(&ir->ljpme_combination_rule);
}
serializer->doBool(&ir->bContinuation);
- serializer->doInt(&ir->etc);
+ serializer->doEnumAsInt(&ir->etc);
/* before version 18, ir->etc was a gmx_bool (ir->btc),
* but the values 0 and 1 still mean no and
* berendsen temperature coupling, respectively.
{
ir->nsttcouple = ir->nstcalcenergy;
}
- serializer->doInt(&ir->epc);
+ serializer->doEnumAsInt(&ir->epc);
serializer->doInt(&ir->epct);
if (file_version >= 71)
{
{
ir->opts.nhchainlength = 1;
}
- serializer->doInt(&ir->opts.ngacc);
+ int removedOptsNgacc = 0;
+ if (serializer->reading() && file_version < tpxv_RemovedConstantAcceleration)
+ {
+ serializer->doInt(&removedOptsNgacc);
+ }
serializer->doInt(&ir->opts.ngfrz);
serializer->doInt(&ir->opts.ngener);
snew(ir->opts.anneal_temp, ir->opts.ngtc);
snew(ir->opts.tau_t, ir->opts.ngtc);
snew(ir->opts.nFreeze, ir->opts.ngfrz);
- snew(ir->opts.acc, ir->opts.ngacc);
snew(ir->opts.egp_flags, ir->opts.ngener * ir->opts.ngener);
}
if (ir->opts.ngtc > 0)
{
serializer->doIvecArray(ir->opts.nFreeze, ir->opts.ngfrz);
}
- if (ir->opts.ngacc > 0)
+ if (serializer->reading() && file_version < tpxv_RemovedConstantAcceleration && removedOptsNgacc > 0)
+ {
+ std::vector<gmx::RVec> dummy;
+ dummy.resize(removedOptsNgacc);
+ serializer->doRvecArray(reinterpret_cast<rvec*>(dummy.data()), removedOptsNgacc);
+ ir->useConstantAcceleration = std::any_of(dummy.begin(), dummy.end(), [](const gmx::RVec& vec) {
+ return vec[XX] != 0.0 || vec[YY] != 0.0 || vec[ZZ] != 0.0;
+ });
+ }
+ else
{
- serializer->doRvecArray(ir->opts.acc, ir->opts.ngacc);
+ ir->useConstantAcceleration = false;
}
serializer->doIntArray(ir->opts.egp_flags, ir->opts.ngener * ir->opts.ngener);
serializer->doInt(&iparams->cmap.cmapB);
break;
default:
- gmx_fatal(FARGS, "unknown function type %d (%s) in %s line %d", ftype,
- interaction_function[ftype].name, __FILE__, __LINE__);
+ gmx_fatal(FARGS,
+ "unknown function type %d (%s) in %s line %d",
+ ftype,
+ interaction_function[ftype].name,
+ __FILE__,
+ __LINE__);
}
}
}
do_groups(serializer, &mtop->groups, &(mtop->symtab));
+ if (file_version < tpxv_RemovedConstantAcceleration)
+ {
+ mtop->groups.groups[SimulationAtomGroupType::AccelerationUnused].clear();
+ mtop->groups.groupNumbers[SimulationAtomGroupType::AccelerationUnused].clear();
+ }
mtop->haveMoleculeIndices = true;
gmx_fatal(FARGS,
"Unknown precision in file %s: real is %d bytes "
"instead of %zu or %zu",
- filename, precision, sizeof(float), sizeof(double));
+ filename,
+ precision,
+ sizeof(float),
+ sizeof(double));
}
gmx_fio_setprecision(fio, tpx->isDouble);
- fprintf(stderr, "Reading file %s, %s (%s precision)\n", filename, buf.c_str(),
+ fprintf(stderr,
+ "Reading file %s, %s (%s precision)\n",
+ filename,
+ buf.c_str(),
tpx->isDouble ? "double" : "single");
}
else
gmx_fatal(FARGS,
"tpx tag/version mismatch: reading tpx file (%s) version %d, tag '%s' "
"with program for tpx version %d, tag '%s'",
- filename, tpx->fileVersion, fileTag.c_str(), tpx_version, tpx_tag);
+ filename,
+ tpx->fileVersion,
+ fileTag.c_str(),
+ tpx_version,
+ tpx_tag);
}
}
}
|| ((tpx->fileVersion > tpx_version) && !TopOnlyOK) || (tpx->fileGeneration > tpx_generation)
|| tpx_version == 80) /*80 was used by both 5.0-dev and 4.6-dev*/
{
- gmx_fatal(FARGS, "reading tpx file (%s) version %d with version %d program", filename,
- tpx->fileVersion, tpx_version);
+ gmx_fatal(FARGS,
+ "reading tpx file (%s) version %d with version %d program",
+ filename,
+ tpx->fileVersion,
+ tpx_version);
}
serializer->doInt(&tpx->natoms);
// TPR file for now - and thus we ask the serializer to swap if this host is little endian.
gmx::InMemorySerializer tprBodySerializer(gmx::EndianSwapBehavior::SwapIfHostIsLittleEndian);
- do_tpx_body(&tprBodySerializer, &tpx, const_cast<t_inputrec*>(ir), const_cast<t_state*>(state),
- nullptr, nullptr, const_cast<gmx_mtop_t*>(mtop));
+ do_tpx_body(&tprBodySerializer,
+ &tpx,
+ const_cast<t_inputrec*>(ir),
+ const_cast<t_state*>(state),
+ nullptr,
+ nullptr,
+ const_cast<gmx_mtop_t*>(mtop));
std::vector<char> tprBody = tprBodySerializer.finishAndGetBuffer();
tpx.sizeOfTprBody = tprBody.size();
const rvec* f)
{
t_fileio* fio = gmx_trr_open(fn, "w");
- do_trr_frame(fio, false, &step, &t, &lambda, const_cast<rvec*>(box), &natoms,
- const_cast<rvec*>(x), const_cast<rvec*>(v), const_cast<rvec*>(f));
+ do_trr_frame(fio,
+ false,
+ &step,
+ &t,
+ &lambda,
+ const_cast<rvec*>(box),
+ &natoms,
+ const_cast<rvec*>(x),
+ const_cast<rvec*>(v),
+ const_cast<rvec*>(f));
gmx_trr_close(fio);
}
const rvec* v,
const rvec* f)
{
- if (!do_trr_frame(fio, false, &step, &t, &lambda, const_cast<rvec*>(box), &natoms,
- const_cast<rvec*>(x), const_cast<rvec*>(v), const_cast<rvec*>(f)))
+ if (!do_trr_frame(fio,
+ false,
+ &step,
+ &t,
+ &lambda,
+ const_cast<rvec*>(box),
+ &natoms,
+ const_cast<rvec*>(x),
+ const_cast<rvec*>(v),
+ const_cast<rvec*>(f)))
{
gmx_file("Cannot write trajectory frame; maybe you are out of disk space?");
}
*/
#include "gmxpre.h"
-#include "trxio.h"
+#include "gromacs/fileio/trxio.h"
#include "config.h"
}
if (debug)
{
- fprintf(debug, "t=%g, t0=%g, b=%g, e=%g, dt=%g: r=%d\n", t, t0, rTimeValue(TBEGIN),
- rTimeValue(TEND), rTimeValue(TDELTA), r);
+ fprintf(debug,
+ "t=%g, t0=%g, b=%g, e=%g, dt=%g: r=%d\n",
+ t,
+ t0,
+ rTimeValue(TBEGIN),
+ rTimeValue(TEND),
+ rTimeValue(TDELTA),
+ r);
}
return r;
}
if (filetype == efXTC)
{
- lasttime = xdr_xtc_get_last_frame_time(gmx_fio_getfp(stfio), gmx_fio_getxdr(stfio),
- status->natoms, &bOK);
+ lasttime = xdr_xtc_get_last_frame_time(
+ gmx_fio_getfp(stfio), gmx_fio_getxdr(stfio), status->natoms, &bOK);
if (!bOK)
{
gmx_fatal(FARGS, "Error reading last frame. Maybe seek not supported.");
case efTNG: gmx_write_tng_from_trxframe(status->tng, fr, nind); break;
case efXTC: write_xtc(status->fio, nind, fr->step, fr->time, fr->box, xout, prec); break;
case efTRR:
- gmx_trr_write_frame(status->fio, nframes_read(status), fr->time, fr->step, fr->box,
- nind, xout, vout, fout);
+ gmx_trr_write_frame(
+ status->fio, nframes_read(status), fr->time, fr->step, fr->box, nind, xout, vout, fout);
break;
case efGRO:
case efPDB:
sprintf(title, "frame t= %.3f", fr->time);
if (ftp == efGRO)
{
- write_hconf_indexed_p(gmx_fio_getfp(status->fio), title, fr->atoms, nind, ind,
- fr->x, fr->bV ? fr->v : nullptr, fr->box);
+ write_hconf_indexed_p(gmx_fio_getfp(status->fio),
+ title,
+ fr->atoms,
+ nind,
+ ind,
+ fr->x,
+ fr->bV ? fr->v : nullptr,
+ fr->box);
}
else
{
- write_pdbfile_indexed(gmx_fio_getfp(status->fio), title, fr->atoms, fr->x,
- PbcType::Unset, fr->box, ' ', fr->step, nind, ind, gc, FALSE);
+ write_pdbfile_indexed(gmx_fio_getfp(status->fio),
+ title,
+ fr->atoms,
+ fr->x,
+ PbcType::Unset,
+ fr->box,
+ ' ',
+ fr->step,
+ nind,
+ ind,
+ gc,
+ FALSE);
}
break;
case efG96:
if (in != nullptr)
{
- gmx_prepare_tng_writing(filename, filemode, &in->tng, &out->tng, natoms, mtop, index,
- index_group_name);
+ gmx_prepare_tng_writing(
+ filename, filemode, &in->tng, &out->tng, natoms, mtop, index, index_group_name);
}
else if ((infile) && (efTNG == fn2ftp(infile)))
{
gmx_tng_trajectory_t tng_in;
gmx_tng_open(infile, 'r', &tng_in);
- gmx_prepare_tng_writing(filename, filemode, &tng_in, &out->tng, natoms, mtop, index,
- index_group_name);
+ gmx_prepare_tng_writing(
+ filename, filemode, &tng_in, &out->tng, natoms, mtop, index, index_group_name);
}
else
{
// we start from a file that is not a tng file or have been unable to load the
// input file, so we need to populate the fields independently of it
- gmx_prepare_tng_writing(filename, filemode, nullptr, &out->tng, natoms, mtop, index,
- index_group_name);
+ gmx_prepare_tng_writing(
+ filename, filemode, nullptr, &out->tng, natoms, mtop, index, index_group_name);
}
return out;
}
default:
if (!fr->bX)
{
- gmx_fatal(FARGS, "Need coordinates to write a %s trajectory",
+ gmx_fatal(FARGS,
+ "Need coordinates to write a %s trajectory",
ftp2ext(gmx_fio_getftp(status->fio)));
}
break;
write_xtc(status->fio, fr->natoms, fr->step, fr->time, fr->box, fr->x, prec);
break;
case efTRR:
- gmx_trr_write_frame(status->fio, fr->step, fr->time, fr->lambda, fr->box, fr->natoms,
- fr->bX ? fr->x : nullptr, fr->bV ? fr->v : nullptr,
+ gmx_trr_write_frame(status->fio,
+ fr->step,
+ fr->time,
+ fr->lambda,
+ fr->box,
+ fr->natoms,
+ fr->bX ? fr->x : nullptr,
+ fr->bV ? fr->v : nullptr,
fr->bF ? fr->f : nullptr);
break;
case efGRO:
case efENT:
if (!fr->bAtoms)
{
- gmx_fatal(FARGS, "Can not write a %s file without atom names",
+ gmx_fatal(FARGS,
+ "Can not write a %s file without atom names",
ftp2ext(gmx_fio_getftp(status->fio)));
}
sprintf(title, "frame t= %.3f", fr->time);
if (gmx_fio_getftp(status->fio) == efGRO)
{
- write_hconf_p(gmx_fio_getfp(status->fio), title, fr->atoms, fr->x,
- fr->bV ? fr->v : nullptr, fr->box);
+ write_hconf_p(
+ gmx_fio_getfp(status->fio), title, fr->atoms, fr->x, fr->bV ? fr->v : nullptr, fr->box);
}
else
{
- write_pdbfile(gmx_fio_getfp(status->fio), title, fr->atoms, fr->x,
- fr->bPBC ? fr->pbcType : PbcType::Unset, fr->box, ' ', fr->step, gc);
+ write_pdbfile(gmx_fio_getfp(status->fio),
+ title,
+ fr->atoms,
+ fr->x,
+ fr->bPBC ? fr->pbcType : PbcType::Unset,
+ fr->box,
+ ' ',
+ fr->step,
+ gc);
}
break;
case efG96: write_g96_conf(gmx_fio_getfp(status->fio), title, fr, -1, nullptr); break;
default:
- gmx_fatal(FARGS, "Sorry, write_trxframe can not write %s",
- ftp2ext(gmx_fio_getftp(status->fio)));
+ gmx_fatal(FARGS, "Sorry, write_trxframe can not write %s", ftp2ext(gmx_fio_getftp(status->fio)));
}
return 0;
{
if (na != fr->natoms)
{
- gmx_fatal(FARGS, "Number of atoms in pdb frame %d is %d instead of %d",
- nframes_read(status), na, fr->natoms);
+ gmx_fatal(FARGS,
+ "Number of atoms in pdb frame %d is %d instead of %d",
+ nframes_read(status),
+ na,
+ fr->natoms);
}
return TRUE;
}
case efG96:
{
t_symtab* symtab = nullptr;
- read_g96_conf(gmx_fio_getfp(status->fio), nullptr, nullptr, fr, symtab,
- status->persistent_line);
+ read_g96_conf(gmx_fio_getfp(status->fio), nullptr, nullptr, fr, symtab, status->persistent_line);
bRet = (fr->natoms > 0);
break;
}
}
initcount(status);
}
- bRet = (read_next_xtc(status->fio, fr->natoms, &fr->step, &fr->time, fr->box, fr->x,
- &fr->prec, &bOK)
+ bRet = (read_next_xtc(
+ status->fio, fr->natoms, &fr->step, &fr->time, fr->box, fr->x, &fr->prec, &bOK)
!= 0);
fr->bPrec = (bRet && fr->prec > 0);
fr->bStep = bRet;
#if GMX_USE_PLUGINS
bRet = read_next_vmd_frame(status->vmdplugin, fr);
#else
- gmx_fatal(FARGS, "DEATH HORROR in read_next_frame ftp=%s,status=%s",
- ftp2ext(gmx_fio_getftp(status->fio)), gmx_fio_getname(status->fio));
+ gmx_fatal(FARGS,
+ "DEATH HORROR in read_next_frame ftp=%s,status=%s",
+ ftp2ext(gmx_fio_getftp(status->fio)),
+ gmx_fio_getname(status->fio));
#endif
}
status->tf = fr->time;
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2009-2018, The GROMACS development team.
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
{
if (debug)
{
- fprintf(debug, "\nUnable to open dynamic library %s.\n%s\n", fullpath,
- vmddlerror()); /*only to debug because of stdc++ erros */
+ fprintf(debug, "\nUnable to open dynamic library %s.\n%s\n", fullpath, vmddlerror()); /*only to debug because of stdc++ erros */
}
return 0;
}
{
if (wi->lineno != -1)
{
- fprintf(stderr, "\n%s %d [file %s, line %d]:\n%s\n\n", wtype, n, wi->filenm.c_str(),
- wi->lineno, temp2);
+ fprintf(stderr, "\n%s %d [file %s, line %d]:\n%s\n\n", wtype, n, wi->filenm.c_str(), wi->lineno, temp2);
}
else
{
print_warn_count("note", wi->nwarn_note);
print_warn_count("warning", wi->nwarn_warn);
- gmx_fatal(f_errno, file, line, "There %s %d error%s in input file(s)",
- (wi->nwarn_error == 1) ? "was" : "were", wi->nwarn_error, (wi->nwarn_error == 1) ? "" : "s");
+ gmx_fatal(f_errno,
+ file,
+ line,
+ "There %s %d error%s in input file(s)",
+ (wi->nwarn_error == 1) ? "was" : "were",
+ wi->nwarn_error,
+ (wi->nwarn_error == 1) ? "" : "s");
}
void check_warning_error(warninp_t wi, int f_errno, const char* file, int line)
if (wi->maxwarn >= 0 && wi->nwarn_warn > wi->maxwarn)
{
- gmx_fatal(f_errno, file, line,
+ gmx_fatal(f_errno,
+ file,
+ line,
"Too many warnings (%d).\n"
"If you are sure all warnings are harmless, use the -maxwarn option.",
wi->nwarn_warn);
fprintf(ps->fp,
"/by {def currentpoint "
"%g y r %g %g r %g y neg r %g %g r f y add moveto} bind def\n",
- 0.0, xbox, 0.0, 0.0, -xbox, 0.0);
+ 0.0,
+ xbox,
+ 0.0,
+ 0.0,
+ -xbox,
+ 0.0);
/* macro bn is used in ps_rgb_nbox to draw rectangular boxes */
}
fprintf(ps->fp,
"/b {currentpoint "
"%g %g r %g %g r %g %g r %g %g r f %g add moveto} bind def\n",
- 0.0, ybox, xbox, 0.0, 0.0, -ybox, -xbox, 0.0, ybox);
+ 0.0,
+ ybox,
+ xbox,
+ 0.0,
+ 0.0,
+ -ybox,
+ -xbox,
+ 0.0,
+ ybox);
/* macro b is used in search_col to define macro B */
}
void ps_arcslice(t_psdata* ps, real xc, real yc, real rad1, real rad2, real a0, real a1)
{
- fprintf(ps->fp, "newpath %g %g %g %g %g arc %g %g %g %g %g arcn closepath s\n", xc, yc, rad1,
- a0, a1, xc, yc, rad2, a1, a0);
+ fprintf(ps->fp, "newpath %g %g %g %g %g arc %g %g %g %g %g arcn closepath s\n", xc, yc, rad1, a0, a1, xc, yc, rad2, a1, a0);
}
void ps_fillarcslice(t_psdata* ps, real xc, real yc, real rad1, real rad2, real a0, real a1)
{
- fprintf(ps->fp, "newpath %g %g %g %g %g arc %g %g %g %g %g arcn closepath f\n", xc, yc, rad1,
- a0, a1, xc, yc, rad2, a1, a0);
+ fprintf(ps->fp, "newpath %g %g %g %g %g arc %g %g %g %g %g arcn closepath f\n", xc, yc, rad1, a0, a1, xc, yc, rad2, a1, a0);
}
void ps_circle(t_psdata* ps, real x1, real y1, real rad)
fprintf(debug,
"\nXTC error: read/write of %s failed, "
"source file %s, line %d\n",
- str, file, line);
+ str,
+ file,
+ line);
}
return 0;
}
}
/* write data */
- bOK = xtc_coord(xd, &natoms, const_cast<rvec*>(box), const_cast<rvec*>(x), &prec,
- FALSE); /* bOK will be 1 if writing went well */
+ bOK = xtc_coord(xd, &natoms, const_cast<rvec*>(box), const_cast<rvec*>(x), &prec, FALSE); /* bOK will be 1 if writing went well */
if (bOK)
{
gmx_fatal(FARGS,
"Output buffer length in xvgstr (%d) too small to process xvg input string "
"'%s'",
- buflen, gmx.c_str());
+ buflen,
+ gmx.c_str());
}
if (gmx[g] == '\\')
{
"@ world ymin %g\n"
"@ world xmax %g\n"
"@ world ymax %g\n",
- xmin, ymin, xmax, ymax);
+ xmin,
+ ymin,
+ xmax,
+ ymax);
}
}
{
if (output_env_get_xvg_format(oenv) == XvgFormat::Xmgr)
{
- fprintf(out, "@ legend string %d \"%s\"\n", i + nr_first,
+ fprintf(out,
+ "@ legend string %d \"%s\"\n",
+ i + nr_first,
xvgrstr(setname[i], oenv, buf, STRLEN));
}
else
{
- fprintf(out, "@ s%d legend \"%s\"\n", i + nr_first,
- xvgrstr(setname[i], oenv, buf, STRLEN));
+ fprintf(out, "@ s%d legend \"%s\"\n", i + nr_first, xvgrstr(setname[i], oenv, buf, STRLEN));
}
}
}
fprintf(stderr,
"Invalid line in %s:\n%s"
"Using zeros for the last %d sets\n",
- fn, line0, narg - a);
+ fn,
+ line0,
+ narg - a);
}
n++;
}
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2013,2014,2015,2017,2019, by the GROMACS development team, led by
+# Copyright (c) 2013,2014,2015,2017,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.
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+# Set up the module library
+add_library(gmxana INTERFACE)
+
file(GLOB GMXANA_SOURCES *.cpp)
set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${GMXANA_SOURCES} PARENT_SCOPE)
+# Source files have the following private module dependencies.
+target_link_libraries(gmxana PRIVATE
+ )
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(gmxana PUBLIC
+target_include_directories(gmxana INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(gmxana PUBLIC
+target_link_libraries(gmxana INTERFACE
+ legacy_api
+ )
+
+# TODO: when gmxana is an OBJECT target
+#target_link_libraries(gmxana PUBLIC legacy_api)
+#target_link_libraries(gmxana PRIVATE common)
+
+# Module dependencies
+# gmxana interfaces convey transitive dependence on these modules.
+#target_link_libraries(gmxana PUBLIC
+target_link_libraries(gmxana INTERFACE
+ utility
+ )
+
if(BUILD_TESTING)
add_subdirectory(tests)
endif()
multiplicity[k] = 3;
}
- low_ana_dih_trans(TRUE, fn_trans, TRUE, fn_histo, maxchi, dih, nlist, dlist, nframes, nangles,
- grpname, multiplicity, time, bRb, 0.5, oenv);
+ low_ana_dih_trans(
+ TRUE, fn_trans, TRUE, fn_histo, maxchi, dih, nlist, dlist, nframes, nangles, grpname, multiplicity, time, bRb, 0.5, oenv);
sfree(dlist);
sfree(multiplicity);
}
if (bAll)
{
/* print cuml rotamer vs time */
- print_one(oenv, "chiproduct", dlist[i].name, "chi product for",
- "cumulative rotamer", nframes, time, chi_prtrj);
+ print_one(oenv, "chiproduct", dlist[i].name, "chi product for", "cumulative rotamer", nframes, time, chi_prtrj);
}
/* make a histogram pf culm. rotamer occupancy too */
for (i = ix = 0; (ix < n3); i++, ix += 3)
{
- ang[i] = bond_angle(x_s[index[ix]], x_s[index[ix + 1]], x_s[index[ix + 2]], pbc, r_ij, r_kj,
- &costh, &t1, &t2);
+ ang[i] = bond_angle(
+ x_s[index[ix]], x_s[index[ix + 1]], x_s[index[ix + 2]], pbc, r_ij, r_kj, &costh, &t1, &t2);
}
if (debug)
{
- fprintf(debug, "Angle[0]=%g, costh=%g, index0 = %d, %d, %d\n", ang[0], costh, index[0],
- index[1], index[2]);
+ fprintf(debug, "Angle[0]=%g, costh=%g, index0 = %d, %d, %d\n", ang[0], costh, index[0], index[1], index[2]);
pr_rvec(debug, 0, "rij", r_ij, DIM, TRUE);
pr_rvec(debug, 0, "rkj", r_kj, DIM, TRUE);
}
for (i = ix = 0; (ix < n4); i++, ix += 4)
{
- aaa = dih_angle(x_s[index[ix]], x_s[index[ix + 1]], x_s[index[ix + 2]], x_s[index[ix + 3]],
- pbc, r_ij, r_kj, r_kl, m, n, &t1, &t2, &t3);
+ aaa = dih_angle(x_s[index[ix]],
+ x_s[index[ix + 1]],
+ x_s[index[ix + 2]],
+ x_s[index[ix + 3]],
+ pbc,
+ r_ij,
+ r_kj,
+ r_kl,
+ m,
+ n,
+ &t1,
+ &t2,
+ &t3);
ang[i] = aaa; /* not taking into account ryckaert bellemans yet */
}
dx = npoints / (maxx - minx);
if (debug)
{
- fprintf(debug, "Histogramming: ndata=%d, nhisto=%d, minx=%g,maxx=%g,dx=%g\n", ndata,
- npoints, minx, maxx, dx);
+ fprintf(debug, "Histogramming: ndata=%d, nhisto=%d, minx=%g,maxx=%g,dx=%g\n", ndata, npoints, minx, maxx, dx);
}
for (i = 0; (i < ndata); i++)
{
fprintf(debug,
"Could not find N atom but could find other atoms"
" in residue %s%d\n",
- thisres, ires + r0);
+ thisres,
+ ires + r0);
}
}
fprintf(stderr, "\n");
}
if (bPhi)
{
- fprintf(fp, " Phi [%5d,%5d,%5d,%5d]",
- (dl[i].atm.H == -1) ? 1 + dl[i].atm.minC : 1 + dl[i].atm.H, 1 + dl[i].atm.N,
- 1 + dl[i].atm.Cn[1], 1 + dl[i].atm.C);
+ fprintf(fp,
+ " Phi [%5d,%5d,%5d,%5d]",
+ (dl[i].atm.H == -1) ? 1 + dl[i].atm.minC : 1 + dl[i].atm.H,
+ 1 + dl[i].atm.N,
+ 1 + dl[i].atm.Cn[1],
+ 1 + dl[i].atm.C);
pr_props(fp, &dl[i], edPhi, dt);
}
if (bPsi)
{
- fprintf(fp, " Psi [%5d,%5d,%5d,%5d]", 1 + dl[i].atm.N, 1 + dl[i].atm.Cn[1],
- 1 + dl[i].atm.C, 1 + dl[i].atm.O);
+ fprintf(fp,
+ " Psi [%5d,%5d,%5d,%5d]",
+ 1 + dl[i].atm.N,
+ 1 + dl[i].atm.Cn[1],
+ 1 + dl[i].atm.C,
+ 1 + dl[i].atm.O);
pr_props(fp, &dl[i], edPsi, dt);
}
if (bOmega && has_dihedral(edOmega, &(dl[i])))
{
- fprintf(fp, " Omega [%5d,%5d,%5d,%5d]", 1 + dl[i].atm.minCalpha, 1 + dl[i].atm.minC,
- 1 + dl[i].atm.N, 1 + dl[i].atm.Cn[1]);
+ fprintf(fp,
+ " Omega [%5d,%5d,%5d,%5d]",
+ 1 + dl[i].atm.minCalpha,
+ 1 + dl[i].atm.minC,
+ 1 + dl[i].atm.N,
+ 1 + dl[i].atm.Cn[1]);
pr_props(fp, &dl[i], edOmega, dt);
}
for (Xi = 0; Xi < MAXCHI; Xi++)
{
if (bChi && (Xi < maxchi) && (dl[i].atm.Cn[Xi + 3] != -1))
{
- fprintf(fp, " Chi%d[%5d,%5d,%5d,%5d]", Xi + 1, 1 + dl[i].atm.Cn[Xi],
- 1 + dl[i].atm.Cn[Xi + 1], 1 + dl[i].atm.Cn[Xi + 2], 1 + dl[i].atm.Cn[Xi + 3]);
+ fprintf(fp,
+ " Chi%d[%5d,%5d,%5d,%5d]",
+ Xi + 1,
+ 1 + dl[i].atm.Cn[Xi],
+ 1 + dl[i].atm.Cn[Xi + 1],
+ 1 + dl[i].atm.Cn[Xi + 2],
+ 1 + dl[i].atm.Cn[Xi + 3]);
pr_props(fp, &dl[i], Xi + edChi1, dt); /* Xi+2 was wrong here */
}
}
*bFit = (head.lambda > -0.5);
if (*bFit)
{
- fprintf(stderr, "Read %smass weighted reference structure with %d atoms from %s\n",
- *bDMR ? "" : "non ", *natoms, file);
+ fprintf(stderr,
+ "Read %smass weighted reference structure with %d atoms from %s\n",
+ *bDMR ? "" : "non ",
+ *natoms,
+ file);
}
else
{
}
else
{
- fprintf(stderr, "Read %smass weighted average/minimum structure with %d atoms from %s\n",
- *bDMA ? "" : "non ", *natoms, file);
+ fprintf(stderr,
+ "Read %smass weighted average/minimum structure with %d atoms from %s\n",
+ *bDMA ? "" : "non ",
+ *natoms,
+ file);
}
snew(x, *natoms);
clear_mat(zerobox);
snew(x, natoms);
- fprintf(stderr, "\nWriting %saverage structure & eigenvectors %d--%d to %s\n",
- (WriteXref == eWXR_YES) ? "reference, " : "", begin, end, trrname);
+ fprintf(stderr,
+ "\nWriting %saverage structure & eigenvectors %d--%d to %s\n",
+ (WriteXref == eWXR_YES) ? "reference, " : "",
+ begin,
+ end,
+ trrname);
trrout = gmx_trr_open(trrname, "w");
if (WriteXref == eWXR_YES)
mass[ai] = 10.0;
/*#define DEBUG*/
#ifdef DEBUG
- fprintf(stderr, "%5d %8.3f %8.3f %8.3f %8.3f %8.3f %8.3f\n", ai, x[ai][XX], x[ai][YY],
- x[ai][ZZ], xref[ai][XX], xref[ai][YY], xref[ai][ZZ]);
+ fprintf(stderr,
+ "%5d %8.3f %8.3f %8.3f %8.3f %8.3f %8.3f\n",
+ ai,
+ x[ai][XX],
+ x[ai][YY],
+ x[ai][ZZ],
+ xref[ai][XX],
+ xref[ai][YY],
+ xref[ai][ZZ]);
#endif
phi0 += tw;
}
fprintf(stdout, "Trace of the two matrices: %g and %g\n", sum1, sum2);
if (neig1 != n || neig2 != n)
{
- fprintf(stdout, "this is %d%% and %d%% of the total trace\n",
- gmx::roundToInt(100 * sum1 / trace1), gmx::roundToInt(100 * sum2 / trace2));
+ fprintf(stdout,
+ "this is %d%% and %d%% of the total trace\n",
+ gmx::roundToInt(100 * sum1 / trace1),
+ gmx::roundToInt(100 * sum2 / trace2));
}
fprintf(stdout, "Square root of the traces: %g and %g\n", std::sqrt(sum1), std::sqrt(sum2));
rhi.b = 0;
nlevels = 41;
out = gmx_ffopen(matfile, "w");
- write_xpm(out, 0, "Eigenvector inner-products", "in.prod.", "run 1", "run 2", nx, ny, t_x, t_y,
- mat, 0.0, maxval, rlo, rhi, &nlevels);
+ write_xpm(out, 0, "Eigenvector inner-products", "in.prod.", "run 1", "run 2", nx, ny, t_x, t_y, mat, 0.0, maxval, rlo, rhi, &nlevels);
gmx_ffclose(out);
}
gmx_fatal(FARGS,
"the number of atoms in your trajectory (%d) is larger than the number of "
"atoms in your structure file (%d)",
- nat, atoms->nr);
+ nat,
+ atoms->nr);
}
snew(all_at, nat);
ylabel[v] = gmx_strdup(str);
}
sprintf(str, "projection on eigenvectors (%s)", proj_unit);
- write_xvgr_graphs(projfile, noutvec, 1, str, nullptr, output_env_get_xvgr_tlabel(oenv),
- ylabel, nframes, inprod[noutvec], inprod, nullptr,
- output_env_get_time_factor(oenv), FALSE, bSplit, oenv);
+ write_xvgr_graphs(projfile,
+ noutvec,
+ 1,
+ str,
+ nullptr,
+ output_env_get_xvgr_tlabel(oenv),
+ ylabel,
+ nframes,
+ inprod[noutvec],
+ inprod,
+ nullptr,
+ output_env_get_time_factor(oenv),
+ FALSE,
+ bSplit,
+ oenv);
}
if (twodplotfile)
"You have selected four or more eigenvectors:\n"
"fourth eigenvector will be plotted "
"in bfactor field of pdb file\n");
- sprintf(str, "4D proj. of traj. on eigenv. %d, %d, %d and %d", eignr[outvec[0]] + 1,
- eignr[outvec[1]] + 1, eignr[outvec[2]] + 1, eignr[outvec[3]] + 1);
+ sprintf(str,
+ "4D proj. of traj. on eigenv. %d, %d, %d and %d",
+ eignr[outvec[0]] + 1,
+ eignr[outvec[1]] + 1,
+ eignr[outvec[2]] + 1,
+ eignr[outvec[3]] + 1);
}
else
{
- sprintf(str, "3D proj. of traj. on eigenv. %d, %d and %d", eignr[outvec[0]] + 1,
- eignr[outvec[1]] + 1, eignr[outvec[2]] + 1);
+ sprintf(str,
+ "3D proj. of traj. on eigenv. %d, %d and %d",
+ eignr[outvec[0]] + 1,
+ eignr[outvec[1]] + 1,
+ eignr[outvec[2]] + 1);
}
init_t_atoms(&atoms, nframes, FALSE);
snew(x, nframes);
fprintf(out, "TER\n");
j = 0;
}
- gmx_fprintf_pdb_atomline(out, epdbATOM, i + 1, "C", ' ', "PRJ", ' ', j + 1, ' ',
- 10 * x[i][XX], 10 * x[i][YY], 10 * x[i][ZZ], 1.0,
- 10 * b[i], "");
+ gmx_fprintf_pdb_atomline(out,
+ epdbATOM,
+ i + 1,
+ "C",
+ ' ',
+ "PRJ",
+ ' ',
+ j + 1,
+ ' ',
+ 10 * x[i][XX],
+ 10 * x[i][YY],
+ 10 * x[i][ZZ],
+ 1.0,
+ 10 * b[i],
+ "");
if (j > 0)
{
fprintf(out, "CONECT%5d%5d\n", i, i + 1);
}
pmin[v] = inprod[v][imin];
pmax[v] = inprod[v][imax];
- fprintf(stderr, "%7d %10.6f %10d %10.6f %10d\n", eignr[outvec[v]] + 1, pmin[v],
- imin, pmax[v], imax);
+ fprintf(stderr, "%7d %10.6f %10d %10.6f %10d\n", eignr[outvec[v]] + 1, pmin[v], imin, pmax[v], imax);
}
}
else
}
}
}
- write_xvgr_graphs(outfile, noutvec, 4, "Eigenvector components",
- "black: total, red: x, green: y, blue: z", "Atom number", ylabel, natoms, x,
- nullptr, y, 1, FALSE, FALSE, oenv);
+ write_xvgr_graphs(outfile,
+ noutvec,
+ 4,
+ "Eigenvector components",
+ "black: total, red: x, green: y, blue: z",
+ "Atom number",
+ ylabel,
+ natoms,
+ x,
+ nullptr,
+ y,
+ 1,
+ FALSE,
+ FALSE,
+ oenv);
fprintf(stderr, "\n");
}
v = outvec[g];
if (eignr[v] >= neig)
{
- gmx_fatal(FARGS, "Selected vector %d is larger than the number of eigenvalues (%d)",
- eignr[v] + 1, neig);
+ gmx_fatal(FARGS,
+ "Selected vector %d is larger than the number of eigenvalues (%d)",
+ eignr[v] + 1,
+ neig);
}
sprintf(str, "vec %d", eignr[v] + 1);
ylabel[g] = gmx_strdup(str);
y[g][i] = std::sqrt(eigval[eignr[v]] * norm2(eigvec[v][i])) / sqrtm[i];
}
}
- write_xvgr_graphs(outfile, noutvec, 1, "RMS fluctuation (nm) ", nullptr, "Atom number", ylabel,
- natoms, x, y, nullptr, 1, TRUE, FALSE, oenv);
+ write_xvgr_graphs(
+ outfile, noutvec, 1, "RMS fluctuation (nm) ", nullptr, "Atom number", ylabel, natoms, x, y, nullptr, 1, TRUE, FALSE, oenv);
fprintf(stderr, "\n");
}
};
#define NFILE asize(fnm)
- if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_TIME_UNIT | PCA_CAN_VIEW, NFILE, fnm,
- NPA, pa, asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_TIME | PCA_TIME_UNIT | PCA_CAN_VIEW, NFILE, fnm, NPA, pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
bCompare = (Vec2File != nullptr) || (Eig2File != nullptr);
bPDB3D = fn2ftp(ThreeDPlotFile) == efPDB;
- read_eigenvectors(VecFile, &natoms, &bFit1, &xref1, &bDMR1, &xav1, &bDMA1, &nvec1, &eignr1,
- &eigvec1, &eigval1);
+ read_eigenvectors(
+ VecFile, &natoms, &bFit1, &xref1, &bDMR1, &xav1, &bDMA1, &nvec1, &eignr1, &eigvec1, &eigval1);
neig1 = std::min(nvec1, DIM * natoms);
if (nvec1 != DIM * natoms)
{
fprintf(stderr,
"Warning: number of eigenvectors %d does not match three times\n"
"the number of atoms %d in %s. Using %d eigenvectors.\n\n",
- nvec1, natoms, VecFile, neig1);
+ nvec1,
+ natoms,
+ VecFile,
+ neig1);
}
/* Overwrite eigenvalues from separate files if the user provides them */
{
fprintf(stderr,
"Warning: number of eigenvalues in xvg file (%d) does not mtch trr file (%d)\n",
- neig1, natoms);
+ neig1,
+ natoms);
}
neig1 = neig_tmp;
srenew(eigval1, neig1);
eigval1[j] = xvgdata[1][j];
if (debug && (eigval1[j] != tmp))
{
- fprintf(debug, "Replacing eigenvalue %d. From trr: %10g, from xvg: %10g\n", j, tmp,
- eigval1[j]);
+ fprintf(debug, "Replacing eigenvalue %d. From trr: %10g, from xvg: %10g\n", j, tmp, eigval1[j]);
}
}
for (j = 0; j < i; j++)
gmx_fatal(FARGS, "Need a second eigenvector file to do this analysis.");
}
int natoms2;
- read_eigenvectors(Vec2File, &natoms2, &bFit2, &xref2, &bDMR2, &xav2, &bDMA2, &nvec2,
- &eignr2, &eigvec2, &eigval2);
+ read_eigenvectors(
+ Vec2File, &natoms2, &bFit2, &xref2, &bDMR2, &xav2, &bDMA2, &nvec2, &eignr2, &eigvec2, &eigval2);
neig2 = std::min(nvec2, DIM * natoms2);
if (neig2 != neig1)
gmx_fatal(FARGS,
"you selected a group with %d elements instead of %d, your selection "
"does not fit the reference structure in the eigenvector file.",
- nfit, natoms);
+ nfit,
+ natoms);
}
for (i = 0; (i < nfit); i++)
{
if (bProj)
{
- project(bTraj ? opt2fn("-f", NFILE, fnm) : nullptr, bTop ? &top : nullptr, pbcType, topbox,
- ProjOnVecFile, TwoDPlotFile, ThreeDPlotFile, FilterFile, skip, ExtremeFile,
- bFirstLastSet, max, nextr, atoms, natoms, index, bFit1, xrefp, nfit, ifit, w_rls,
- sqrtm, xav1, eignr1, eigvec1, noutvec, outvec, bSplit, oenv);
+ project(bTraj ? opt2fn("-f", NFILE, fnm) : nullptr,
+ bTop ? &top : nullptr,
+ pbcType,
+ topbox,
+ ProjOnVecFile,
+ TwoDPlotFile,
+ ThreeDPlotFile,
+ FilterFile,
+ skip,
+ ExtremeFile,
+ bFirstLastSet,
+ max,
+ nextr,
+ atoms,
+ natoms,
+ index,
+ bFit1,
+ xrefp,
+ nfit,
+ ifit,
+ w_rls,
+ sqrtm,
+ xav1,
+ eignr1,
+ eigvec1,
+ noutvec,
+ outvec,
+ bSplit,
+ oenv);
}
if (OverlapFile)
if (InpMatFile)
{
- inprod_matrix(InpMatFile, natoms, nvec1, eignr1, eigvec1, nvec2, eignr2, eigvec2,
- bFirstLastSet, noutvec, outvec);
+ inprod_matrix(
+ InpMatFile, natoms, nvec1, eignr1, eigvec1, nvec2, eignr2, eigvec2, bFirstLastSet, noutvec, outvec);
}
if (bCompare)
fprintf(stdout,
"Errorbars: discarding %d points on both sides: %d%%"
" interval\n",
- edge, gmx::roundToInt(100. * (nset - 2 * edge) / nset));
+ edge,
+ gmx::roundToInt(100. * (nset - 2 * edge) / nset));
}
else
{
* to halfway between tau1_est and the total time (on log scale).
*/
fitparm[2] = std::sqrt(tau1_est * (n - 1) * dt);
- do_lmfit(nbs, ybs, fitsig, 0, tbs, 0, dt * n, oenv, bDebugMode(), effnERREST,
- fitparm, 0, nullptr);
+ do_lmfit(nbs, ybs, fitsig, 0, tbs, 0, dt * n, oenv, bDebugMode(), effnERREST, fitparm, 0, nullptr);
}
if (bSingleExpFit || fitparm[0] < 0 || fitparm[2] < 0 || fitparm[1] < 0
|| (fitparm[1] > 1 && !bAllowNegLTCorr) || fitparm[2] > (n - 1) * dt)
{
fprintf(stdout, "a fitted parameter is negative\n");
}
- fprintf(stdout, "invalid fit: e.e. %g a %g tau1 %g tau2 %g\n",
- optimal_error_estimate(sig[s], fitparm, n * dt), fitparm[1], fitparm[0],
+ fprintf(stdout,
+ "invalid fit: e.e. %g a %g tau1 %g tau2 %g\n",
+ optimal_error_estimate(sig[s], fitparm, n * dt),
+ fitparm[1],
+ fitparm[0],
fitparm[2]);
/* Do a fit with tau2 fixed at the total time.
* One could also choose any other large value for tau2.
fitparm[1] = 0.95;
fitparm[2] = (n - 1) * dt;
fprintf(stdout, "Will fix tau2 at the total time: %g\n", fitparm[2]);
- do_lmfit(nbs, ybs, fitsig, 0, tbs, 0, dt * n, oenv, bDebugMode(), effnERREST,
- fitparm, 4, nullptr);
+ do_lmfit(nbs, ybs, fitsig, 0, tbs, 0, dt * n, oenv, bDebugMode(), effnERREST, fitparm, 4, nullptr);
}
if (bSingleExpFit || fitparm[0] < 0 || fitparm[1] < 0 || (fitparm[1] > 1 && !bAllowNegLTCorr))
{
if (!bSingleExpFit)
{
fprintf(stdout, "a fitted parameter is negative\n");
- fprintf(stdout, "invalid fit: e.e. %g a %g tau1 %g tau2 %g\n",
- optimal_error_estimate(sig[s], fitparm, n * dt), fitparm[1],
- fitparm[0], fitparm[2]);
+ fprintf(stdout,
+ "invalid fit: e.e. %g a %g tau1 %g tau2 %g\n",
+ optimal_error_estimate(sig[s], fitparm, n * dt),
+ fitparm[1],
+ fitparm[0],
+ fitparm[2]);
}
/* Do a single exponential fit */
fprintf(stderr, "Will use a single exponential fit for set %d\n", s + 1);
fitparm[0] = tau1_est;
fitparm[1] = 1.0;
fitparm[2] = 0.0;
- do_lmfit(nbs, ybs, fitsig, 0, tbs, 0, dt * n, oenv, bDebugMode(), effnERREST,
- fitparm, 6, nullptr);
+ do_lmfit(nbs, ybs, fitsig, 0, tbs, 0, dt * n, oenv, bDebugMode(), effnERREST, fitparm, 6, nullptr);
}
}
ee = optimal_error_estimate(sig[s], fitparm, n * dt);
if (output_env_get_xvg_format(oenv) == XvgFormat::Xmgr)
{
fprintf(fp, "@ legend string %d \"av %f\"\n", 2 * s, av[s]);
- fprintf(fp, "@ legend string %d \"ee %6g\"\n", 2 * s + 1,
+ fprintf(fp,
+ "@ legend string %d \"ee %6g\"\n",
+ 2 * s + 1,
optimal_error_estimate(sig[s], fitparm, n * dt));
}
else if (output_env_get_xvg_format(oenv) == XvgFormat::Xmgrace)
{
fprintf(fp, "@ s%d legend \"av %f\"\n", 2 * s, av[s]);
- fprintf(fp, "@ s%d legend \"ee %6g\"\n", 2 * s + 1,
- optimal_error_estimate(sig[s], fitparm, n * dt));
+ fprintf(fp, "@ s%d legend \"ee %6g\"\n", 2 * s + 1, optimal_error_estimate(sig[s], fitparm, n * dt));
}
for (i = 0; i < nbs; i++)
{
- fprintf(fp, "%g %g %g\n", tbs[i], sig[s] * std::sqrt(ybs[i] / (n * dt)),
+ fprintf(fp,
+ "%g %g %g\n",
+ tbs[i],
+ sig[s] * std::sqrt(ybs[i] / (n * dt)),
sig[s] * std::sqrt(fit_function(effnERREST, fitparm, tbs[i]) / (n * dt)));
}
fitsig[i] = 1;
}
}
- low_do_autocorr(nullptr, oenv, nullptr, n, 1, -1, &ac, dt, eacNormal, 1, FALSE, TRUE,
- FALSE, 0, 0, effnNONE);
+ low_do_autocorr(
+ nullptr, oenv, nullptr, n, 1, -1, &ac, dt, eacNormal, 1, FALSE, TRUE, FALSE, 0, 0, effnNONE);
fitlen = n / nb_min;
ac_fit[0] = 0.5 * acint;
ac_fit[1] = 0.95;
ac_fit[2] = 10 * acint;
- do_lmfit(n / nb_min, ac, fitsig, dt, nullptr, 0, fitlen * dt, oenv, bDebugMode(),
- effnEXPEXP, ac_fit, 0, nullptr);
+ do_lmfit(n / nb_min, ac, fitsig, dt, nullptr, 0, fitlen * dt, oenv, bDebugMode(), effnEXPEXP, ac_fit, 0, nullptr);
ac_fit[3] = 1 - ac_fit[1];
- fprintf(stdout, "Set %3d: ac erest %g a %g tau1 %g tau2 %g\n", s + 1,
- optimal_error_estimate(sig[s], ac_fit, n * dt), ac_fit[1], ac_fit[0], ac_fit[2]);
+ fprintf(stdout,
+ "Set %3d: ac erest %g a %g tau1 %g tau2 %g\n",
+ s + 1,
+ optimal_error_estimate(sig[s], ac_fit, n * dt),
+ ac_fit[1],
+ ac_fit[0],
+ ac_fit[2]);
fprintf(fp, "%s\n", output_env_get_print_xvgr_codes(oenv) ? "&" : "");
for (i = 0; i < nbs; i++)
{
- fprintf(fp, "%g %g\n", tbs[i],
+ fprintf(fp,
+ "%g %g\n",
+ tbs[i],
sig[s] * std::sqrt(fit_function(effnERREST, ac_fit, tbs[i])) / (n * dt));
}
npargs = asize(pa);
ppa = add_acf_pargs(&npargs, pa);
- if (!parse_common_args(&argc, argv, PCA_CAN_VIEW, NFILE, fnm, npargs, ppa, asize(desc), desc, 0,
- nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_VIEW, NFILE, fnm, npargs, ppa, asize(desc), desc, 0, nullptr, &oenv))
{
sfree(ppa);
return 0;
fitfile = opt2fn_null("-g", NFILE, fnm);
}
- val = read_xvg_time(opt2fn("-f", NFILE, fnm), bHaveT, opt2parg_bSet("-b", npargs, ppa), tb,
- opt2parg_bSet("-e", npargs, ppa), te, nsets_in, &nset, &n, &dt, &t);
+ val = read_xvg_time(opt2fn("-f", NFILE, fnm),
+ bHaveT,
+ opt2parg_bSet("-b", npargs, ppa),
+ tb,
+ opt2parg_bSet("-e", npargs, ppa),
+ te,
+ nsets_in,
+ &nset,
+ &n,
+ &dt,
+ &t);
printf("Read %d sets of %d points, dt = %g\n\n", nset, n, dt);
if (bDer)
if (fitfile != nullptr)
{
- print_fitted_function(fitfile, opt2fn_null("-fitted", NFILE, fnm), bXYdy, nset, n, t, val,
- npargs, ppa, oenv);
+ print_fitted_function(
+ fitfile, opt2fn_null("-fitted", NFILE, fnm), bXYdy, nset, n, t, val, npargs, ppa, oenv);
}
printf(" std. dev. relative deviation of\n");
{
error = 0;
}
- printf("SS%d %13.6e %12.6e %12.6e %6.3f %6.3f\n", s + 1, av[s], sig[s], error,
+ printf("SS%d %13.6e %12.6e %12.6e %6.3f %6.3f\n",
+ s + 1,
+ av[s],
+ sig[s],
+ error,
sig[s] != 0.0 ? cum3 / (sig[s] * sig[s] * sig[s] * std::sqrt(8 / M_PI)) : 0,
sig[s] != 0.0 ? cum4 / (sig[s] * sig[s] * sig[s] * sig[s] * 3) - 1 : 0);
}
npargs = asize(pa);
ppa = add_acf_pargs(&npargs, pa);
- if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, npargs, ppa,
- asize(desc), desc, asize(bugs), bugs, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, npargs, ppa, asize(desc), desc, asize(bugs), bugs, &oenv))
{
sfree(ppa);
return 0;
gmx_fatal(FARGS,
"number of index elements not multiple of %d, "
"these can not be %s\n",
- mult, (mult == 3) ? "angle triplets" : "dihedral quadruplets");
+ mult,
+ (mult == 3) ? "angle triplets" : "dihedral quadruplets");
}
snew(angstat, maxangstat);
- read_ang_dih(ftp2fn(efTRX, NFILE, fnm), (mult == 3),
- bALL || bCorr || bTrans || opt2bSet("-or", NFILE, fnm), bRb, bPBC, maxangstat,
- angstat, &nframes, &time, isize, index, &trans_frac, &aver_angle, dih, oenv);
+ read_ang_dih(ftp2fn(efTRX, NFILE, fnm),
+ (mult == 3),
+ bALL || bCorr || bTrans || opt2bSet("-or", NFILE, fnm),
+ bRb,
+ bPBC,
+ maxangstat,
+ angstat,
+ &nframes,
+ &time,
+ isize,
+ index,
+ &trans_frac,
+ &aver_angle,
+ dih,
+ oenv);
dt = (time[nframes - 1] - time[0]) / (nframes - 1);
if (bTrans)
{
- ana_dih_trans(opt2fn("-ot", NFILE, fnm), opt2fn("-oh", NFILE, fnm), dih, nframes, nangles,
- grpname, time, bRb, oenv);
+ ana_dih_trans(
+ opt2fn("-ot", NFILE, fnm), opt2fn("-oh", NFILE, fnm), dih, nframes, nangles, grpname, time, bRb, oenv);
}
if (bCorr)
{
mode = eacCos;
}
- do_autocorr(opt2fn("-oc", NFILE, fnm), oenv, "Dihedral Autocorrelation Function",
- nframes, nangles, dih, dt, mode, bAverCorr);
+ do_autocorr(opt2fn("-oc", NFILE, fnm),
+ oenv,
+ "Dihedral Autocorrelation Function",
+ nframes,
+ nangles,
+ dih,
+ dt,
+ mode,
+ bAverCorr);
}
}
OutputFileType outputFileType,
size_t numLegend)
{
- const std::array<std::string, maxAwhGraphs> legendBase = {
- { "PMF", "Coord bias", "Coord distr", "Ref value distr", "Target ref value distr",
- "Friction metric" }
- };
+ const std::array<std::string, maxAwhGraphs> legendBase = { { "PMF",
+ "Coord bias",
+ "Coord distr",
+ "Ref value distr",
+ "Target ref value distr",
+ "Friction metric" } };
std::vector<std::string> legend;
/* Give legends to dimensions higher than the first */
yLabel_ = useKTForEnergy_ ? "(k\\sB\\NT)" : "(kJ/mol)";
if (graphSelection == AwhGraphSelection::All)
{
- yLabel_ += gmx::formatString(", (nm\\S-%d\\N or rad\\S-%d\\N), (-)", awhBiasParams->ndim,
- awhBiasParams->ndim);
+ yLabel_ += gmx::formatString(
+ ", (nm\\S-%d\\N or rad\\S-%d\\N), (-)", awhBiasParams->ndim, awhBiasParams->ndim);
}
}
std::unique_ptr<OutputFile> awhOutputFile(new OutputFile(
opt2fn("-o", numFileOptions, filenames), "AWH", awhParams->numBias, k));
- awhOutputFile->initializeAwhOutputFile(subblockStart, numSubBlocks, awhBiasParams,
- awhGraphSelection, energyUnit, kT);
+ awhOutputFile->initializeAwhOutputFile(
+ subblockStart, numSubBlocks, awhBiasParams, awhGraphSelection, energyUnit, kT);
std::unique_ptr<OutputFile> frictionOutputFile;
if (outputFriction)
frictionOutputFile = std::make_unique<OutputFile>(
opt2fn("-fric", numFileOptions, filenames), "Friction tensor", awhParams->numBias, k);
- frictionOutputFile->initializeFrictionOutputFile(subblockStart, numSubBlocks,
- awhBiasParams, energyUnit, kT);
+ frictionOutputFile->initializeFrictionOutputFile(
+ subblockStart, numSubBlocks, awhBiasParams, energyUnit, kT);
}
- biasOutputSetups_.emplace_back(BiasOutputSetup(subblockStart, std::move(awhOutputFile),
- std::move(frictionOutputFile)));
+ biasOutputSetups_.emplace_back(BiasOutputSetup(
+ subblockStart, std::move(awhOutputFile), std::move(frictionOutputFile)));
subblockStart += numSubBlocks;
}
FILE* fpAwh = awhOutputFile.openBiasOutputFile(time, oenv);
/* Now do the actual printing. Metadata in first subblock is treated separately. */
- fprintf(fpAwh, "# AWH metadata: target error = %.2f kT = %.2f kJ/mol\n",
- block.sub[subStart].fval[1], block.sub[subStart].fval[1] * kT_);
+ fprintf(fpAwh,
+ "# AWH metadata: target error = %.2f kT = %.2f kJ/mol\n",
+ block.sub[subStart].fval[1],
+ block.sub[subStart].fval[1] * kT_);
fprintf(fpAwh, "# AWH metadata: log sample weight = %4.2f\n", block.sub[subStart].fval[2]);
{ efXVG, "-o", "awh", ffWRITE },
{ efXVG, "-fric", "friction", ffOPTWR } };
const int nfile = asize(fnm);
- if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_BEGIN | PCA_CAN_END, nfile, fnm,
- asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(&argc,
+ argv,
+ PCA_CAN_VIEW | PCA_CAN_BEGIN | PCA_CAN_END,
+ nfile,
+ fnm,
+ asize(pa),
+ pa,
+ asize(desc),
+ desc,
+ 0,
+ nullptr,
+ &oenv))
{
return 0;
}
AwhGraphSelection awhGraphSelection =
(moreGraphs ? AwhGraphSelection::All : AwhGraphSelection::Pmf);
EnergyUnit energyUnit = (kTUnit ? EnergyUnit::KT : EnergyUnit::KJPerMol);
- awhReader = std::make_unique<AwhReader>(ir.awhParams, nfile, fnm, awhGraphSelection,
- energyUnit, BOLTZ * ir.opts.ref_t[0], block);
+ awhReader = std::make_unique<AwhReader>(
+ ir.awhParams, nfile, fnm, awhGraphSelection, energyUnit, BOLTZ * ir.opts.ref_t[0], block);
}
awhReader->processAwhFrame(*block, frame->t, oenv);
GMX_ASSERT(sc->next->s, "Next not properly initialized!");
if (sc->temp != s->temp)
{
- gmx_fatal(FARGS, "Temperatures in files %s and %s are not the same!", s->filename,
+ gmx_fatal(FARGS,
+ "Temperatures in files %s and %s are not the same!",
+ s->filename,
sc->next->s[0]->filename);
}
if (!lambda_vec_same(sc->native_lambda, s->native_lambda))
{
- gmx_fatal(FARGS, "Native lambda in files %s and %s are not the same (and they should be)!",
- s->filename, sc->next->s[0]->filename);
+ gmx_fatal(FARGS,
+ "Native lambda in files %s and %s are not the same (and they should be)!",
+ s->filename,
+ sc->next->s[0]->filename);
}
if (!lambda_vec_same(sc->foreign_lambda, s->foreign_lambda))
{
- gmx_fatal(FARGS, "Foreign lambda in files %s and %s are not the same (and they should be)!",
- s->filename, sc->next->s[0]->filename);
+ gmx_fatal(FARGS,
+ "Foreign lambda in files %s and %s are not the same (and they should be)!",
+ s->filename,
+ sc->next->s[0]->filename);
}
/* check if there's room */
"them.\nAlternatively, use the -extp option if (and only if) the "
"Hamiltonian\ndepends linearly on lambda, which is NOT normally the "
"case.\n\n%s\n%s\n",
- descX, descY);
+ descX,
+ descY);
}
/* normal delta H */
gmx_fatal(FARGS,
"Could not find a set for foreign lambda (state X below)\nin the files for "
"main lambda (state Y below)\n\n%s\n%s\n",
- descX, descY);
+ descX,
+ descY);
}
if (!sc)
{
gmx_fatal(FARGS,
"Could not find a set for foreign lambda (state X below)\nin the files for "
"main lambda (state Y below)\n\n%s\n%s\n",
- descX, descY);
+ descX,
+ descY);
}
br->a = scprev;
br->b = sc;
if (!lambda_components_check(lc, 0, "", 0))
{
gmx_fatal(FARGS,
- "lambda vector components in %s don't match those previously read", fn);
+ "lambda vector components in %s don't match those previously read",
+ fn);
}
}
else
snew(s, barsim->nset);
for (i = 0; i < barsim->nset; i++)
{
- samples_init(s + i, &(barsim->native_lambda), &(barsim->lambda[i]), barsim->temp,
- lambda_vec_same(&(barsim->native_lambda), &(barsim->lambda[i])), fn);
+ samples_init(s + i,
+ &(barsim->native_lambda),
+ &(barsim->lambda[i]),
+ barsim->temp,
+ lambda_vec_same(&(barsim->native_lambda), &(barsim->lambda[i])),
+ fn);
s[i].du = barsim->y[i];
s[i].ndu = barsim->np[i];
s[i].t = barsim->t;
char buf[STRLEN];
lambda_vec_print(s[0].native_lambda, buf, FALSE);
- printf("%s: %.1f - %.1f; lambda = %s\n dH/dl & foreign lambdas:\n", fn, s[0].t[0],
- s[0].t[s[0].ndu - 1], buf);
+ printf("%s: %.1f - %.1f; lambda = %s\n dH/dl & foreign lambdas:\n",
+ fn,
+ s[0].t[0],
+ s[0].t[s[0].ndu - 1],
+ buf);
for (i = 0; i < barsim->nset; i++)
{
lambda_vec_print(s[i].foreign_lambda, buf, TRUE);
if ((*temp != rtemp) && (*temp > 0))
{
gmx_fatal(FARGS,
- "Temperature in file %s different from earlier files or setting\n", fn);
+ "Temperature in file %s different from earlier files or setting\n",
+ fn);
}
*temp = rtemp;
gmx_fatal(FARGS,
"Native lambda not constant in file %s: started at %f, and becomes %f at "
"time %f",
- fn, native_lambda->val[0], start_lambda.val[0], start_time);
+ fn,
+ native_lambda->val[0],
+ start_lambda.val[0],
+ start_time);
}
/* check the number of samples against the previous number */
if (((nblocks_raw + nblocks_hist) != nsamples) || (nlam != 1))
{
- gmx_fatal(FARGS, "Unexpected block count in %s: was %d, now %d\n", fn, nsamples + 1,
+ gmx_fatal(FARGS,
+ "Unexpected block count in %s: was %d, now %d\n",
+ fn,
+ nsamples + 1,
nblocks_raw + nblocks_hist + nlam);
}
/* check whether last iterations's end time matches with
if (type == dhbtDH || type == dhbtDHDL)
{
int ndu;
- read_edr_rawdh_block(&(samples_rawdh[k]), &ndu, &(fr->block[i]), start_time,
- delta_time, native_lambda, rtemp, &last_t, fn);
+ read_edr_rawdh_block(&(samples_rawdh[k]),
+ &ndu,
+ &(fr->block[i]),
+ start_time,
+ delta_time,
+ native_lambda,
+ rtemp,
+ &last_t,
+ fn);
npts[k] += ndu;
if (samples_rawdh[k])
{
int j;
int nb = 0;
samples_t* s; /* this is where the data will go */
- s = read_edr_hist_block(&nb, &(fr->block[i]), start_time, delta_time,
- native_lambda, rtemp, &last_t, fn);
+ s = read_edr_hist_block(
+ &nb, &(fr->block[i]), start_time, delta_time, native_lambda, rtemp, &last_t, fn);
nhists[k] += nb;
if (nb > 0)
{
double sum_histrange_err = 0.; /* histogram range error */
double stat_err = 0.; /* statistical error */
- if (!parse_common_args(&argc, argv, PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, asize(desc), desc,
- 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
if (opt2bSet("-o", NFILE, fnm))
{
sprintf(buf, "%s (%s)", "\\DeltaG", "kT");
- fpb = xvgropen_type(opt2fn("-o", NFILE, fnm), "Free energy differences", "\\lambda", buf,
- exvggtXYDY, oenv);
+ fpb = xvgropen_type(
+ opt2fn("-o", NFILE, fnm), "Free energy differences", "\\lambda", buf, exvggtXYDY, oenv);
}
fpi = nullptr;
};
#define NFILE asize(fnm)
- if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_TIME_UNIT, NFILE, fnm, asize(pa), pa,
- asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_TIME | PCA_TIME_UNIT, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
snew(bun.dir, n);
snew(bun.len, n);
- flen = xvgropen(opt2fn("-ol", NFILE, fnm), "Axis lengths", output_env_get_xvgr_tlabel(oenv),
- "(nm)", oenv);
- fdist = xvgropen(opt2fn("-od", NFILE, fnm), "Distance of axis centers",
- output_env_get_xvgr_tlabel(oenv), "(nm)", oenv);
- fz = xvgropen(opt2fn("-oz", NFILE, fnm), "Z-shift of axis centers",
- output_env_get_xvgr_tlabel(oenv), "(nm)", oenv);
- ftilt = xvgropen(opt2fn("-ot", NFILE, fnm), "Axis tilts", output_env_get_xvgr_tlabel(oenv),
- "(degrees)", oenv);
- ftiltr = xvgropen(opt2fn("-otr", NFILE, fnm), "Radial axis tilts",
- output_env_get_xvgr_tlabel(oenv), "(degrees)", oenv);
- ftiltl = xvgropen(opt2fn("-otl", NFILE, fnm), "Lateral axis tilts",
- output_env_get_xvgr_tlabel(oenv), "(degrees)", oenv);
+ flen = xvgropen(
+ opt2fn("-ol", NFILE, fnm), "Axis lengths", output_env_get_xvgr_tlabel(oenv), "(nm)", oenv);
+ fdist = xvgropen(opt2fn("-od", NFILE, fnm),
+ "Distance of axis centers",
+ output_env_get_xvgr_tlabel(oenv),
+ "(nm)",
+ oenv);
+ fz = xvgropen(opt2fn("-oz", NFILE, fnm),
+ "Z-shift of axis centers",
+ output_env_get_xvgr_tlabel(oenv),
+ "(nm)",
+ oenv);
+ ftilt = xvgropen(
+ opt2fn("-ot", NFILE, fnm), "Axis tilts", output_env_get_xvgr_tlabel(oenv), "(degrees)", oenv);
+ ftiltr = xvgropen(opt2fn("-otr", NFILE, fnm),
+ "Radial axis tilts",
+ output_env_get_xvgr_tlabel(oenv),
+ "(degrees)",
+ oenv);
+ ftiltl = xvgropen(opt2fn("-otl", NFILE, fnm),
+ "Lateral axis tilts",
+ output_env_get_xvgr_tlabel(oenv),
+ "(degrees)",
+ oenv);
if (bKink)
{
- fkink = xvgropen(opt2fn("-ok", NFILE, fnm), "Kink angles", output_env_get_xvgr_tlabel(oenv),
- "(degrees)", oenv);
- fkinkr = xvgropen(opt2fn("-okr", NFILE, fnm), "Radial kink angles",
- output_env_get_xvgr_tlabel(oenv), "(degrees)", oenv);
+ fkink = xvgropen(opt2fn("-ok", NFILE, fnm),
+ "Kink angles",
+ output_env_get_xvgr_tlabel(oenv),
+ "(degrees)",
+ oenv);
+ fkinkr = xvgropen(opt2fn("-okr", NFILE, fnm),
+ "Radial kink angles",
+ output_env_get_xvgr_tlabel(oenv),
+ "(degrees)",
+ oenv);
if (output_env_get_print_xvgr_codes(oenv))
{
fprintf(fkinkr, "@ subtitle \"+ = ) ( - = ( )\"\n");
}
- fkinkl = xvgropen(opt2fn("-okl", NFILE, fnm), "Lateral kink angles",
- output_env_get_xvgr_tlabel(oenv), "(degrees)", oenv);
+ fkinkl = xvgropen(opt2fn("-okl", NFILE, fnm),
+ "Lateral kink angles",
+ output_env_get_xvgr_tlabel(oenv),
+ "(degrees)",
+ oenv);
}
if (opt2bSet("-oa", NFILE, fnm))
}
else if (debug)
{
- fprintf(debug, "Res. %d has imcomplete occupancy or bfacs > %g\n",
- dlist[i].resnr, bfac_max);
+ fprintf(debug, "Res. %d has imcomplete occupancy or bfacs > %g\n", dlist[i].resnr, bfac_max);
}
}
else
break;
default:
sprintf(hisfile, "histo-chi%d%s", Dih - NONCHI + 1, residue_name);
- sprintf(title, "\\xc\\f{}\\s%d\\N Distribution for %s", Dih - NONCHI + 1,
- residue_name);
+ sprintf(title, "\\xc\\f{}\\s%d\\N Distribution for %s", Dih - NONCHI + 1, residue_name);
}
std::strcpy(hhisfile, hisfile);
std::strcat(hhisfile, ".xvg");
lo += 180;
hi += 180;
nlevels = 20;
- write_xpm3(fp, 0, "Omega/Ramachandran Plot", "Deg", "Phi", "Psi", NMAT, NMAT, axis,
- axis, mat, lo, 180.0, hi, rlo, rmid, rhi, &nlevels);
+ write_xpm3(fp,
+ 0,
+ "Omega/Ramachandran Plot",
+ "Deg",
+ "Phi",
+ "Psi",
+ NMAT,
+ NMAT,
+ axis,
+ axis,
+ mat,
+ lo,
+ 180.0,
+ hi,
+ rlo,
+ rmid,
+ rhi,
+ &nlevels);
gmx_ffclose(fp);
for (j = 0; (j < NMAT); j++)
{
if ((has_dihedral(edChi1, &(dlist[i]))) && (has_dihedral(edChi2, &(dlist[i]))))
{
sprintf(fn, "ramaX1X2%s.xvg", dlist[i].name);
- fp = rama_file(fn, "\\8c\\4\\s1\\N-\\8c\\4\\s2\\N Ramachandran Plot",
- "\\8c\\4\\s1\\N (deg)", "\\8c\\4\\s2\\N (deg)", oenv);
+ fp = rama_file(fn,
+ "\\8c\\4\\s1\\N-\\8c\\4\\s2\\N Ramachandran Plot",
+ "\\8c\\4\\s1\\N (deg)",
+ "\\8c\\4\\s2\\N (deg)",
+ oenv);
Xi1 = dlist[i].j0[edChi1];
Xi2 = dlist[i].j0[edChi2];
for (j = 0; (j < nf); j++)
z0 *= 10.0; /* nm -> angstrom */
for (i = 0; (i < 10); i++)
{
- gmx_fprintf_pdb_atomline(fp, epdbATOM, atoms->nr + 1 + i, "CA", ' ', "LEG", ' ',
- atoms->nres + 1, ' ', x0, y0, z0 + (1.2 * i), 0.0, -0.1 * i,
+ gmx_fprintf_pdb_atomline(fp,
+ epdbATOM,
+ atoms->nr + 1 + i,
+ "CA",
+ ' ',
+ "LEG",
+ ' ',
+ atoms->nres + 1,
+ ' ',
+ x0,
+ y0,
+ z0 + (1.2 * i),
+ 0.0,
+ -0.1 * i,
"");
}
gmx_ffclose(fp);
npargs = asize(pa);
ppa = add_acf_pargs(&npargs, pa);
- if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, npargs, ppa,
- asize(desc), desc, asize(bugs), bugs, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, npargs, ppa, asize(desc), desc, asize(bugs), bugs, &oenv))
{
sfree(ppa);
return 0;
snew(dih, ndih);
/* COMPUTE ALL DIHEDRALS! */
- read_ang_dih(ftp2fn(efTRX, NFILE, fnm), FALSE, TRUE, FALSE, bPBC, 1, &idum, &nf, &time, isize,
- index, &trans_frac, &aver_angle, dih, oenv);
+ read_ang_dih(
+ ftp2fn(efTRX, NFILE, fnm), FALSE, TRUE, FALSE, bPBC, 1, &idum, &nf, &time, isize, index, &trans_frac, &aver_angle, dih, oenv);
dt = (time[nf - 1] - time[0]) / (nf - 1); /* might want this for corr or n. transit*/
if (bCorr)
}
/* Histogramming & J coupling constants & calc of S2 order params */
- histogramming(log, nbin, &rt, nf, maxchi, dih, nlist, dlist, index, bPhi, bPsi, bOmega, bChi,
- bNormHisto, bSSHisto, ftp2fn(efDAT, NFILE, fnm), bfac_max, &atoms, bDo_jc,
- opt2fn("-jc", NFILE, fnm), oenv);
+ histogramming(log,
+ nbin,
+ &rt,
+ nf,
+ maxchi,
+ dih,
+ nlist,
+ dlist,
+ index,
+ bPhi,
+ bPsi,
+ bOmega,
+ bChi,
+ bNormHisto,
+ bSSHisto,
+ ftp2fn(efDAT, NFILE, fnm),
+ bfac_max,
+ &atoms,
+ bDo_jc,
+ opt2fn("-jc", NFILE, fnm),
+ oenv);
/* transitions
*
}
- low_ana_dih_trans(bDo_ot, opt2fn("-ot", NFILE, fnm), bDo_oh, opt2fn("-oh", NFILE, fnm), maxchi, dih,
- nlist, dlist, nf, nactdih, grpname, multiplicity, time, FALSE, core_frac, oenv);
+ low_ana_dih_trans(bDo_ot,
+ opt2fn("-ot", NFILE, fnm),
+ bDo_oh,
+ opt2fn("-oh", NFILE, fnm),
+ maxchi,
+ dih,
+ nlist,
+ dlist,
+ nf,
+ nactdih,
+ grpname,
+ multiplicity,
+ time,
+ FALSE,
+ core_frac,
+ oenv);
/* Order parameters */
- order_params(log, opt2fn("-o", NFILE, fnm), maxchi, nlist, dlist, ftp2fn_null(efPDB, NFILE, fnm),
- bfac_init, &atoms, x, pbcType, box, bPhi, bPsi, bChi, oenv);
+ order_params(log,
+ opt2fn("-o", NFILE, fnm),
+ maxchi,
+ nlist,
+ dlist,
+ ftp2fn_null(efPDB, NFILE, fnm),
+ bfac_init,
+ &atoms,
+ x,
+ pbcType,
+ box,
+ bPhi,
+ bPsi,
+ bChi,
+ oenv);
/* Print ramachandran maps! */
if (bRama)
}
mk_chi_lookup(chi_lookup, maxchi, nlist, dlist);
- get_chi_product_traj(dih, nf, nactdih, maxchi, dlist, time, chi_lookup, multiplicity, FALSE,
- bNormHisto, core_frac, bAll, opt2fn("-cp", NFILE, fnm), oenv);
+ get_chi_product_traj(dih,
+ nf,
+ nactdih,
+ maxchi,
+ dlist,
+ time,
+ chi_lookup,
+ multiplicity,
+ FALSE,
+ bNormHisto,
+ core_frac,
+ bAll,
+ opt2fn("-cp", NFILE, fnm),
+ oenv);
for (i = 0; i < nlist; i++)
{
/* Correlation comes last because it messes up the angles */
if (bCorr)
{
- do_dihcorr(opt2fn("-corr", NFILE, fnm), nf, ndih, dih, dt, nlist, dlist, time, maxchi, bPhi,
- bPsi, bChi, bOmega, oenv);
+ do_dihcorr(opt2fn("-corr", NFILE, fnm), nf, ndih, dih, dt, nlist, dlist, time, maxchi, bPhi, bPsi, bChi, bOmega, oenv);
}
nuphill++;
}
- fprintf(log, "Iter: %d Swapped %4d and %4d (energy: %g prob: %g)\n", i, iswap, jswap,
- enext, prob);
+ fprintf(log, "Iter: %d Swapped %4d and %4d (energy: %g prob: %g)\n", i, iswap, jswap, enext, prob);
if (nullptr != fp)
{
fprintf(fp, "%6d %10g\n", i, enext);
fprintf(log, "Swapped time and frame indices and RMSD to next neighbor:\n");
for (i = 0; (i < m->nn); i++)
{
- fprintf(log, "%10g %5d %10g\n", time[m->m_ind[i]], m->m_ind[i],
+ fprintf(log,
+ "%10g %5d %10g\n",
+ time[m->m_ind[i]],
+ m->m_ind[i],
(i < m->nn - 1) ? m->mat[m->m_ind[i]][m->m_ind[i + 1]] : 0);
}
trans[clust->cl[i] - 1][clust->cl[i - 1] - 1]));
}
}
- ffprintf_dd(stderr, log, buf,
+ ffprintf_dd(stderr,
+ log,
+ buf,
"Counted %d transitions in total, "
"max %d between two specific clusters\n",
- ntranst, maxtrans);
+ ntranst,
+ maxtrans);
if (transfn)
{
fp = gmx_ffopen(transfn, "w");
i = std::min(maxtrans + 1, 80);
- write_xpm(fp, 0, "Cluster Transitions", "# transitions", "from cluster", "to cluster",
- clust->ncl, clust->ncl, axis, axis, trans, 0, maxtrans, rlo, rhi, &i);
+ write_xpm(fp,
+ 0,
+ "Cluster Transitions",
+ "# transitions",
+ "from cluster",
+ "to cluster",
+ clust->ncl,
+ clust->ncl,
+ axis,
+ axis,
+ trans,
+ 0,
+ maxtrans,
+ rlo,
+ rhi,
+ &i);
gmx_ffclose(fp);
}
if (ntransfn)
trxsfn = parse_filename(trxfn, std::max(write_ncl, clust->ncl));
snew(bWrite, nf);
}
- ffprintf_ss(stderr, log, buf, "Writing %s structure for each cluster to %s\n",
- bAverage ? "average" : "middle", trxfn);
+ ffprintf_ss(stderr,
+ log,
+ buf,
+ "Writing %s structure for each cluster to %s\n",
+ bAverage ? "average" : "middle",
+ trxfn);
if (write_ncl)
{
/* find out what we want to tell the user:
}
snew(structure, nf);
- fprintf(log, "\n%3s | %3s %4s | %6s %4s | cluster members\n", "cl.", "#st", "rmsd", "middle",
+ fprintf(log,
+ "\n%3s | %3s %4s | %6s %4s | cluster members\n",
+ "cl.",
+ "#st",
+ "rmsd",
+ "middle",
"rmsd");
for (cl = 1; cl <= clust->ncl; cl++)
{
}
if (bWrite[i])
{
- write_trx(trxsout, iosize, outidx, atoms, i, time[structure[i]],
- boxes[structure[i]], xx[structure[i]], nullptr, nullptr);
+ write_trx(trxsout,
+ iosize,
+ outidx,
+ atoms,
+ i,
+ time[structure[i]],
+ boxes[structure[i]],
+ xx[structure[i]],
+ nullptr,
+ nullptr);
}
}
close_trx(trxsout);
};
#define NFILE asize(fnm)
- if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME | PCA_TIME_UNIT, NFILE, fnm,
- asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(&argc,
+ argv,
+ PCA_CAN_VIEW | PCA_CAN_TIME | PCA_TIME_UNIT,
+ NFILE,
+ fnm,
+ asize(pa),
+ pa,
+ asize(desc),
+ desc,
+ 0,
+ nullptr,
+ &oenv))
{
return 0;
}
}
if (bReadMat && output_env_get_time_factor(oenv) != 1)
{
- fprintf(stderr, "\nWarning: assuming the time unit in %s is %s\n",
- opt2fn("-dm", NFILE, fnm), output_env_get_time_unit(oenv).c_str());
+ fprintf(stderr,
+ "\nWarning: assuming the time unit in %s is %s\n",
+ opt2fn("-dm", NFILE, fnm),
+ output_env_get_time_unit(oenv).c_str());
}
if (trx_out_fn && !bReadTraj)
{
gmx_fatal(FARGS,
"Matrix size (%dx%d) does not match the number of "
"frames (%d)",
- readmat[0].nx, readmat[0].ny, nf);
+ readmat[0].nx,
+ readmat[0].ny,
+ nf);
}
nf = readmat[0].nx;
fprintf(stderr,
"WARNING: rmsd cutoff %g is outside range of rmsd values "
"%g to %g\n",
- rmsdcut, rms->minrms, rms->maxrms);
+ rmsdcut,
+ rms->minrms,
+ rms->maxrms);
}
if (bAnalyze && (rmsmin < rms->minrms))
{
eigensolver(eigenvectors, nf, 0, nf, eigenvalues, rms->mat[0]);
sfree(eigenvectors);
- fp = xvgropen(opt2fn("-ev", NFILE, fnm), "RMSD matrix Eigenvalues", "Eigenvector index",
- "Eigenvalues (nm\\S2\\N)", oenv);
+ fp = xvgropen(opt2fn("-ev", NFILE, fnm),
+ "RMSD matrix Eigenvalues",
+ "Eigenvector index",
+ "Eigenvalues (nm\\S2\\N)",
+ oenv);
for (i = 0; (i < nf); i++)
{
fprintf(fp, "%10d %10g\n", i, eigenvalues[i]);
copy_rvec(xtps[index[i]], usextps[i]);
}
useatoms.nr = isize;
- analyze_clusters(nf, &clust, rms->mat, isize, &useatoms, usextps, mass, xx, time, boxes,
- frameindices, ifsize, fitidx, iosize, outidx,
- bReadTraj ? trx_out_fn : nullptr, opt2fn_null("-sz", NFILE, fnm),
- opt2fn_null("-tr", NFILE, fnm), opt2fn_null("-ntr", NFILE, fnm),
- opt2fn_null("-clid", NFILE, fnm), opt2fn_null("-clndx", NFILE, fnm),
- bAverage, write_ncl, write_nst, rmsmin, bFit, log, rlo_bot, rhi_bot, oenv);
+ analyze_clusters(nf,
+ &clust,
+ rms->mat,
+ isize,
+ &useatoms,
+ usextps,
+ mass,
+ xx,
+ time,
+ boxes,
+ frameindices,
+ ifsize,
+ fitidx,
+ iosize,
+ outidx,
+ bReadTraj ? trx_out_fn : nullptr,
+ opt2fn_null("-sz", NFILE, fnm),
+ opt2fn_null("-tr", NFILE, fnm),
+ opt2fn_null("-ntr", NFILE, fnm),
+ opt2fn_null("-clid", NFILE, fnm),
+ opt2fn_null("-clndx", NFILE, fnm),
+ bAverage,
+ write_ncl,
+ write_nst,
+ rmsmin,
+ bFit,
+ log,
+ rlo_bot,
+ rhi_bot,
+ oenv);
sfree(boxes);
sfree(frameindices);
}
fprintf(stderr, "Writing rms distance/clustering matrix ");
if (bReadMat)
{
- write_xpm(fp, 0, readmat[0].title, readmat[0].legend, readmat[0].label_x,
- readmat[0].label_y, nf, nf, readmat[0].axis_x.data(), readmat[0].axis_y.data(),
- rms->mat, 0.0, rms->maxrms, rlo_top, rhi_top, &nlevels);
+ write_xpm(fp,
+ 0,
+ readmat[0].title,
+ readmat[0].legend,
+ readmat[0].label_x,
+ readmat[0].label_y,
+ nf,
+ nf,
+ readmat[0].axis_x.data(),
+ readmat[0].axis_y.data(),
+ rms->mat,
+ 0.0,
+ rms->maxrms,
+ rlo_top,
+ rhi_top,
+ &nlevels);
}
else
{
auto title = gmx::formatString("RMS%sDeviation / Cluster Index", bRMSdist ? " Distance " : " ");
if (minstruct > 1)
{
- write_xpm_split(fp, 0, title, "RMSD (nm)", timeLabel, timeLabel, nf, nf, time, time,
- rms->mat, 0.0, rms->maxrms, &nlevels, rlo_top, rhi_top, 0.0, ncluster,
- &ncluster, TRUE, rlo_bot, rhi_bot);
+ write_xpm_split(fp,
+ 0,
+ title,
+ "RMSD (nm)",
+ timeLabel,
+ timeLabel,
+ nf,
+ nf,
+ time,
+ time,
+ rms->mat,
+ 0.0,
+ rms->maxrms,
+ &nlevels,
+ rlo_top,
+ rhi_top,
+ 0.0,
+ ncluster,
+ &ncluster,
+ TRUE,
+ rlo_bot,
+ rhi_bot);
}
else
{
- write_xpm(fp, 0, title, "RMSD (nm)", timeLabel, timeLabel, nf, nf, time, time, rms->mat,
- 0.0, rms->maxrms, rlo_top, rhi_top, &nlevels);
+ write_xpm(fp,
+ 0,
+ title,
+ "RMSD (nm)",
+ timeLabel,
+ timeLabel,
+ nf,
+ nf,
+ time,
+ time,
+ rms->mat,
+ 0.0,
+ rms->maxrms,
+ rlo_top,
+ rhi_top,
+ &nlevels);
}
}
fprintf(stderr, "\n");
fp = opt2FILE("-om", NFILE, fnm, "w");
auto timeLabel = output_env_get_time_label(oenv);
auto title = gmx::formatString("RMS%sDeviation", bRMSdist ? " Distance " : " ");
- write_xpm(fp, 0, title, "RMSD (nm)", timeLabel, timeLabel, nf, nf, time, time, orig->mat,
- 0.0, orig->maxrms, rlo_top, rhi_top, &nlevels);
+ write_xpm(fp,
+ 0,
+ title,
+ "RMSD (nm)",
+ timeLabel,
+ timeLabel,
+ nf,
+ nf,
+ time,
+ time,
+ orig->mat,
+ 0.0,
+ orig->maxrms,
+ rlo_top,
+ rhi_top,
+ &nlevels);
gmx_ffclose(fp);
done_mat(&orig);
sfree(orig);
{
if (clust_size[cj] <= 0)
{
- gmx_fatal(FARGS, "negative cluster size %d for element %d",
- clust_size[cj], cj);
+ gmx_fatal(FARGS,
+ "negative cluster size %d for element %d",
+ clust_size[cj],
+ cj);
}
clust_size[cj]--;
clust_index[k] = ci;
fprintf(stderr, "cmid: %g, cmax: %g, max_size: %d\n", cmid, cmax, max_size);
cmid = 1;
fp = gmx_ffopen(xpm, "w");
- write_xpm3(fp, 0, "Cluster size distribution", "# clusters", timeLabel, "Size", n_x, max_size,
- t_x, t_y, cs_dist, 0, cmid, cmax, rlo, rmid, rhi, &nlevels);
+ write_xpm3(fp,
+ 0,
+ "Cluster size distribution",
+ "# clusters",
+ timeLabel,
+ "Size",
+ n_x,
+ max_size,
+ t_x,
+ t_y,
+ cs_dist,
+ 0,
+ cmid,
+ cmax,
+ rlo,
+ rmid,
+ rhi,
+ &nlevels);
gmx_ffclose(fp);
cmid = 100.0;
cmax = 0.0;
}
fprintf(stderr, "cmid: %g, cmax: %g, max_size: %d\n", cmid, cmax, max_size);
fp = gmx_ffopen(xpmw, "w");
- write_xpm3(fp, 0, "Weighted cluster size distribution", "Fraction", timeLabel, "Size", n_x,
- max_size, t_x, t_y, cs_dist, 0, cmid, cmax, rlo, rmid, rhi, &nlevels);
+ write_xpm3(fp,
+ 0,
+ "Weighted cluster size distribution",
+ "Fraction",
+ timeLabel,
+ "Size",
+ n_x,
+ max_size,
+ t_x,
+ t_y,
+ cs_dist,
+ 0,
+ cmid,
+ cmax,
+ rlo,
+ rmid,
+ rhi,
+ &nlevels);
gmx_ffclose(fp);
delete mtop;
sfree(t_x);
};
#define NFILE asize(fnm)
- if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME | PCA_TIME_UNIT, NFILE, fnm,
- NPA, pa, asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME | PCA_TIME_UNIT, NFILE, fnm, NPA, pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
gmx_fatal(FARGS, "You need a tpr file for the -mol option");
}
- clust_size(fnNDX, ftp2fn(efTRX, NFILE, fnm), opt2fn("-o", NFILE, fnm), opt2fn("-ow", NFILE, fnm),
- opt2fn("-nc", NFILE, fnm), opt2fn("-ac", NFILE, fnm), opt2fn("-mc", NFILE, fnm),
- opt2fn("-hc", NFILE, fnm), opt2fn("-temp", NFILE, fnm), opt2fn("-mcn", NFILE, fnm),
- bMol, bPBC, fnTPR, cutoff, nskip, nlevels, rgblo, rgbhi, ndf, oenv);
+ clust_size(fnNDX,
+ ftp2fn(efTRX, NFILE, fnm),
+ opt2fn("-o", NFILE, fnm),
+ opt2fn("-ow", NFILE, fnm),
+ opt2fn("-nc", NFILE, fnm),
+ opt2fn("-ac", NFILE, fnm),
+ opt2fn("-mc", NFILE, fnm),
+ opt2fn("-hc", NFILE, fnm),
+ opt2fn("-temp", NFILE, fnm),
+ opt2fn("-mcn", NFILE, fnm),
+ bMol,
+ bPBC,
+ fnTPR,
+ cutoff,
+ nskip,
+ nlevels,
+ rgblo,
+ rgbhi,
+ ndf,
+ oenv);
output_env_done(oenv);
{
if (debug)
{
- fprintf(debug, "%d.%d.%dX%sX%s", dx, rr1, rr2, *resinfo1[index1[rr1 + 1]].name,
+ fprintf(debug,
+ "%d.%d.%dX%sX%s",
+ dx,
+ rr1,
+ rr2,
+ *resinfo1[index1[rr1 + 1]].name,
*resinfo2[index2[rr2 + 1]].name);
}
dx = 1;
}
if (debug)
{
- fprintf(debug, " -> %s%d-%s%d %s%d-%s%d", *resinfo1[rnr1].name, rnr1, *atnms1[index1[i1]],
- index1[i1], *resinfo2[rnr2].name, rnr2, *atnms2[index2[i2]], index2[i2]);
+ fprintf(debug,
+ " -> %s%d-%s%d %s%d-%s%d",
+ *resinfo1[rnr1].name,
+ rnr1,
+ *atnms1[index1[i1]],
+ index1[i1],
+ *resinfo2[rnr2].name,
+ rnr2,
+ *atnms2[index2[i2]],
+ index2[i2]);
}
m1 = find_res_end(i1, *isize1, index1, atoms1);
m2 = find_res_end(i2, *isize2, index2, atoms2);
real* msds;
- if (!parse_common_args(&argc, argv, PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, asize(desc), desc,
- 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
if (matchndxfile)
{
fp = gmx_ffopen(matchndxfile, "w");
- fprintf(fp, "; Matching atoms between %s from %s and %s from %s\n", groupnames1,
- conf1file, groupnames2, conf2file);
+ fprintf(fp,
+ "; Matching atoms between %s from %s and %s from %s\n",
+ groupnames1,
+ conf1file,
+ groupnames2,
+ conf2file);
fprintf(fp, "[ Match_%s_%s ]\n", conf1file, groupnames1);
for (i = 0; i < isize1; i++)
{
{
if (warn < 20)
{
- fprintf(stderr, "Warning: atomnames at index %d don't match: %d %s, %d %s\n", i + 1,
- index1[i] + 1, name1, index2[i] + 1, name2);
+ fprintf(stderr,
+ "Warning: atomnames at index %d don't match: %d %s, %d %s\n",
+ i + 1,
+ index1[i] + 1,
+ name1,
+ index2[i] + 1,
+ name2);
}
warn++;
}
default:
if (bBfac)
{
- fprintf(stderr, "WARNING: cannot write B-factor values to %s file\n",
+ fprintf(stderr,
+ "WARNING: cannot write B-factor values to %s file\n",
ftp2ext(fn2ftp(outfile)));
}
if (!bOne)
{
- fprintf(stderr, "WARNING: cannot write the reference structure to %s file\n",
+ fprintf(stderr,
+ "WARNING: cannot write the reference structure to %s file\n",
ftp2ext(fn2ftp(outfile)));
}
write_sto_conf(outfile, *top2->name, atoms2, x2, v2, pbcType2, box2);
};
#define NFILE asize(fnm)
- if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_TIME_UNIT, NFILE, fnm, asize(pa), pa,
- asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_TIME | PCA_TIME_UNIT, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
fprintf(stderr,
"\nWARNING: number of atoms in structure file (%d) and trajectory (%d) do not "
"match\n",
- natoms, nat);
+ natoms,
+ nat);
}
gmx::throwErrorIfIndexOutOfBounds({ ifit, ifit + nfit }, nat, "fitting");
gmx::throwErrorIfIndexOutOfBounds({ index, index + natoms }, nat, "analysis");
xread[index[i]][d] = xav[i][d];
}
}
- write_sto_conf_indexed(opt2fn("-av", NFILE, fnm), "Average structure", atoms, xread, nullptr,
- PbcType::No, zerobox, natoms, index);
+ write_sto_conf_indexed(
+ opt2fn("-av", NFILE, fnm), "Average structure", atoms, xread, nullptr, PbcType::No, zerobox, natoms, index);
sfree(xread);
- fprintf(stderr, "Constructing covariance matrix (%dx%d) ...\n", static_cast<int>(ndim),
+ fprintf(stderr,
+ "Constructing covariance matrix (%dx%d) ...\n",
+ static_cast<int>(ndim),
static_cast<int>(ndim));
nframes = 0;
nat = read_first_x(oenv, &status, trxfile, &t, &xread, box);
{
for (i = 0; i < ndim; i += 3)
{
- fprintf(out, "%g %g %g\n", mat[ndim * j + i], mat[ndim * j + i + 1],
- mat[ndim * j + i + 2]);
+ fprintf(out, "%g %g %g\n", mat[ndim * j + i], mat[ndim * j + i + 1], mat[ndim * j + i + 2]);
}
}
gmx_ffclose(out);
rhi.b = 0;
out = gmx_ffopen(xpmfile, "w");
nlevels = 80;
- write_xpm3(out, 0, "Covariance", bM ? "u nm^2" : "nm^2", "dim", "dim", ndim, ndim, axis,
- axis, mat2, min, 0.0, max, rlo, rmi, rhi, &nlevels);
+ write_xpm3(out,
+ 0,
+ "Covariance",
+ bM ? "u nm^2" : "nm^2",
+ "dim",
+ "dim",
+ ndim,
+ ndim,
+ axis,
+ axis,
+ mat2,
+ min,
+ 0.0,
+ max,
+ rlo,
+ rmi,
+ rhi,
+ &nlevels);
gmx_ffclose(out);
sfree(axis);
sfree(mat2);
rhi.b = 0;
out = gmx_ffopen(xpmafile, "w");
nlevels = 80;
- write_xpm3(out, 0, "Covariance", bM ? "u nm^2" : "nm^2", "atom", "atom", ndim / DIM,
- ndim / DIM, axis, axis, mat2, min, 0.0, max, rlo, rmi, rhi, &nlevels);
+ write_xpm3(out,
+ 0,
+ "Covariance",
+ bM ? "u nm^2" : "nm^2",
+ "atom",
+ "atom",
+ ndim / DIM,
+ ndim / DIM,
+ axis,
+ axis,
+ mat2,
+ min,
+ 0.0,
+ max,
+ rlo,
+ rmi,
+ rhi,
+ &nlevels);
gmx_ffclose(out);
sfree(axis);
for (i = 0; i < ndim / DIM; i++)
if (nframes - 1 < ndim)
{
end = nframes - 1;
- fprintf(stderr,
- "\nWARNING: there are fewer frames in your trajectory than there are\n");
+ fprintf(stderr, "\nWARNING: there are fewer frames in your trajectory than there are\n");
fprintf(stderr, "degrees of freedom in your system. Only generating the first\n");
fprintf(stderr, "%d out of %d eigenvectors and eigenvalues.\n", end, static_cast<int>(ndim));
}
WriteXref = eWXR_NOFIT;
}
- write_eigenvectors(eigvecfile, natoms, mat, TRUE, 1, end, WriteXref, x, bDiffMass1, xproj, bM,
- eigenvalues);
+ write_eigenvectors(
+ eigvecfile, natoms, mat, TRUE, 1, end, WriteXref, x, bDiffMass1, xproj, bM, eigenvalues);
out = gmx_ffopen(logfile, "w");
fprintf(out, "Working directory: %s\n\n", str);
- fprintf(out, "Read %d frames from %s (time %g to %g %s)\n", nframes, trxfile,
- output_env_conv_time(oenv, tstart), output_env_conv_time(oenv, tend),
+ fprintf(out,
+ "Read %d frames from %s (time %g to %g %s)\n",
+ nframes,
+ trxfile,
+ output_env_conv_time(oenv, tstart),
+ output_env_conv_time(oenv, tend),
output_env_get_time_unit(oenv).c_str());
if (bFit)
{
{
fprintf(out, "Fit is %smass weighted\n", bDiffMass1 ? "" : "non-");
}
- fprintf(out, "Diagonalized the %dx%d covariance matrix\n", static_cast<int>(ndim),
- static_cast<int>(ndim));
+ fprintf(out, "Diagonalized the %dx%d covariance matrix\n", static_cast<int>(ndim), static_cast<int>(ndim));
fprintf(out, "Trace of the covariance matrix before diagonalizing: %g\n", trace);
fprintf(out, "Trace of the covariance matrix after diagonalizing: %g\n\n", sum);
mj2 += iprod(mtrans[nfr], mtrans[nfr]);
md2 += iprod(mu[nfr], mu[nfr]);
- fprintf(fmj, "%.3f\t%8.5f\t%8.5f\t%8.5f\t%8.5f\t%8.5f\n", time[nfr], mtrans[nfr][XX],
- mtrans[nfr][YY], mtrans[nfr][ZZ], mj2 / refr, norm(mja_tmp) / refr);
- fprintf(fmd, "%.3f\t%8.5f\t%8.5f\t%8.5f\t%8.5f\t%8.5f\n", time[nfr], mu[nfr][XX],
- mu[nfr][YY], mu[nfr][ZZ], md2 / refr, norm(mdvec) / refr);
+ fprintf(fmj,
+ "%.3f\t%8.5f\t%8.5f\t%8.5f\t%8.5f\t%8.5f\n",
+ time[nfr],
+ mtrans[nfr][XX],
+ mtrans[nfr][YY],
+ mtrans[nfr][ZZ],
+ mj2 / refr,
+ norm(mja_tmp) / refr);
+ fprintf(fmd,
+ "%.3f\t%8.5f\t%8.5f\t%8.5f\t%8.5f\t%8.5f\n",
+ time[nfr],
+ mu[nfr][XX],
+ mu[nfr][YY],
+ mu[nfr][ZZ],
+ md2 / refr,
+ norm(mdvec) / refr);
nfr++;
printf("\n\nAverage translational dipole moment M_J [enm] after %d frames (|M|^2): %f %f %f "
"(%f)\n",
- nfr, mja_tmp[XX], mja_tmp[YY], mja_tmp[ZZ], mj2);
+ nfr,
+ mja_tmp[XX],
+ mja_tmp[YY],
+ mja_tmp[ZZ],
+ mj2);
printf("\n\nAverage molecular dipole moment M_D [enm] after %d frames (|M|^2): %f %f %f (%f)\n",
- nfr, mdvec[XX], mdvec[YY], mdvec[ZZ], md2);
+ nfr,
+ mdvec[XX],
+ mdvec[YY],
+ mdvec[ZZ],
+ md2);
if (v0 != nullptr)
{
dk_f = calceps(prefactor, md2 - mdav2, mj2 - mj, mjd - mjdav, eps_rf, FALSE);
fprintf(stderr, "\n\nFluctuations:\n epsilon=%f\n\n", dk_f);
- fprintf(stderr, "\n deltaM_D , deltaM_J, deltaM_JD: (%f, %f, %f)\n", md2 - mdav2, mj2 - mj,
- mjd - mjdav);
+ fprintf(stderr, "\n deltaM_D , deltaM_J, deltaM_JD: (%f, %f, %f)\n", md2 - mdav2, mj2 - mj, mjd - mjdav);
fprintf(stderr, "\n********************************************\n");
if (bINT)
{
if (bACF && (ii < nvfr))
{
fprintf(stderr, "Integral and integrated fit to the current acf yields at t=%f:\n", time[vfr[ii]]);
- fprintf(stderr, "sigma=%8.3f (pure integral: %.3f)\n",
- sgk - malt * std::pow(time[vfr[ii]], sigma), sgk);
+ fprintf(stderr, "sigma=%8.3f (pure integral: %.3f)\n", sgk - malt * std::pow(time[vfr[ii]], sigma), sgk);
}
if (ei > bi)
/* At first the arguments will be parsed and the system information processed */
- if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa,
- asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
{
if (bACF)
{
- outf = xvgropen(opt2fn("-caf", NFILE, fnm), "Current autocorrelation function",
- output_env_get_xvgr_tlabel(oenv), "ACF (e nm/ps)\\S2", oenv);
+ outf = xvgropen(opt2fn("-caf", NFILE, fnm),
+ "Current autocorrelation function",
+ output_env_get_xvgr_tlabel(oenv),
+ "ACF (e nm/ps)\\S2",
+ oenv);
fprintf(outf, "# time\t acf\t average \t std.dev\n");
}
- fcur = xvgropen(opt2fn("-o", NFILE, fnm), "Current", output_env_get_xvgr_tlabel(oenv),
- "J(t) (e nm/ps)", oenv);
+ fcur = xvgropen(opt2fn("-o", NFILE, fnm),
+ "Current",
+ output_env_get_xvgr_tlabel(oenv),
+ "J(t) (e nm/ps)",
+ oenv);
fprintf(fcur, "# time\t Jx\t Jy \t J_z \n");
if (bINT)
{
mcor = xvgropen(opt2fn("-mc", NFILE, fnm),
"M\\sD\\N - current autocorrelation function",
output_env_get_xvgr_tlabel(oenv),
- "< M\\sD\\N (0)\\c7\\CJ(t) > (e nm/ps)\\S2", oenv);
+ "< M\\sD\\N (0)\\c7\\CJ(t) > (e nm/ps)\\S2",
+ oenv);
fprintf(mcor, "# time\t M_D(0) J(t) acf \t Integral acf\n");
}
}
- fmj = xvgropen(opt2fn("-mj", NFILE, fnm), "Averaged translational part of M",
- output_env_get_xvgr_tlabel(oenv), "< M\\sJ\\N > (enm)", oenv);
+ fmj = xvgropen(opt2fn("-mj", NFILE, fnm),
+ "Averaged translational part of M",
+ output_env_get_xvgr_tlabel(oenv),
+ "< M\\sJ\\N > (enm)",
+ oenv);
fprintf(fmj, "# time\t x\t y \t z \t average of M_J^2 \t std.dev\n");
- fmd = xvgropen(opt2fn("-md", NFILE, fnm), "Averaged rotational part of M",
- output_env_get_xvgr_tlabel(oenv), "< M\\sD\\N > (enm)", oenv);
+ fmd = xvgropen(opt2fn("-md", NFILE, fnm),
+ "Averaged rotational part of M",
+ output_env_get_xvgr_tlabel(oenv),
+ "< M\\sD\\N > (enm)",
+ oenv);
fprintf(fmd, "# time\t x\t y \t z \t average of M_D^2 \t std.dev\n");
fmjdsp = xvgropen(
- opt2fn("-dsp", NFILE, fnm), "MSD of the squared translational dipole moment M",
+ opt2fn("-dsp", NFILE, fnm),
+ "MSD of the squared translational dipole moment M",
output_env_get_xvgr_tlabel(oenv),
- "<|M\\sJ\\N(t)-M\\sJ\\N(0)|\\S2\\N > / 6.0*V*k\\sB\\N*T / Sm\\S-1\\Nps\\S-1\\N", oenv);
+ "<|M\\sJ\\N(t)-M\\sJ\\N(0)|\\S2\\N > / 6.0*V*k\\sB\\N*T / Sm\\S-1\\Nps\\S-1\\N",
+ oenv);
/* System information is read and prepared, dielectric() processes the frames
* and calculates the requested quantities */
- dielectric(fmj, fmd, outf, fcur, mcor, fmjdsp, bNoJump, bACF, bINT, pbcType, top, fr, temp, bfit, efit,
- bvit, evit, status, isize, nmols, nshift, index0, indexm, mass2, qmol, eps_rf, oenv);
+ dielectric(fmj,
+ fmd,
+ outf,
+ fcur,
+ mcor,
+ fmjdsp,
+ bNoJump,
+ bACF,
+ bINT,
+ pbcType,
+ top,
+ fr,
+ temp,
+ bfit,
+ efit,
+ bvit,
+ evit,
+ status,
+ isize,
+ nmols,
+ nshift,
+ index0,
+ indexm,
+ mass2,
+ qmol,
+ eps_rf,
+ oenv);
xvgrclose(fmj);
xvgrclose(fmd);
i = index_center[k];
if (i >= atoms->nr)
{
- gmx_fatal(FARGS, "Index %d refers to atom %d, which is larger than natoms (%d).", k + 1,
- i + 1, atoms->nr);
+ gmx_fatal(FARGS,
+ "Index %d refers to atom %d, which is larger than natoms (%d).",
+ k + 1,
+ i + 1,
+ atoms->nr);
}
mm = atoms->atom[i].m;
tmass += mm;
/* now find the number of electrons. This is not efficient. */
found = static_cast<t_electron*>(
- bsearch(&sought, eltab, nr, sizeof(t_electron),
+ bsearch(&sought,
+ eltab,
+ nr,
+ sizeof(t_electron),
reinterpret_cast<int (*)(const void*, const void*)>(compare)));
if (found == nullptr)
{
- fprintf(stderr, "Couldn't find %s. Add it to the .dat file\n",
+ fprintf(stderr,
+ "Couldn't find %s. Add it to the .dat file\n",
*(top->atoms.atomname[index[n][i]]));
}
else
#define NFILE asize(fnm)
- if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, asize(pa), pa,
- asize(desc), desc, asize(bugs), bugs, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, asize(pa), pa, asize(desc), desc, asize(bugs), bugs, &oenv))
{
return 0;
}
nr_electrons = get_electrons(&el_tab, ftp2fn(efDAT, NFILE, fnm));
fprintf(stderr, "Read %d atomtypes from datafile\n", nr_electrons);
- calc_electron_density(ftp2fn(efTRX, NFILE, fnm), index, ngx, &density, &nslices, top,
- pbcType, axis, ngrps, &slWidth, el_tab, nr_electrons, bCenter,
- index_center, ncenter, bRelative, oenv);
+ calc_electron_density(ftp2fn(efTRX, NFILE, fnm),
+ index,
+ ngx,
+ &density,
+ &nslices,
+ top,
+ pbcType,
+ axis,
+ ngrps,
+ &slWidth,
+ el_tab,
+ nr_electrons,
+ bCenter,
+ index_center,
+ ncenter,
+ bRelative,
+ oenv);
}
else
{
- calc_density(ftp2fn(efTRX, NFILE, fnm), index, ngx, &density, &nslices, top, pbcType, axis,
- ngrps, &slWidth, bCenter, index_center, ncenter, bRelative, oenv, dens_opt);
- }
-
- plot_density(density, opt2fn("-o", NFILE, fnm), nslices, ngrps, grpname, slWidth, dens_opt,
- bCenter, bRelative, bSymmetrize, oenv);
+ calc_density(ftp2fn(efTRX, NFILE, fnm),
+ index,
+ ngx,
+ &density,
+ &nslices,
+ top,
+ pbcType,
+ axis,
+ ngrps,
+ &slWidth,
+ bCenter,
+ index_center,
+ ncenter,
+ bRelative,
+ oenv,
+ dens_opt);
+ }
+
+ plot_density(
+ density, opt2fn("-o", NFILE, fnm), nslices, ngrps, grpname, slWidth, dens_opt, bCenter, bRelative, bSymmetrize, oenv);
do_view(oenv, opt2fn("-o", NFILE, fnm), "-nxy"); /* view xvgr file */
return 0;
npargs = asize(pa);
- if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, npargs, pa,
- asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, npargs, pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
else
{
fp = gmx_ffopen(ftp2fn(efXPM, NFILE, fnm), "w");
- write_xpm(fp, MAT_SPATIAL_X | MAT_SPATIAL_Y, buf, unit, bRadial ? "axial (nm)" : label[c1],
- bRadial ? "r (nm)" : label[c2], n1, n2, tickx, tickz, grid, dmin, maxgrid, rlo,
- rhi, &nlev);
+ write_xpm(fp,
+ MAT_SPATIAL_X | MAT_SPATIAL_Y,
+ buf,
+ unit,
+ bRadial ? "axial (nm)" : label[c1],
+ bRadial ? "r (nm)" : label[c2],
+ n1,
+ n2,
+ tickx,
+ tickz,
+ grid,
+ dmin,
+ maxgrid,
+ rlo,
+ rhi,
+ &nlev);
gmx_ffclose(fp);
}
*yslices = 1;
}
}
- fprintf(stderr, "\nDividing the box in %5d x %5d x %5d slices with binw %f along axis %d\n",
- *xslices, *yslices, *zslices, bw, axis);
+ fprintf(stderr,
+ "\nDividing the box in %5d x %5d x %5d slices with binw %f along axis %d\n",
+ *xslices,
+ *yslices,
+ *zslices,
+ bw,
+ axis);
/****Start trajectory processing***/
if (debug)
{
- xvg = xvgropen("DensprofileonZ.xvg", "Averaged Densityprofile on Z", "z[nm]",
- "Density[kg/m^3]", oenv);
+ xvg = xvgropen(
+ "DensprofileonZ.xvg", "Averaged Densityprofile on Z", "z[nm]", "Density[kg/m^3]", oenv);
for (k = 0; k < zslices; k++)
{
fprintf(xvg, "%4f.3 %8f.4\n", k * binwidth, zDensavg[k]);
/*Fit average density in z over whole trajectory to obtain tentative fit-parameters in fit1 and fit2*/
/*Fit 1st half of box*/
- do_lmfit(zslices, zDensavg, sigma1, binwidth, nullptr, startpoint, splitpoint, oenv, FALSE,
- effnERF, beginfit1, 8, nullptr);
+ do_lmfit(zslices, zDensavg, sigma1, binwidth, nullptr, startpoint, splitpoint, oenv, FALSE, effnERF, beginfit1, 8, nullptr);
/*Fit 2nd half of box*/
- do_lmfit(zslices, zDensavg, sigma2, binwidth, nullptr, splitpoint, endpoint, oenv, FALSE,
- effnERF, beginfit2, 8, nullptr);
+ do_lmfit(zslices, zDensavg, sigma2, binwidth, nullptr, splitpoint, endpoint, oenv, FALSE, effnERF, beginfit2, 8, nullptr);
/*Initialise the const arrays for storing the average fit parameters*/
avgfit1 = beginfit1;
fit2[k] = avgfit2[k];
}
/*Now fit and store in structures in row-major order int[n][i][j]*/
- do_lmfit(zslices, Densmap[n][i][j], sigma1, binwidth, nullptr, startpoint,
- splitpoint, oenv, FALSE, effnERF, fit1, 0, nullptr);
+ do_lmfit(zslices,
+ Densmap[n][i][j],
+ sigma1,
+ binwidth,
+ nullptr,
+ startpoint,
+ splitpoint,
+ oenv,
+ FALSE,
+ effnERF,
+ fit1,
+ 0,
+ nullptr);
int1[n][j + (yslices * i)]->Z = fit1[2];
int1[n][j + (yslices * i)]->t = fit1[3];
- do_lmfit(zslices, Densmap[n][i][j], sigma2, binwidth, nullptr, splitpoint,
- endpoint, oenv, FALSE, effnERF, fit2, 0, nullptr);
+ do_lmfit(zslices,
+ Densmap[n][i][j],
+ sigma2,
+ binwidth,
+ nullptr,
+ splitpoint,
+ endpoint,
+ oenv,
+ FALSE,
+ effnERF,
+ fit2,
+ 0,
+ nullptr);
int2[n][j + (yslices * i)]->Z = fit2[2];
int2[n][j + (yslices * i)]->t = fit2[3];
}
}
}
- write_xpm(xpmfile1, 3, numbuf, "Height", "x[nm]", "y[nm]", xbins, ybins, xticks, yticks,
- profile1, min1, max1, lo, hi, &maplevels);
- write_xpm(xpmfile2, 3, numbuf, "Height", "x[nm]", "y[nm]", xbins, ybins, xticks, yticks,
- profile2, min2, max2, lo, hi, &maplevels);
+ write_xpm(xpmfile1, 3, numbuf, "Height", "x[nm]", "y[nm]", xbins, ybins, xticks, yticks, profile1, min1, max1, lo, hi, &maplevels);
+ write_xpm(xpmfile2, 3, numbuf, "Height", "x[nm]", "y[nm]", xbins, ybins, xticks, yticks, profile2, min2, max2, lo, hi, &maplevels);
}
gmx_ffclose(xpmfile1);
{
for (j = 0; j < ybins; j++)
{
- fprintf(raw1, "%i %i %8.5f %6.4f\n", i, j, (int1[n][j + ybins * i])->Z,
+ fprintf(raw1,
+ "%i %i %8.5f %6.4f\n",
+ i,
+ j,
+ (int1[n][j + ybins * i])->Z,
(int1[n][j + ybins * i])->t);
- fprintf(raw2, "%i %i %8.5f %6.4f\n", i, j, (int2[n][j + ybins * i])->Z,
+ fprintf(raw2,
+ "%i %i %8.5f %6.4f\n",
+ i,
+ j,
+ (int2[n][j + ybins * i])->Z,
(int2[n][j + ybins * i])->t);
}
}
{ efTPR, "-s", nullptr, ffREAD }, /* this is for the topology */
{ efTRX, "-f", nullptr, ffREAD }, /* and this for the trajectory */
{ efNDX, "-n", nullptr, ffREAD }, /* this is to select groups */
- { efDAT, "-o", "Density4D",
- ffOPTWR }, /* This is for outputting the entire 4D densityfield in binary format */
- { efOUT, "-or", nullptr,
- ffOPTWRMULT }, /* This is for writing out the entire information in the t_interf arrays */
- { efXPM, "-og", "interface",
- ffOPTWRMULT }, /* This is for writing out the interface meshes - one xpm-file per tblock*/
+ { efDAT, "-o", "Density4D", ffOPTWR }, /* This is for outputting the entire 4D densityfield in binary format */
+ { efOUT, "-or", nullptr, ffOPTWRMULT }, /* This is for writing out the entire information in the t_interf arrays */
+ { efXPM, "-og", "interface", ffOPTWRMULT }, /* This is for writing out the interface meshes - one xpm-file per tblock*/
{ efOUT, "-Spect", "intfspect", ffOPTWRMULT }, /* This is for the trajectory averaged Fourier-spectra*/
};
/* This is the routine responsible for adding default options,
* calling the X/motif interface, etc. */
- if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa,
- asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
get_index(&top->atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, ngx, index, grpname);
- density_in_time(ftp2fn(efTRX, NFILE, fnm), index, ngx, binw, binwz, nsttblock, &Densmap,
- &xslices, &yslices, &zslices, &tblock, top, pbcType, axis, bCenter, b1d, oenv);
+ density_in_time(ftp2fn(efTRX, NFILE, fnm),
+ index,
+ ngx,
+ binw,
+ binwz,
+ nsttblock,
+ &Densmap,
+ &xslices,
+ &yslices,
+ &zslices,
+ &tblock,
+ top,
+ pbcType,
+ axis,
+ bCenter,
+ b1d,
+ oenv);
if (ftorder > 0)
{
outputfield(opt2fn("-o", NFILE, fnm), Densmap, xslices, yslices, zslices, tblock);
}
- interfaces_txy(Densmap, xslices, yslices, zslices, tblock, binwz, eMeth, dens1, dens2, &surf1,
- &surf2, oenv);
+ interfaces_txy(
+ Densmap, xslices, yslices, zslices, tblock, binwz, eMeth, dens1, dens2, &surf1, &surf2, oenv);
if (bGraph)
{
fprintf(fp, "%10.5e %10.5e %10.5e\n", nu, kw.re, kw.im);
fprintf(cp, "%10.5e %10.5e\n", kw.re, kw.im);
}
- printf("MAXEPS = %10.5e at frequency %10.5e GHz (tauD = %8.1f ps)\n", maxeps, numax,
+ printf("MAXEPS = %10.5e at frequency %10.5e GHz (tauD = %8.1f ps)\n",
+ maxeps,
+ numax,
1000 / (2 * M_PI * numax));
xvgrclose(fp);
xvgrclose(cp);
{ "-nsmooth", FALSE, etINT, { &nsmooth }, "Number of points for smoothing" }
};
- if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa,
- asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
}
printf("DATA INTEGRAL: %5.1f, tauD(old) = %5.1f ps, "
"tau_slope = %5.1f, tau_slope,D = %5.1f ps\n",
- integral, integral * rffac, fitparms[0], fitparms[0] * rffac);
+ integral,
+ integral * rffac,
+ fitparms[0],
+ fitparms[0] * rffac);
- printf("tau_D from tau1 = %8.3g , eps(Infty) = %8.3f\n", fitparms[0] * (1 + fitparms[1] * lambda),
+ printf("tau_D from tau1 = %8.3g , eps(Infty) = %8.3f\n",
+ fitparms[0] * (1 + fitparms[1] * lambda),
1 + ((1 - fitparms[1]) * (eps0 - 1)) / (1 + fitparms[1] * lambda));
fitintegral = numerical_deriv(nx, y[0], y[1], y[3], y[4], y[5], tendInt, nsmooth);
copy_rvec(xcm[grp1][j], xk);
rvec_add(xj, mu[gi], xi);
rvec_add(xk, mu[gj], xl);
- phi = dih_angle(xi, xj, xk, xl, &pbc, r_ij, r_kj, r_kl, mm, nn, /* out */
- &t1, &t2, &t3);
+ phi = dih_angle(xi,
+ xj,
+ xk,
+ xl,
+ &pbc,
+ r_ij,
+ r_kj,
+ r_kl,
+ mm,
+ nn, /* out */
+ &t1,
+ &t2,
+ &t3);
cosa = std::cos(phi);
}
else
fprintf(debug ? debug : stderr,
"mu[%d] = %5.2f %5.2f %5.2f |mi| = %5.2f, mu[%d] = %5.2f %5.2f %5.2f "
"|mj| = %5.2f rr = %5.2f cosa = %5.2f\n",
- gi, mu[gi][XX], mu[gi][YY], mu[gi][ZZ], norm(mu[gi]), gj, mu[gj][XX],
- mu[gj][YY], mu[gj][ZZ], norm(mu[gj]), rr, cosa);
+ gi,
+ mu[gi][XX],
+ mu[gi][YY],
+ mu[gi][ZZ],
+ norm(mu[gi]),
+ gj,
+ mu[gj][XX],
+ mu[gj][YY],
+ mu[gj][ZZ],
+ norm(mu[gj]),
+ rr,
+ cosa);
}
add2gkr(gb, rr, cosa, phi);
/*2.0*j/(gb->ny-1.0)-1.0;*/
}
out = gmx_ffopen(cmap, "w");
- write_xpm(out, 0, "Dipole Orientation Distribution", "Fraction", "r (nm)", gb->bPhi ? "Phi" : "Alpha",
- gb->nx, gb->ny, xaxis, yaxis, gb->cmap, 0, hi, rlo, rhi, nlevels);
+ write_xpm(out,
+ 0,
+ "Dipole Orientation Distribution",
+ "Fraction",
+ "r (nm)",
+ gb->bPhi ? "Phi" : "Alpha",
+ gb->nx,
+ gb->ny,
+ xaxis,
+ yaxis,
+ gb->cmap,
+ 0,
+ hi,
+ rlo,
+ rhi,
+ nlevels);
gmx_ffclose(out);
sfree(xaxis);
sfree(yaxis);
fprintf(stderr,
"Something strange: expected %d entries in energy file at step %s\n(time %g) but "
"found %d entries\n",
- nre, gmx_step_str(fr->step, buf), fr->t, fr->nre);
+ nre,
+ gmx_step_str(fr->step, buf),
+ fr->t,
+ fr->nre);
}
if (bCont)
char buf[STRLEN];
int i;
real mutot;
- const char* leg_dim[4] = { "\\f{12}m\\f{4}\\sX\\N", "\\f{12}m\\f{4}\\sY\\N",
- "\\f{12}m\\f{4}\\sZ\\N", "\\f{12}m\\f{4}\\stot\\N" };
+ const char* leg_dim[4] = { "\\f{12}m\\f{4}\\sX\\N",
+ "\\f{12}m\\f{4}\\sY\\N",
+ "\\f{12}m\\f{4}\\sZ\\N",
+ "\\f{12}m\\f{4}\\stot\\N" };
sprintf(buf, "Box-%c (nm)", 'X' + idim);
fp = xvgropen(fn, "Average dipole moment per slab", buf, "\\f{12}m\\f{4} (D)", oenv);
for (i = 0; (i < nslice); i++)
{
mutot = norm(slab_dipole[i]) / nframes;
- fprintf(fp, "%10.3f %10.3f %10.3f %10.3f %10.3f\n",
- ((i + 0.5) * box[idim][idim]) / nslice, slab_dipole[i][XX] / nframes,
- slab_dipole[i][YY] / nframes, slab_dipole[i][ZZ] / nframes, mutot);
+ fprintf(fp,
+ "%10.3f %10.3f %10.3f %10.3f %10.3f\n",
+ ((i + 0.5) * box[idim][idim]) / nslice,
+ slab_dipole[i][XX] / nframes,
+ slab_dipole[i][YY] / nframes,
+ slab_dipole[i][ZZ] / nframes,
+ mutot);
}
xvgrclose(fp);
do_view(oenv, fn, "-autoscale xy -nxy");
#define NLEGMTOT asize(leg_mtot)
const char* leg_eps[] = { "epsilon", "G\\sk", "g\\sk" };
#define NLEGEPS asize(leg_eps)
- const char* leg_aver[] = { "< |M|\\S2\\N >", "< |M| >\\S2\\N", "< |M|\\S2\\N > - < |M| >\\S2\\N",
+ const char* leg_aver[] = { "< |M|\\S2\\N >",
+ "< |M| >\\S2\\N",
+ "< |M|\\S2\\N > - < |M| >\\S2\\N",
"< |M| >\\S2\\N / < |M|\\S2\\N >" };
#define NLEGAVER asize(leg_aver)
- const char* leg_cosaver[] = { "\\f{4}<|cos\\f{12}q\\f{4}\\sij\\N|>", "RMSD cos",
+ const char* leg_cosaver[] = { "\\f{4}<|cos\\f{12}q\\f{4}\\sij\\N|>",
+ "RMSD cos",
"\\f{4}<|cos\\f{12}q\\f{4}\\siX\\N|>",
"\\f{4}<|cos\\f{12}q\\f{4}\\siY\\N|>",
"\\f{4}<|cos\\f{12}q\\f{4}\\siZ\\N|>" };
mulsq = gmx_stats_init();
/* Open all the files */
- outmtot = xvgropen(out_mtot, "Total dipole moment of the simulation box vs. time", "Time (ps)",
- "Total Dipole Moment (Debye)", oenv);
+ outmtot = xvgropen(out_mtot,
+ "Total dipole moment of the simulation box vs. time",
+ "Time (ps)",
+ "Total Dipole Moment (Debye)",
+ oenv);
outeps = xvgropen(out_eps, "Epsilon and Kirkwood factors", "Time (ps)", "", oenv);
outaver = xvgropen(out_aver, "Total dipole moment", "Time (ps)", "D", oenv);
if (bSlab)
}
if (cosaver)
{
- caver = xvgropen(cosaver, bPairs ? "Average pair orientation" : "Average absolute dipole orientation",
- "Time (ps)", "", oenv);
+ caver = xvgropen(cosaver,
+ bPairs ? "Average pair orientation" : "Average absolute dipole orientation",
+ "Time (ps)",
+ "",
+ oenv);
xvgr_legend(caver, NLEGCOSAVER, bPairs ? leg_cosaver : &(leg_cosaver[1]), oenv);
}
{
fprintf(dip3d,
"set arrow %d from %f, %f, %f to %f, %f, %f lt %d # %d %d\n",
- i + 1, x[ind0][XX], x[ind0][YY], x[ind0][ZZ],
- x[ind0][XX] + dipole[i][XX] / 25, x[ind0][YY] + dipole[i][YY] / 25,
- x[ind0][ZZ] + dipole[i][ZZ] / 25, ncolour, ind0, i);
+ i + 1,
+ x[ind0][XX],
+ x[ind0][YY],
+ x[ind0][ZZ],
+ x[ind0][XX] + dipole[i][XX] / 25,
+ x[ind0][YY] + dipole[i][YY] / 25,
+ x[ind0][ZZ] + dipole[i][ZZ] / 25,
+ ncolour,
+ ind0,
+ i);
}
}
} /* End loop of all molecules in frame */
+ gmx::square(dipaxis[ZZ] - 0.5));
if (bPairs)
{
- fprintf(caver, "%10.3e %10.3e %10.3e %10.3e %10.3e %10.3e\n", t, dd, rms_cos,
- dipaxis[XX], dipaxis[YY], dipaxis[ZZ]);
+ fprintf(caver,
+ "%10.3e %10.3e %10.3e %10.3e %10.3e %10.3e\n",
+ t,
+ dd,
+ rms_cos,
+ dipaxis[XX],
+ dipaxis[YY],
+ dipaxis[ZZ]);
}
else
{
- fprintf(caver, "%10.3e %10.3e %10.3e %10.3e %10.3e\n", t, rms_cos, dipaxis[XX],
- dipaxis[YY], dipaxis[ZZ]);
+ fprintf(caver,
+ "%10.3e %10.3e %10.3e %10.3e %10.3e\n",
+ t,
+ rms_cos,
+ dipaxis[XX],
+ dipaxis[YY],
+ dipaxis[ZZ]);
}
}
*/
if ((skip == 0) || ((teller % skip) == 0))
{
- fprintf(outmtot, "%10g %12.8e %12.8e %12.8e %12.8e\n", t, M_av[XX], M_av[YY], M_av[ZZ],
+ fprintf(outmtot,
+ "%10g %12.8e %12.8e %12.8e %12.8e\n",
+ t,
+ M_av[XX],
+ M_av[YY],
+ M_av[ZZ],
std::sqrt(M_av2[XX] + M_av2[YY] + M_av2[ZZ]));
}
* the two. Here M is sum mu_i. Further write the finite system
* Kirkwood G factor and epsilon.
*/
- fprintf(outaver, "%10g %10.3e %10.3e %10.3e %10.3e\n", t, M2_ave, M_ave2, M_diff,
- M_ave2 / M2_ave);
+ fprintf(outaver, "%10g %10.3e %10.3e %10.3e %10.3e\n", t, M2_ave, M_ave2, M_diff, M_ave2 / M2_ave);
if (fnadip)
{
if (bTotal)
{
- do_autocorr(corf, oenv, "Autocorrelation Function of Total Dipole", teller, 1,
- muall, dt, mode, TRUE);
+ do_autocorr(
+ corf, oenv, "Autocorrelation Function of Total Dipole", teller, 1, muall, dt, mode, TRUE);
}
else
{
- do_autocorr(corf, oenv, "Dipole Autocorrelation Function", teller, gnx_tot, muall,
- dt, mode, std::strcmp(corrtype, "molsep") != 0);
+ do_autocorr(corf,
+ oenv,
+ "Dipole Autocorrelation Function",
+ teller,
+ gnx_tot,
+ muall,
+ dt,
+ mode,
+ std::strcmp(corrtype, "molsep") != 0);
}
}
}
}
if (m == mols->nr)
{
- gmx_fatal(FARGS, "index[%d]=%d does not correspond to the first atom of a molecule",
- i + 1, index[i] + 1);
+ gmx_fatal(FARGS,
+ "index[%d]=%d does not correspond to the first atom of a molecule",
+ i + 1,
+ index[i] + 1);
}
for (j = mols->index[m]; j < mols->index[m + 1]; j++)
{
npargs = asize(pa);
ppa = add_acf_pargs(&npargs, pa);
- if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, npargs, ppa,
- asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, npargs, ppa, asize(desc), desc, 0, nullptr, &oenv))
{
sfree(ppa);
return 0;
}
nFF[0] = nFA;
nFF[1] = nFB;
- do_dip(top, pbcType, det(box), ftp2fn(efTRX, NFILE, fnm), opt2fn("-o", NFILE, fnm),
- opt2fn("-eps", NFILE, fnm), opt2fn("-a", NFILE, fnm), opt2fn("-d", NFILE, fnm),
- opt2fn_null("-cos", NFILE, fnm), opt2fn_null("-dip3d", NFILE, fnm),
- opt2fn_null("-adip", NFILE, fnm), bPairs, corrtype[0], opt2fn("-c", NFILE, fnm), bGkr,
- opt2fn("-g", NFILE, fnm), bPhi, &nlevels, ndegrees, ncos, opt2fn("-cmap", NFILE, fnm),
- rcmax, bQuad, bMU, opt2fn("-en", NFILE, fnm), gnx, grpindex, mu_max, mu_aver, epsilonRF,
- temp, nFF, skip, bSlab, nslices, axtitle, opt2fn("-slab", NFILE, fnm), oenv);
+ do_dip(top,
+ pbcType,
+ det(box),
+ ftp2fn(efTRX, NFILE, fnm),
+ opt2fn("-o", NFILE, fnm),
+ opt2fn("-eps", NFILE, fnm),
+ opt2fn("-a", NFILE, fnm),
+ opt2fn("-d", NFILE, fnm),
+ opt2fn_null("-cos", NFILE, fnm),
+ opt2fn_null("-dip3d", NFILE, fnm),
+ opt2fn_null("-adip", NFILE, fnm),
+ bPairs,
+ corrtype[0],
+ opt2fn("-c", NFILE, fnm),
+ bGkr,
+ opt2fn("-g", NFILE, fnm),
+ bPhi,
+ &nlevels,
+ ndegrees,
+ ncos,
+ opt2fn("-cmap", NFILE, fnm),
+ rcmax,
+ bQuad,
+ bMU,
+ opt2fn("-en", NFILE, fnm),
+ gnx,
+ grpindex,
+ mu_max,
+ mu_aver,
+ epsilonRF,
+ temp,
+ nFF,
+ skip,
+ bSlab,
+ nslices,
+ axtitle,
+ opt2fn("-slab", NFILE, fnm),
+ oenv);
do_view(oenv, opt2fn("-o", NFILE, fnm), "-autoscale xy -nxy");
do_view(oenv, opt2fn("-eps", NFILE, fnm), "-autoscale xy -nxy");
gmx_fatal(FARGS,
"Label mismatch in distance restrains. Label for restraint %d is %d, "
"expected it to be either %d or %d",
- i / nat, label, label_old, label_old + 1);
+ i / nat,
+ label,
+ label_old,
+ label_old + 1);
}
}
dr[clust_id].aver_6[ndr] += disresdata->Rt_6[label];
snew(fshift, SHIFTS);
- ta_disres(n, &forceatoms[i], forceparams.data(), x, f, fshift, pbc, lam, &dvdl, nullptr,
- &fcd, nullptr);
+ ta_disres(n, &forceatoms[i], forceparams.data(), x, f, fshift, pbc, lam, &dvdl, nullptr, &fcd, nullptr);
sfree(fshift);
viol = disresdata->sumviol;
{
break;
}
- fprintf(log, "%6d%5s%8.3f%8.3f%8.3f%8.3f%8.3f%8.3f%8.3f\n", drs[i].label,
- yesno_names[drs[i].bCore], drs[i].up1, drs[i].r, drs[i].rT3, drs[i].rT6,
- drs[i].viol, drs[i].violT3, drs[i].violT6);
+ fprintf(log,
+ "%6d%5s%8.3f%8.3f%8.3f%8.3f%8.3f%8.3f%8.3f\n",
+ drs[i].label,
+ yesno_names[drs[i].bCore],
+ drs[i].up1,
+ drs[i].r,
+ drs[i].rT3,
+ drs[i].rT6,
+ drs[i].viol,
+ drs[i].violT3,
+ drs[i].violT6);
}
}
dump_viol(log, dd.nres, drs, FALSE);
fprintf(log, "+++ Sorted by linear averaged violations: +++\n");
- std::sort(drs, drs + dd.nres,
- [](const t_dr_stats& a, const t_dr_stats& b) { return a.viol > b.viol; }); // Reverse sort
+ std::sort(drs, drs + dd.nres, [](const t_dr_stats& a, const t_dr_stats& b) {
+ return a.viol > b.viol;
+ }); // Reverse sort
dump_viol(log, dd.nres, drs, TRUE);
dump_dump(log, dd.nres, drs);
gmx_fatal(FARGS,
"Inconsistency in cluster %s.\n"
"Found %d frames in trajectory rather than the expected %d\n",
- clust_name[k], dr[k].nframes, clust->index[k + 1] - clust->index[k]);
+ clust_name[k],
+ dr[k].nframes,
+ clust->index[k + 1] - clust->index[k]);
}
if (!clust_name[k])
{
{
mmm++;
}
- fprintf(fp, "%-10s%6d%8.3f %8.3f %8.3f %8.3f %8.3f %8.3f\n", clust_name[k],
- dr[k].nframes, sumV, maxV, sumVT3, maxVT3, sumVT6, maxVT6);
+ fprintf(fp,
+ "%-10s%6d%8.3f %8.3f %8.3f %8.3f %8.3f %8.3f\n",
+ clust_name[k],
+ dr[k].nframes,
+ sumV,
+ maxV,
+ sumVT3,
+ maxVT3,
+ sumVT6,
+ maxVT6);
}
fflush(fp);
sfree(drs);
{
printf("Warning: the maxdr that you have specified (%g) is smaller than\nthe largest "
"value in your simulation (%g)\n",
- max_dr, hi);
+ max_dr,
+ hi);
}
hi = max_dr;
}
printf("Highest level in the matrix will be %g\n", hi);
fp = gmx_ffopen(fn, "w");
- write_xpm(fp, 0, "Distance Violations", "<V> (nm)", "Residue", "Residue", n_res, n_res, t_res,
- t_res, matrix, 0, hi, rlo, rhi, &nlevels);
+ write_xpm(fp,
+ 0,
+ "Distance Violations",
+ "<V> (nm)",
+ "Residue",
+ "Residue",
+ n_res,
+ n_res,
+ t_res,
+ t_res,
+ matrix,
+ 0,
+ hi,
+ rlo,
+ rhi,
+ &nlevels);
gmx_ffclose(fp);
}
{ efNDX, "-c", "clust", ffOPTRD }, { efXPM, "-x", "matrix", ffOPTWR } };
#define NFILE asize(fnm)
- if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa,
- asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
ir->dr_tau = 0.0;
t_disresdata disresdata;
- init_disres(fplog, topInfo.mtop(), ir, DisResRunMode::AnalysisTool, DDRole::Master,
- NumRanks::Single, MPI_COMM_NULL, nullptr, &disresdata, nullptr, FALSE);
+ init_disres(fplog,
+ topInfo.mtop(),
+ ir,
+ DisResRunMode::AnalysisTool,
+ DDRole::Master,
+ NumRanks::Single,
+ MPI_COMM_NULL,
+ nullptr,
+ &disresdata,
+ nullptr,
+ FALSE);
int natoms = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box);
snew(f, 5 * natoms);
}
my_clust = clust->inv_clust[j];
range_check(my_clust, 0, clust->clust->nr);
- check_viol(fplog, idef.il[F_DISRES], idef.iparams, x, f, pbc_null, dr_clust, my_clust,
- isize, index, vvindex, &disresdata);
+ check_viol(
+ fplog, idef.il[F_DISRES], idef.iparams, x, f, pbc_null, dr_clust, my_clust, isize, index, vvindex, &disresdata);
}
else
{
- check_viol(fplog, idef.il[F_DISRES], idef.iparams, x, f, pbc_null, &dr, 0, isize, index,
- vvindex, &disresdata);
+ check_viol(fplog, idef.il[F_DISRES], idef.iparams, x, f, pbc_null, &dr, 0, isize, index, vvindex, &disresdata);
}
if (bPDB)
{
if (clust)
{
- dump_clust_stats(fplog, disresdata, idef.il[F_DISRES], idef.iparams, clust->clust, dr_clust,
- clust->grpname, isize, index);
+ dump_clust_stats(
+ fplog, disresdata, idef.il[F_DISRES], idef.iparams, clust->clust, dr_clust, clust->grpname, isize, index);
}
else
{
- dump_stats(fplog, j, disresdata, idef.il[F_DISRES], idef.iparams, &dr, isize, index,
- bPDB ? atoms.get() : nullptr);
+ dump_stats(fplog, j, disresdata, idef.il[F_DISRES], idef.iparams, &dr, isize, index, bPDB ? atoms.get() : nullptr);
if (bPDB)
{
- write_sto_conf(opt2fn("-q", NFILE, fnm), "Coloured by average violation in Angstrom",
- atoms.get(), xav, nullptr, ir->pbcType, box);
+ write_sto_conf(opt2fn("-q", NFILE, fnm),
+ "Coloured by average violation in Angstrom",
+ atoms.get(),
+ xav,
+ nullptr,
+ ir->pbcType,
+ box);
}
- dump_disre_matrix(opt2fn_null("-x", NFILE, fnm), &dr, disresdata.nres, j, idef,
- topInfo.mtop(), max_dr, nlevels, bThird);
+ dump_disre_matrix(
+ opt2fn_null("-x", NFILE, fnm), &dr, disresdata.nres, j, idef, topInfo.mtop(), max_dr, nlevels, bThird);
xvgrclose(out);
xvgrclose(aver);
xvgrclose(numv);
#if HAVE_PIPES || GMX_NATIVE_WINDOWS
sprintf(dssp, "%s -i %s %s", strings.dptr.c_str(), strings.pdbfile.c_str(), redirectionString.c_str());
#else
- sprintf(dssp, "%s -i %s -o %s > %s %s", strings.dptr.c_str(), strings.pdbfile.c_str(),
- strings.tmpfile.c_str(), NULL_DEVICE, redirectionString.c_str());
+ sprintf(dssp,
+ "%s -i %s -o %s > %s %s",
+ strings.dptr.c_str(),
+ strings.pdbfile.c_str(),
+ strings.tmpfile.c_str(),
+ NULL_DEVICE,
+ redirectionString.c_str());
#endif
}
{
if (nullptr != acc)
{
- fprintf(stderr, "%d residues were classified as hydrophobic and %d as hydrophilic.\n",
- naccb, naccf);
+ fprintf(stderr, "%d residues were classified as hydrophobic and %d as hydrophilic.\n", naccb, naccf);
}
mat->title = "Secondary structure";
if (i != j)
{
fprintf(stderr,
- "Not all residues were recognized (%d from %d), the result may be inaccurate!\n", j, i);
+ "Not all residues were recognized (%d from %d), the result may be inaccurate!\n",
+ j,
+ i);
}
for (i = 0; (i < n_surf); i++)
}
else
{
- fprintf(stderr, "Residue %s not found in surface database (%s)\n",
- *atoms->resinfo[i].name, surffn);
+ fprintf(stderr, "Residue %s not found in surface database (%s)\n", *atoms->resinfo[i].name, surffn);
}
}
}
}
fp = gmx_ffopen(fn, "w");
nlev = static_cast<int>(hi - lo + 1);
- write_xpm(fp, 0, "Solvent Accessible Surface", "Surface (A^2)", "Time", "Residue Index",
- nframe, nres, mat->axis_x.data(), mat->axis_y.data(), accr, lo, hi, rlo, rhi, &nlev);
+ write_xpm(fp,
+ 0,
+ "Solvent Accessible Surface",
+ "Surface (A^2)",
+ "Time",
+ "Residue Index",
+ nframe,
+ nres,
+ mat->axis_x.data(),
+ mat->axis_y.data(),
+ accr,
+ lo,
+ hi,
+ rlo,
+ rhi,
+ &nlev);
gmx_ffclose(fp);
}
}
leg.emplace_back(m.desc);
}
- fp = xvgropen(outfile, "Secondary Structure", output_env_get_xvgr_tlabel(oenv),
- "Number of Residues", oenv);
+ fp = xvgropen(
+ outfile, "Secondary Structure", output_env_get_xvgr_tlabel(oenv), "Number of Residues", oenv);
if (output_env_get_print_xvgr_codes(oenv))
{
fprintf(fp, "@ subtitle \"Structure = ");
int gmx_do_dssp(int argc, char* argv[])
{
const char* desc[] = {
- "[THISMODULE] ", "reads a trajectory file and computes the secondary structure for",
- "each time frame ", "calling the dssp program. If you do not have the dssp program,",
+ "[THISMODULE] ",
+ "reads a trajectory file and computes the secondary structure for",
+ "each time frame ",
+ "calling the dssp program. If you do not have the dssp program,",
"get it from http://swift.cmbi.ru.nl/gv/dssp. [THISMODULE] assumes ",
"that the dssp executable is located in ",
// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
"[TT]" GMX_DSSP_PROGRAM_PATH "[tt]. If this is not the case, then you should",
- "set an environment variable [TT]DSSP[tt] pointing to the dssp", "executable, e.g.: [PAR]",
+ "set an environment variable [TT]DSSP[tt] pointing to the dssp",
+ "executable, e.g.: [PAR]",
"[TT]setenv DSSP /opt/dssp/bin/dssp[tt][PAR]",
"Since version 2.0.0, dssp is invoked with a syntax that differs",
"from earlier versions. If you have an older version of dssp,",
"[REF].xpm[ref] matrix file. This file can be visualized with for instance",
"[TT]xv[tt] and can be converted to postscript with [TT]xpm2ps[tt].",
"Individual chains are separated by light grey lines in the [REF].xpm[ref] and",
- "postscript files.", "The number of residues with each secondary structure type and the",
+ "postscript files.",
+ "The number of residues with each secondary structure type and the",
"total secondary structure ([TT]-sss[tt]) count as a function of",
"time are also written to file ([TT]-sc[tt]).[PAR]",
"Solvent accessible surface (SAS) per residue can be calculated, both in",
};
#define NFILE asize(fnm)
- if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW | PCA_TIME_UNIT, NFILE, fnm,
- asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(&argc,
+ argv,
+ PCA_CAN_TIME | PCA_CAN_VIEW | PCA_TIME_UNIT,
+ NFILE,
+ fnm,
+ asize(pa),
+ pa,
+ asize(desc),
+ desc,
+ 0,
+ nullptr,
+ &oenv))
{
return 0;
}
if (fnTArea)
{
- fTArea = xvgropen(fnTArea, "Solvent Accessible Surface Area",
- output_env_get_xvgr_tlabel(oenv), "Area (nm\\S2\\N)", oenv);
+ fTArea = xvgropen(fnTArea,
+ "Solvent Accessible Surface Area",
+ output_env_get_xvgr_tlabel(oenv),
+ "Area (nm\\S2\\N)",
+ oenv);
xvgr_legend(fTArea, 2, leg, oenv);
}
else
npargs = asize(pa);
ppa = add_acf_pargs(&npargs, pa);
- if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, npargs, ppa,
- asize(desc), desc, asize(bugs), bugs, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, npargs, ppa, asize(desc), desc, asize(bugs), bugs, &oenv))
{
sfree(ppa);
return 0;
if (nframes < min_frames)
{
- gmx_fatal(FARGS, "You need at least %d frames in the trajectory and you only have %d.",
- min_frames, nframes);
+ gmx_fatal(FARGS, "You need at least %d frames in the trajectory and you only have %d.", min_frames, nframes);
}
dt = (t1 - t0) / (nframes - 1);
if (nV > 0)
normalizeAutocorrelation = opt2parg_bool("-normalize", npargs, ppa);
/* Note that we always disable normalization here, regardless of user settings */
- low_do_autocorr(nullptr, oenv, nullptr, nframes, gnx, nframes, c1, dt, eacNormal, 0, FALSE,
- FALSE, FALSE, -1, -1, 0);
+ low_do_autocorr(
+ nullptr, oenv, nullptr, nframes, gnx, nframes, c1, dt, eacNormal, 0, FALSE, FALSE, FALSE, -1, -1, 0);
snew(dos, DOS_NR);
for (j = 0; (j < DOS_NR); j++)
{
}
}
- fp = xvgropen(opt2fn("-vacf", NFILE, fnm), "Velocity autocorrelation function", "Time (ps)",
- "C(t)", oenv);
+ fp = xvgropen(
+ opt2fn("-vacf", NFILE, fnm), "Velocity autocorrelation function", "Time (ps)", "C(t)", oenv);
snew(tt, nframes / 2);
invNormalize = normalizeAutocorrelation ? 1.0 / dos[VACF][0] : 1.0;
}
xvgrclose(fp);
- fp = xvgropen(opt2fn("-mvacf", NFILE, fnm), "Mass-weighted velocity autocorrelation function",
- "Time (ps)", "C(t)", oenv);
+ fp = xvgropen(opt2fn("-mvacf", NFILE, fnm),
+ "Mass-weighted velocity autocorrelation function",
+ "Time (ps)",
+ "C(t)",
+ oenv);
invNormalize = normalizeAutocorrelation ? 1.0 / dos[VACF][0] : 1.0;
fprintf(fplog, "DoSTot = %g\n", dostot);
/* Now compute solid (2) and diffusive (3) components */
- fp = xvgropen(opt2fn("-dos", NFILE, fnm), "Density of states",
- bRecip ? "E (cm\\S-1\\N)" : "\\f{12}n\\f{4} (1/ps)", "\\f{4}S(\\f{12}n\\f{4})", oenv);
+ fp = xvgropen(opt2fn("-dos", NFILE, fnm),
+ "Density of states",
+ bRecip ? "E (cm\\S-1\\N)" : "\\f{12}n\\f{4} (1/ps)",
+ "\\f{4}S(\\f{12}n\\f{4})",
+ oenv);
xvgr_legend(fp, asize(DoSlegend), DoSlegend, oenv);
recip_fac = bRecip ? (1e7 / SPEED_OF_LIGHT) : 1.0;
for (j = 0; (j < nframes / 4); j++)
{
dos[DOS_DIFF][j] = DoS0 / (1 + gmx::square(DoS0 * M_PI * nu[j] / (6 * f * Natom)));
dos[DOS_SOLID][j] = dos[DOS][j] - dos[DOS_DIFF][j];
- fprintf(fp, "%10g %10g %10g %10g\n", recip_fac * nu[j], dos[DOS][j] / recip_fac,
- dos[DOS_SOLID][j] / recip_fac, dos[DOS_DIFF][j] / recip_fac);
+ fprintf(fp,
+ "%10g %10g %10g %10g\n",
+ recip_fac * nu[j],
+ dos[DOS][j] / recip_fac,
+ dos[DOS_SOLID][j] / recip_fac,
+ dos[DOS_DIFF][j] / recip_fac);
}
xvgrclose(fp);
rrange, krange, rincr, kincr, Rfrac;
int rkcount = 0, rblocksallocated = 0, kblocksallocated = 0;
- if (!parse_common_args(&argc, argv, PCA_CAN_BEGIN | PCA_CAN_END | PCA_CAN_VIEW | PCA_TIME_UNIT,
- NFILE, fnm, NPA, pa, asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(&argc,
+ argv,
+ PCA_CAN_BEGIN | PCA_CAN_END | PCA_CAN_VIEW | PCA_TIME_UNIT,
+ NFILE,
+ fnm,
+ NPA,
+ pa,
+ asize(desc),
+ desc,
+ 0,
+ nullptr,
+ &oenv))
{
return 0;
}
if (bRKout)
{
- rkfp = xvgropen(out_xvgrkfile, "Distance and \\f{Symbol}k\\f{}\\S2\\N trajectory",
- "Time (ps)", "Distance (nm) / \\f{Symbol}k\\f{}\\S2\\N", oenv);
+ rkfp = xvgropen(out_xvgrkfile,
+ "Distance and \\f{Symbol}k\\f{}\\S2\\N trajectory",
+ "Time (ps)",
+ "Distance (nm) / \\f{Symbol}k\\f{}\\S2\\N",
+ oenv);
xvgr_legend(rkfp, 2, rkleg, oenv);
}
if (bInstEffout)
{
- iefp = xvgropen(out_xvginstefffile, "Instantaneous RET Efficiency", "Time (ps)",
- "RET Efficiency", oenv);
+ iefp = xvgropen(out_xvginstefffile,
+ "Instantaneous RET Efficiency",
+ "Time (ps)",
+ "RET Efficiency",
+ oenv);
xvgr_legend(iefp, 1, ieleg, oenv);
}
{
rhist[i] /= rkcount * rrange / histbins;
}
- rhfp = xvgropen(out_xvgrhistfile, "Distance Distribution", "R (nm)",
- "Normalized Probability", oenv);
+ rhfp = xvgropen(out_xvgrhistfile,
+ "Distance Distribution",
+ "R (nm)",
+ "Normalized Probability",
+ oenv);
}
else
{
- rhfp = xvgropen(out_xvgrhistfile, "Distance Distribution", "R (nm)",
- "Probability", oenv);
+ rhfp = xvgropen(
+ out_xvgrhistfile, "Distance Distribution", "R (nm)", "Probability", oenv);
}
xvgr_legend(rhfp, 1, rhleg, oenv);
for (i = 0; i < histbins; i++)
{
khist[i] /= rkcount * krange / histbins;
}
- khfp = xvgropen(out_xvgkhistfile, "\\f{Symbol}k\\f{}\\S2\\N Distribution",
- "\\f{Symbol}k\\f{}\\S2\\N", "Normalized Probability", oenv);
+ khfp = xvgropen(out_xvgkhistfile,
+ "\\f{Symbol}k\\f{}\\S2\\N Distribution",
+ "\\f{Symbol}k\\f{}\\S2\\N",
+ "Normalized Probability",
+ oenv);
}
else
{
- khfp = xvgropen(out_xvgkhistfile, "\\f{Symbol}k\\f{}\\S2\\N Distribution",
- "\\f{Symbol}k\\f{}\\S2\\N", "Probability", oenv);
+ khfp = xvgropen(out_xvgkhistfile,
+ "\\f{Symbol}k\\f{}\\S2\\N Distribution",
+ "\\f{Symbol}k\\f{}\\S2\\N",
+ "Probability",
+ oenv);
}
xvgr_legend(khfp, 1, khleg, oenv);
for (i = 0; i < histbins; i++)
{ efXVG, "-etot", "energy", ffWRITE } };
#define NFILE asize(fnm)
- if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, asize(pa), pa,
- asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
fprintf(stderr,
"WARNING! could not find group %s (%d,%d) "
"in energy file\n",
- groupname, i, j);
+ groupname,
+ i,
+ j);
}
else
{
fprintf(stderr,
"Will build energy half-matrix of %d groups, %d elements, "
"over %d frames\n",
- ngroups, nset, nenergy);
+ ngroups,
+ nset,
+ nenergy);
snew(emat, egNR + egSP);
for (j = 0; (j < egNR + egSP); j++)
fprintf(stderr,
"Matrix of %s energy is uniform at %f "
"(will not produce output).\n",
- egrp_nm[m], emax);
+ egrp_nm[m],
+ emax);
}
else
{
out = gmx_ffopen(fn, "w");
if (emin >= emid)
{
- write_xpm(out, 0, label, "Energy (kJ/mol)", "Residue Index",
- "Residue Index", ngroups, ngroups, groupnr, groupnr, emat[m],
- emid, emax, rmid, rhi, &nlevels);
+ write_xpm(out,
+ 0,
+ label,
+ "Energy (kJ/mol)",
+ "Residue Index",
+ "Residue Index",
+ ngroups,
+ ngroups,
+ groupnr,
+ groupnr,
+ emat[m],
+ emid,
+ emax,
+ rmid,
+ rhi,
+ &nlevels);
}
else if (emax <= emid)
{
- write_xpm(out, 0, label, "Energy (kJ/mol)", "Residue Index",
- "Residue Index", ngroups, ngroups, groupnr, groupnr, emat[m],
- emin, emid, rlo, rmid, &nlevels);
+ write_xpm(out,
+ 0,
+ label,
+ "Energy (kJ/mol)",
+ "Residue Index",
+ "Residue Index",
+ ngroups,
+ ngroups,
+ groupnr,
+ groupnr,
+ emat[m],
+ emin,
+ emid,
+ rlo,
+ rmid,
+ &nlevels);
}
else
{
- write_xpm3(out, 0, label, "Energy (kJ/mol)", "Residue Index",
- "Residue Index", ngroups, ngroups, groupnr, groupnr, emat[m],
- emin, emid, emax, rlo, rmid, rhi, &nlevels);
+ write_xpm3(out,
+ 0,
+ label,
+ "Energy (kJ/mol)",
+ "Residue Index",
+ "Residue Index",
+ ngroups,
+ ngroups,
+ groupnr,
+ groupnr,
+ emat[m],
+ emin,
+ emid,
+ emax,
+ rlo,
+ rmid,
+ rhi,
+ &nlevels);
}
gmx_ffclose(out);
}
avold[i] = 0;
}
fp0 = xvgropen(fni, "Shear viscosity integral", "Time (ps)", "(kg m\\S-1\\N s\\S-1\\N ps)", oenv);
- fp1 = xvgropen(fn, "Shear viscosity using Einstein relation", "Time (ps)",
- "(kg m\\S-1\\N s\\S-1\\N)", oenv);
+ fp1 = xvgropen(
+ fn, "Shear viscosity using Einstein relation", "Time (ps)", "(kg m\\S-1\\N s\\S-1\\N)", oenv);
for (i = 0; i < nf4; i++)
{
for (m = 0; m <= nsets; m++)
if (debug)
{
char buf1[STEPSTRSIZE], buf2[STEPSTRSIZE];
- fprintf(debug, "Requested %d blocks, we have %d blocks, min %s nsteps %s\n", nb,
- eee[nb].b, gmx_step_str(eee[nb].nst_min, buf1), gmx_step_str(edat->nsteps, buf2));
+ fprintf(debug,
+ "Requested %d blocks, we have %d blocks, min %s nsteps %s\n",
+ nb,
+ eee[nb].b,
+ gmx_step_str(eee[nb].nst_min, buf1),
+ gmx_step_str(edat->nsteps, buf2));
}
if (eee[nb].b == nb && 5 * nb * eee[nb].nst_min >= 4 * edat->nsteps)
{
}
if (varh != NOTSET)
{
- fprintf(fp, "Enthalpy = %10g kJ/mol\n",
- hh * AVOGADRO / (KILO * nmol));
+ fprintf(fp, "Enthalpy = %10g kJ/mol\n", hh * AVOGADRO / (KILO * nmol));
}
if (alpha != NOTSET)
{
/* Calculate the time difference */
delta_t = t - start_t;
- fprintf(stdout, "\nStatistics over %s steps [ %.4f through %.4f ps ], %d data sets\n",
- gmx_step_str(nsteps, buf), start_t, t, nset);
+ fprintf(stdout,
+ "\nStatistics over %s steps [ %.4f through %.4f ps ], %d data sets\n",
+ gmx_step_str(nsteps, buf),
+ start_t,
+ t,
+ nset);
calc_averages(nset, edat, nbmin, nbmax);
fprintf(stdout, " '%s'", leg[i]);
}
}
- fprintf(stdout, " %s has statistics over %d points (frames)\n",
- nnotexact == 1 ? "is" : "are", edat->nframes);
+ fprintf(stdout,
+ " %s has statistics over %d points (frames)\n",
+ nnotexact == 1 ? "is" : "are",
+ edat->nframes);
fprintf(stdout, "All other statistics are over %s points\n", gmx_step_str(edat->npoints, buf));
}
fprintf(stdout, "\n");
- fprintf(stdout, "%-24s %10s %10s %10s %10s", "Energy", "Average", "Err.Est.", "RMSD",
+ fprintf(stdout,
+ "%-24s %10s %10s %10s %10s",
+ "Energy",
+ "Average",
+ "Err.Est.",
+ "RMSD",
"Tot-Drift");
if (bFee)
{
{
totaldrift = (edat->nsteps - 1) * esum->s[0].slope;
ee_pr(esum->s[0].ee / nmol, sizeof(eebuf), eebuf);
- fprintf(stdout, "%-24s %10g %10s %10s %10g (%s)", "Total", esum->s[0].av / nmol, eebuf,
- "--", totaldrift / nmol, enm[set[0]].unit);
+ fprintf(stdout,
+ "%-24s %10g %10s %10s %10g (%s)",
+ "Total",
+ esum->s[0].av / nmol,
+ eebuf,
+ "--",
+ totaldrift / nmol,
+ enm[set[0]].unit);
/* pr_aver,pr_stddev,a,totaldrift */
if (bFee)
{
- fprintf(stdout, " %10g %10g\n", std::log(expEtot) / beta + esum->s[0].av / nmol,
+ fprintf(stdout,
+ " %10g %10g\n",
+ std::log(expEtot) / beta + esum->s[0].av / nmol,
std::log(expEtot) / beta);
}
else
/*do_autocorr(corrfn,buf,nenergy,3,eneset,Dt,eacNormal,TRUE);*/
/* Do it for shear viscosity */
std::strcpy(buf, "Shear Viscosity");
- low_do_autocorr(corrfn, oenv, buf, edat->nframes, 3, (edat->nframes + 1) / 2, eneset,
- Dt, eacNormal, 1, TRUE, FALSE, FALSE, 0.0, 0.0, 0);
+ low_do_autocorr(corrfn,
+ oenv,
+ buf,
+ edat->nframes,
+ 3,
+ (edat->nframes + 1) / 2,
+ eneset,
+ Dt,
+ eacNormal,
+ 1,
+ TRUE,
+ FALSE,
+ FALSE,
+ 0.0,
+ 0.0,
+ 0);
/* Now for bulk viscosity */
std::strcpy(buf, "Bulk Viscosity");
- low_do_autocorr(corrfn, oenv, buf, edat->nframes, 1, (edat->nframes + 1) / 2,
- &(eneset[11]), Dt, eacNormal, 1, TRUE, FALSE, FALSE, 0.0, 0.0, 0);
+ low_do_autocorr(corrfn,
+ oenv,
+ buf,
+ edat->nframes,
+ 1,
+ (edat->nframes + 1) / 2,
+ &(eneset[11]),
+ Dt,
+ eacNormal,
+ 1,
+ TRUE,
+ FALSE,
+ FALSE,
+ 0.0,
+ 0.0,
+ 0);
factor = (Vaver * 1e-26 / (BOLTZMANN * Temp)) * Dt;
fp = xvgropen(visfn, buf, "Time (ps)", "\\8h\\4 (cp)", oenv);
if (fr->t != time[nenergy2])
{
- fprintf(stderr, "\nWARNING time mismatch %g!=%g at frame %s\n", fr->t,
- time[nenergy2], gmx_step_str(fr->step, buf));
+ fprintf(stderr,
+ "\nWARNING time mismatch %g!=%g at frame %s\n",
+ fr->t,
+ time[nenergy2],
+ gmx_step_str(fr->step, buf));
}
for (i = 0; i < nset; i++)
{
fp = nullptr;
if (runavgfn)
{
- fp = xvgropen(runavgfn, "Running average free energy difference", "Time (" unit_time ")",
- "\\8D\\4E (" unit_energy ")", oenv);
+ fp = xvgropen(runavgfn,
+ "Running average free energy difference",
+ "Time (" unit_time ")",
+ "\\8D\\4E (" unit_energy ")",
+ oenv);
xvgr_legend(fp, asize(ravgleg), ravgleg, oenv);
}
fprintf(stdout, "\n%-24s %10s\n", "Energy", "dF = -kT ln < exp(-(EB-EA)/kT) >A");
if (!derivative)
{
- sprintf(legend, "N(%s(%s=%g) | %s=%g)", deltag, lambda, foreign_lambda,
- lambda, start_lambda);
+ sprintf(legend, "N(%s(%s=%g) | %s=%g)", deltag, lambda, foreign_lambda, lambda, start_lambda);
}
else
{
if (j == 1 && ir->bExpanded)
{
- fprintf(*fp_dhdl, "%4d",
- static_cast<int>(value)); /* if expanded ensembles and zero, this is a state value, it's an integer. We need a cleaner conditional than if j==1! */
+ fprintf(*fp_dhdl, "%4d", static_cast<int>(value)); /* if expanded ensembles and zero, this is a state value, it's an integer. We need a cleaner conditional than if j==1! */
}
else
{
npargs = asize(pa);
ppa = add_acf_pargs(&npargs, pa);
- if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_BEGIN | PCA_CAN_END, NFILE, fnm,
- npargs, ppa, asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_VIEW | PCA_CAN_BEGIN | PCA_CAN_END, NFILE, fnm, npargs, ppa, asize(desc), desc, 0, nullptr, &oenv))
{
sfree(ppa);
return 0;
}
if (bDHDL)
{
- do_dhdl(fr, ir, &fp_dhdl, opt2fn("-odh", NFILE, fnm), bDp, &dh_blocks, &dh_hists,
- &dh_samples, &dh_lambdas, oenv);
+ do_dhdl(fr, ir, &fp_dhdl, opt2fn("-odh", NFILE, fnm), bDp, &dh_blocks, &dh_hists, &dh_samples, &dh_lambdas, oenv);
}
/*******************************************
else
{
double dt = (frame[cur].t - start_t) / (edat.nframes - 1);
- analyse_ener(opt2bSet("-corr", NFILE, fnm), opt2fn("-corr", NFILE, fnm),
- opt2fn("-evisco", NFILE, fnm), opt2fn("-eviscoi", NFILE, fnm), bFee, bSum,
- bFluct, bVisco, opt2fn("-vis", NFILE, fnm), nmol, start_step, start_t,
- frame[cur].step, frame[cur].t, reftemp, &edat, nset, set, bIsEner, leg, enm,
- Vaver, ezero, nbmin, nbmax, oenv);
+ analyse_ener(opt2bSet("-corr", NFILE, fnm),
+ opt2fn("-corr", NFILE, fnm),
+ opt2fn("-evisco", NFILE, fnm),
+ opt2fn("-eviscoi", NFILE, fnm),
+ bFee,
+ bSum,
+ bFluct,
+ bVisco,
+ opt2fn("-vis", NFILE, fnm),
+ nmol,
+ start_step,
+ start_t,
+ frame[cur].step,
+ frame[cur].t,
+ reftemp,
+ &edat,
+ nset,
+ set,
+ bIsEner,
+ leg,
+ enm,
+ Vaver,
+ ezero,
+ nbmin,
+ nbmax,
+ oenv);
if (bFluctProps)
{
calc_fluctuation_props(stdout, bDriftCorr, dt, nset, nmol, leg, &edat, nbmin, nbmax);
}
if (opt2bSet("-f2", NFILE, fnm))
{
- fec(opt2fn("-f2", NFILE, fnm), opt2fn("-ravg", NFILE, fnm), reftemp, nset, set, leg, &edat,
- time, oenv);
+ fec(opt2fn("-f2", NFILE, fnm), opt2fn("-ravg", NFILE, fnm), reftemp, nset, set, leg, &edat, time, oenv);
}
// Clean up!
done_enerdata_t(nset, &edat);
{ efTRO, "-oh", "highpass", ffOPTWR } };
#define NFILE asize(fnm)
- if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa,
- asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
}
if (outl && (bLowAll || fr % nf == nf - 1))
{
- write_trx(outl, nat, ind, topfile ? &(top.atoms) : nullptr, 0, t[nf - 1],
- bFit ? topbox : boxf, xf, nullptr, nullptr);
+ write_trx(outl,
+ nat,
+ ind,
+ topfile ? &(top.atoms) : nullptr,
+ 0,
+ t[nf - 1],
+ bFit ? topbox : boxf,
+ xf,
+ nullptr,
+ nullptr);
}
if (outh)
{
boxf[j][d] = topbox[j][d] + box[nf - 1][j][d] - boxf[j][d];
}
}
- write_trx(outh, nat, ind, topfile ? &(top.atoms) : nullptr, 0, t[nf - 1],
- bFit ? topbox : boxf, xf, nullptr, nullptr);
+ write_trx(outh,
+ nat,
+ ind,
+ topfile ? &(top.atoms) : nullptr,
+ 0,
+ t[nf - 1],
+ bFit ? topbox : boxf,
+ xf,
+ nullptr,
+ nullptr);
}
}
/* Cycle all the pointer and the box by one */
npargs = asize(pa);
ppa = add_acf_pargs(&npargs, pa);
- if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, npargs, ppa,
- asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, npargs, ppa, asize(desc), desc, 0, nullptr, &oenv))
{
sfree(ppa);
return 0;
t0 = t;
if (bQ)
{
- out = xvgropen(ftp2fn(efXVG, NFILE, fnm), "Radius of Charge (total and around axes)",
- "Time (ps)", "Rg (nm)", oenv);
+ out = xvgropen(ftp2fn(efXVG, NFILE, fnm),
+ "Radius of Charge (total and around axes)",
+ "Time (ps)",
+ "Rg (nm)",
+ oenv);
}
else if (bMOI)
{
- out = xvgropen(ftp2fn(efXVG, NFILE, fnm), "Moments of inertia (total and around axes)",
- "Time (ps)", "I (a.m.u. nm\\S2\\N)", oenv);
+ out = xvgropen(ftp2fn(efXVG, NFILE, fnm),
+ "Moments of inertia (total and around axes)",
+ "Time (ps)",
+ "I (a.m.u. nm\\S2\\N)",
+ oenv);
}
else
{
- out = xvgropen(ftp2fn(efXVG, NFILE, fnm), "Radius of gyration (total and around axes)",
- "Time (ps)", "Rg (nm)", oenv);
+ out = xvgropen(ftp2fn(efXVG, NFILE, fnm),
+ "Radius of gyration (total and around axes)",
+ "Time (ps)",
+ "Rg (nm)",
+ oenv);
}
if (bMOI)
{
tm = sub_xcm(nz == 0 ? x_s : x, nam, index + mol * nam, top.atoms.atom, xcm, bQ);
if (nz == 0)
{
- gyro += calc_gyro(x_s, nam, index + mol * nam, top.atoms.atom, tm, gvec1, d1, bQ,
- bRot, bMOI, trans);
+ gyro += calc_gyro(
+ x_s, nam, index + mol * nam, top.atoms.atom, tm, gvec1, d1, bQ, bRot, bMOI, trans);
}
else
{
{
int mode = eacVector;
- do_autocorr(opt2fn("-acf", NFILE, fnm), oenv, "Moment of inertia vector ACF", j, 3,
- moi_trans, (t - t0) / j, mode, FALSE);
+ do_autocorr(opt2fn("-acf", NFILE, fnm),
+ oenv,
+ "Moment of inertia vector ACF",
+ j,
+ 3,
+ moi_trans,
+ (t - t0) / j,
+ mode,
+ FALSE);
do_view(oenv, opt2fn("-acf", NFILE, fnm), "-nxy");
}
for (slice = 0; slice < nslices; slice++)
{
- fprintf(ord, "%8.3f %8.3f %8.3f %8.3f %e\n", slWidth * slice, factor * dipole[slice][XX],
- factor * dipole[slice][YY], factor * dipole[slice][ZZ], order[slice]);
+ fprintf(ord,
+ "%8.3f %8.3f %8.3f %8.3f %e\n",
+ slWidth * slice,
+ factor * dipole[slice][XX],
+ factor * dipole[slice][YY],
+ factor * dipole[slice][ZZ],
+ order[slice]);
}
xvgrclose(ord);
#define NFILE asize(fnm)
// Parse the user input in argv into pa
- if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, asize(pa), pa,
- asize(desc), desc, asize(bugs), bugs, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, asize(pa), pa, asize(desc), desc, asize(bugs), bugs, &oenv))
{
return 0;
}
rd_index(opt2fn("-nm", NFILE, fnm), 1, &nmic, &micelle, &micname);
}
- calc_h2order(ftp2fn(efTRX, NFILE, fnm), index, ngx, &slDipole, &slOrder, &slWidth, &nslices,
- top, pbcType, axis, bMicel, micelle, nmic, oenv);
+ calc_h2order(ftp2fn(efTRX, NFILE, fnm),
+ index,
+ ngx,
+ &slDipole,
+ &slOrder,
+ &slWidth,
+ &nslices,
+ top,
+ pbcType,
+ axis,
+ bMicel,
+ micelle,
+ nmic,
+ oenv);
h2order_plot(slDipole, slOrder, opt2fn("-o", NFILE, fnm), nslices, slWidth, oenv);
{
if (debug && bDebug)
{
- fprintf(debug, "Acc. group inconsist.. grp[%d] = %d, grp = %d (%s, %d)\n", ai,
- a->grp[ai], grp, file, line);
+ fprintf(debug, "Acc. group inconsist.. grp[%d] = %d, grp = %d (%s, %d)\n", ai, a->grp[ai], grp, file, line);
}
return NOTSET;
}
{
if (debug && bDebug)
{
- fprintf(debug, "Don. group inconsist.. grp[%d] = %d, grp = %d (%s, %d)\n", di,
- d->grp[di], grp, file, line);
+ fprintf(debug, "Don. group inconsist.. grp[%d] = %d, grp = %d (%s, %d)\n", di, d->grp[di], grp, file, line);
}
return NOTSET;
}
}
else if (grpd != hb->d.grp[id])
{
- gmx_fatal(FARGS, "Inconsistent donor groups, %d instead of %d, atom %d", grpd,
- hb->d.grp[id], d + 1);
+ gmx_fatal(FARGS, "Inconsistent donor groups, %d instead of %d, atom %d", grpd, hb->d.grp[id], d + 1);
}
if ((ia = hb->a.aptr[a]) == NOTSET)
{
}
else if (grpa != hb->a.grp[ia])
{
- gmx_fatal(FARGS, "Inconsistent acceptor groups, %d instead of %d, atom %d", grpa,
- hb->a.grp[ia], a + 1);
+ gmx_fatal(FARGS, "Inconsistent acceptor groups, %d instead of %d, atom %d", grpa, hb->a.grp[ia], a + 1);
}
if (bMerge)
}
else if (grpd != hb->d.grp[id])
{
- gmx_fatal(FARGS, "Inconsistent donor groups, %d instead of %d, atom %d", grpd,
- hb->d.grp[id], d + 1);
+ gmx_fatal(FARGS,
+ "Inconsistent donor groups, %d instead of %d, atom %d",
+ grpd,
+ hb->d.grp[id],
+ d + 1);
}
if ((ia = hb->a.aptr[a]) == NOTSET)
{
}
else if (grpa != hb->a.grp[ia])
{
- gmx_fatal(FARGS, "Inconsistent acceptor groups, %d instead of %d, atom %d", grpa,
- hb->a.grp[ia], a + 1);
+ gmx_fatal(FARGS,
+ "Inconsistent acceptor groups, %d instead of %d, atom %d",
+ grpa,
+ hb->a.grp[ia],
+ a + 1);
}
}
}
}
else
{
- printf("\nWill do grid-search on %dx%dx%d grid, rcut=%3.8f\n", ngrid[XX], ngrid[YY],
- ngrid[ZZ], rcut);
+ printf("\nWill do grid-search on %dx%dx%d grid, rcut=%3.8f\n", ngrid[XX], ngrid[YY], ngrid[ZZ], rcut);
}
if (((ngrid[XX] * ngrid[YY] * ngrid[ZZ]) * sizeof(grid)) > INT_MAX)
{
"the maximum of %zu. "
"You are likely either using a box that is too large (box dimensions are %3.8f "
"nm x%3.8f nm x%3.8f nm) or a cutoff (%3.8f nm) that is too small.",
- ngrid[XX], ngrid[YY], ngrid[ZZ], INT_MAX / sizeof(grid), box[XX][XX], box[YY][YY],
- box[ZZ][ZZ], rcut);
+ ngrid[XX],
+ ngrid[YY],
+ ngrid[ZZ],
+ INT_MAX / sizeof(grid),
+ box[XX][XX],
+ box[YY][YY],
+ box[ZZ][ZZ],
+ rcut);
}
snew(grid, ngrid[ZZ]);
for (z = 0; z < ngrid[ZZ]; z++)
}
else
{
- fp = xvgropen(fn, "Uninterrupted hydrogen bond lifetime", output_env_get_xvgr_tlabel(oenv),
- "()", oenv);
+ fp = xvgropen(
+ fn, "Uninterrupted hydrogen bond lifetime", output_env_get_xvgr_tlabel(oenv), "()", oenv);
}
xvgr_legend(fp, asize(leg), leg, oenv);
{
chi2 += gmx::square(k * ct[i] - kp * nt[i] - kt[i]);
}
- compute_weighted_rates(n, t, ct, nt, kt, sigma_ct, sigma_nt, sigma_kt, &k, &kp,
- &sigma_k, &sigma_kp, fit_start);
+ compute_weighted_rates(
+ n, t, ct, nt, kt, sigma_ct, sigma_nt, sigma_kt, &k, &kp, &sigma_k, &sigma_kp, fit_start);
Q = 0; /* quality_of_fit(chi2, 2);*/
ddg = BOLTZ * temp * sigma_k / k;
printf("Fitting paramaters chi^2 = %10g, Quality of fit = %10g\n", chi2, Q);
printf("The Rate and Delta G are followed by an error estimate\n");
printf("----------------------------------------------------------\n"
"Type Rate (1/ps) Sigma Time (ps) DG (kJ/mol) Sigma\n");
- printf("Forward %10.3f %6.2f %8.3f %10.3f %6.2f\n", k, sigma_k, 1 / k,
- calc_dg(1 / k, temp), ddg);
+ printf("Forward %10.3f %6.2f %8.3f %10.3f %6.2f\n",
+ k,
+ sigma_k,
+ 1 / k,
+ calc_dg(1 / k, temp),
+ ddg);
ddg = BOLTZ * temp * sigma_kp / kp;
- printf("Backward %10.3f %6.2f %8.3f %10.3f %6.2f\n", kp, sigma_kp, 1 / kp,
- calc_dg(1 / kp, temp), ddg);
+ printf("Backward %10.3f %6.2f %8.3f %10.3f %6.2f\n",
+ kp,
+ sigma_kp,
+ 1 / kp,
+ calc_dg(1 / kp, temp),
+ ddg);
}
else
{
if (sc2 > 0)
{
kow = 2 * sck / sc2;
- printf("One-way %10.3f %s%8.3f %10.3f\n", kow, bError ? " " : "", 1 / kow,
+ printf("One-way %10.3f %s%8.3f %10.3f\n",
+ kow,
+ bError ? " " : "",
+ 1 / kow,
calc_dg(1 / kow, temp));
}
else
{
printf(" - Numerical problems computing HB thermodynamics:\n"
"sc2 = %g sn2 = %g sk2 = %g sck = %g snk = %g scn = %g\n",
- sc2, sn2, sk2, sck, snk, scn);
+ sc2,
+ sn2,
+ sk2,
+ sck,
+ snk,
+ scn);
}
/* Determine integral of the correlation function */
tau_hb = evaluate_integral(n, t, ct, nullptr, (t[n - 1] - t[0]) / 2, &dtau);
- printf("Integral %10.3f %s%8.3f %10.3f\n", 1 / tau_hb, bError ? " " : "", tau_hb,
+ printf("Integral %10.3f %s%8.3f %10.3f\n",
+ 1 / tau_hb,
+ bError ? " " : "",
+ tau_hb,
calc_dg(tau_hb, temp));
e_1 = std::exp(-1.0);
for (i = 0; (i < n - 2); i++)
{
/* Determine tau_relax from linear interpolation */
tau_rlx = t[i] - t[0] + (e_1 - ct[i]) * (t[i + 1] - t[i]) / (ct[i + 1] - ct[i]);
- printf("Relaxation %10.3f %8.3f %s%10.3f\n", 1 / tau_rlx, tau_rlx,
- bError ? " " : "", calc_dg(tau_rlx, temp));
+ printf("Relaxation %10.3f %8.3f %s%10.3f\n",
+ 1 / tau_rlx,
+ tau_rlx,
+ bError ? " " : "",
+ calc_dg(tau_rlx, temp));
}
}
else
FILE* fp;
int i, j, k, m, ihb, idist, n2, nn;
- const char* legLuzar[] = { "Ac\\sfin sys\\v{}\\z{}(t)", "Ac(t)", "Cc\\scontact,hb\\v{}\\z{}(t)",
+ const char* legLuzar[] = { "Ac\\sfin sys\\v{}\\z{}(t)",
+ "Ac(t)",
+ "Cc\\scontact,hb\\v{}\\z{}(t)",
"-dAc\\sfs\\v{}\\z{}/dt" };
- gmx_bool bNorm = FALSE;
- double nhb = 0;
- real * rhbex = nullptr, *ht, *gt, *ght, *dght, *kt;
- real * ct, tail, tail2, dtail, *cct;
- const real tol = 1e-3;
- int nframes = hb->nframes;
+ gmx_bool bNorm = FALSE;
+ double nhb = 0;
+ real * rhbex = nullptr, *ht, *gt, *ght, *dght, *kt;
+ real * ct, tail, tail2, dtail, *cct;
+ const real tol = 1e-3;
+ int nframes = hb->nframes;
unsigned int **h = nullptr, **g = nullptr;
int nh, nhbonds, nhydro;
t_hbond* hbh;
}
/* The autocorrelation function is normalized after summation only */
- low_do_autocorr(nullptr, oenv, nullptr, nframes, 1, -1, &rhbex,
- hb->time[1] - hb->time[0], eacNormal, 1, FALSE, bNorm, FALSE, 0,
- -1, 0);
+ low_do_autocorr(nullptr,
+ oenv,
+ nullptr,
+ nframes,
+ 1,
+ -1,
+ &rhbex,
+ hb->time[1] - hb->time[0],
+ eacNormal,
+ 1,
+ FALSE,
+ bNorm,
+ FALSE,
+ 0,
+ -1,
+ 0);
/* Cross correlation analysis for thermodynamics */
for (j = nframes; (j < n2); j++)
printf("\nWARNING: Correlation function is probably not long enough\n"
"because the standard deviation in the tail of C(t) > %g\n"
"Tail value (average C(t) over second half of acf): %g +/- %g\n",
- tol, tail, dtail);
+ tol,
+ tail,
+ dtail);
}
for (j = 0; (j < nn); j++)
{
for (j = 0; (j < nn); j++)
{
- fprintf(fp, "%10g %10g %10g %10g %10g\n", hb->time[j] - hb->time[0], ct[j], cct[j],
- ght[j], kt[j]);
+ fprintf(fp, "%10g %10g %10g %10g %10g\n", hb->time[j] - hb->time[0], ct[j], cct[j], ght[j], kt[j]);
}
xvgrclose(fp);
"If you set [TT]-shell[tt], you will be asked for an additional index group",
"which should contain exactly one atom. In this case, only hydrogen",
- "bonds between atoms within the shell distance from the one atom are", "considered.[PAR]",
+ "bonds between atoms within the shell distance from the one atom are",
+ "considered.[PAR]",
"With option -ac, rate constants for hydrogen bonding can be derived with the",
"model of Luzar and Chandler (Nature 379:55, 1996; J. Chem. Phys. 113:23, 2000).",
"n(t) can be defined as either all pairs that are not within contact distance r at time t",
"(corresponding to leaving the -r2 option at the default value 0) or all pairs that",
"are within distance r2 (corresponding to setting a second cut-off value with option -r2).",
- "See mentioned literature for more details and definitions.", "[PAR]",
+ "See mentioned literature for more details and definitions.",
+ "[PAR]",
/* "It is also possible to analyse specific hydrogen bonds with",
"[TT]-sel[tt]. This index file must contain a group of atom triplets",
"note also that no check is made for the types of atoms.[PAR]",
*/
- "[BB]Output:[bb]", "", " * [TT]-num[tt]: number of hydrogen bonds as a function of time.",
+ "[BB]Output:[bb]",
+ "",
+ " * [TT]-num[tt]: number of hydrogen bonds as a function of time.",
" * [TT]-ac[tt]: average over all autocorrelations of the existence",
" functions (either 0 or 1) of all hydrogen bonds.",
" * [TT]-dist[tt]: distance distribution of all hydrogen bonds.",
" all solvent atoms involved in insertion.",
" * [TT]-hbm[tt]: existence matrix for all hydrogen bonds over all",
" frames, this also contains information on solvent insertion",
- " into hydrogen bonds. Ordering is identical to that in [TT]-hbn[tt]", " index file.",
+ " into hydrogen bonds. Ordering is identical to that in [TT]-hbn[tt]",
+ " index file.",
" * [TT]-dan[tt]: write out the number of donors and acceptors analyzed for",
" each timeframe. This is especially useful when using [TT]-shell[tt].",
" * [TT]-nhbdist[tt]: compute the number of HBonds per hydrogen in order to",
- " compare results to Raman Spectroscopy.", "",
+ " compare results to Raman Spectroscopy.",
+ "",
"Note: options [TT]-ac[tt], [TT]-life[tt], [TT]-hbn[tt] and [TT]-hbm[tt]",
"require an amount of memory proportional to the total numbers of donors",
"times the total number of acceptors in the selected group(s)."
npargs = asize(pa);
ppa = add_acf_pargs(&npargs, pa);
- if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_TIME_UNIT, NFILE, fnm, npargs, ppa,
- asize(desc), desc, asize(bugs), bugs, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_TIME | PCA_TIME_UNIT, NFILE, fnm, npargs, ppa, asize(desc), desc, asize(bugs), bugs, &oenv))
{
sfree(ppa);
return 0;
if (opt2bSet("-nhbdist", NFILE, fnm))
{
const char* leg[MAXHH + 1] = { "0 HBs", "1 HB", "2 HBs", "3 HBs", "Total" };
- fpnhb = xvgropen(opt2fn("-nhbdist", NFILE, fnm), "Number of donor-H with N HBs",
- output_env_get_xvgr_tlabel(oenv), "N", oenv);
+ fpnhb = xvgropen(opt2fn("-nhbdist", NFILE, fnm),
+ "Number of donor-H with N HBs",
+ output_env_get_xvgr_tlabel(oenv),
+ "N",
+ oenv);
xvgr_legend(fpnhb, asize(leg), leg, oenv);
}
{
if (ISINGRP(datable[index[1][i]]))
{
- gmx_fatal(FARGS, "Partial overlap between groups '%s' and '%s'", grpnames[0],
- grpnames[1]);
+ gmx_fatal(FARGS, "Partial overlap between groups '%s' and '%s'", grpnames[0], grpnames[1]);
}
}
}
{
printf("Calculating %s "
"between %s (%d atoms) and %s (%d atoms)\n",
- bContact ? "contacts" : "hydrogen bonds", grpnames[0], isize[0], grpnames[1],
+ bContact ? "contacts" : "hydrogen bonds",
+ grpnames[0],
+ isize[0],
+ grpnames[1],
isize[1]);
}
else
{
- fprintf(stderr, "Calculating %s in %s (%d atoms)\n",
- bContact ? "contacts" : "hydrogen bonds", grpnames[0], isize[0]);
+ fprintf(stderr,
+ "Calculating %s in %s (%d atoms)\n",
+ bContact ? "contacts" : "hydrogen bonds",
+ grpnames[0],
+ isize[0]);
}
}
sfree(datable);
gen_datable(index[i], isize[i], datable, top.atoms.nr);
if (bContact)
{
- search_acceptors(&top, isize[i], index[i], &hb->a, i, bNitAcc, TRUE,
- (bTwo && (i == gr0)) || !bTwo, datable);
- search_donors(&top, isize[i], index[i], &hb->d, i, TRUE,
- (bTwo && (i == gr1)) || !bTwo, datable);
+ search_acceptors(
+ &top, isize[i], index[i], &hb->a, i, bNitAcc, TRUE, (bTwo && (i == gr0)) || !bTwo, datable);
+ search_donors(&top, isize[i], index[i], &hb->d, i, TRUE, (bTwo && (i == gr1)) || !bTwo, datable);
}
else
{
shatom = shidx[0];
printf("Will calculate hydrogen bonds within a shell "
"of %g nm around atom %i\n",
- rshell, shatom + 1);
+ rshell,
+ shatom + 1);
}
/* Analyze trajectory */
/* Make a thread pool here,
* instead of forking anew at every frame. */
-#pragma omp parallel firstprivate(i) private( \
- j, h, ii, hh, xi, yi, zi, xj, yj, zj, threadNr, dist, ang, icell, jcell, grp, ogrp, ai, \
- aj, xjj, yjj, zjj, ihb, resdist, k, bTric, bEdge_xjj, bEdge_yjj) default(shared)
+#pragma omp parallel firstprivate(i) private(j, \
+ h, \
+ ii, \
+ hh, \
+ xi, \
+ yi, \
+ zi, \
+ xj, \
+ yj, \
+ zj, \
+ threadNr, \
+ dist, \
+ ang, \
+ icell, \
+ jcell, \
+ grp, \
+ ogrp, \
+ ai, \
+ aj, \
+ xjj, \
+ yjj, \
+ zjj, \
+ ihb, \
+ resdist, \
+ k, \
+ bTric, \
+ bEdge_xjj, \
+ bEdge_yjj) default(shared)
{ /* Start of parallel region */
if (bOMP)
{
{
try
{
- build_grid(hb, x, x[shatom], bBox, box, hbox, (rcut > r2cut) ? rcut : r2cut,
- rshell, ngrid, grid);
+ build_grid(hb, x, x[shatom], bBox, box, hbox, (rcut > r2cut) ? rcut : r2cut, rshell, ngrid, grid);
reset_nhbonds(&(hb->d));
if (debug && bDebug)
int dd = index[0][i];
int aa = index[0][i + 2];
/* int */ hh = index[0][i + 1];
- ihb = is_hbond(hb, ii, ii, dd, aa, rcut, r2cut, ccut, x, bBox, box,
- hbox, &dist, &ang, bDA, &h, bContact, bMerge);
+ ihb = is_hbond(
+ hb, ii, ii, dd, aa, rcut, r2cut, ccut, x, bBox, box, hbox, &dist, &ang, bDA, &h, bContact, bMerge);
if (ihb)
{
/* loop over all adjacent gridcells (xj,yj,zj) */
for (zjj = grid_loop_begin(ngrid[ZZ], zi, bTric, FALSE);
- zjj <= grid_loop_end(ngrid[ZZ], zi, bTric, FALSE); zjj++)
+ zjj <= grid_loop_end(ngrid[ZZ], zi, bTric, FALSE);
+ zjj++)
{
zj = grid_mod(zjj, ngrid[ZZ]);
bEdge_yjj = (zj == 0) || (zj == ngrid[ZZ] - 1);
j = jcell->atoms[aj];
/* check if this once was a h-bond */
- ihb = is_hbond(__HBDATA, grp, ogrp, i, j,
- rcut, r2cut, ccut, x, bBox,
- box, hbox, &dist, &ang, bDA,
- &h, bContact, bMerge);
+ ihb = is_hbond(__HBDATA,
+ grp,
+ ogrp,
+ i,
+ j,
+ rcut,
+ r2cut,
+ ccut,
+ x,
+ bBox,
+ box,
+ hbox,
+ &dist,
+ &ang,
+ bDA,
+ &h,
+ bContact,
+ bMerge);
if (ihb)
{
/* add to index if not already there */
/* Add a hbond */
- add_hbond(__HBDATA, i, j, h, grp, ogrp,
- nframes, bMerge, ihb, bContact);
+ add_hbond(__HBDATA, i, j, h, grp, ogrp, nframes, bMerge, ihb, bContact);
/* make angle and distance distributions */
if (ihb == hbHB && !bContact)
{
gmx_fatal(
FARGS,
- "Invalid donor %d", i);
+ "Invalid donor %d",
+ i);
}
if (acceptor_index(&hb->a, ogrp, j)
== NOTSET)
if (nframes < 2 && (opt2bSet("-ac", NFILE, fnm) || opt2bSet("-life", NFILE, fnm)))
{
- gmx_fatal(FARGS,
- "Cannot calculate autocorrelation of life times with less than two frames");
+ gmx_fatal(FARGS, "Cannot calculate autocorrelation of life times with less than two frames");
}
free_grid(ngrid, &grid);
{
printf("Found %d different %s in trajectory\n"
"Found %d different atom-pairs within %s distance\n",
- hb->nrhb, bContact ? "contacts" : "hydrogen bonds", hb->nrdist,
+ hb->nrhb,
+ bContact ? "contacts" : "hydrogen bonds",
+ hb->nrdist,
(r2cut > 0) ? "second cut-off" : "hydrogen bonding");
if (bMerge)
/* Print out number of hbonds and distances */
aver_nhb = 0;
aver_dist = 0;
- fp = xvgropen(opt2fn("-num", NFILE, fnm), bContact ? "Contacts" : "Hydrogen Bonds",
- output_env_get_xvgr_tlabel(oenv), "Number", oenv);
+ fp = xvgropen(opt2fn("-num", NFILE, fnm),
+ bContact ? "Contacts" : "Hydrogen Bonds",
+ output_env_get_xvgr_tlabel(oenv),
+ "Number",
+ oenv);
snew(leg, 2);
snew(leg[0], STRLEN);
snew(leg[1], STRLEN);
sum += rdist[i];
}
- fp = xvgropen(opt2fn("-dist", NFILE, fnm), "Hydrogen Bond Distribution",
+ fp = xvgropen(opt2fn("-dist", NFILE, fnm),
+ "Hydrogen Bond Distribution",
bDA ? "Donor - Acceptor Distance (nm)" : "Hydrogen - Acceptor Distance (nm)",
- "", oenv);
+ "",
+ oenv);
for (i = 0; i < nrbin; i++)
{
fprintf(fp, "%10g %10g\n", (i + 0.5) * rbin, rdist[i] / (rbin * sum));
sum += adist[i];
}
- fp = xvgropen(opt2fn("-ang", NFILE, fnm), "Hydrogen Bond Distribution",
- "Hydrogen - Donor - Acceptor Angle (\\SO\\N)", "", oenv);
+ fp = xvgropen(opt2fn("-ang", NFILE, fnm),
+ "Hydrogen Bond Distribution",
+ "Hydrogen - Donor - Acceptor Angle (\\SO\\N)",
+ "",
+ oenv);
for (i = 0; i < nabin; i++)
{
fprintf(fp, "%10g %10g\n", (i + 0.5) * abin, adist[i] / (abin * sum));
/* Print HB in alpha-helix */
if (opt2bSet("-hx", NFILE, fnm))
{
- fp = xvgropen(opt2fn("-hx", NFILE, fnm), "Hydrogen Bonds", output_env_get_xvgr_tlabel(oenv),
- "Count", oenv);
+ fp = xvgropen(opt2fn("-hx", NFILE, fnm),
+ "Hydrogen Bonds",
+ output_env_get_xvgr_tlabel(oenv),
+ "Count",
+ oenv);
xvgr_legend(fp, NRHXTYPES, hxtypenames, oenv);
for (i = 0; i < nframes; i++)
{
}
printf("Average number of %s per timeframe %.3f out of %g possible\n",
- bContact ? "contacts" : "hbonds", bContact ? aver_dist : aver_nhb, max_nhb);
+ bContact ? "contacts" : "hbonds",
+ bContact ? aver_dist : aver_nhb,
+ max_nhb);
/* Do Autocorrelation etc. */
if (hb->bHBmap)
}
if (opt2bSet("-ac", NFILE, fnm))
{
- do_hbac(opt2fn("-ac", NFILE, fnm), hb, nDump, bMerge, bContact, fit_start, temp,
- r2cut > 0, oenv, nThreads);
+ do_hbac(opt2fn("-ac", NFILE, fnm), hb, nDump, bMerge, bContact, fit_start, temp, r2cut > 0, oenv, nThreads);
}
if (opt2bSet("-life", NFILE, fnm))
{
#define USE_THIS_GROUP(j) (((j) == gr0) || (bTwo && ((j) == gr1)))
- fp = xvgropen(opt2fn("-dan", NFILE, fnm), "Donors and Acceptors",
- output_env_get_xvgr_tlabel(oenv), "Count", oenv);
+ fp = xvgropen(opt2fn("-dan", NFILE, fnm),
+ "Donors and Acceptors",
+ output_env_get_xvgr_tlabel(oenv),
+ "Count",
+ oenv);
nleg = (bTwo ? 2 : 1) * 2;
snew(legnames, nleg);
i = 0;
};
#define NFILE asize(fnm)
- if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, asize(pa), pa,
- asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
gmx_fatal(FARGS,
"Sorry can only run when the number of atoms in the run input file (%d) is equal "
"to the number in the trajectory (%d)",
- top->atoms.nr, natoms);
+ top->atoms.nr,
+ natoms);
}
- bb = mkbbind(ftp2fn(efNDX, NFILE, fnm), &nres, &nbb, r0, &nall, &allindex, top->atoms.atomname,
- top->atoms.atom, top->atoms.resinfo);
+ bb = mkbbind(ftp2fn(efNDX, NFILE, fnm),
+ &nres,
+ &nbb,
+ r0,
+ &nall,
+ &allindex,
+ top->atoms.atomname,
+ top->atoms.atom,
+ top->atoms.resinfo);
snew(bbindex, natoms);
snew(caindex, nres);
if (teller == 1)
{
- write_sto_conf(opt2fn("-cz", NFILE, fnm), "Helix fitted to Z-Axis", &(top->atoms),
- x, nullptr, pbcType, box);
+ write_sto_conf(
+ opt2fn("-cz", NFILE, fnm), "Helix fitted to Z-Axis", &(top->atoms), x, nullptr, pbcType, box);
}
xf[efhRAD].val = radius(xf[efhRAD].fp2, nca, caindex, x);
}
av_phipsi(xf[efhPHI].fp, xf[efhPSI].fp, xf[efhPHI].fp2, xf[efhPSI].fp2, t, nres, bb);
- av_hblen(xf[efhHB3].fp, xf[efhHB3].fp2, xf[efhHB4].fp, xf[efhHB4].fp2, xf[efhHB5].fp,
- xf[efhHB5].fp2, t, nres, bb);
+ av_hblen(xf[efhHB3].fp,
+ xf[efhHB3].fp2,
+ xf[efhHB4].fp,
+ xf[efhHB4].fp2,
+ xf[efhHB5].fp,
+ xf[efhHB5].fp2,
+ t,
+ nres,
+ bb);
}
} while (read_next_x(oenv, status, &t, x, box));
fprintf(stderr, "\n");
fprintf(xf[efhRMSA].fp, "%10d %10g\n", r0 + i, bb[i].rmsa / bb[i].nrms);
}
fprintf(xf[efhAHX].fp, "%10d %10g\n", r0 + i, (bb[i].nhx * 100.0) / static_cast<real>(teller));
- fprintf(xf[efhJCA].fp, "%10d %10g\n", r0 + i,
- 140.3 + (bb[i].jcaha / static_cast<double>(teller)));
+ fprintf(xf[efhJCA].fp, "%10d %10g\n", r0 + i, 140.3 + (bb[i].jcaha / static_cast<double>(teller)));
}
for (i = 0; (i < efhNR); i++)
};
#define NFILE asize(fnm)
- if (!parse_common_args(&argc, argv, PCA_CAN_TIME, NFILE, fnm, NPA, pa, asize(desc), desc, 0,
- nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_TIME, NFILE, fnm, NPA, pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
if (bIncremental)
{
- fptilt = xvgropen(opt2fn("-otilt", NFILE, fnm), "Incremental local helix tilt", "Time(ps)",
- "Tilt (degrees)", oenv);
- fprotation = xvgropen(opt2fn("-orot", NFILE, fnm), "Incremental local helix rotation",
- "Time(ps)", "Rotation (degrees)", oenv);
+ fptilt = xvgropen(opt2fn("-otilt", NFILE, fnm),
+ "Incremental local helix tilt",
+ "Time(ps)",
+ "Tilt (degrees)",
+ oenv);
+ fprotation = xvgropen(opt2fn("-orot", NFILE, fnm),
+ "Incremental local helix rotation",
+ "Time(ps)",
+ "Rotation (degrees)",
+ oenv);
}
else
{
- fptilt = xvgropen(opt2fn("-otilt", NFILE, fnm), "Cumulative local helix tilt", "Time(ps)",
- "Tilt (degrees)", oenv);
- fprotation = xvgropen(opt2fn("-orot", NFILE, fnm), "Cumulative local helix rotation",
- "Time(ps)", "Rotation (degrees)", oenv);
+ fptilt = xvgropen(opt2fn("-otilt", NFILE, fnm),
+ "Cumulative local helix tilt",
+ "Time(ps)",
+ "Tilt (degrees)",
+ oenv);
+ fprotation = xvgropen(opt2fn("-orot", NFILE, fnm),
+ "Cumulative local helix rotation",
+ "Time(ps)",
+ "Rotation (degrees)",
+ oenv);
}
clear_rvecs(3, unitaxes);
rvec_sub(bSC ? x_SC[i] : x_CA[i], residueorigin[i], residuevector[i]);
svmul(1.0 / norm(residuevector[i]), residuevector[i], residuevector[i]);
cprod(residuehelixaxis[i], residuevector[i], axis3[i]);
- fprintf(fpaxis, "%15.12g %15.12g %15.12g ", residuehelixaxis[i][0],
- residuehelixaxis[i][1], residuehelixaxis[i][2]);
- fprintf(fpcenter, "%15.12g %15.12g %15.12g ", residueorigin[i][0],
- residueorigin[i][1], residueorigin[i][2]);
+ fprintf(fpaxis,
+ "%15.12g %15.12g %15.12g ",
+ residuehelixaxis[i][0],
+ residuehelixaxis[i][1],
+ residuehelixaxis[i][2]);
+ fprintf(fpcenter,
+ "%15.12g %15.12g %15.12g ",
+ residueorigin[i][0],
+ residueorigin[i][1],
+ residueorigin[i][2]);
fprintf(fprise, "%15.12g ", residuerise[i]);
fprintf(fpradius, "%15.12g ", residueradius[i]);
}
}
- find_tetra_order_grid(top, pbcType, natoms, box, x, isize[0], index[0], &sg, &sk, *nslicex,
- *nslicey, nslicez, sg_grid, sk_grid);
+ find_tetra_order_grid(
+ top, pbcType, natoms, box, x, isize[0], index[0], &sg, &sk, *nslicex, *nslicey, nslicez, sg_grid, sk_grid);
GMX_RELEASE_ASSERT(sk_fravg != nullptr, "Trying to dereference NULL sk_fravg pointer");
for (i = 0; i < *nslicex; i++)
{
/*Debugging for printing out the entire order parameter meshes.*/
if (debug)
{
- fpsg = xvgropen("sg_ang_mesh", "S\\sg\\N Angle Order Parameter / Meshpoint", "(nm)",
- "S\\sg\\N", oenv);
- fpsk = xvgropen("sk_dist_mesh", "S\\sk\\N Distance Order Parameter / Meshpoint", "(nm)",
- "S\\sk\\N", oenv);
+ fpsg = xvgropen(
+ "sg_ang_mesh", "S\\sg\\N Angle Order Parameter / Meshpoint", "(nm)", "S\\sg\\N", oenv);
+ fpsk = xvgropen(
+ "sk_dist_mesh", "S\\sk\\N Distance Order Parameter / Meshpoint", "(nm)", "S\\sk\\N", oenv);
for (n = 0; n < (*nframes); n++)
{
fprintf(fpsg, "%i\n", n);
{
for (k = 0; k < nslicez; k++)
{
- fprintf(fpsg, "%4f %4f %4f %8f\n", (i + 0.5) * box[XX][XX] / (*nslicex),
+ fprintf(fpsg,
+ "%4f %4f %4f %8f\n",
+ (i + 0.5) * box[XX][XX] / (*nslicex),
(j + 0.5) * box[YY][YY] / (*nslicey),
- (k + 0.5) * box[ZZ][ZZ] / nslicez, sg_4d[n][i][j][k]);
- fprintf(fpsk, "%4f %4f %4f %8f\n", (i + 0.5) * box[XX][XX] / (*nslicex),
+ (k + 0.5) * box[ZZ][ZZ] / nslicez,
+ sg_4d[n][i][j][k]);
+ fprintf(fpsk,
+ "%4f %4f %4f %8f\n",
+ (i + 0.5) * box[XX][XX] / (*nslicex),
(j + 0.5) * box[YY][YY] / (*nslicey),
- (k + 0.5) * box[ZZ][ZZ] / nslicez, sk_4d[n][i][j][k]);
+ (k + 0.5) * box[ZZ][ZZ] / nslicez,
+ sk_4d[n][i][j][k]);
}
}
}
}
}
- write_xpm(xpmfile1, 3, numbuf, "Height", "x[nm]", "y[nm]", xbins, ybins, xticks, yticks,
- profile1, min1, max1, lo, hi, &maplevels);
- write_xpm(xpmfile2, 3, numbuf, "Height", "x[nm]", "y[nm]", xbins, ybins, xticks, yticks,
- profile2, min2, max2, lo, hi, &maplevels);
+ write_xpm(xpmfile1, 3, numbuf, "Height", "x[nm]", "y[nm]", xbins, ybins, xticks, yticks, profile1, min1, max1, lo, hi, &maplevels);
+ write_xpm(xpmfile2, 3, numbuf, "Height", "x[nm]", "y[nm]", xbins, ybins, xticks, yticks, profile2, min2, max2, lo, hi, &maplevels);
}
gmx_ffclose(xpmfile1);
const char * ndxfnm, *tpsfnm, *trxfnm;
gmx_output_env_t* oenv;
- if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, asize(pa), pa,
- asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
{
gmx_fatal(FARGS, "No or not correct number (2) of output-files: %td", intfn.ssize());
}
- calc_tetra_order_interface(ndxfnm, tpsfnm, trxfnm, binwidth, nsttblock, &frames, &xslices,
- &yslices, sg1, sg2, &intfpos, oenv);
+ calc_tetra_order_interface(
+ ndxfnm, tpsfnm, trxfnm, binwidth, nsttblock, &frames, &xslices, &yslices, sg1, sg2, &intfpos, oenv);
writesurftoxpms(intfpos, frames, xslices, yslices, binwidth, intfn, nlevels);
if (bFourier)
t_filenm fnm[] = { { efEDR, "-f", "ener", ffREAD }, { efXVG, "-o", "lie", ffWRITE } };
#define NFILE asize(fnm)
- if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, NPA, pa,
- asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, NPA, pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
ld = analyze_names(nre, enm, ligand);
snew(fr, 1);
- out = xvgropen(ftp2fn(efXVG, NFILE, fnm), "LIE free energy estimate", "Time (ps)",
- "DGbind (kJ/mol)", oenv);
+ out = xvgropen(
+ ftp2fn(efXVG, NFILE, fnm), "LIE free energy estimate", "Time (ps)", "DGbind (kJ/mol)", oenv);
while (do_enx(fp, fr))
{
ct = check_times(fr->t);
if (nframes > 0)
{
- printf("DGbind = %.3f (%.3f)\n", lieaver / nframes,
+ printf("DGbind = %.3f (%.3f)\n",
+ lieaver / nframes,
std::sqrt(lieav2 / nframes - gmx::square(lieaver / nframes)));
}
/* format error occured */
case sError:
- gmx_fatal(FARGS, "Error in the list of eigenvectors for %s at pos %td with char %c",
- listname, pos - startpos, *(pos - 1));
+ gmx_fatal(FARGS,
+ "Error in the list of eigenvectors for %s at pos %td with char %c",
+ listname,
+ pos - startpos,
+ *(pos - 1));
/* logical error occured */
case sZero:
gmx_fatal(FARGS,
"Error in the list of eigenvectors for %s at pos %td: eigenvector 0 is "
"not valid",
- listname, pos - startpos);
+ listname,
+ pos - startpos);
case sSmaller:
gmx_fatal(FARGS,
"Error in the list of eigenvectors for %s at pos %td: second index %d is "
"not bigger than %d",
- listname, pos - startpos, end_number, number);
+ listname,
+ pos - startpos,
+ end_number,
+ number);
}
++pos; /* read next character */
} /*scanner has finished */
gmx_fatal(FARGS,
"Selected eigenvector %d is higher than maximum number %d of available "
"eigenvectors",
- eig_list[n], nvec);
+ eig_list[n],
+ nvec);
}
copy_rvec(eigvecs[eig_list[n] - 1][i], x);
fprintf(fp, "%8.5f %8.5f %8.5f\n", x[XX], x[YY], x[ZZ]);
/* write edi-file */
/*Header*/
- fprintf(fp, "#MAGIC\n %d \n#NINI\n %d\n#FITMAS\n %d\n#ANALYSIS_MAS\n %d\n", MAGIC, edpars->nini,
- int(edpars->fitmas), int(edpars->pcamas));
- fprintf(fp, "#OUTFRQ\n %d\n#MAXLEN\n %d\n#SLOPECRIT\n %f\n", edpars->outfrq, edpars->maxedsteps,
- edpars->slope);
+ fprintf(fp,
+ "#MAGIC\n %d \n#NINI\n %d\n#FITMAS\n %d\n#ANALYSIS_MAS\n %d\n",
+ MAGIC,
+ edpars->nini,
+ int(edpars->fitmas),
+ int(edpars->pcamas));
+ fprintf(fp, "#OUTFRQ\n %d\n#MAXLEN\n %d\n#SLOPECRIT\n %f\n", edpars->outfrq, edpars->maxedsteps, edpars->slope);
fprintf(fp,
"#PRESTEPS\n %d\n#DELTA_F0\n %f\n#INIT_DELTA_F\n %f\n#TAU\n %f\n#EFL_NULL\n "
"%f\n#ALPHA2\n %f\n#KT\n %f\n#HARMONIC\n %d\n#CONST_FORCE_FLOODING\n %d\n",
- edpars->presteps, edpars->flood.deltaF0, edpars->flood.deltaF, edpars->flood.tau,
- edpars->flood.constEfl, edpars->flood.alpha2, edpars->flood.kT,
- int(edpars->flood.bHarmonic), int(edpars->flood.bConstForce));
+ edpars->presteps,
+ edpars->flood.deltaF0,
+ edpars->flood.deltaF,
+ edpars->flood.tau,
+ edpars->flood.constEfl,
+ edpars->flood.alpha2,
+ edpars->flood.kT,
+ int(edpars->flood.bHarmonic),
+ int(edpars->flood.bConstForce));
/* Average and reference positions */
write_t_edx(fp, edpars->sref, "NREF, XREF");
/*Eigenvectors */
write_eigvec(fp, edpars->ned, eig_listen[evMON], eigvecs, nvec, "COMPONENTS GROUP 1", nullptr);
- write_eigvec(fp, edpars->ned, eig_listen[evLINFIX], eigvecs, nvec, "COMPONENTS GROUP 2",
- evStepList[evLINFIX]);
- write_eigvec(fp, edpars->ned, eig_listen[evLINACC], eigvecs, nvec, "COMPONENTS GROUP 3",
- evStepList[evLINACC]);
- write_eigvec(fp, edpars->ned, eig_listen[evRADFIX], eigvecs, nvec, "COMPONENTS GROUP 4",
- evStepList[evRADFIX]);
+ write_eigvec(fp, edpars->ned, eig_listen[evLINFIX], eigvecs, nvec, "COMPONENTS GROUP 2", evStepList[evLINFIX]);
+ write_eigvec(fp, edpars->ned, eig_listen[evLINACC], eigvecs, nvec, "COMPONENTS GROUP 3", evStepList[evLINACC]);
+ write_eigvec(fp, edpars->ned, eig_listen[evRADFIX], eigvecs, nvec, "COMPONENTS GROUP 4", evStepList[evRADFIX]);
write_eigvec(fp, edpars->ned, eig_listen[evRADACC], eigvecs, nvec, "COMPONENTS GROUP 5", nullptr);
write_eigvec(fp, edpars->ned, eig_listen[evRADCON], eigvecs, nvec, "COMPONENTS GROUP 6", nullptr);
- write_eigvec(fp, edpars->ned, eig_listen[evFLOOD], eigvecs, nvec, "COMPONENTS GROUP 7",
- evStepList[evFLOOD]);
+ write_eigvec(fp, edpars->ned, eig_listen[evFLOOD], eigvecs, nvec, "COMPONENTS GROUP 7", evStepList[evFLOOD]);
/*Target and Origin positions */
ntar = read_conffile(StructureFile, &xtar);
printf("Select an index group of %d elements that corresponds to the atoms in the structure "
"file %s\n",
- ntar, StructureFile);
+ ntar,
+ StructureFile);
get_index(atoms, IndexFile, 1, &ngro, &igro, &grpname);
if (ngro != ntar)
{
if (opt2parg_bSet(evOptions[ev_class], NPA, pa))
{
/*get list of eigenvectors*/
- nvecs = sscan_list(&(listen[ev_class]), opt2parg_str(evOptions[ev_class], NPA, pa),
- evOptions[ev_class]);
+ nvecs = sscan_list(
+ &(listen[ev_class]), opt2parg_str(evOptions[ev_class], NPA, pa), evOptions[ev_class]);
if (ev_class < evStepNr - 2)
{
/*if apropriate get list of stepsizes for these eigenvectors*/
if (opt2parg_bSet(evStepOptions[ev_class], NPA, pa))
{
- evStepList[ev_class] = scan_vecparams(opt2parg_str(evStepOptions[ev_class], NPA, pa),
- evStepOptions[ev_class], nvecs);
+ evStepList[ev_class] = scan_vecparams(
+ opt2parg_str(evStepOptions[ev_class], NPA, pa), evStepOptions[ev_class], nvecs);
}
else /*if list is not given fill with zeros */
{
EigvecFile = opt2fn("-f", NFILE, fnm);
/*read eigenvectors from eigvec.trr*/
- read_eigenvectors(EigvecFile, &nav, &bFit1, &xref1, &edi_params.fitmas, &xav1,
- &edi_params.pcamas, &nvec1, &eignr1, &eigvec1, &eigval1);
+ read_eigenvectors(
+ EigvecFile, &nav, &bFit1, &xref1, &edi_params.fitmas, &xav1, &edi_params.pcamas, &nvec1, &eignr1, &eigvec1, &eigval1);
read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &pbcType, &xtop, nullptr, topbox, false);
atoms = &top.atoms;
if (listen[evFLOOD][0] != 0)
{
- read_eigenvalues(listen[evFLOOD], opt2fn("-eig", NFILE, fnm), evStepList[evFLOOD],
- bHesse, kB * T, nav);
+ read_eigenvalues(
+ listen[evFLOOD], opt2fn("-eig", NFILE, fnm), evStepList[evFLOOD], bHesse, kB * T, nav);
}
edi_params.flood.tau = tau;
gmx_output_env_t* oenv;
gmx_rmpbc_t gpbc = nullptr;
- if (!parse_common_args(&argc, argv, PCA_CAN_TIME, NFILE, fnm, asize(pa), pa, asize(desc), desc,
- 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_TIME, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
useatoms.resinfo[i] = top.atoms.resinfo[prevres];
if (debug)
{
- fprintf(debug, "New residue: atom %5s %5s %6d, index entry %5d, newres %5d\n",
+ fprintf(debug,
+ "New residue: atom %5s %5s %6d, index entry %5d, newres %5d\n",
*(top.atoms.resinfo[top.atoms.atom[ii].resind].name),
- *(top.atoms.atomname[ii]), ii, i, newres);
+ *(top.atoms.atomname[ii]),
+ ii,
+ i,
+ newres);
}
}
useatoms.atom[i].resind = newres;
if (bFrames)
{
sprintf(label, "t=%.0f ps", t);
- write_xpm(out, 0, label, "Distance (nm)", "Residue Index", "Residue Index", nres, nres,
- resnr, resnr, mdmat, 0, truncate, rlo, rhi, &nlevels);
+ write_xpm(out,
+ 0,
+ label,
+ "Distance (nm)",
+ "Residue Index",
+ "Residue Index",
+ nres,
+ nres,
+ resnr,
+ resnr,
+ mdmat,
+ 0,
+ truncate,
+ rlo,
+ rhi,
+ &nlevels);
}
} while (read_next_x(oenv, status, &t, x, box));
fprintf(stderr, "\n");
totmdmat[i][j] /= nframes;
}
}
- write_xpm(opt2FILE("-mean", NFILE, fnm, "w"), 0, "Mean smallest distance", "Distance (nm)",
- "Residue Index", "Residue Index", nres, nres, resnr, resnr, totmdmat, 0, truncate,
- rlo, rhi, &nlevels);
+ write_xpm(opt2FILE("-mean", NFILE, fnm, "w"),
+ 0,
+ "Mean smallest distance",
+ "Distance (nm)",
+ "Residue Index",
+ "Residue Index",
+ nres,
+ nres,
+ resnr,
+ resnr,
+ totmdmat,
+ 0,
+ truncate,
+ rlo,
+ rhi,
+ &nlevels);
if (bCalcN)
{
snew(legend[i], STRLEN);
}
tot_nmat(nres, natoms, nframes, totnmat, tot_n, mean_n);
- fp = xvgropen(ftp2fn(efXVG, NFILE, fnm), "Increase in number of contacts", "Residue",
- "Ratio", oenv);
+ fp = xvgropen(
+ ftp2fn(efXVG, NFILE, fnm), "Increase in number of contacts", "Residue", "Ratio", oenv);
sprintf(legend[0], "Total/mean");
sprintf(legend[1], "Total");
sprintf(legend[2], "Mean");
{
ratio = tot_n[i] / mean_n[i];
}
- fprintf(fp, "%3d %8.3f %3d %8.3f %3d %8.3f\n", i + 1, ratio, tot_n[i], mean_n[i],
- natm[i], mean_n[i] / natm[i]);
+ fprintf(fp,
+ "%3d %8.3f %3d %8.3f %3d %8.3f\n",
+ i + 1,
+ ratio,
+ tot_n[i],
+ mean_n[i],
+ natm[i],
+ mean_n[i] / natm[i]);
}
xvgrclose(fp);
}
check_index(nullptr, n, index, nullptr, natoms);
- out = xvgropen(outfn, "Minimum distance to periodic image", output_env_get_time_label(oenv),
- "Distance (nm)", oenv);
+ out = xvgropen(outfn,
+ "Minimum distance to periodic image",
+ output_env_get_time_label(oenv),
+ "Distance (nm)",
+ oenv);
if (output_env_get_print_xvgr_codes(oenv))
{
fprintf(out, "@ subtitle \"and maximum internal distance\"\n");
{
fprintf(out, "%s\n", output_env_get_print_xvgr_codes(oenv) ? "&" : "");
}
- fprintf(out, "\t%g\t%6.3f %6.3f %6.3f %6.3f %6.3f\n", output_env_conv_time(oenv, t), rmin,
- rmax, norm(box[0]), norm(box[1]), norm(box[2]));
+ fprintf(out,
+ "\t%g\t%6.3f %6.3f %6.3f %6.3f %6.3f\n",
+ output_env_conv_time(oenv, t),
+ rmin,
+ rmax,
+ norm(box[0]),
+ norm(box[1]),
+ norm(box[2]));
bFirst = FALSE;
} while (read_next_x(oenv, status, &t, x, box));
fprintf(stdout,
"\nThe shortest periodic distance is %g (nm) at time %g (%s),\n"
"between atoms %d and %d\n",
- rmint, output_env_conv_time(oenv, tmint), output_env_get_time_unit(oenv).c_str(),
- index[ind_mini] + 1, index[ind_minj] + 1);
+ rmint,
+ output_env_conv_time(oenv, tmint),
+ output_env_get_time_unit(oenv).c_str(),
+ index[ind_mini] + 1,
+ index[ind_minj] + 1);
}
static void calc_dist(real rcut,
for (j = 0; j < nres; j++)
{
- fprintf(respertime, "%s%d ",
+ fprintf(respertime,
+ "%s%d ",
*(atoms->resinfo[atoms->atom[index[0][residue[j]]].resind].name),
atoms->atom[index[0][residue[j]]].resind);
}
{
if (ng == 1)
{
- calc_dist(rcut, bPBC, pbcType, box, x0, gnx[0], gnx[0], index[0], index[0], bGroup,
- &dmin, &dmax, &nmin, &nmax, &min1, &min2, &max1, &max2);
+ calc_dist(rcut,
+ bPBC,
+ pbcType,
+ box,
+ x0,
+ gnx[0],
+ gnx[0],
+ index[0],
+ index[0],
+ bGroup,
+ &dmin,
+ &dmax,
+ &nmin,
+ &nmax,
+ &min1,
+ &min2,
+ &max1,
+ &max2);
fprintf(dist, " %12e", bMin ? dmin : dmax);
if (num)
{
{
for (k = i + 1; (k < ng); k++)
{
- calc_dist(rcut, bPBC, pbcType, box, x0, gnx[i], gnx[k], index[i], index[k],
- bGroup, &dmin, &dmax, &nmin, &nmax, &min1, &min2, &max1, &max2);
+ calc_dist(rcut,
+ bPBC,
+ pbcType,
+ box,
+ x0,
+ gnx[i],
+ gnx[k],
+ index[i],
+ index[k],
+ bGroup,
+ &dmin,
+ &dmax,
+ &nmin,
+ &nmax,
+ &min1,
+ &min2,
+ &max1,
+ &max2);
fprintf(dist, " %12e", bMin ? dmin : dmax);
if (num)
{
GMX_RELEASE_ASSERT(ng > 1, "Must have more than one group when not using -matrix");
for (i = 1; (i < ng); i++)
{
- calc_dist(rcut, bPBC, pbcType, box, x0, gnx[0], gnx[i], index[0], index[i], bGroup,
- &dmin, &dmax, &nmin, &nmax, &min1, &min2, &max1, &max2);
+ calc_dist(rcut,
+ bPBC,
+ pbcType,
+ box,
+ x0,
+ gnx[0],
+ gnx[i],
+ index[0],
+ index[i],
+ bGroup,
+ &dmin,
+ &dmax,
+ &nmin,
+ &nmax,
+ &min1,
+ &min2,
+ &max1,
+ &max2);
fprintf(dist, " %12e", bMin ? dmin : dmax);
if (num)
{
{
for (j = 0; j < nres; j++)
{
- calc_dist(rcut, bPBC, pbcType, box, x0, residue[j + 1] - residue[j], gnx[i],
- &(index[0][residue[j]]), index[i], bGroup, &dmin, &dmax, &nmin,
- &nmax, &min1r, &min2r, &max1r, &max2r);
+ calc_dist(rcut,
+ bPBC,
+ pbcType,
+ box,
+ x0,
+ residue[j + 1] - residue[j],
+ gnx[i],
+ &(index[0][residue[j]]),
+ index[i],
+ bGroup,
+ &dmin,
+ &dmax,
+ &nmin,
+ &nmax,
+ &min1r,
+ &min2r,
+ &max1r,
+ &max2r);
mindres[i - 1][j] = std::min(mindres[i - 1][j], dmin);
maxdres[i - 1][j] = std::max(maxdres[i - 1][j], dmax);
}
{
if (atm)
{
- fprintf(atm, "%12e %12d %12d\n", output_env_conv_time(oenv, t),
- 1 + (bMin ? min1 : max1), 1 + (bMin ? min2 : max2));
+ fprintf(atm,
+ "%12e %12d %12d\n",
+ output_env_conv_time(oenv, t),
+ 1 + (bMin ? min1 : max1),
+ 1 + (bMin ? min2 : max2));
}
}
{ efTRO, "-ox", "mindist", ffOPTWR }, { efXVG, "-or", "mindistres", ffOPTWR } };
#define NFILE asize(fnm)
- if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME | PCA_TIME_UNIT, NFILE, fnm,
- asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(&argc,
+ argv,
+ PCA_CAN_VIEW | PCA_CAN_TIME | PCA_TIME_UNIT,
+ NFILE,
+ fnm,
+ asize(pa),
+ pa,
+ asize(desc),
+ desc,
+ 0,
+ nullptr,
+ &oenv))
{
return 0;
}
}
else
{
- dist_plot(trxfnm, atmfnm, distfnm, numfnm, resfnm, oxfnm, rcutoff, bMat,
- top ? &(top->atoms) : nullptr, ng, index, gnx, grpname, bSplit, !bMax, nres,
- residues, bPBC, pbcType, bGroup, bEachResEachTime, bPrintResName, oenv);
+ dist_plot(trxfnm,
+ atmfnm,
+ distfnm,
+ numfnm,
+ resfnm,
+ oxfnm,
+ rcutoff,
+ bMat,
+ top ? &(top->atoms) : nullptr,
+ ng,
+ index,
+ gnx,
+ grpname,
+ bSplit,
+ !bMax,
+ nres,
+ residues,
+ bPBC,
+ pbcType,
+ bGroup,
+ bEachResEachTime,
+ bPrintResName,
+ oenv);
}
do_view(oenv, distfnm, "-nxy");
out = xvgropen(fn, title, output_env_get_xvgr_tlabel(oenv), yaxis, oenv);
if (DD)
{
- fprintf(out, "# MSD gathered over %g %s with %d restarts\n", msdtime,
- output_env_get_time_unit(oenv).c_str(), curr->nrestart);
- fprintf(out, "# Diffusion constants fitted from time %g to %g %s\n", beginfit, endfit,
+ fprintf(out,
+ "# MSD gathered over %g %s with %d restarts\n",
+ msdtime,
+ output_env_get_time_unit(oenv).c_str(),
+ curr->nrestart);
+ fprintf(out,
+ "# Diffusion constants fitted from time %g to %g %s\n",
+ beginfit,
+ endfit,
output_env_get_time_unit(oenv).c_str());
for (i = 0; i < curr->ngrp; i++)
{
fprintf(out, " %10g", curr->data[j][i]);
if (bTen)
{
- fprintf(out, " %10g %10g %10g %10g %10g %10g", curr->datam[j][i][XX][XX],
- curr->datam[j][i][YY][YY], curr->datam[j][i][ZZ][ZZ], curr->datam[j][i][YY][XX],
- curr->datam[j][i][ZZ][XX], curr->datam[j][i][ZZ][YY]);
+ fprintf(out,
+ " %10g %10g %10g %10g %10g %10g",
+ curr->datam[j][i][XX][XX],
+ curr->datam[j][i][YY][YY],
+ curr->datam[j][i][ZZ][ZZ],
+ curr->datam[j][i][YY][XX],
+ curr->datam[j][i][ZZ][XX],
+ curr->datam[j][i][ZZ][YY]);
}
}
fprintf(out, "\n");
Dav /= curr->nmol;
D2av /= curr->nmol;
VarD = D2av - gmx::square(Dav);
- printf("<D> = %.4f Std. Dev. = %.4f Error = %.4f\n", Dav, std::sqrt(VarD),
- std::sqrt(VarD / curr->nmol));
+ printf("<D> = %.4f Std. Dev. = %.4f Error = %.4f\n", Dav, std::sqrt(VarD), std::sqrt(VarD / curr->nmol));
if (fn_pdb && x)
{
fprintf(stderr,
"WARNING: The trajectory only contains part of the system (%d of %d atoms) and "
"therefore the COM motion of only this part of the system will be removed\n",
- natoms, top->atoms.nr);
+ natoms,
+ top->atoms.nr);
}
snew(x[prev], natoms);
curr->nframes++;
} while (read_next_x(oenv, status, &t, x[cur], box));
- fprintf(stderr, "\nUsed %d restart points spaced %g %s over %g %s\n\n", curr->nrestart,
- output_env_conv_time(oenv, dt), output_env_get_time_unit(oenv).c_str(),
+ fprintf(stderr,
+ "\nUsed %d restart points spaced %g %s over %g %s\n\n",
+ curr->nrestart,
+ output_env_conv_time(oenv, dt),
+ output_env_get_time_unit(oenv).c_str(),
output_env_conv_time(oenv, curr->time[curr->nframes - 1]),
output_env_get_time_unit(oenv).c_str());
index_atom2mol(&gnx[0], index[0], &top->mols);
}
- msd = std::make_unique<t_corr>(nrgrp, type, axis, dim_factor, mol_file == nullptr ? 0 : gnx[0],
- bTen, bMW, dt, top, beginfit, endfit);
-
- nat_trx = corr_loop(msd.get(), trx_file, top, pbcType, mol_file ? gnx[0] != 0 : false, gnx.data(),
- index, (mol_file != nullptr) ? calc1_mol : (bMW ? calc1_mw : calc1_norm),
- bTen, gnx_com, index_com, dt, t_pdb, pdb_file ? &x : nullptr, box, oenv);
+ msd = std::make_unique<t_corr>(
+ nrgrp, type, axis, dim_factor, mol_file == nullptr ? 0 : gnx[0], bTen, bMW, dt, top, beginfit, endfit);
+
+ nat_trx = corr_loop(msd.get(),
+ trx_file,
+ top,
+ pbcType,
+ mol_file ? gnx[0] != 0 : false,
+ gnx.data(),
+ index,
+ (mol_file != nullptr) ? calc1_mol : (bMW ? calc1_mw : calc1_norm),
+ bTen,
+ gnx_com,
+ index_com,
+ dt,
+ t_pdb,
+ pdb_file ? &x : nullptr,
+ box,
+ oenv);
/* Correct for the number of points */
for (j = 0; (j < msd->ngrp); j++)
fprintf(stderr,
"\nNo frame found need time tpdb = %g ps\n"
"Can not write %s\n\n",
- t_pdb, pdb_file);
+ t_pdb,
+ pdb_file);
}
i = top->atoms.nr;
top->atoms.nr = nat_trx;
{
for (i1 = i0; i1 < msd->nframes && msd->time[i1] <= endfit; i1++) {}
}
- fprintf(stdout, "Fitting from %g to %g %s\n\n", beginfit, endfit,
- output_env_get_time_unit(oenv).c_str());
+ fprintf(stdout, "Fitting from %g to %g %s\n\n", beginfit, endfit, output_env_get_time_unit(oenv).c_str());
N = i1 - i0;
if (N <= 2)
}
}
/* Print mean square displacement */
- corr_print(msd.get(), bTen, msd_file, "Mean Square Displacement", "MSD (nm\\S2\\N)",
- msd->time[msd->nframes - 1], beginfit, endfit, DD.data(), SigmaD.data(), grpname, oenv);
+ corr_print(msd.get(),
+ bTen,
+ msd_file,
+ "Mean Square Displacement",
+ "MSD (nm\\S2\\N)",
+ msd->time[msd->nframes - 1],
+ beginfit,
+ endfit,
+ DD.data(),
+ SigmaD.data(),
+ grpname,
+ oenv);
}
int gmx_msd(int argc, char* argv[])
real dim_factor;
gmx_output_env_t* oenv;
- if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_BEGIN | PCA_CAN_END | PCA_TIME_UNIT,
- NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(&argc,
+ argv,
+ PCA_CAN_VIEW | PCA_CAN_BEGIN | PCA_CAN_END | PCA_TIME_UNIT,
+ NFILE,
+ fnm,
+ asize(pa),
+ pa,
+ asize(desc),
+ desc,
+ 0,
+ nullptr,
+ &oenv))
{
return 0;
}
gmx_fatal(FARGS, "Could not read a topology from %s. Try a tpr file instead.", tps_file);
}
- do_corr(trx_file, ndx_file, msd_file, mol_file, pdb_file, t_pdb, ngroup, &top, pbcType, bTen,
- bMW, bRmCOMM, type, dim_factor, axis, dt, beginfit, endfit, oenv);
+ do_corr(trx_file,
+ ndx_file,
+ msd_file,
+ mol_file,
+ pdb_file,
+ t_pdb,
+ ngroup,
+ &top,
+ pbcType,
+ bTen,
+ bMW,
+ bRmCOMM,
+ type,
+ dim_factor,
+ axis,
+ dt,
+ beginfit,
+ endfit,
+ oenv);
done_top(&top);
view_all(oenv, NFILE, fnm);
gmx_fatal(FARGS,
"You asked to store %d eigenvectors of size %d, which requires more than the "
"supported %d elements; %sdecrease -last",
- numVector, nrow, INT_MAX, ignoreBegin ? "" : "increase -first and/or ");
+ numVector,
+ nrow,
+ INT_MAX,
+ ignoreBegin ? "" : "increase -first and/or ");
}
real* eigenvectors;
gmx_fatal(FARGS,
"Hessian size is %d x %d, which is larger than the maximum allowed %d "
"elements.",
- nrow, ncol, INT_MAX);
+ nrow,
+ ncol,
+ INT_MAX);
}
snew(full_hessian, hessianSize);
for (i = 0; i < nrow * ncol; i++)
/* now write the output */
fprintf(stderr, "Writing eigenvalues...\n");
- out = xvgropen(opt2fn("-ol", NFILE, fnm), "Eigenvalues", "Eigenvalue index",
- "Eigenvalue [Gromacs units]", oenv);
+ out = xvgropen(opt2fn("-ol", NFILE, fnm),
+ "Eigenvalues",
+ "Eigenvalue index",
+ "Eigenvalue [Gromacs units]",
+ oenv);
if (output_env_get_print_xvgr_codes(oenv))
{
if (bM)
}
printf("Writing eigenfrequencies - negative eigenvalues will be set to zero.\n");
- out = xvgropen(opt2fn("-of", NFILE, fnm), "Eigenfrequencies", "Eigenvector index",
- "Wavenumber [cm\\S-1\\N]", oenv);
+ out = xvgropen(opt2fn("-of", NFILE, fnm),
+ "Eigenfrequencies",
+ "Eigenvector index",
+ "Wavenumber [cm\\S-1\\N]",
+ oenv);
if (output_env_get_print_xvgr_codes(oenv))
{
if (bM)
snew(spectrum, maxspec);
spec = xvgropen(opt2fn("-os", NFILE, fnm),
"Vibrational spectrum based on harmonic approximation",
- "\\f{12}w\\f{4} (cm\\S-1\\N)", "Intensity [Gromacs units]", oenv);
+ "\\f{12}w\\f{4} (cm\\S-1\\N)",
+ "Intensity [Gromacs units]",
+ oenv);
for (i = 0; (i < maxspec); i++)
{
spectrum[i] = 0;
/* The sparse matrix diagonalization store all eigenvectors up to end */
eigenvectorPtr = eigenvectors + (begin - 1) * atom_index.size();
}
- write_eigenvectors(opt2fn("-v", NFILE, fnm), atom_index.size(), eigenvectorPtr, FALSE, begin,
- end, eWXR_NO, nullptr, FALSE, top_x, bM, eigenvalues);
+ write_eigenvectors(opt2fn("-v", NFILE, fnm),
+ atom_index.size(),
+ eigenvectorPtr,
+ FALSE,
+ begin,
+ end,
+ eWXR_NO,
+ nullptr,
+ FALSE,
+ top_x,
+ bM,
+ eigenvalues);
if (begin == 1)
{
- analyzeThermochemistry(stdout, top, top_x, atom_index, eigenvalues, T, P, sigma_r,
- scale_factor, linear_toler);
+ analyzeThermochemistry(
+ stdout, top, top_x, atom_index, eigenvalues, T, P, sigma_r, scale_factor, linear_toler);
please_cite(stdout, "Spoel2018a");
}
else
indexfile = ftp2fn_null(efNDX, NFILE, fnm);
- read_eigenvectors(opt2fn("-v", NFILE, fnm), &natoms, &bFit, &xref, &bDMR, &xav, &bDMA, &nvec,
- &eignr, &eigvec, &eigval);
+ read_eigenvectors(
+ opt2fn("-v", NFILE, fnm), &natoms, &bFit, &xref, &bDMR, &xav, &bDMA, &nvec, &eignr, &eigvec, &eigval);
read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &pbcType, &xtop, nullptr, box, bDMA);
atoms = &top.atoms;
int npargs;
npargs = asize(pa);
- if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_BEGIN | PCA_CAN_END, NFILE, fnm,
- npargs, pa, asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_VIEW | PCA_CAN_BEGIN | PCA_CAN_END, NFILE, fnm, npargs, pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
}
if (bORT)
{
- fort = xvgropen(opt2fn("-ort", NFILE, fnm), "Calculated orientations",
- "Time (ps)", "", oenv);
+ fort = xvgropen(
+ opt2fn("-ort", NFILE, fnm), "Calculated orientations", "Time (ps)", "", oenv);
if (bOrinst && output_env_get_print_xvgr_codes(oenv))
{
fprintf(fort, "%s", orinst_sub);
}
if (bODT)
{
- fodt = xvgropen(opt2fn("-odt", NFILE, fnm), "Orientation restraint deviation",
- "Time (ps)", "", oenv);
+ fodt = xvgropen(opt2fn("-odt", NFILE, fnm),
+ "Orientation restraint deviation",
+ "Time (ps)",
+ "",
+ oenv);
if (bOrinst && output_env_get_print_xvgr_codes(oenv))
{
fprintf(fodt, "%s", orinst_sub);
xvgr_legend(out_disre, 2, drleg, oenv);
if (bDRAll)
{
- fp_pairs = xvgropen(opt2fn("-pairs", NFILE, fnm), "Pair Distances", "Time (ps)",
- "Distance (nm)", oenv);
+ fp_pairs = xvgropen(
+ opt2fn("-pairs", NFILE, fnm), "Pair Distances", "Time (ps)", "Distance (nm)", oenv);
if (output_env_get_print_xvgr_codes(oenv))
{
fprintf(fp_pairs, "@ subtitle \"averaged (tau=%g) and instantaneous\"\n", ir->dr_tau);
gmx_fatal(FARGS,
"Number of disre pairs in the energy file (%d) does not match the "
"number in the run input file (%d)\n",
- ndisre, ilist.size() / 3);
+ ndisre,
+ ilist.size() / 3);
}
snew(pairleg, ndisre);
int molb = 0;
k = fa[3 * i + 2];
mtopGetAtomAndResidueName(topInfo.mtop(), j, &molb, &anm_j, &resnr_j, &resnm_j, nullptr);
mtopGetAtomAndResidueName(topInfo.mtop(), k, &molb, &anm_k, &resnr_k, &resnm_k, nullptr);
- sprintf(pairleg[i], "%d %s %d %s (%d)", resnr_j, anm_j, resnr_k, anm_k,
+ sprintf(pairleg[i],
+ "%d %s %d %s (%d)",
+ resnr_j,
+ anm_j,
+ resnr_k,
+ anm_k,
ip[fa[3 * i]].disres.label);
}
set = select_it(ndisre, pairleg, &nset);
}
/* Subtract bounds from distances, to calculate violations */
- calc_violations(disre_rt, disre_rm3tav, nbounds, pair, bounds, violaver,
- &sumt, &sumaver);
+ calc_violations(
+ disre_rt, disre_rm3tav, nbounds, pair, bounds, violaver, &sumt, &sumaver);
fprintf(out_disre, " %8.4f %8.4f\n", sumaver, sumt);
if (bDRAll)
gmx_fatal(FARGS,
"Number of orientation restraints in energy file (%d) does "
"not match with the topology (%d)",
- blk->sub[0].nr, nor);
+ blk->sub[0].nr,
+ nor);
}
if (bORA || bODA)
{
gmx_fatal(FARGS,
"Number of orientation experiments in energy file (%d) does "
"not match with the topology (%d)",
- blk->sub[0].nr / 12, nex);
+ blk->sub[0].nr / 12,
+ nex);
}
fprintf(foten, " %10f", fr.t);
for (i = 0; i < nex; i++)
}
if (bORA)
{
- FILE* out = xvgropen(opt2fn("-ora", NFILE, fnm), "Average calculated orientations",
- "Restraint label", "", oenv);
+ FILE* out = xvgropen(
+ opt2fn("-ora", NFILE, fnm), "Average calculated orientations", "Restraint label", "", oenv);
if (bOrinst && output_env_get_print_xvgr_codes(oenv))
{
fprintf(out, "%s", orinst_sub);
}
if (bODA)
{
- FILE* out = xvgropen(opt2fn("-oda", NFILE, fnm), "Average restraint deviation",
- "Restraint label", "", oenv);
+ FILE* out = xvgropen(
+ opt2fn("-oda", NFILE, fnm), "Average restraint deviation", "Restraint label", "", oenv);
if (bOrinst && output_env_get_print_xvgr_codes(oenv))
{
fprintf(out, "%s", orinst_sub);
}
if (bODR)
{
- FILE* out = xvgropen(opt2fn("-odr", NFILE, fnm), "RMS orientation restraint deviations",
- "Restraint label", "", oenv);
+ FILE* out = xvgropen(opt2fn("-odr", NFILE, fnm),
+ "RMS orientation restraint deviations",
+ "Restraint label",
+ "",
+ oenv);
if (bOrinst && output_env_get_print_xvgr_codes(oenv))
{
fprintf(out, "%s", orinst_sub);
if (bDisRe)
{
- analyse_disre(opt2fn("-viol", NFILE, fnm), teller_disre, violaver, bounds, index, pair,
- nbounds, oenv);
+ analyse_disre(opt2fn("-viol", NFILE, fnm), teller_disre, violaver, bounds, index, pair, nbounds, oenv);
}
{
const char* nxy = "-nxy";
return 0;
}
- read_eigenvectors(opt2fn("-v", NFILE, fnm), &natoms, &bFit, &xref, &bDMR, &xav, &bDMA, &nvec,
- &eignr, &eigvec, &eigval);
+ read_eigenvectors(
+ opt2fn("-v", NFILE, fnm), &natoms, &bFit, &xref, &bDMR, &xav, &bDMA, &nvec, &eignr, &eigvec, &eigval);
read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &pbcType, &xtop, nullptr, box, bDMA);
nframes = 0;
do
{
- find_nearest_neighbours(pbcType, natoms, box, x, isize[0], index[0], &sg, &sk, nslice,
- slice_dim, sg_slice, sk_slice, gpbc);
+ find_nearest_neighbours(
+ pbcType, natoms, box, x, isize[0], index[0], &sg, &sk, nslice, slice_dim, sg_slice, sk_slice, gpbc);
for (i = 0; (i < nslice); i++)
{
sg_slice_tot[i] += sg_slice[i];
fpsk = xvgropen(skslfn, "S\\sk\\N Distance Order Parameter / Slab", "(nm)", "S\\sk\\N", oenv);
for (i = 0; (i < nslice); i++)
{
- fprintf(fpsg, "%10g %10g\n", (i + 0.5) * box[slice_dim][slice_dim] / nslice,
+ fprintf(fpsg,
+ "%10g %10g\n",
+ (i + 0.5) * box[slice_dim][slice_dim] / nslice,
sg_slice_tot[i] / static_cast<real>(nframes));
- fprintf(fpsk, "%10g %10g\n", (i + 0.5) * box[slice_dim][slice_dim] / nslice,
+ fprintf(fpsk,
+ "%10g %10g\n",
+ (i + 0.5) * box[slice_dim][slice_dim] / nslice,
sk_slice_tot[i] / static_cast<real>(nframes));
}
xvgrclose(fpsg);
fprintf(stderr, "Using following groups: \n");
for (i = 0; i < ngrps; i++)
{
- fprintf(stderr, "Groupname: %s First atomname: %s First atomnr %d\n", groups[i],
- *(top->atoms.atomname[a[index[i]]]), a[index[i]]);
+ fprintf(stderr,
+ "Groupname: %s First atomname: %s First atomnr %d\n",
+ groups[i],
+ *(top->atoms.atomname[a[index[i]]]),
+ a[index[i]]);
}
fprintf(stderr, "\n");
}
fprintf(stderr,
"WARNING: distance between atoms %d and "
"%d > 0.3 nm (%f). Index file might be corrupt.\n",
- a, b, length);
+ a,
+ b,
+ length);
}
}
for (i = 1; i < ngrps - 1; i++)
{
svmul(1.0 / nr_frames, (*order)[i], (*order)[i]);
- fprintf(stderr, "Atom %d Tensor: x=%g , y=%g, z=%g\n", i, (*order)[i][XX], (*order)[i][YY],
+ fprintf(stderr,
+ "Atom %d Tensor: x=%g , y=%g, z=%g\n",
+ i,
+ (*order)[i][XX],
+ (*order)[i][YY],
(*order)[i][ZZ]);
if (bSliced || permolecule)
{
if (bUnsat)
{
- fprintf(stderr, "Average angle between double bond and normal: %f\n",
+ fprintf(stderr,
+ "Average angle between double bond and normal: %f\n",
180 * sdbangle / (nr_frames * static_cast<real>(size) * M_PI));
}
slOrd = xvgropen(bfile, buf, "Molecule", "S", oenv);
for (atom = 1; atom < ngrps - 1; atom++)
{
- fprintf(ord, "%12d %12g\n", atom,
+ fprintf(ord,
+ "%12d %12g\n",
+ atom,
-1.0 * (2.0 / 3.0 * order[atom][XX] + 1.0 / 3.0 * order[atom][YY]));
}
{
S += slOrder[slice][atom];
}
- fprintf(slOrd, "%12g %12g\n", static_cast<real>(slice) * slWidth,
- S / static_cast<real>(atom));
+ fprintf(slOrd, "%12g %12g\n", static_cast<real>(slice) * slWidth, S / static_cast<real>(atom));
}
}
else
for (atom = 1; atom < ngrps - 1; atom++)
{
- fprintf(ord, "%12d %12g %12g %12g\n", atom, order[atom][XX], order[atom][YY],
- order[atom][ZZ]);
- fprintf(slOrd, "%12d %12g\n", atom,
+ fprintf(ord, "%12d %12g %12g %12g\n", atom, order[atom][XX], order[atom][YY], order[atom][ZZ]);
+ fprintf(slOrd,
+ "%12d %12g\n",
+ atom,
-1.0 * (2.0 / 3.0 * order[atom][XX] + 1.0 / 3.0 * order[atom][YY]));
}
}
}
}
- write_sto_conf(opt2fn("-ob", nfile, fnm), "Order parameters", &useatoms, frout.x, nullptr,
- frout.pbcType, frout.box);
+ write_sto_conf(
+ opt2fn("-ob", nfile, fnm), "Order parameters", &useatoms, frout.x, nullptr, frout.pbcType, frout.box);
sfree(frout.x);
done_atom(&useatoms);
const char * sgfnm, *skfnm, *ndxfnm, *tpsfnm, *trxfnm;
gmx_output_env_t* oenv;
- if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, asize(pa), pa,
- asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
/* If either of theoptions is set we compute both */
sgfnm = opt2fn("-Sg", NFILE, fnm);
skfnm = opt2fn("-Sk", NFILE, fnm);
- calc_tetra_order_parm(ndxfnm, tpsfnm, trxfnm, sgfnm, skfnm, nslices, axis,
- opt2fn("-Sgsl", NFILE, fnm), opt2fn("-Sksl", NFILE, fnm), oenv);
+ calc_tetra_order_parm(ndxfnm,
+ tpsfnm,
+ trxfnm,
+ sgfnm,
+ skfnm,
+ nslices,
+ axis,
+ opt2fn("-Sgsl", NFILE, fnm),
+ opt2fn("-Sksl", NFILE, fnm),
+ oenv);
/* view xvgr files */
do_view(oenv, opt2fn("-Sg", NFILE, fnm), nullptr);
do_view(oenv, opt2fn("-Sk", NFILE, fnm), nullptr);
/* show atomtypes, to check if index file is correct */
print_types(index, a, ngrps, grpname, top);
- calc_order(ftp2fn(efTRX, NFILE, fnm), index, a, &order, &slOrder, &slWidth, nslices,
- bSliced, bUnsat, top, pbcType, ngrps, axis, permolecule, radial, distcalc,
- opt2fn_null("-nr", NFILE, fnm), &distvals, oenv);
+ calc_order(ftp2fn(efTRX, NFILE, fnm),
+ index,
+ a,
+ &order,
+ &slOrder,
+ &slWidth,
+ nslices,
+ bSliced,
+ bUnsat,
+ top,
+ pbcType,
+ ngrps,
+ axis,
+ permolecule,
+ radial,
+ distcalc,
+ opt2fn_null("-nr", NFILE, fnm),
+ &distvals,
+ oenv);
if (radial)
{
ngrps--; /*don't print the last group--was used for
center-of-mass determination*/
}
- order_plot(order, slOrder, opt2fn("-o", NFILE, fnm), opt2fn("-os", NFILE, fnm),
- opt2fn("-od", NFILE, fnm), ngrps, nslices, slWidth, bSzonly, permolecule,
- distvals, oenv);
+ order_plot(order,
+ slOrder,
+ opt2fn("-o", NFILE, fnm),
+ opt2fn("-os", NFILE, fnm),
+ opt2fn("-od", NFILE, fnm),
+ ngrps,
+ nslices,
+ slWidth,
+ bSzonly,
+ permolecule,
+ distvals,
+ oenv);
if (opt2bSet("-ob", NFILE, fnm))
{
char ** legp, buf[STRLEN];
gmx_rmpbc_t gpbc = nullptr;
- if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME | PCA_TIME_UNIT, NFILE, fnm,
- asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(&argc,
+ argv,
+ PCA_CAN_VIEW | PCA_CAN_TIME | PCA_TIME_UNIT,
+ NFILE,
+ fnm,
+ asize(pa),
+ pa,
+ asize(desc),
+ desc,
+ 0,
+ nullptr,
+ &oenv))
{
return 0;
}
if (opt2bSet("-v", NFILE, fnm))
{
- outv = xvgropen(opt2fn("-v", NFILE, fnm), "Principal components",
- output_env_get_xvgr_tlabel(oenv), "(nm)", oenv);
+ outv = xvgropen(opt2fn("-v", NFILE, fnm),
+ "Principal components",
+ output_env_get_xvgr_tlabel(oenv),
+ "(nm)",
+ oenv);
snew(legp, DIM * DIM);
for (d = 0; d < DIM; d++)
{
if (opt2bSet("-p", NFILE, fnm))
{
- outp = xvgropen(opt2fn("-p", NFILE, fnm), "Persistence length",
- output_env_get_xvgr_tlabel(oenv), "bonds", oenv);
+ outp = xvgropen(opt2fn("-p", NFILE, fnm),
+ "Persistence length",
+ output_env_get_xvgr_tlabel(oenv),
+ "bonds",
+ oenv);
snew(bond, nat_max - 1);
snew(sum_inp, nat_min / 2);
snew(ninp, nat_min / 2);
if (opt2bSet("-i", NFILE, fnm))
{
- outi = xvgropen(opt2fn("-i", NFILE, fnm), "Internal distances", "n",
- "<R\\S2\\N(n)>/n (nm\\S2\\N)", oenv);
- i = index[molind[1] - 1] - index[molind[0]]; /* Length of polymer -1 */
+ outi = xvgropen(
+ opt2fn("-i", NFILE, fnm), "Internal distances", "n", "<R\\S2\\N(n)>/n (nm\\S2\\N)", oenv);
+ i = index[molind[1] - 1] - index[molind[0]]; /* Length of polymer -1 */
snew(intd, i);
}
else
gyro_eigen(gyr_all, eig, eigv, ord);
- fprintf(out, "%10.3f %8.4f %8.4f %8.4f %8.4f %8.4f", t * output_env_get_time_factor(oenv),
- std::sqrt(sum_eed2), sqrt(sum_gyro), std::sqrt(eig[ord[0]]), std::sqrt(eig[ord[1]]),
+ fprintf(out,
+ "%10.3f %8.4f %8.4f %8.4f %8.4f %8.4f",
+ t * output_env_get_time_factor(oenv),
+ std::sqrt(sum_eed2),
+ sqrt(sum_gyro),
+ std::sqrt(eig[ord[0]]),
+ std::sqrt(eig[ord[1]]),
std::sqrt(eig[ord[2]]));
if (bPC)
{
gmx_fatal(FARGS,
"You selected a group with %d atoms, but only %d atoms\n"
"were found in the trajectory.\n",
- gnx[n], natoms);
+ gnx[n],
+ natoms);
}
for (i = 0; i < gnx[n]; i++) /* loop over all atoms in index file */
{
#define NFILE asize(fnm)
- if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, asize(pa), pa,
- asize(desc), desc, asize(bugs), bugs, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, asize(pa), pa, asize(desc), desc, asize(bugs), bugs, &oenv))
{
return 0;
}
rd_index(ftp2fn(efNDX, NFILE, fnm), ngrps, ngx, index, grpname);
- calc_potential(ftp2fn(efTRX, NFILE, fnm), index, ngx, &potential, &charge, &field, &nslices,
- top, pbcType, axis, ngrps, &slWidth, fudge_z, bSpherical, bCorrect, oenv);
-
- plot_potential(potential, charge, field, opt2fn("-o", NFILE, fnm), opt2fn("-oc", NFILE, fnm),
- opt2fn("-of", NFILE, fnm), nslices, ngrps, grpname, slWidth, oenv);
+ calc_potential(ftp2fn(efTRX, NFILE, fnm),
+ index,
+ ngx,
+ &potential,
+ &charge,
+ &field,
+ &nslices,
+ top,
+ pbcType,
+ axis,
+ ngrps,
+ &slWidth,
+ fudge_z,
+ bSpherical,
+ bCorrect,
+ oenv);
+
+ plot_potential(potential,
+ charge,
+ field,
+ opt2fn("-o", NFILE, fnm),
+ opt2fn("-oc", NFILE, fnm),
+ opt2fn("-of", NFILE, fnm),
+ nslices,
+ ngrps,
+ grpname,
+ slWidth,
+ oenv);
do_view(oenv, opt2fn("-o", NFILE, fnm), nullptr); /* view xvgr file */
do_view(oenv, opt2fn("-oc", NFILE, fnm), nullptr); /* view xvgr file */
{ efXVG, "-om", "moi", ffWRITE } };
#define NFILE asize(fnm)
- if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_TIME_UNIT | PCA_CAN_VIEW, NFILE, fnm,
- asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(&argc,
+ argv,
+ PCA_CAN_TIME | PCA_TIME_UNIT | PCA_CAN_VIEW,
+ NFILE,
+ fnm,
+ asize(pa),
+ pa,
+ asize(desc),
+ desc,
+ 0,
+ nullptr,
+ &oenv))
{
return 0;
}
sprintf(legend[i], "%c component", 'X' + i);
}
- axis1 = xvgropen(opt2fn("-a1", NFILE, fnm), "Principal axis 1 (major axis)",
- output_env_get_xvgr_tlabel(oenv), "Component (nm)", oenv);
+ axis1 = xvgropen(opt2fn("-a1", NFILE, fnm),
+ "Principal axis 1 (major axis)",
+ output_env_get_xvgr_tlabel(oenv),
+ "Component (nm)",
+ oenv);
xvgr_legend(axis1, DIM, legend, oenv);
- axis2 = xvgropen(opt2fn("-a2", NFILE, fnm), "Principal axis 2 (middle axis)",
- output_env_get_xvgr_tlabel(oenv), "Component (nm)", oenv);
+ axis2 = xvgropen(opt2fn("-a2", NFILE, fnm),
+ "Principal axis 2 (middle axis)",
+ output_env_get_xvgr_tlabel(oenv),
+ "Component (nm)",
+ oenv);
xvgr_legend(axis2, DIM, legend, oenv);
- axis3 = xvgropen(opt2fn("-a3", NFILE, fnm), "Principal axis 3 (minor axis)",
- output_env_get_xvgr_tlabel(oenv), "Component (nm)", oenv);
+ axis3 = xvgropen(opt2fn("-a3", NFILE, fnm),
+ "Principal axis 3 (minor axis)",
+ output_env_get_xvgr_tlabel(oenv),
+ "Component (nm)",
+ oenv);
xvgr_legend(axis3, DIM, legend, oenv);
sprintf(legend[XX], "Axis 1 (major)");
sprintf(legend[YY], "Axis 2 (middle)");
sprintf(legend[ZZ], "Axis 3 (minor)");
- fmoi = xvgropen(opt2fn("-om", NFILE, fnm), "Moments of inertia around inertial axes",
- output_env_get_xvgr_tlabel(oenv), "I (au nm\\S2\\N)", oenv);
+ fmoi = xvgropen(opt2fn("-om", NFILE, fnm),
+ "Moments of inertia around inertial axes",
+ output_env_get_xvgr_tlabel(oenv),
+ "I (au nm\\S2\\N)",
+ oenv);
xvgr_legend(fmoi, DIM, legend, oenv);
for (i = 0; i < DIM; i++)
calc_principal_axes(&top, x, index, gnx, axes, moi);
- fprintf(axis1, "%15.10f %15.10f %15.10f %15.10f\n", t, axes[XX][XX], axes[XX][YY],
- axes[XX][ZZ]);
- fprintf(axis2, "%15.10f %15.10f %15.10f %15.10f\n", t, axes[YY][XX], axes[YY][YY],
- axes[YY][ZZ]);
- fprintf(axis3, "%15.10f %15.10f %15.10f %15.10f\n", t, axes[ZZ][XX], axes[ZZ][YY],
- axes[ZZ][ZZ]);
+ fprintf(axis1, "%15.10f %15.10f %15.10f %15.10f\n", t, axes[XX][XX], axes[XX][YY], axes[XX][ZZ]);
+ fprintf(axis2, "%15.10f %15.10f %15.10f %15.10f\n", t, axes[YY][XX], axes[YY][YY], axes[YY][ZZ]);
+ fprintf(axis3, "%15.10f %15.10f %15.10f %15.10f\n", t, axes[ZZ][XX], axes[ZZ][YY], axes[ZZ][ZZ]);
fprintf(fmoi, "%15.10f %15.10f %15.10f %15.10f\n", t, moi[XX], moi[YY], moi[ZZ]);
} while (read_next_x(oenv, status, &t, x, box));
{ efXVG, nullptr, "rama", ffWRITE } };
#define NFILE asize(fnm)
- if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, 0, nullptr,
- asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, 0, nullptr, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
};
#define NFILE asize(fnm)
- if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_TIME_UNIT | PCA_CAN_VIEW, NFILE, fnm,
- asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(&argc,
+ argv,
+ PCA_CAN_TIME | PCA_TIME_UNIT | PCA_CAN_VIEW,
+ NFILE,
+ fnm,
+ asize(pa),
+ pa,
+ asize(desc),
+ desc,
+ 0,
+ nullptr,
+ &oenv))
{
return 0;
}
natoms_trx = read_first_x(oenv, &status, opt2fn("-f", NFILE, fnm), &t, &x, box);
if (natoms_trx != top.atoms.nr)
{
- fprintf(stderr, "\nWARNING: topology has %d atoms, whereas trajectory has %d\n",
- top.atoms.nr, natoms_trx);
+ fprintf(stderr, "\nWARNING: topology has %d atoms, whereas trajectory has %d\n", top.atoms.nr, natoms_trx);
}
natoms = std::min(top.atoms.nr, natoms_trx);
if (bMat || bBond || bPrev)
gmx_fatal(FARGS,
"Second trajectory (%d atoms) does not match the first one"
" (%d atoms)",
- natoms_trx2, natoms_trx);
+ natoms_trx2,
+ natoms_trx);
}
frame2 = 0;
do
{
if (bFile2 || (i < j))
{
- rmsd_mat[i][j] = calc_similar_ind(ewhat != ewRMSD, irms[0], ind_rms_m,
- w_rms_m, mat_x[i], mat_x2_j);
+ rmsd_mat[i][j] = calc_similar_ind(
+ ewhat != ewRMSD, irms[0], ind_rms_m, w_rms_m, mat_x[i], mat_x2_j);
if (rmsd_mat[i][j] > rmsd_max)
{
rmsd_max = rmsd_mat[i][j];
fprintf(stderr, "Min and Max value set to resp. %f and %f\n", rmsd_min, rmsd_max);
}
sprintf(buf, "%s %s matrix", gn_rms[0], whatname[ewhat]);
- write_xpm(opt2FILE("-m", NFILE, fnm, "w"), 0, buf, whatlabel[ewhat],
- output_env_get_time_label(oenv), output_env_get_time_label(oenv), tel_mat,
- tel_mat2, axis, axis2, rmsd_mat, rmsd_min, rmsd_max, rlo, rhi, &nlevels);
+ write_xpm(opt2FILE("-m", NFILE, fnm, "w"),
+ 0,
+ buf,
+ whatlabel[ewhat],
+ output_env_get_time_label(oenv),
+ output_env_get_time_label(oenv),
+ tel_mat,
+ tel_mat2,
+ axis,
+ axis2,
+ rmsd_mat,
+ rmsd_min,
+ rmsd_max,
+ rlo,
+ rhi,
+ &nlevels);
/* Print the distribution of RMSD values */
if (opt2bSet("-dist", NFILE, fnm))
{
}
sprintf(buf, "%s %s vs. delta t", gn_rms[0], whatname[ewhat]);
fp = gmx_ffopen("delta.xpm", "w");
- write_xpm(fp, 0, buf, "density", output_env_get_time_label(oenv), whatlabel[ewhat],
- delta_xsize, del_lev + 1, del_xaxis, del_yaxis, delta, 0.0, delta_max,
- rlo, rhi, &nlevels);
+ write_xpm(fp,
+ 0,
+ buf,
+ "density",
+ output_env_get_time_label(oenv),
+ whatlabel[ewhat],
+ delta_xsize,
+ del_lev + 1,
+ del_xaxis,
+ del_yaxis,
+ delta,
+ 0.0,
+ delta_max,
+ rlo,
+ rhi,
+ &nlevels);
gmx_ffclose(fp);
}
if (opt2bSet("-bin", NFILE, fnm))
fprintf(stderr,
"Bond angle Min and Max set to:\n"
"Min. angle: %f, Max. angle: %f\n",
- bond_min, bond_max);
+ bond_min,
+ bond_max);
}
rlo.r = 1;
rlo.g = 1;
rhi.g = 0;
rhi.b = 0;
sprintf(buf, "%s av. bond angle deviation", gn_rms[0]);
- write_xpm(opt2FILE("-bm", NFILE, fnm, "w"), 0, buf, "degrees",
- output_env_get_time_label(oenv), output_env_get_time_label(oenv), tel_mat,
- tel_mat2, axis, axis2, bond_mat, bond_min, bond_max, rlo, rhi, &nlevels);
+ write_xpm(opt2FILE("-bm", NFILE, fnm, "w"),
+ 0,
+ buf,
+ "degrees",
+ output_env_get_time_label(oenv),
+ output_env_get_time_label(oenv),
+ tel_mat,
+ tel_mat2,
+ axis,
+ axis2,
+ bond_mat,
+ bond_min,
+ bond_max,
+ rlo,
+ rhi,
+ &nlevels);
}
}
}
else
{
- sprintf(buf, "%s with frame %g %s ago", whatxvgname[ewhat], time[prev * freq] - time[0],
+ sprintf(buf,
+ "%s with frame %g %s ago",
+ whatxvgname[ewhat],
+ time[prev * freq] - time[0],
output_env_get_time_label(oenv).c_str());
}
- fp = xvgropen(opt2fn("-o", NFILE, fnm), buf, output_env_get_xvgr_tlabel(oenv),
- whatxvglabel[ewhat], oenv);
+ fp = xvgropen(opt2fn("-o", NFILE, fnm), buf, output_env_get_xvgr_tlabel(oenv), whatxvglabel[ewhat], oenv);
if (output_env_get_print_xvgr_codes(oenv))
{
- fprintf(fp, "@ subtitle \"%s%s after %s%s%s\"\n", (nrms == 1) ? "" : "of ", gn_rms[0],
- fitgraphlabel[efit], bFit ? " to " : "", bFit ? gn_fit : "");
+ fprintf(fp,
+ "@ subtitle \"%s%s after %s%s%s\"\n",
+ (nrms == 1) ? "" : "of ",
+ gn_rms[0],
+ fitgraphlabel[efit],
+ bFit ? " to " : "",
+ bFit ? gn_fit : "");
}
if (nrms != 1)
{
{
if (output_env_get_print_xvgr_codes(oenv))
{
- fprintf(fp, "@ subtitle \"of %s after lsq fit to mirror of %s\"\n", gn_rms[0],
- bFit ? gn_fit : "");
+ fprintf(fp, "@ subtitle \"of %s after lsq fit to mirror of %s\"\n", gn_rms[0], bFit ? gn_fit : "");
}
}
else
j = i + 1;
rnri = atoms->atom[index[i]].resind;
rnrj = atoms->atom[index[j]].resind;
- bEquiv = is_equiv(neq, equiv, &nnm[i], rnri, *atoms->resinfo[rnri].name,
- *atoms->atomname[index[i]], rnrj, *atoms->resinfo[rnrj].name,
+ bEquiv = is_equiv(neq,
+ equiv,
+ &nnm[i],
+ rnri,
+ *atoms->resinfo[rnri].name,
+ *atoms->atomname[index[i]],
+ rnrj,
+ *atoms->resinfo[rnrj].name,
*atoms->atomname[index[j]]);
if (nnm[i] && bEquiv)
{
for (i = 0; i < isize; i++)
{
rnri = atoms->atom[index[i]].resind;
- fprintf(debug, "%s %s %d -> %s\n", *atoms->atomname[index[i]],
- *atoms->resinfo[rnri].name, rnri, nnm[i] ? nnm[i] : "");
+ fprintf(debug,
+ "%s %s %d -> %s\n",
+ *atoms->atomname[index[i]],
+ *atoms->resinfo[rnri].name,
+ rnri,
+ nnm[i] ? nnm[i] : "");
}
}
/* dump group definitions */
if (debug)
{
- fprintf(debug, "%d %d %d %d %s %s %d\n", i, gi, noe_gr[gi].ianr, noe_gr[gi].anr,
- noe_gr[gi].aname, noe_gr[gi].rname, noe_gr[gi].rnr);
+ fprintf(debug,
+ "%d %d %d %d %s %s %d\n",
+ i,
+ gi,
+ noe_gr[gi].ianr,
+ noe_gr[gi].anr,
+ noe_gr[gi].aname,
+ noe_gr[gi].rname,
+ noe_gr[gi].rnr);
}
}
}
t_noe_gr gri, grj;
min3 = min6 = 1e6;
- fprintf(fp, ";%4s %3s %4s %4s%3s %4s %4s %4s %4s%3s %5s %5s %8s %2s %2s %s\n", "ianr", "anr",
- "anm", "rnm", "rnr", "ianr", "anr", "anm", "rnm", "rnr", "1/r^3", "1/r^6", "intnsty",
- "Dr", "Da", "scale");
+ fprintf(fp,
+ ";%4s %3s %4s %4s%3s %4s %4s %4s %4s%3s %5s %5s %8s %2s %2s %s\n",
+ "ianr",
+ "anr",
+ "anm",
+ "rnm",
+ "rnr",
+ "ianr",
+ "anr",
+ "anm",
+ "rnm",
+ "rnr",
+ "1/r^3",
+ "1/r^6",
+ "intnsty",
+ "Dr",
+ "Da",
+ "scale");
for (i = 0; i < gnr; i++)
{
gri = noe_gr[i];
{
std::strcpy(b6, "-");
}
- fprintf(fp, "%4d %4d %4s %4s%3d %4d %4d %4s %4s%3d %5s %5s %8d %2d %2s %s\n",
- gri.ianr + 1, gri.anr + 1, gri.aname, gri.rname, gri.rnr + 1, grj.ianr + 1,
- grj.anr + 1, grj.aname, grj.rname, grj.rnr + 1, b3, b6,
- gmx::roundToInt(noe[i][j].i_6), grj.rnr - gri.rnr, buf, noe2scale(r3, r6, rmax));
+ fprintf(fp,
+ "%4d %4d %4s %4s%3d %4d %4d %4s %4s%3d %5s %5s %8d %2d %2s %s\n",
+ gri.ianr + 1,
+ gri.anr + 1,
+ gri.aname,
+ gri.rname,
+ gri.rnr + 1,
+ grj.ianr + 1,
+ grj.anr + 1,
+ grj.aname,
+ grj.rname,
+ grj.rnr + 1,
+ b3,
+ b6,
+ gmx::roundToInt(noe[i][j].i_6),
+ grj.rnr - gri.rnr,
+ buf,
+ noe2scale(r3, r6, rmax));
}
}
}
fprintf(stdout,
"NOTE: no 1/r^%d averaged distances found below %g, "
"smallest was %g\n",
- i, rmax, MINI);
+ i,
+ rmax,
+ MINI);
}
else
{
};
#define NFILE asize(fnm)
- if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, asize(pa), pa,
- asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
/* make list of noe atom groups */
snew(noe_index, isize + 1);
snew(noe_gr, isize);
- gnr = analyze_noe_equivalent(opt2fn_null("-equiv", NFILE, fnm), atoms, isize, index, bSumH,
- noe_index, noe_gr);
+ gnr = analyze_noe_equivalent(
+ opt2fn_null("-equiv", NFILE, fnm), atoms, isize, index, bSumH, noe_index, noe_gr);
fprintf(stdout, "Found %d non-equivalent atom-groups in %d atoms\n", gnr, isize);
/* make half matrix of of noe-group distances from atom distances */
snew(noe, gnr);
if (bRMS)
{
- write_xpm(opt2FILE("-rms", NFILE, fnm, "w"), 0, "RMS of distance", "RMS (nm)", "Atom Index",
- "Atom Index", isize, isize, resnr, resnr, rms, 0.0, rmsmax, rlo, rhi, &nlevels);
+ write_xpm(opt2FILE("-rms", NFILE, fnm, "w"),
+ 0,
+ "RMS of distance",
+ "RMS (nm)",
+ "Atom Index",
+ "Atom Index",
+ isize,
+ isize,
+ resnr,
+ resnr,
+ rms,
+ 0.0,
+ rmsmax,
+ rlo,
+ rhi,
+ &nlevels);
}
if (bScale)
{
- write_xpm(opt2FILE("-scl", NFILE, fnm, "w"), 0, "Relative RMS", "RMS", "Atom Index",
- "Atom Index", isize, isize, resnr, resnr, rmsc, 0.0, rmscmax, rlo, rhi, &nlevels);
+ write_xpm(opt2FILE("-scl", NFILE, fnm, "w"),
+ 0,
+ "Relative RMS",
+ "RMS",
+ "Atom Index",
+ "Atom Index",
+ isize,
+ isize,
+ resnr,
+ resnr,
+ rmsc,
+ 0.0,
+ rmscmax,
+ rlo,
+ rhi,
+ &nlevels);
}
if (bMean)
{
- write_xpm(opt2FILE("-mean", NFILE, fnm, "w"), 0, "Mean Distance", "Distance (nm)",
- "Atom Index", "Atom Index", isize, isize, resnr, resnr, mean, 0.0, meanmax, rlo,
- rhi, &nlevels);
+ write_xpm(opt2FILE("-mean", NFILE, fnm, "w"),
+ 0,
+ "Mean Distance",
+ "Distance (nm)",
+ "Atom Index",
+ "Atom Index",
+ isize,
+ isize,
+ resnr,
+ resnr,
+ mean,
+ 0.0,
+ meanmax,
+ rlo,
+ rhi,
+ &nlevels);
}
if (bNMR3)
{
- write_xpm(opt2FILE("-nmr3", NFILE, fnm, "w"), 0, "1/r^3 averaged distances",
- "Distance (nm)", "Atom Index", "Atom Index", isize, isize, resnr, resnr, dtot1_3,
- 0.0, max1_3, rlo, rhi, &nlevels);
+ write_xpm(opt2FILE("-nmr3", NFILE, fnm, "w"),
+ 0,
+ "1/r^3 averaged distances",
+ "Distance (nm)",
+ "Atom Index",
+ "Atom Index",
+ isize,
+ isize,
+ resnr,
+ resnr,
+ dtot1_3,
+ 0.0,
+ max1_3,
+ rlo,
+ rhi,
+ &nlevels);
}
if (bNMR6)
{
- write_xpm(opt2FILE("-nmr6", NFILE, fnm, "w"), 0, "1/r^6 averaged distances",
- "Distance (nm)", "Atom Index", "Atom Index", isize, isize, resnr, resnr, dtot1_6,
- 0.0, max1_6, rlo, rhi, &nlevels);
+ write_xpm(opt2FILE("-nmr6", NFILE, fnm, "w"),
+ 0,
+ "1/r^6 averaged distances",
+ "Distance (nm)",
+ "Atom Index",
+ "Atom Index",
+ isize,
+ isize,
+ resnr,
+ resnr,
+ dtot1_6,
+ 0.0,
+ max1_6,
+ rlo,
+ rhi,
+ &nlevels);
}
if (bNOE)
{ efXVG, "-oc", "correl", ffOPTWR }, { efLOG, "-dir", "rmsf", ffOPTWR } };
#define NFILE asize(fnm)
- if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pargs),
- pargs, asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pargs), pargs, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
|| top.atoms.atom[index[i]].resind != top.atoms.atom[index[i + 1]].resind)
{
resind = top.atoms.atom[index[i]].resind;
- pdb_bfac = find_pdb_bfac(pdbatoms, &top.atoms.resinfo[resind],
- *(top.atoms.atomname[index[i]]));
+ pdb_bfac = find_pdb_bfac(
+ pdbatoms, &top.atoms.resinfo[resind], *(top.atoms.atomname[index[i]]));
- fprintf(fp, "%5d %10.5f %10.5f\n",
+ fprintf(fp,
+ "%5d %10.5f %10.5f\n",
bRes ? top.atoms.resinfo[top.atoms.atom[index[i]].resind].nr : index[i] + 1,
- rmsf[i] * bfac, pdb_bfac);
+ rmsf[i] * bfac,
+ pdb_bfac);
}
}
xvgrclose(fp);
if (!bRes || i + 1 == isize
|| top.atoms.atom[index[i]].resind != top.atoms.atom[index[i + 1]].resind)
{
- fprintf(fp, "%5d %8.4f\n",
+ fprintf(fp,
+ "%5d %8.4f\n",
bRes ? top.atoms.resinfo[top.atoms.atom[index[i]].resind].nr : index[i] + 1,
std::sqrt(rmsf[i]));
}
if (!bRes || i + 1 == isize
|| top.atoms.atom[index[i]].resind != top.atoms.atom[index[i + 1]].resind)
{
- fprintf(fp, "%5d %8.4f\n",
+ fprintf(fp,
+ "%5d %8.4f\n",
bRes ? top.atoms.resinfo[top.atoms.atom[index[i]].resind].nr : index[i] + 1,
std::sqrt(rmsf[i]));
}
{
rvec_inc(pdbx[index[i]], xcm);
}
- write_sto_conf_indexed(opt2fn("-oq", NFILE, fnm), title, pdbatoms, pdbx, nullptr, pbcType,
- pdbbox, isize, index);
+ write_sto_conf_indexed(
+ opt2fn("-oq", NFILE, fnm), title, pdbatoms, pdbx, nullptr, pbcType, pdbbox, isize, index);
}
if (opt2bSet("-ox", NFILE, fnm))
{
}
}
/* Write a .pdb file with B-factors and optionally anisou records */
- write_sto_conf_indexed(opt2fn("-ox", NFILE, fnm), title, pdbatoms, bFactorX, nullptr,
- pbcType, pdbbox, isize, index);
+ write_sto_conf_indexed(
+ opt2fn("-ox", NFILE, fnm), title, pdbatoms, bFactorX, nullptr, pbcType, pdbbox, isize, index);
sfree(bFactorX);
}
if (bAniso)
npargs = asize(pa);
ppa = add_acf_pargs(&npargs, pa);
- if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, npargs, ppa,
- asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, npargs, ppa, asize(desc), desc, 0, nullptr, &oenv))
{
sfree(ppa);
return 0;
mode = eacVector;
- do_autocorr(ftp2fn(efXVG, NFILE, fnm), oenv, "Rotational Correlation Function", teller,
- nvec, c1, dt, mode, bAver);
+ do_autocorr(
+ ftp2fn(efXVG, NFILE, fnm), oenv, "Rotational Correlation Function", teller, nvec, c1, dt, mode, bAver);
}
do_view(oenv, ftp2fn(efXVG, NFILE, fnm), nullptr);
{
gmx_fatal(FARGS,
"Atom index (%d) is larger than the number of atoms in the trajecory (%d)",
- index[a] + 1, natoms);
+ index[a] + 1,
+ natoms);
}
w_rls[a] = (bMW ? top->atoms.atom[index[a]].m : 1.0);
tot_mass += w_rls[a];
{ efXVG, nullptr, "rotmat", ffWRITE } };
#define NFILE asize(fnm)
- if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa,
- asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
GMX_RELEASE_ASSERT(reffit[0] != nullptr, "Options inconsistency; reffit[0] is NULL");
if (reffit[0][0] != 'n')
{
- get_refx(oenv, ftp2fn(efTRX, NFILE, fnm), reffit[0][2] == 'z' ? 3 : 2, skip, gnx, index,
- bMW, &top, pbcType, x_ref);
+ get_refx(oenv, ftp2fn(efTRX, NFILE, fnm), reffit[0][2] == 'z' ? 3 : 2, skip, gnx, index, bMW, &top, pbcType, x_ref);
}
natoms = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box);
{
gmx_fatal(FARGS,
"Atom index (%d) is larger than the number of atoms in the trajecory (%d)",
- index[i] + 1, natoms);
+ index[i] + 1,
+ natoms);
}
w_rls[index[i]] = (bMW ? top.atoms.atom[index[i]].m : 1.0);
}
calc_fit_R(DIM, natoms, w_rls, x_ref, x, R);
- fprintf(out, "%7g %7.4f %7.4f %7.4f %7.4f %7.4f %7.4f %7.4f %7.4f %7.4f\n", t, R[XX][XX],
- R[XX][YY], R[XX][ZZ], R[YY][XX], R[YY][YY], R[YY][ZZ], R[ZZ][XX], R[ZZ][YY], R[ZZ][ZZ]);
+ fprintf(out,
+ "%7g %7.4f %7.4f %7.4f %7.4f %7.4f %7.4f %7.4f %7.4f %7.4f\n",
+ t,
+ R[XX][XX],
+ R[XX][YY],
+ R[XX][ZZ],
+ R[YY][XX],
+ R[YY][YY],
+ R[YY][ZZ],
+ R[ZZ][XX],
+ R[ZZ][YY],
+ R[ZZ][ZZ]);
} while (read_next_x(oenv, status, &t, x, box));
gmx_rmpbc_done(gpbc);
matrix box;
gmx_output_env_t* oenv;
- if (!parse_common_args(&argc, argv, PCA_CAN_TIME, NFILE, fnm, asize(pa), pa, asize(desc), desc,
- 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_TIME, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
nthreads = gmx_omp_get_max_threads();
- if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_TIME_UNIT, NFILE, fnm, asize(pa), pa,
- asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_TIME | PCA_TIME_UNIT, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
fnTRX = ftp2fn(efTRX, NFILE, fnm);
gnsf = gmx_neutronstructurefactors_init(fnDAT);
- fprintf(stderr, "Read %d atom names from %s with neutron scattering parameters\n\n",
- gnsf->nratoms, fnDAT);
+ fprintf(stderr, "Read %d atom names from %s with neutron scattering parameters\n\n", gnsf->nratoms, fnDAT);
snew(top, 1);
snew(grpname, 1);
natoms = read_first_x(oenv, &status, fnTRX, &t, &x, box);
if (natoms != top->atoms.nr)
{
- fprintf(stderr, "\nWARNING: number of atoms in tpx (%d) and trajectory (%d) do not match\n",
- natoms, top->atoms.nr);
+ fprintf(stderr,
+ "\nWARNING: number of atoms in tpx (%d) and trajectory (%d) do not match\n",
+ natoms,
+ top->atoms.nr);
}
do
snew(pr, 1);
}
/* realy calc p(r) */
- prframecurrent = calc_radial_distribution_histogram(gsans, x, box, index, isize, binwidth,
- bMC, bNORM, mcover, seed);
+ prframecurrent = calc_radial_distribution_histogram(
+ gsans, x, box, index, isize, binwidth, bMC, bNORM, mcover, seed);
/* copy prframecurrent -> pr and summ up pr->gr[i] */
/* allocate and/or resize memory for pr->gr[i] and pr->r[i] */
if (pr->gr == nullptr)
auto fnmdup = filenames;
sprintf(suffix, "-t%.2f", t);
add_suffix_to_output_names(fnmdup.data(), NFILE, suffix);
- fp = xvgropen(opt2fn_null("-prframe", NFILE, fnmdup.data()), hdr, "Distance (nm)",
- "Probability", oenv);
+ fp = xvgropen(opt2fn_null("-prframe", NFILE, fnmdup.data()),
+ hdr,
+ "Distance (nm)",
+ "Probability",
+ oenv);
for (i = 0; i < prframecurrent->grn; i++)
{
fprintf(fp, "%10.6f%10.6f\n", prframecurrent->r[i], prframecurrent->gr[i]);
auto fnmdup = filenames;
sprintf(suffix, "-t%.2f", t);
add_suffix_to_output_names(fnmdup.data(), NFILE, suffix);
- fp = xvgropen(opt2fn_null("-sqframe", NFILE, fnmdup.data()), hdr, "q (nm^-1)",
- "s(q)/s(0)", oenv);
+ fp = xvgropen(
+ opt2fn_null("-sqframe", NFILE, fnmdup.data()), hdr, "q (nm^-1)", "s(q)/s(0)", oenv);
for (i = 0; i < sqframecurrent->qn; i++)
{
fprintf(fp, "%10.6f%10.6f\n", sqframecurrent->q[i], sqframecurrent->s[i]);
{ efXVG, "-sq", "sq", ffWRITE },
};
#define NFILE asize(fnm)
- if (!parse_common_args(&argc, argv, PCA_CAN_TIME, NFILE, fnm, NPA, pa, asize(desc), desc, 0,
- nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_TIME, NFILE, fnm, NPA, pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
fnDAT = ftp2fn(efDAT, NFILE, fnm);
fnNDX = ftp2fn_null(efNDX, NFILE, fnm);
- do_scattering_intensity(fnTPS, fnNDX, opt2fn("-sq", NFILE, fnm), fnTRX, fnDAT, start_q, end_q,
- energy, ngroups, oenv);
+ do_scattering_intensity(
+ fnTPS, fnNDX, opt2fn("-sq", NFILE, fnm), fnTRX, fnDAT, start_q, end_q, energy, ngroups, oenv);
please_cite(stdout, "Cromer1968a");
fprintf(fp, "\n 2 !NTITLE\n");
fprintf(fp, " REMARKS Energy Landscape from GROMACS\n");
fprintf(fp, " REMARKS DATE: 2004-12-21 \n");
- fprintf(fp, " %7d %7d %7d %7d %7d %7d %7d %7d %7d\n", map->Nx, map->dmin[0], map->dmax[0],
- map->Ny, map->dmin[1], map->dmax[1], map->Nz, map->dmin[2], map->dmax[2]);
- fprintf(fp, "%12.5E%12.5E%12.5E%12.5E%12.5E%12.5E\n", map->cell[0], map->cell[1], map->cell[2],
- map->cell[3], map->cell[4], map->cell[5]);
+ fprintf(fp,
+ " %7d %7d %7d %7d %7d %7d %7d %7d %7d\n",
+ map->Nx,
+ map->dmin[0],
+ map->dmax[0],
+ map->Ny,
+ map->dmin[1],
+ map->dmax[1],
+ map->Nz,
+ map->dmin[2],
+ map->dmax[2]);
+ fprintf(fp,
+ "%12.5E%12.5E%12.5E%12.5E%12.5E%12.5E\n",
+ map->cell[0],
+ map->cell[1],
+ map->cell[2],
+ map->cell[3],
+ map->cell[4],
+ map->cell[5]);
fprintf(fp, "ZYX\n");
z = map->dmin[2];
fprintf(fp,
"Minimum %d at index "
"%" PRId64 " energy %10.3f\n",
- num, min->index, min->ener);
+ num,
+ min->index,
+ min->ener);
}
static inline void add_minimum(FILE* fp, int num, const t_minimum* min, t_minimum* mm)
this_min.index = index3(ibox, i, j, k);
this_min.ener = W[this_min.index];
if (is_local_minimum_from_below(&this_min, i, 0, index3(ibox, i - 1, j, k), W)
- && is_local_minimum_from_above(&this_min, i, ibox[0] - 1,
- index3(ibox, i + 1, j, k), W)
+ && is_local_minimum_from_above(
+ &this_min, i, ibox[0] - 1, index3(ibox, i + 1, j, k), W)
&& is_local_minimum_from_below(&this_min, j, 0, index3(ibox, i, j - 1, k), W)
- && is_local_minimum_from_above(&this_min, j, ibox[1] - 1,
- index3(ibox, i, j + 1, k), W)
+ && is_local_minimum_from_above(
+ &this_min, j, ibox[1] - 1, index3(ibox, i, j + 1, k), W)
&& is_local_minimum_from_below(&this_min, k, 0, index3(ibox, i, j, k - 1), W)
- && is_local_minimum_from_above(&this_min, k, ibox[2] - 1,
- index3(ibox, i, j, k + 1), W))
+ && is_local_minimum_from_above(
+ &this_min, k, ibox[2] - 1, index3(ibox, i, j, k + 1), W))
{
add_minimum(fp, nmin, &this_min, mm);
nmin++;
int index = this_point[i];
this_point[i]--;
bMin = bMin
- && is_local_minimum_from_below(&this_min, index, 0,
- indexn(ndim, ibox, this_point), W);
+ && is_local_minimum_from_below(
+ &this_min, index, 0, indexn(ndim, ibox, this_point), W);
this_point[i] += 2;
bMin = bMin
- && is_local_minimum_from_above(&this_min, index, ibox[i] - 1,
- indexn(ndim, ibox, this_point), W);
+ && is_local_minimum_from_above(
+ &this_min, index, ibox[i] - 1, indexn(ndim, ibox, this_point), W);
this_point[i]--;
}
if (bMin)
{
if (max_eig[i] > xmax[i])
{
- gmx_warning("Your xmax[%d] value %f is smaller than the largest data point %f", i,
- xmax[i], max_eig[i]);
+ gmx_warning("Your xmax[%d] value %f is smaller than the largest data point %f",
+ i,
+ xmax[i],
+ max_eig[i]);
}
max_eig[i] = xmax[i];
}
{
if (min_eig[i] < xmin[i])
{
- gmx_warning("Your xmin[%d] value %f is larger than the smallest data point %f", i,
- xmin[i], min_eig[i]);
+ gmx_warning("Your xmin[%d] value %f is larger than the smallest data point %f",
+ i,
+ xmin[i],
+ min_eig[i]);
}
min_eig[i] = xmin[i];
}
SS[i] = &(S[i * ibox[1]]);
}
fp = gmx_ffopen(xpmP, "w");
- write_xpm(fp, flags, "Probability Distribution", "", "PC1", "PC2", ibox[0], ibox[1], axis_x,
- axis_y, PP, 0, Pmax, rlo, rhi, &nlevels);
+ write_xpm(fp,
+ flags,
+ "Probability Distribution",
+ "",
+ "PC1",
+ "PC2",
+ ibox[0],
+ ibox[1],
+ axis_x,
+ axis_y,
+ PP,
+ 0,
+ Pmax,
+ rlo,
+ rhi,
+ &nlevels);
gmx_ffclose(fp);
fp = gmx_ffopen(xpm, "w");
- write_xpm(fp, flags, "Gibbs Energy Landscape", "G (kJ/mol)", "PC1", "PC2", ibox[0], ibox[1],
- axis_x, axis_y, WW, 0, gmax, rlo, rhi, &nlevels);
+ write_xpm(fp,
+ flags,
+ "Gibbs Energy Landscape",
+ "G (kJ/mol)",
+ "PC1",
+ "PC2",
+ ibox[0],
+ ibox[1],
+ axis_x,
+ axis_y,
+ WW,
+ 0,
+ gmax,
+ rlo,
+ rhi,
+ &nlevels);
gmx_ffclose(fp);
fp = gmx_ffopen(xpm2, "w");
- write_xpm(fp, flags, "Enthalpy Landscape", "H (kJ/mol)", "PC1", "PC2", ibox[0], ibox[1],
- axis_x, axis_y, EE, emin ? *emin : Emin, emax ? *emax : Einf, rlo, rhi, &nlevels);
+ write_xpm(fp,
+ flags,
+ "Enthalpy Landscape",
+ "H (kJ/mol)",
+ "PC1",
+ "PC2",
+ ibox[0],
+ ibox[1],
+ axis_x,
+ axis_y,
+ EE,
+ emin ? *emin : Emin,
+ emax ? *emax : Einf,
+ rlo,
+ rhi,
+ &nlevels);
gmx_ffclose(fp);
fp = gmx_ffopen(xpm3, "w");
- write_xpm(fp, flags, "Entropy Landscape", "TDS (kJ/mol)", "PC1", "PC2", ibox[0], ibox[1],
- axis_x, axis_y, SS, 0, Sinf, rlo, rhi, &nlevels);
+ write_xpm(fp,
+ flags,
+ "Entropy Landscape",
+ "TDS (kJ/mol)",
+ "PC1",
+ "PC2",
+ ibox[0],
+ ibox[1],
+ axis_x,
+ axis_y,
+ SS,
+ 0,
+ Sinf,
+ rlo,
+ rhi,
+ &nlevels);
gmx_ffclose(fp);
}
else if (neig == 3)
index = index3(ibox, i, j, k);
if (P[index] > 0)
{
- fprintf(fp, "%-6s%5d %-4.4s%3.3s %4d %8.3f%8.3f%8.3f%6.2f%6.2f\n",
- "ATOM", (index + 1) % 10000, "H", "H", (index + 1) % 10000, xxx[XX],
- xxx[YY], xxx[ZZ], 1.0, W[index]);
+ fprintf(fp,
+ "%-6s%5d %-4.4s%3.3s %4d %8.3f%8.3f%8.3f%6.2f%6.2f\n",
+ "ATOM",
+ (index + 1) % 10000,
+ "H",
+ "H",
+ (index + 1) % 10000,
+ xxx[XX],
+ xxx[YY],
+ xxx[ZZ],
+ 1.0,
+ W[index]);
}
}
}
sprintf(buf, "%s", xpm);
sprintf(&buf[std::strlen(xpm) - 4], "12.xpm");
fp = gmx_ffopen(buf, "w");
- write_xpm(fp, flags, "Gibbs Energy Landscape", "W (kJ/mol)", "PC1", "PC2", ibox[0], ibox[1],
- axis_x, axis_y, WW, 0, gmax, rlo, rhi, &nlevels);
+ write_xpm(fp,
+ flags,
+ "Gibbs Energy Landscape",
+ "W (kJ/mol)",
+ "PC1",
+ "PC2",
+ ibox[0],
+ ibox[1],
+ axis_x,
+ axis_y,
+ WW,
+ 0,
+ gmax,
+ rlo,
+ rhi,
+ &nlevels);
gmx_ffclose(fp);
for (i = 0; (i < ibox[0]); i++)
{
}
sprintf(&buf[std::strlen(xpm) - 4], "13.xpm");
fp = gmx_ffopen(buf, "w");
- write_xpm(fp, flags, "SHAM Energy Landscape", "kJ/mol", "PC1", "PC3", ibox[0], ibox[2],
- axis_x, axis_z, WW, 0, gmax, rlo, rhi, &nlevels);
+ write_xpm(fp,
+ flags,
+ "SHAM Energy Landscape",
+ "kJ/mol",
+ "PC1",
+ "PC3",
+ ibox[0],
+ ibox[2],
+ axis_x,
+ axis_z,
+ WW,
+ 0,
+ gmax,
+ rlo,
+ rhi,
+ &nlevels);
gmx_ffclose(fp);
for (i = 0; (i < ibox[1]); i++)
{
}
sprintf(&buf[std::strlen(xpm) - 4], "23.xpm");
fp = gmx_ffopen(buf, "w");
- write_xpm(fp, flags, "SHAM Energy Landscape", "kJ/mol", "PC2", "PC3", ibox[1], ibox[2],
- axis_y, axis_z, WW, 0, gmax, rlo, rhi, &nlevels);
+ write_xpm(fp,
+ flags,
+ "SHAM Energy Landscape",
+ "kJ/mol",
+ "PC2",
+ "PC3",
+ ibox[1],
+ ibox[2],
+ axis_y,
+ axis_z,
+ WW,
+ 0,
+ gmax,
+ rlo,
+ rhi,
+ &nlevels);
gmx_ffclose(fp);
sfree(buf);
}
int npargs;
npargs = asize(pa);
- if (!parse_common_args(&argc, argv, PCA_CAN_VIEW, NFILE, fnm, npargs, pa, asize(desc), desc, 0,
- nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_VIEW, NFILE, fnm, npargs, pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
- val = read_xvg_time(opt2fn("-f", NFILE, fnm), bHaveT, opt2parg_bSet("-b", npargs, pa), tb - ttol,
- opt2parg_bSet("-e", npargs, pa), te + ttol, nsets_in, &nset, &n, &dt, &t);
+ val = read_xvg_time(opt2fn("-f", NFILE, fnm),
+ bHaveT,
+ opt2parg_bSet("-b", npargs, pa),
+ tb - ttol,
+ opt2parg_bSet("-e", npargs, pa),
+ te + ttol,
+ nsets_in,
+ &nset,
+ &n,
+ &dt,
+ &t);
printf("Read %d sets of %d points, dt = %g\n\n", nset, n, dt);
fn_ge = opt2fn_null("-ge", NFILE, fnm);
if (fn_ge || fn_ene)
{
- et_val = read_xvg_time(fn_ge ? fn_ge : fn_ene, bHaveT, opt2parg_bSet("-b", npargs, pa),
- tb - ttol, opt2parg_bSet("-e", npargs, pa), te + ttol, 1, &e_nset,
- &e_n, &e_dt, &e_t);
+ et_val = read_xvg_time(fn_ge ? fn_ge : fn_ene,
+ bHaveT,
+ opt2parg_bSet("-b", npargs, pa),
+ tb - ttol,
+ opt2parg_bSet("-e", npargs, pa),
+ te + ttol,
+ 1,
+ &e_nset,
+ &e_n,
+ &e_dt,
+ &e_t);
if (fn_ge)
{
if (e_nset != 1)
if (e_nset != 1 && e_nset != 2)
{
gmx_fatal(FARGS,
- "Can only handle one energy component or one energy and one T in %s", fn_ene);
+ "Can only handle one energy component or one energy and one T in %s",
+ fn_ene);
}
}
if (e_n != n)
{
- gmx_fatal(FARGS, "Number of energies (%d) does not match number of entries (%d) in %s",
- e_n, n, opt2fn("-f", NFILE, fnm));
+ gmx_fatal(FARGS,
+ "Number of energies (%d) does not match number of entries (%d) in %s",
+ e_n,
+ n,
+ opt2fn("-f", NFILE, fnm));
}
}
else
}
/* The number of grid points fits in a int64_t. */
- do_sham(opt2fn("-dist", NFILE, fnm), opt2fn("-bin", NFILE, fnm), opt2fn("-lp", NFILE, fnm),
- opt2fn("-ls", NFILE, fnm), opt2fn("-lsh", NFILE, fnm), opt2fn("-lss", NFILE, fnm),
- opt2fn("-ls3", NFILE, fnm), opt2fn("-g", NFILE, fnm), n, nset, val, fn_ge != nullptr,
- e_nset, et_val, Tref, pmax, gmax, opt2parg_bSet("-emin", NPA, pa) ? &emin : nullptr,
- opt2parg_bSet("-emax", NPA, pa) ? &emax : nullptr, nlevels, pmin, idim, ibox,
- opt2parg_bSet("-xmin", NPA, pa), rmin, opt2parg_bSet("-xmax", NPA, pa), rmax);
+ do_sham(opt2fn("-dist", NFILE, fnm),
+ opt2fn("-bin", NFILE, fnm),
+ opt2fn("-lp", NFILE, fnm),
+ opt2fn("-ls", NFILE, fnm),
+ opt2fn("-lsh", NFILE, fnm),
+ opt2fn("-lss", NFILE, fnm),
+ opt2fn("-ls3", NFILE, fnm),
+ opt2fn("-g", NFILE, fnm),
+ n,
+ nset,
+ val,
+ fn_ge != nullptr,
+ e_nset,
+ et_val,
+ Tref,
+ pmax,
+ gmax,
+ opt2parg_bSet("-emin", NPA, pa) ? &emin : nullptr,
+ opt2parg_bSet("-emax", NPA, pa) ? &emax : nullptr,
+ nlevels,
+ pmin,
+ idim,
+ ibox,
+ opt2parg_bSet("-xmin", NPA, pa),
+ rmin,
+ opt2parg_bSet("-xmax", NPA, pa),
+ rmax);
return 0;
}
int cur = 0;
#define next (1 - cur)
- if (!parse_common_args(&argc, argv, PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, asize(desc), desc,
- 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
{
minimum = oldx + dp[cur] * (x - oldx) / (dp[cur] - dp[next]);
mval = pot(minimum, qq, c6, cn, npow);
- printf("Van der Waals + Coulomb minimum at r = %g (nm). Value = %g (kJ/mol)\n",
- minimum, mval);
+ printf("Van der Waals + Coulomb minimum at r = %g (nm). Value = %g (kJ/mol)\n", minimum, mval);
}
}
cur = next;
{ efXVG, "-co", "scum", ffWRITE }, { efXVG, "-rc", "scount", ffWRITE } };
#define NFILE asize(fnm)
- if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa,
- asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
xvgr_legend(fp, 2, legr, oenv);
for (i = 0; i < nrbin; i++)
{
- fprintf(fp, "%g %g %g\n", (i + 0.5) * rbinw, histn[i] ? histi1[i] / histn[i] : 0,
+ fprintf(fp,
+ "%g %g %g\n",
+ (i + 0.5) * rbinw,
+ histn[i] ? histi1[i] / histn[i] : 0,
histn[i] ? histi2[i] / histn[i] : 0);
}
xvgrclose(fp);
/* This is the routine responsible for adding default options,
* calling the X/motif interface, etc. */
- if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa,
- asize(desc), desc, asize(bugs), bugs, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, asize(desc), desc, asize(bugs), bugs, &oenv))
{
return 0;
}
{
printf("There was an item outside of the allocated memory. Increase the value "
"given with the -nab option.\n");
- printf("Memory was allocated for [%f,%f,%f]\tto\t[%f,%f,%f]\n", MINBIN[XX],
- MINBIN[YY], MINBIN[ZZ], MAXBIN[XX], MAXBIN[YY], MAXBIN[ZZ]);
- printf("Memory was required for [%f,%f,%f]\n", fr.x[index[i]][XX],
- fr.x[index[i]][YY], fr.x[index[i]][ZZ]);
+ printf("Memory was allocated for [%f,%f,%f]\tto\t[%f,%f,%f]\n",
+ MINBIN[XX],
+ MINBIN[YY],
+ MINBIN[ZZ],
+ MAXBIN[XX],
+ MAXBIN[YY],
+ MAXBIN[ZZ]);
+ printf("Memory was required for [%f,%f,%f]\n",
+ fr.x[index[i]][XX],
+ fr.x[index[i]][YY],
+ fr.x[index[i]][ZZ]);
exit(1);
}
x = static_cast<int>(std::ceil((fr.x[index[i]][XX] - MINBIN[XX]) / rBINWIDTH));
flp = gmx_ffopen("grid.cube", "w");
fprintf(flp, "Spatial Distribution Function\n");
fprintf(flp, "test\n");
- fprintf(flp, "%5d%12.6f%12.6f%12.6f\n", nidxp,
+ fprintf(flp,
+ "%5d%12.6f%12.6f%12.6f\n",
+ nidxp,
(MINBIN[XX] + (minx + iIGNOREOUTER) * rBINWIDTH) * 10. / bohr,
(MINBIN[YY] + (miny + iIGNOREOUTER) * rBINWIDTH) * 10. / bohr,
(MINBIN[ZZ] + (minz + iIGNOREOUTER) * rBINWIDTH) * 10. / bohr);
- fprintf(flp, "%5d%12.6f%12.6f%12.6f\n", maxx - minx + 1 - (2 * iIGNOREOUTER),
- rBINWIDTH * 10. / bohr, 0., 0.);
- fprintf(flp, "%5d%12.6f%12.6f%12.6f\n", maxy - miny + 1 - (2 * iIGNOREOUTER), 0.,
- rBINWIDTH * 10. / bohr, 0.);
- fprintf(flp, "%5d%12.6f%12.6f%12.6f\n", maxz - minz + 1 - (2 * iIGNOREOUTER), 0., 0.,
- rBINWIDTH * 10. / bohr);
+ fprintf(flp, "%5d%12.6f%12.6f%12.6f\n", maxx - minx + 1 - (2 * iIGNOREOUTER), rBINWIDTH * 10. / bohr, 0., 0.);
+ fprintf(flp, "%5d%12.6f%12.6f%12.6f\n", maxy - miny + 1 - (2 * iIGNOREOUTER), 0., rBINWIDTH * 10. / bohr, 0.);
+ fprintf(flp, "%5d%12.6f%12.6f%12.6f\n", maxz - minz + 1 - (2 * iIGNOREOUTER), 0., 0., rBINWIDTH * 10. / bohr);
for (i = 0; i < nidxp; i++)
{
v = 2;
{
v = 16;
}
- fprintf(flp, "%5d%12.6f%12.6f%12.6f%12.6f\n", v, 0., fr.x[indexp[i]][XX] * 10.0 / bohr,
- fr.x[indexp[i]][YY] * 10.0 / bohr, fr.x[indexp[i]][ZZ] * 10.0 / bohr);
+ fprintf(flp,
+ "%5d%12.6f%12.6f%12.6f%12.6f\n",
+ v,
+ 0.,
+ fr.x[indexp[i]][XX] * 10.0 / bohr,
+ fr.x[indexp[i]][YY] * 10.0 / bohr,
+ fr.x[indexp[i]][ZZ] * 10.0 / bohr);
}
tot = 0;
if (bCALCDIV)
{
printf("Counts per frame in all %d cubes divided by %le\n", numcu, 1.0 / norm);
- printf("Normalized data: average %le, min %le, max %le\n", 1.0, minval * norm / numfr,
+ printf("Normalized data: average %le, min %le, max %le\n",
+ 1.0,
+ minval * norm / numfr,
maxval * norm / numfr);
}
else
{
printf("grid.cube contains counts per frame in all %d cubes\n", numcu);
- printf("Raw data: average %le, min %le, max %le\n", 1.0 / norm,
- static_cast<double>(minval) / numfr, static_cast<double>(maxval) / numfr);
+ printf("Raw data: average %le, min %le, max %le\n",
+ 1.0 / norm,
+ static_cast<double>(minval) / numfr,
+ static_cast<double>(maxval) / numfr);
}
return 0;
}
if (m == mols->nr)
{
- gmx_fatal(FARGS, "index[%d]=%d does not correspond to the first atom of a molecule",
- i + 1, index[i] + 1);
+ gmx_fatal(FARGS,
+ "index[%d]=%d does not correspond to the first atom of a molecule",
+ i + 1,
+ index[i] + 1);
}
for (j = mols->index[m]; j < mols->index[m + 1]; j++)
{
{ efXVG, nullptr, "scdist", ffWRITE } };
#define NFILE asize(fnm)
- if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa,
- asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
sfree(x);
close_trx(status);
- fprintf(stderr, "Average number of molecules within %g nm is %.1f\n", rmax,
- static_cast<real>(ntot) / nf);
+ fprintf(stderr, "Average number of molecules within %g nm is %.1f\n", rmax, static_cast<real>(ntot) / nf);
if (ntot > 0)
{
sdip /= ntot;
sdip2 /= ntot;
sinp /= ntot;
sdinp /= ntot;
- fprintf(stderr, "Average dipole: %f (D), std.dev. %f\n", sdip,
+ fprintf(stderr,
+ "Average dipole: %f (D), std.dev. %f\n",
+ sdip,
std::sqrt(sdip2 - gmx::square(sdip)));
fprintf(stderr, "Average radial component of the dipole: %f (D)\n", sinp);
fprintf(stderr, "Average radial component of the polarization: %f (D)\n", sdinp);
sig[i] = std::exp(0.5 * i * dt / wt);
}
- low_do_autocorr(fn_tca, oenv, "Transverse Current Autocorrelation Functions", nframes, ntc,
- ncorr, tc, dt, eacNormal, 1, FALSE, FALSE, FALSE, 0, 0, 0);
+ low_do_autocorr(fn_tca,
+ oenv,
+ "Transverse Current Autocorrelation Functions",
+ nframes,
+ ntc,
+ ncorr,
+ tc,
+ dt,
+ eacNormal,
+ 1,
+ FALSE,
+ FALSE,
+ FALSE,
+ 0,
+ 0,
+ 0);
do_view(oenv, fn_tca, "-nxy");
fp = xvgropen(fn_tc, "Transverse Current Autocorrelation Functions", "Time (ps)", "TCAF", oenv);
tcaf[k][0] = 1.0;
fitparms[0] = 1;
fitparms[1] = 1;
- do_lmfit(ncorr, tcaf[k], sig, dt, nullptr, 0, ncorr * dt, oenv, bDebugMode(), effnVAC,
- fitparms, 0, nullptr);
+ do_lmfit(ncorr, tcaf[k], sig, dt, nullptr, 0, ncorr * dt, oenv, bDebugMode(), effnVAC, fitparms, 0, nullptr);
eta = 1000 * fitparms[1] * rho / (4 * fitparms[0] * PICO * norm2(kfac[k]) / (NANO * NANO));
fprintf(stdout, "k %6.3f tau %6.3f eta %8.5f 10^-3 kg/(m s)\n", norm(kfac[k]), fitparms[0], eta);
fprintf(fp_vk, "%6.3f %g\n", norm(kfac[k]), eta);
tcafc[k][0] = 1.0;
fitparms[0] = 1;
fitparms[1] = 1;
- do_lmfit(ncorr, tcafc[k], sig, dt, nullptr, 0, ncorr * dt, oenv, bDebugMode(), effnVAC,
- fitparms, 0, nullptr);
+ do_lmfit(ncorr, tcafc[k], sig, dt, nullptr, 0, ncorr * dt, oenv, bDebugMode(), effnVAC, fitparms, 0, nullptr);
eta = 1000 * fitparms[1] * rho
/ (4 * fitparms[0] * PICO * norm2(kfac[kset_c[k]]) / (NANO * NANO));
- fprintf(stdout, "k %6.3f tau %6.3f Omega %6.3f eta %8.5f 10^-3 kg/(m s)\n",
- norm(kfac[kset_c[k]]), fitparms[0], fitparms[1], eta);
+ fprintf(stdout,
+ "k %6.3f tau %6.3f Omega %6.3f eta %8.5f 10^-3 kg/(m s)\n",
+ norm(kfac[kset_c[k]]),
+ fitparms[0],
+ fitparms[1],
+ eta);
fprintf(fp_vk, "%6.3f %g\n", norm(kfac[kset_c[k]]), eta);
for (i = 0; i < ncorr; i++)
{
npargs = asize(pa);
ppa = add_acf_pargs(&npargs, pa);
- if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, npargs, ppa,
- asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, npargs, ppa, asize(desc), desc, 0, nullptr, &oenv))
{
sfree(ppa);
return 0;
rho *= sysmass / nframes * AMU / (NANO * NANO * NANO);
fprintf(stdout, "Density = %g (kg/m^3)\n", rho);
- process_tcaf(nframes, dt, nkc, tc, kfac, rho, wt, opt2fn_null("-ot", NFILE, fnm),
- opt2fn("-oa", NFILE, fnm), opt2fn("-o", NFILE, fnm), opt2fn("-of", NFILE, fnm),
- opt2fn_null("-oc", NFILE, fnm), opt2fn("-ov", NFILE, fnm), oenv);
+ process_tcaf(nframes,
+ dt,
+ nkc,
+ tc,
+ kfac,
+ rho,
+ wt,
+ opt2fn_null("-ot", NFILE, fnm),
+ opt2fn("-oa", NFILE, fnm),
+ opt2fn("-o", NFILE, fnm),
+ opt2fn("-of", NFILE, fnm),
+ opt2fn_null("-oc", NFILE, fnm),
+ opt2fn("-ov", NFILE, fnm),
+ oenv);
return 0;
}
fp = xvgropen(xname, title, "Atom", "Spatial component", oenv);
for (i = 0; i < isize; i++)
{
- fprintf(fp, "%-5d %10.3f %10.3f %10.3f\n", 1 + i, sum[index[i]][XX],
- sum[index[i]][YY], sum[index[i]][ZZ]);
+ fprintf(fp,
+ "%-5d %10.3f %10.3f %10.3f\n",
+ 1 + i,
+ sum[index[i]][XX],
+ sum[index[i]][YY],
+ sum[index[i]][ZZ]);
}
xvgrclose(fp);
max = 0;
}
}
- printf("Maximum %s is %g on atom %d %s, res. %s %d\n", title, std::sqrt(max), maxi + 1,
- *(atoms->atomname[maxi]), *(atoms->resinfo[atoms->atom[maxi].resind].name),
+ printf("Maximum %s is %g on atom %d %s, res. %s %d\n",
+ title,
+ std::sqrt(max),
+ maxi + 1,
+ *(atoms->atomname[maxi]),
+ *(atoms->resinfo[atoms->atom[maxi].resind].name),
atoms->resinfo[atoms->atom[maxi].resind].nr);
if (atoms->pdbinfo == nullptr)
};
#define NFILE asize(fnm)
- if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_TIME_UNIT | PCA_CAN_VIEW, NFILE, fnm,
- asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(&argc,
+ argv,
+ PCA_CAN_TIME | PCA_TIME_UNIT | PCA_CAN_VIEW,
+ NFILE,
+ fnm,
+ asize(pa),
+ pa,
+ asize(desc),
+ desc,
+ 0,
+ nullptr,
+ &oenv))
{
return 0;
}
}
std::string sffmt6 = gmx::formatString("%s%s%s%s%s%s", sffmt, sffmt, sffmt, sffmt, sffmt, sffmt);
- bTop = read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &pbcType, &xtop, nullptr, topbox,
+ bTop = read_tps_conf(ftp2fn(efTPS, NFILE, fnm),
+ &top,
+ &pbcType,
+ &xtop,
+ nullptr,
+ topbox,
bCom && (bOX || bOXT || bOV || bOT || bEKT || bEKR));
sfree(xtop);
if ((bMol || bCV || bCF) && !bTop)
{
if (index0[0][i] < 0 || index0[0][i] >= mols->nr)
{
- gmx_fatal(FARGS, "Molecule index (%d) is out of range (%d-%d)", index0[0][i] + 1, 1,
- mols->nr);
+ gmx_fatal(FARGS, "Molecule index (%d) is out of range (%d-%d)", index0[0][i] + 1, 1, mols->nr);
}
isize[i] = atndx[index0[0][i] + 1] - atndx[index0[0][i]];
snew(index[i], isize[i]);
if (bOX)
{
flags = flags | TRX_READ_X;
- outx = xvgropen(opt2fn("-ox", NFILE, fnm), bCom ? "Center of mass" : "Coordinate", label,
- "Coordinate (nm)", oenv);
+ outx = xvgropen(opt2fn("-ox", NFILE, fnm),
+ bCom ? "Center of mass" : "Coordinate",
+ label,
+ "Coordinate (nm)",
+ oenv);
make_legend(outx, ngroups, isize0[0], index0[0], grpname, bCom, bMol, bDim, oenv);
}
if (bOXT)
if (bOV)
{
flags = flags | TRX_READ_V;
- outv = xvgropen(opt2fn("-ov", NFILE, fnm), bCom ? "Center of mass velocity" : "Velocity",
- label, "Velocity (nm/ps)", oenv);
+ outv = xvgropen(opt2fn("-ov", NFILE, fnm),
+ bCom ? "Center of mass velocity" : "Velocity",
+ label,
+ "Velocity (nm/ps)",
+ oenv);
make_legend(outv, ngroups, isize0[0], index0[0], grpname, bCom, bMol, bDim, oenv);
}
if (bOF)
{
flags = flags | TRX_READ_F;
- outf = xvgropen(opt2fn("-of", NFILE, fnm), "Force", label,
- "Force (kJ mol\\S-1\\N nm\\S-1\\N)", oenv);
+ outf = xvgropen(
+ opt2fn("-of", NFILE, fnm), "Force", label, "Force (kJ mol\\S-1\\N nm\\S-1\\N)", oenv);
make_legend(outf, ngroups, isize0[0], index0[0], grpname, bCom, bMol, bDim, oenv);
}
if (bOB)
bDum[ZZ] = FALSE;
bDum[DIM] = TRUE;
flags = flags | TRX_READ_V;
- outekt = xvgropen(opt2fn("-ekt", NFILE, fnm), "Center of mass translation", label,
- "Energy (kJ mol\\S-1\\N)", oenv);
+ outekt = xvgropen(opt2fn("-ekt", NFILE, fnm),
+ "Center of mass translation",
+ label,
+ "Energy (kJ mol\\S-1\\N)",
+ oenv);
make_legend(outekt, ngroups, isize[0], index[0], grpname, bCom, bMol, bDum, oenv);
}
if (bEKR)
bDum[ZZ] = FALSE;
bDum[DIM] = TRUE;
flags = flags | TRX_READ_X | TRX_READ_V;
- outekr = xvgropen(opt2fn("-ekr", NFILE, fnm), "Center of mass rotation", label,
- "Energy (kJ mol\\S-1\\N)", oenv);
+ outekr = xvgropen(opt2fn("-ekr", NFILE, fnm),
+ "Center of mass rotation",
+ label,
+ "Energy (kJ mol\\S-1\\N)",
+ oenv);
make_legend(outekr, ngroups, isize[0], index[0], grpname, bCom, bMol, bDum, oenv);
}
if (bVD)
if (bOB && fr.bBox)
{
fprintf(outb, "\t%g", fr.time);
- fprintf(outb, sffmt6.c_str(), fr.box[XX][XX], fr.box[YY][YY], fr.box[ZZ][ZZ],
- fr.box[YY][XX], fr.box[ZZ][XX], fr.box[ZZ][YY]);
+ fprintf(outb,
+ sffmt6.c_str(),
+ fr.box[XX][XX],
+ fr.box[YY][YY],
+ fr.box[ZZ][ZZ],
+ fr.box[YY][XX],
+ fr.box[ZZ][XX],
+ fr.box[ZZ][YY]);
fprintf(outb, "\n");
}
if (bOT && fr.bV)
}
if (bCV)
{
- write_pdb_bfac(opt2fn("-cv", NFILE, fnm), opt2fn("-av", NFILE, fnm), "average velocity",
- &(top.atoms), pbcType, topbox, isize[0], index[0], nr_xfr, sumx, nr_vfr,
- sumv, bDim, scale, oenv);
+ write_pdb_bfac(opt2fn("-cv", NFILE, fnm),
+ opt2fn("-av", NFILE, fnm),
+ "average velocity",
+ &(top.atoms),
+ pbcType,
+ topbox,
+ isize[0],
+ index[0],
+ nr_xfr,
+ sumx,
+ nr_vfr,
+ sumv,
+ bDim,
+ scale,
+ oenv);
}
if (bCF)
{
- write_pdb_bfac(opt2fn("-cf", NFILE, fnm), opt2fn("-af", NFILE, fnm), "average force",
- &(top.atoms), pbcType, topbox, isize[0], index[0], nr_xfr, sumx, nr_ffr,
- sumf, bDim, scale, oenv);
+ write_pdb_bfac(opt2fn("-cf", NFILE, fnm),
+ opt2fn("-af", NFILE, fnm),
+ "average force",
+ &(top.atoms),
+ pbcType,
+ topbox,
+ isize[0],
+ index[0],
+ nr_xfr,
+ sumx,
+ nr_ffr,
+ sumf,
+ bDim,
+ scale,
+ oenv);
}
/* view it */
{ efXVG, "-nshell", "nshell", ffOPTWR } };
#define NFILE asize(fnm)
- if (!parse_common_args(&argc, argv, PCA_CAN_TIME, NFILE, fnm, asize(pa), pa, asize(desc), desc,
- 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_TIME, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
if ((isize_sol % na) != 0)
{
- gmx_fatal(FARGS, "Number of atoms in the molecule group (%d) is not a multiple of na (%d)",
- isize[1], na);
+ gmx_fatal(FARGS,
+ "Number of atoms in the molecule group (%d) is not a multiple of na (%d)",
+ isize[1],
+ na);
}
nwat = isize_sol / na;
FILE* fp;
t_rgb rlo = { 1, 1, 1 }, rhi = { 0, 0, 0 };
- if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, asize(pa), pa,
- asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
ticky[i] = i * rbin;
}
fp = gmx_ffopen(matfile, "w");
- write_xpm(fp, MAT_SPATIAL_Y, "Van Hove function", "G (1/nm)",
- sbin == 0 ? "time (ps)" : "sqrt(time) (ps^1/2)", "r (nm)", mat_nx, nbin, tickx,
- ticky, mat, 0, matmax, rlo, rhi, &nlev);
+ write_xpm(fp,
+ MAT_SPATIAL_Y,
+ "Van Hove function",
+ "G (1/nm)",
+ sbin == 0 ? "time (ps)" : "sqrt(time) (ps^1/2)",
+ "r (nm)",
+ mat_nx,
+ nbin,
+ tickx,
+ ticky,
+ mat,
+ 0,
+ matmax,
+ rlo,
+ rhi,
+ &nlev);
gmx_ffclose(fp);
}
fprintf(fp, "%g", i * rbin);
for (fbin = 0; fbin < nr; fbin++)
{
- fprintf(fp, " %g",
+ fprintf(fp,
+ " %g",
static_cast<real>(pr[fbin][i]
/ (rcount[fbin] * isize * rbin * (i == 0 ? 0.5 : 1.0))));
}
{
gmx_fatal(FARGS, "Invalid fft return status %d", status);
}
- fp = xvgropen(fn, "Vibrational Power Spectrum",
- bRecip ? "\\f{12}w\\f{4} (cm\\S-1\\N)" : "\\f{12}n\\f{4} (ps\\S-1\\N)", "a.u.", oenv);
+ fp = xvgropen(fn,
+ "Vibrational Power Spectrum",
+ bRecip ? "\\f{12}w\\f{4} (cm\\S-1\\N)" : "\\f{12}n\\f{4} (ps\\S-1\\N)",
+ "a.u.",
+ oenv);
/* This is difficult.
* The length of the ACF is dt (as passed to this routine).
* We pass the vacf with N time steps from 0 to dt.
npargs = asize(pa);
ppa = add_acf_pargs(&npargs, pa);
- if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, npargs, ppa,
- asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, npargs, ppa, asize(desc), desc, 0, nullptr, &oenv))
{
sfree(ppa);
return 0;
{
/* Compute time step between frames */
dt = (t1 - t0) / (counter - 1);
- do_autocorr(opt2fn("-o", NFILE, fnm), oenv,
+ do_autocorr(opt2fn("-o", NFILE, fnm),
+ oenv,
bMass ? "Momentum Autocorrelation Function" : "Velocity Autocorrelation Function",
- counter, gnx, c1, dt, eacVector, TRUE);
+ counter,
+ gnx,
+ c1,
+ dt,
+ eacVector,
+ TRUE);
do_view(oenv, opt2fn("-o", NFILE, fnm), "-nxy");
opt->tabX[i] = y[0][i];
opt->tabY[i] = y[1][i];
}
- printf("Found equally spaced tabulated potential from %g to %g, spacing %g\n", opt->tabMin,
- opt->tabMax, opt->tabDz);
+ printf("Found equally spaced tabulated potential from %g to %g, spacing %g\n",
+ opt->tabMin,
+ opt->tabMax,
+ opt->tabDz);
}
//! Read the header of an PDO file (position, force const, nr of groups)
gmx_fatal(FARGS,
"This does not appear to be a valid pdo file. Found %s, expected %s\n"
"(Found in first line: `%s')\n",
- Buffer1, "UMBRELLA", line);
+ Buffer1,
+ "UMBRELLA",
+ line);
}
if (std::strcmp(Buffer2, "3.0") != 0)
{
if (opt->verbose)
{
- printf("\tpullgroup %d, pullname = %s, UmbPos = %g, UmbConst = %g\n", i,
- header->PullName[i], header->UmbPos[i][0], header->UmbCons[i][0]);
+ printf("\tpullgroup %d, pullname = %s, UmbPos = %g, UmbConst = %g\n",
+ i,
+ header->PullName[i],
+ header->UmbPos[i][0],
+ header->UmbCons[i][0]);
}
}
gmx_fatal(FARGS,
"Distance %f out of bounds of tabulated potential (jl=%d, ju=%d).\n"
"Provide an extended table.",
- dist, jl, ju);
+ dist,
+ jl,
+ ju);
}
pl = opt->tabY[jl];
pu = opt->tabY[ju];
{
printf("Initialized rapid wham stuff (contrib tolerance %g)\n"
"Evaluating only %d of %d expressions.\n\n",
- wham_contrib_lim, nContrib, nTot);
+ wham_contrib_lim,
+ nContrib,
+ nTot);
}
if (opt->verbose)
if (min > 0. || max < 0.)
{
- gmx_fatal(FARGS, "Cannot symmetrize profile around z=0 with min=%f and max=%f\n", opt->min,
- opt->max);
+ gmx_fatal(FARGS, "Cannot symmetrize profile around z=0 with min=%f and max=%f\n", opt->min, opt->max);
}
snew(prof2, bins);
gmx_fatal(FARGS,
"Ups, random iWin = %d, nPull = %d, nr = %d, "
"blockLength = %d, blockBase = %d\n",
- ipullRandom, nPull, nr, blockLength, blockBase);
+ ipullRandom,
+ nPull,
+ nr,
+ blockLength,
+ blockBase);
}
randomArray[ipull] = ipullRandom;
}
gmx_fatal(FARGS,
"Found %d pull coordinates in %s, but %d columns in the respective line\n"
"coordinate selection file (option -is)\n",
- ir->pull->ncoord, fn, coordsel->n);
+ ir->pull->ncoord,
+ fn,
+ coordsel->n);
}
}
"umbrella coodinates can enter WHAM.\n"
"If you have umrella and non-umbrella coordinates, you can select the "
"umbrella coordinates with gmx wham -is\n",
- fn, i + 1, epull_names[header->pcrd[i].pull_type]);
+ fn,
+ i + 1,
+ epull_names[header->pcrd[i].pull_type]);
}
if (!geometryIsSet)
{
"%s, coordinate %d: %s)\n"
"If you want to use only some pull coordinates in WHAM, please select "
"them with option gmx wham -is\n",
- fn, epullg_names[geom], i + 1, epullg_names[header->pcrd[i].geometry]);
+ fn,
+ epullg_names[geom],
+ i + 1,
+ epullg_names[header->pcrd[i].geometry]);
}
if (thedim[XX] != header->pcrd[i].dim[XX] || thedim[YY] != header->pcrd[i].dim[YY]
|| thedim[ZZ] != header->pcrd[i].dim[ZZ])
"%s %s %s, coordinate %d: %s %s %s)\n"
"If you want to use only some pull coordinates in WHAM, please select "
"them with option gmx wham -is\n",
- fn, int2YN(thedim[XX]), int2YN(thedim[YY]), int2YN(thedim[ZZ]), i + 1,
- int2YN(header->pcrd[i].dim[XX]), int2YN(header->pcrd[i].dim[YY]),
+ fn,
+ int2YN(thedim[XX]),
+ int2YN(thedim[YY]),
+ int2YN(thedim[ZZ]),
+ i + 1,
+ int2YN(header->pcrd[i].dim[XX]),
+ int2YN(header->pcrd[i].dim[YY]),
int2YN(header->pcrd[i].dim[ZZ]));
}
if (header->pcrd[i].geometry == epullgCYL)
FARGS,
"With pull geometry 'cylinder', expected pulling in Z direction only.\n"
"However, found dimensions [%s %s %s]\n",
- int2YN(header->pcrd[i].dim[XX]), int2YN(header->pcrd[i].dim[YY]),
+ int2YN(header->pcrd[i].dim[XX]),
+ int2YN(header->pcrd[i].dim[YY]),
int2YN(header->pcrd[i].dim[ZZ]));
}
}
gmx_fatal(FARGS,
"%s: Pull coordinate %d has force constant of of %g.\n"
"That doesn't seem to be an Umbrella tpr.\n",
- fn, i + 1, header->pcrd[i].k);
+ fn,
+ i + 1,
+ header->pcrd[i].k);
}
}
}
for (int i = 0; i < ir->pull->ncoord; i++)
{
bool use = (coordsel == nullptr || coordsel->bUse[i]);
- printf(fmt, epullg_names[header->pcrd[i].geometry], header->pcrd[i].k, header->pcrd[i].init_dist,
- int2YN(header->pcrd[i].dim[XX]), int2YN(header->pcrd[i].dim[YY]),
- int2YN(header->pcrd[i].dim[ZZ]), header->pcrd[i].ndim, use ? "Yes" : "No");
+ printf(fmt,
+ epullg_names[header->pcrd[i].geometry],
+ header->pcrd[i].k,
+ header->pcrd[i].init_dist,
+ int2YN(header->pcrd[i].dim[XX]),
+ int2YN(header->pcrd[i].dim[YY]),
+ int2YN(header->pcrd[i].dim[ZZ]),
+ header->pcrd[i].ndim,
+ use ? "Yes" : "No");
printf("\tPull group coordinates of %d groups expected in pullx files.\n",
ir->pull->bPrintCOM ? header->pcrd[i].ngroup : 0);
}
printf("\t\treaction coordinate: %d\n"
"\t\tcenter-of-mass of groups: %d\n"
"\t\treference position column: %s\n",
- 1, nColCOMCrd[i], (header->bPrintRefValue ? "Yes" : "No"));
+ 1,
+ nColCOMCrd[i],
+ (header->bPrintRefValue ? "Yes" : "No"));
}
printf("\tFound %d times in %s\n", nt, fn);
bFirst = FALSE;
gmx_fatal(FARGS,
"Expected %d columns (including time column) in %s, but found %d."
" Maybe you confused options -if and -ix ?",
- nColExpect, fn, ny);
+ nColExpect,
+ fn,
+ ny);
}
if (!bGetMinMax)
gmx_fatal(FARGS,
"tpr file contains %d pull groups, but expected %d from group selection "
"file\n",
- header->npullcrds, coordsel->n);
+ header->npullcrds,
+ coordsel->n);
}
window->nPull = coordsel->nUse;
}
gmx_fatal(FARGS,
"gUsed too large (%d, nPull=%d). This error should have been "
"caught before.\n",
- gUsed, window->nPull);
+ gUsed,
+ window->nPull);
}
if (opt->bCalcTauInt && !bGetMinMax)
if (whaminFileType(fnPull[i]) != whamin_pullxf)
{
gmx_fatal(FARGS,
- "Expected the %d'th file in input file to be a xvg (pullx/pullf) file\n", i);
- }
- read_pull_xf(fnPull[i], header, nullptr, opt, TRUE, &mintmp, &maxtmp,
+ "Expected the %d'th file in input file to be a xvg (pullx/pullf) file\n",
+ i);
+ }
+ read_pull_xf(fnPull[i],
+ header,
+ nullptr,
+ opt,
+ TRUE,
+ &mintmp,
+ &maxtmp,
(opt->nCoordsel > 0) ? &opt->coordsel[i] : nullptr);
if (maxtmp > opt->max)
{
read_tpr_header(fnTprs[i], header, opt, (opt->nCoordsel > 0) ? &opt->coordsel[i] : nullptr);
if (whaminFileType(fnPull[i]) != whamin_pullxf)
{
- gmx_fatal(FARGS,
- "Expected the %d'th file in input file to be a xvg (pullx/pullf) file\n", i);
+ gmx_fatal(
+ FARGS, "Expected the %d'th file in input file to be a xvg (pullx/pullf) file\n", i);
}
- read_pull_xf(fnPull[i], header, window + i, opt, FALSE, nullptr, nullptr,
+ read_pull_xf(fnPull[i],
+ header,
+ window + i,
+ opt,
+ FALSE,
+ nullptr,
+ nullptr,
(opt->nCoordsel > 0) ? &opt->coordsel[i] : nullptr);
if (window[i].Ntot[0] == 0)
{
nlines = read_xvg(fn, &iact, &ny);
if (nlines != nwins)
{
- gmx_fatal(FARGS, "Found %d lines with integrated autocorrelation times in %s.\nExpected %d",
- nlines, fn, nwins);
+ gmx_fatal(FARGS,
+ "Found %d lines with integrated autocorrelation times in %s.\nExpected %d",
+ nlines,
+ fn,
+ nwins);
}
for (i = 0; i < nlines; i++)
{
if (opt->verbose)
{
- fpcorr = xvgropen("hist_autocorr.xvg", "Autocorrelation functions of umbrella windows",
- "time [ps]", "autocorrelation function", opt->oenv);
+ fpcorr = xvgropen("hist_autocorr.xvg",
+ "Autocorrelation functions of umbrella windows",
+ "time [ps]",
+ "autocorrelation function",
+ opt->oenv);
}
printf("\n");
for (i = 0; i < nwins; i++)
{
- fprintf(stdout, "\rEstimating integrated autocorrelation times ... [%2.0f%%] ...",
+ fprintf(stdout,
+ "\rEstimating integrated autocorrelation times ... [%2.0f%%] ...",
100. * (i + 1) / nwins);
fflush(stdout);
ntot = window[i].Ntot[0];
gmx_fatal(FARGS,
"Encountered different nr of frames in different pull groups.\n"
"That should not happen. (%d and %d)\n",
- ntot, window[i].Ntot[ig]);
+ ntot,
+ window[i].Ntot[ig]);
}
ztime = window[i].ztime[ig];
fprintf(stderr,
"\nWARNING, no data point in bin %d (z=%g) !\n"
"You may not get a reasonable profile. Check your histograms!\n",
- j, z);
+ j,
+ z);
}
/* and check for poor sampling */
else if (relcount < 0.005 && !bBoundary)
printf("\nUse only these pull coordinates:\n");
for (iline = 0; iline < nTpr; iline++)
{
- printf("%s (%d of %d coordinates):", fnTpr[iline], opt->coordsel[iline].nUse,
+ printf("%s (%d of %d coordinates):",
+ fnTpr[iline],
+ opt->coordsel[iline].nUse,
opt->coordsel[iline].n);
for (i = 0; i < opt->coordsel[iline].n; i++)
{
opt.stepchange = 100;
opt.stepUpdateContrib = 100;
- if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr,
- &opt.oenv))
+ if (!parse_common_args(
+ &argc, argv, 0, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &opt.oenv))
{
return 0;
}
fnPull = opt.bPullf ? opt.fnPullf : opt.fnPullx;
read_wham_in(fnPull, &fninPull, &nfiles2, &opt);
- printf("Found %d tpr and %d pull %s files in %s and %s, respectively\n", nfiles, nfiles2,
- opt.bPullf ? "force" : "position", opt.fnTpr, fnPull);
+ printf("Found %d tpr and %d pull %s files in %s and %s, respectively\n",
+ nfiles,
+ nfiles2,
+ opt.bPullf ? "force" : "position",
+ opt.fnTpr,
+ fnPull);
if (nfiles != nfiles2)
{
gmx_fatal(FARGS, "Found %d file names in %s, but %d in %s\n", nfiles, opt.fnTpr, nfiles2, fnPull);
/* Bootstrap Method */
if (opt.nBootStrap)
{
- do_bootstrapping(opt2fn("-bsres", NFILE, fnm), opt2fn("-bsprof", NFILE, fnm),
- opt2fn("-hist", NFILE, fnm), xlabel, ylabel, profile, window, nwins, &opt);
+ do_bootstrapping(opt2fn("-bsres", NFILE, fnm),
+ opt2fn("-bsprof", NFILE, fnm),
+ opt2fn("-hist", NFILE, fnm),
+ xlabel,
+ ylabel,
+ profile,
+ window,
+ nwins,
+ &opt);
}
sfree(profile);
/* Plot label on lowest graph only */
if (m == mat.begin())
{
- ps_ctext(ps, xx, yy00 - DDD - psr->X.majorticklen - psr->X.tickfontsize * 0.8,
- xtick[x], eXCenter);
+ ps_ctext(ps, xx, yy00 - DDD - psr->X.majorticklen - psr->X.tickfontsize * 0.8, xtick[x], eXCenter);
}
}
else if (bRmod(m->axis_x[x], psr->X.offset, psr->X.minor)
/* Major ticks */
strlength = std::max(strlength, std::strlen(ytick[y]));
ps_line(ps, xx00, yy, xx00 - psr->Y.majorticklen, yy);
- ps_ctext(ps, xx00 - psr->Y.majorticklen - DDD, yy - psr->Y.tickfontsize / 3.0,
- ytick[y], eXRight);
+ ps_ctext(ps, xx00 - psr->Y.majorticklen - DDD, yy - psr->Y.tickfontsize / 3.0, ytick[y], eXRight);
}
else if (bRmod(m->axis_y[y], psr->Y.offset, psr->Y.minor))
{
if (!mylab.empty())
{
ps_strfont(ps, psr->X.font, psr->X.fontsize);
- ps_ctext(ps, x0 + w / 2,
+ ps_ctext(ps,
+ x0 + w / 2,
y0 - DDD - psr->X.majorticklen - psr->X.tickfontsize * FUDGE - psr->X.fontsize,
- mylab, eXCenter);
+ mylab,
+ eXCenter);
}
}
{
gmx_fatal(FARGS, "Not enough symbols to merge the two colormaps\n");
}
- printf("Combining colormaps of %zu and %zu elements into one of %zu elements\n", map1.size(),
- map2.size(), map.size());
+ printf("Combining colormaps of %zu and %zu elements into one of %zu elements\n",
+ map1.size(),
+ map2.size(),
+ map.size());
gmx::index k = 0;
for (gmx::index j = 0; j < gmx::ssize(map1) && k < gmx::ssize(map); ++j, ++k)
{
if (psr->X.major <= 0)
{
tick_spacing((mat[0].flags & MAT_SPATIAL_X) ? mat[0].nx + 1 : mat[0].nx,
- mat[0].axis_x.data(), psr->X.offset, 'X', &(psr->X.major), &(psr->X.minor));
+ mat[0].axis_x.data(),
+ psr->X.offset,
+ 'X',
+ &(psr->X.major),
+ &(psr->X.minor));
}
if (psr->X.minor <= 0)
{
if (psr->Y.major <= 0)
{
tick_spacing((mat[0].flags & MAT_SPATIAL_Y) ? mat[0].ny + 1 : mat[0].ny,
- mat[0].axis_y.data(), psr->Y.offset, 'Y', &(psr->Y.major), &(psr->Y.minor));
+ mat[0].axis_y.data(),
+ psr->Y.offset,
+ 'Y',
+ &(psr->Y.major),
+ &(psr->Y.minor));
}
if (psr->Y.minor <= 0)
{
{
if (elegend != elBoth)
{
- leg_continuous(&out, x0 + w / 2, w / 2, DDD, legend, psr->legfontsize, psr->legfont,
- leg_map, mapoffset);
+ leg_continuous(
+ &out, x0 + w / 2, w / 2, DDD, legend, psr->legfontsize, psr->legfont, leg_map, mapoffset);
}
else
{
assert(!mat2.empty());
- leg_bicontinuous(&out, x0 + w / 2, w, DDD, mat[0].legend, mat2[0].legend,
- psr->legfontsize, psr->legfont, map1, map2);
+ leg_bicontinuous(
+ &out, x0 + w / 2, w, DDD, mat[0].legend, mat2[0].legend, psr->legfontsize, psr->legfont, map1, map2);
}
}
ps_comment(&out, "Done processing");
"Matrix pruning requires matrices of the same size");
for (gmx::index i = 0; i != gmx::ssize(mat); ++i)
{
- fprintf(stderr, "converting %dx%d matrix to %dx%d\n", mat[i].nx, mat[i].ny,
- (mat[i].nx + skip - 1) / skip, (mat[i].ny + skip - 1) / skip);
+ fprintf(stderr,
+ "converting %dx%d matrix to %dx%d\n",
+ mat[i].nx,
+ mat[i].ny,
+ (mat[i].nx + skip - 1) / skip,
+ (mat[i].ny + skip - 1) / skip);
/* walk through matrix */
int xs = 0;
for (int x = 0; (x < mat[i].nx); x++)
gmx_fatal(FARGS,
"Size of frame %zd in 1st (%dx%d) and 2nd matrix (%dx%d) do"
" not match.\n",
- k, mat1[k].nx, mat1[k].ny, mat2[k].nx, mat2[k].ny);
+ k,
+ mat1[k].nx,
+ mat1[k].ny,
+ mat2[k].nx,
+ mat2[k].ny);
}
printf("Combining two %dx%d matrices\n", mat1[k].nx, mat1[k].ny);
rmat1 = matrix2real(&mat1[k], nullptr);
}
else
{
- write_xpm(out, mat1[k].flags, mat1[k].title, mat1[k].legend, mat1[k].label_x,
- mat1[k].label_y, mat1[k].nx, mat1[k].ny, mat1[k].axis_x.data(),
- mat1[k].axis_y.data(), rmat1, rlo, rhi, white, black, &nlevels);
+ write_xpm(out,
+ mat1[k].flags,
+ mat1[k].title,
+ mat1[k].legend,
+ mat1[k].label_x,
+ mat1[k].label_y,
+ mat1[k].nx,
+ mat1[k].ny,
+ mat1[k].axis_x.data(),
+ mat1[k].axis_y.data(),
+ rmat1,
+ rlo,
+ rhi,
+ white,
+ black,
+ &nlevels);
}
}
gmx_ffclose(out);
gmx_fatal(FARGS,
"WAKE UP!! Size of frame %zd in 2nd matrix file (%dx%d) does not match "
"size of 1st matrix (%dx%d) or the other way around.\n",
- k, mat2[k].nx, mat2[k].ny, mat[k].nx, mat[k].ny);
+ k,
+ mat2[k].nx,
+ mat2[k].ny,
+ mat[k].nx,
+ mat[k].ny);
}
for (int j = 0; (j < mat[k].ny); j++)
{
if (epsfile != nullptr)
{
- ps_mat(epsfile, mat, mat2, bFrame, bDiag, bFirstDiag, bTitle, bTitleOnce, bYonce, elegend,
- size, boxx, boxy, m2p, m2pout, mapoffset);
+ ps_mat(epsfile, mat, mat2, bFrame, bDiag, bFirstDiag, bTitle, bTitleOnce, bYonce, elegend, size, boxx, boxy, m2p, m2pout, mapoffset);
}
if (xpmfile != nullptr)
{
{ efEPS, "-o", nullptr, ffOPTWR }, { efXPM, "-xpm", nullptr, ffOPTWR } };
#define NFILE asize(fnm)
- if (!parse_common_args(&argc, argv, PCA_CAN_VIEW, NFILE, fnm, NPA, pa, asize(desc), desc, 0,
- nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_VIEW, NFILE, fnm, NPA, pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
fn = opt2fn("-f", NFILE, fnm);
std::vector<t_matrix> mat, mat2;
mat = read_xpm_matrix(fn);
- fprintf(stderr, "There %s %zu matri%s in %s\n", (mat.size() > 1) ? "are" : "is", mat.size(),
- (mat.size() > 1) ? "ces" : "x", fn);
+ fprintf(stderr,
+ "There %s %zu matri%s in %s\n",
+ (mat.size() > 1) ? "are" : "is",
+ mat.size(),
+ (mat.size() > 1) ? "ces" : "x",
+ fn);
fn = opt2fn_null("-f2", NFILE, fnm);
if (fn)
{
mat2 = read_xpm_matrix(fn);
- fprintf(stderr, "There %s %zu matri%s in %s\n", (mat2.size() > 1) ? "are" : "is",
- mat2.size(), (mat2.size() > 1) ? "ces" : "x", fn);
+ fprintf(stderr,
+ "There %s %zu matri%s in %s\n",
+ (mat2.size() > 1) ? "are" : "is",
+ mat2.size(),
+ (mat2.size() > 1) ? "ces" : "x",
+ fn);
if (mat.size() != mat2.size())
{
fprintf(stderr, "Different number of matrices, using the smallest number.\n");
if (ecombine && ecombine != ecHalves)
{
- write_combined_matrix(ecombine, xpmfile, mat, mat2, opt2parg_bSet("-cmin", NPA, pa) ? &cmin : nullptr,
+ write_combined_matrix(ecombine,
+ xpmfile,
+ mat,
+ mat2,
+ opt2parg_bSet("-cmin", NPA, pa) ? &cmin : nullptr,
opt2parg_bSet("-cmax", NPA, pa) ? &cmax : nullptr);
}
else
{
- do_mat(mat, mat2, bFrame, bZeroLine, bDiag, bFirstDiag, bTitle, bTitleOnce, bYonce, elegend,
- size, boxx, boxy, epsfile, xpmfile, opt2fn_null("-di", NFILE, fnm),
- opt2fn_null("-do", NFILE, fnm), skip, mapoffset);
+ do_mat(mat,
+ mat2,
+ bFrame,
+ bZeroLine,
+ bDiag,
+ bFirstDiag,
+ bTitle,
+ bTitleOnce,
+ bYonce,
+ elegend,
+ size,
+ boxx,
+ boxy,
+ epsfile,
+ xpmfile,
+ opt2fn_null("-di", NFILE, fnm),
+ opt2fn_null("-do", NFILE, fnm),
+ skip,
+ mapoffset);
}
view_all(oenv, NFILE, fnm);
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#define NBB asize(bb_nm)
t_bb* bb;
char* grpname;
- int ai, i, i0, i1, j, k, rnr, gnx, r0, r1;
+ int gnx, r0, r1;
fprintf(stderr, "Please select a group containing the entire backbone\n");
rd_index(fn, 1, &gnx, index, &grpname);
*nall = gnx;
fprintf(stderr, "Checking group %s\n", grpname);
r0 = r1 = atom[(*index)[0]].resind;
- for (i = 1; (i < gnx); i++)
+ for (int i = 1; (i < gnx); i++)
{
r0 = std::min(r0, atom[(*index)[i]].resind);
r1 = std::max(r1, atom[(*index)[i]].resind);
}
- rnr = r1 - r0 + 1;
+ int rnr = r1 - r0 + 1;
fprintf(stderr, "There are %d residues\n", rnr);
snew(bb, rnr);
- for (i = 0; (i < rnr); i++)
+ for (int i = 0; (i < rnr); i++)
{
bb[i].N = bb[i].H = bb[i].CA = bb[i].C = bb[i].O = -1;
bb[i].resno = res0 + i;
}
- for (i = j = 0; (i < gnx); i++)
+ for (int i = 0; (i < gnx); i++)
{
- ai = (*index)[i];
+ int ai = (*index)[i];
// Create an index into the residue index for the topology.
int resindex = atom[ai].resind;
// Create an index into the residues present in the selected
bb[bbindex].H = ai;
}
}
- for (k = 0; (k < NBB); k++)
+ int k = 0;
+ for (; (k < NBB); k++)
{
if (std::strcmp(bb_nm[k], *(atomname[ai])) == 0)
{
}
}
- for (i0 = 0; (i0 < rnr); i0++)
+ int i0 = 0;
+ for (; (i0 < rnr); i0++)
{
if ((bb[i0].N != -1) && (bb[i0].H != -1) && (bb[i0].CA != -1) && (bb[i0].C != -1)
&& (bb[i0].O != -1))
break;
}
}
- for (i1 = rnr - 1; (i1 >= 0); i1--)
+ int i1 = rnr - 1;
+ for (; (i1 >= 0); i1--)
{
if ((bb[i1].N != -1) && (bb[i1].H != -1) && (bb[i1].CA != -1) && (bb[i1].C != -1)
&& (bb[i1].O != -1))
i1--;
}
- for (i = i0; (i < i1); i++)
+ for (int i = i0; (i < i1); i++)
{
bb[i].Cprev = bb[i - 1].C;
bb[i].Nnext = bb[i + 1].N;
}
rnr = std::max(0, i1 - i0 + 1);
- fprintf(stderr, "There are %d complete backbone residues (from %d to %d)\n", rnr, bb[i0].resno,
- bb[i1].resno);
+ fprintf(stderr, "There are %d complete backbone residues (from %d to %d)\n", rnr, bb[i0].resno, bb[i1].resno);
if (rnr == 0)
{
gmx_fatal(FARGS, "Zero complete backbone residues were found, cannot proceed");
}
- for (i = 0; (i < rnr); i++, i0++)
+ for (int i = 0; (i < rnr); i++, i0++)
{
bb[i] = bb[i0];
}
/* Set the labels */
- for (i = 0; (i < rnr); i++)
+ for (int i = 0; (i < rnr); i++)
{
int resindex = atom[bb[i].CA].resind;
sprintf(bb[i].label, "%s%d", *(resinfo[resindex].name), resinfo[resindex].nr);
}
bb[i].phi = RAD2DEG
- * dih_angle(x[bb[i].Cprev], x[bb[i].N], x[bb[i].CA], x[bb[i].C], nullptr, r_ij,
- r_kj, r_kl, m, n, &t1, &t2, &t3);
+ * dih_angle(x[bb[i].Cprev],
+ x[bb[i].N],
+ x[bb[i].CA],
+ x[bb[i].C],
+ nullptr,
+ r_ij,
+ r_kj,
+ r_kl,
+ m,
+ n,
+ &t1,
+ &t2,
+ &t3);
bb[i].psi = RAD2DEG
- * dih_angle(x[bb[i].N], x[bb[i].CA], x[bb[i].C], x[bb[i].Nnext], nullptr, r_ij,
- r_kj, r_kl, m, n, &t1, &t2, &t3);
+ * dih_angle(x[bb[i].N],
+ x[bb[i].CA],
+ x[bb[i].C],
+ x[bb[i].Nnext],
+ nullptr,
+ r_ij,
+ r_kj,
+ r_kl,
+ m,
+ n,
+ &t1,
+ &t2,
+ &t3);
bb[i].pprms2 = gmx::square(bb[i].phi - PHI_AHX) + gmx::square(bb[i].psi - PSI_AHX);
bb[i].jcaha += 1.4 * std::sin((bb[i].psi + 138.0) * DEG2RAD)
int i;
fprintf(fp, "\n");
- fprintf(fp, "%3s %3s %3s %3s %3s %7s %7s %7s %7s %7s %3s\n", "AA", "N", "Ca", "C", "O", "Phi",
- "Psi", "D3", "D4", "D5", "Hx?");
+ fprintf(fp,
+ "%3s %3s %3s %3s %3s %7s %7s %7s %7s %7s %3s\n",
+ "AA",
+ "N",
+ "Ca",
+ "C",
+ "O",
+ "Phi",
+ "Psi",
+ "D3",
+ "D4",
+ "D5",
+ "Hx?");
for (i = 0; (i < nres); i++)
{
- fprintf(fp, "%3d %3d %3d %3d %3d %7.2f %7.2f %7.3f %7.3f %7.3f %3s\n", bb[i].resno, bb[i].N,
- bb[i].CA, bb[i].C, bb[i].O, bb[i].phi, bb[i].psi, bb[i].d3, bb[i].d4, bb[i].d5,
+ fprintf(fp,
+ "%3d %3d %3d %3d %3d %7.2f %7.2f %7.3f %7.3f %7.3f %3s\n",
+ bb[i].resno,
+ bb[i].N,
+ bb[i].CA,
+ bb[i].C,
+ bb[i].O,
+ bb[i].phi,
+ bb[i].psi,
+ bb[i].d3,
+ bb[i].d4,
+ bb[i].d5,
bb[i].bHelix ? "Yes" : "No");
}
fprintf(fp, "\n");
for (i = 0; (i < xr->ndih); i++)
{
dd = &(xr->dih[i]);
- dd->ang = dih_angle(xr->x[dd->ai[0]], xr->x[dd->ai[1]], xr->x[dd->ai[2]], xr->x[dd->ai[3]],
- nullptr, r_ij, r_kj, r_kl, m, n, &t1, &t2, &t3);
+ dd->ang = dih_angle(xr->x[dd->ai[0]],
+ xr->x[dd->ai[1]],
+ xr->x[dd->ai[2]],
+ xr->x[dd->ai[3]],
+ nullptr,
+ r_ij,
+ r_kj,
+ r_kl,
+ m,
+ n,
+ &t1,
+ &t2,
+ &t3);
}
}
xr->pp[xr->npp].iphi = xr->ndih - 2;
xr->pp[xr->npp].ipsi = xr->ndih - 1;
xr->pp[xr->npp].bShow = FALSE;
- sprintf(buf, "%s-%d", *atoms->resinfo[atoms->atom[ff[1]].resind].name,
+ sprintf(buf,
+ "%s-%d",
+ *atoms->resinfo[atoms->atom[ff[1]].resind].name,
atoms->resinfo[atoms->atom[ff[1]].resind].nr);
xr->pp[xr->npp].label = gmx_strdup(buf);
xr->npp++;
{
if (xr->dih[i].mult == 0)
{
- fprintf(stderr, "Dihedral around %d,%d not found in topology. Using mult=%d\n",
- xr->dih[i].ai[1], xr->dih[i].ai[2], mult);
+ fprintf(stderr,
+ "Dihedral around %d,%d not found in topology. Using mult=%d\n",
+ xr->dih[i].ai[1],
+ xr->dih[i].ai[2],
+ mult);
xr->dih[i].mult = mult;
xr->dih[i].phi0 = 180;
}
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012,2013,2014,2015,2016, The GROMACS development team.
- * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2020,2021, 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.
gmx::UniformIntDistribution<int> tdist(0, isize - 1);
tid = gmx_omp_get_thread_num();
/* now starting parallel threads */
- INTEL_DIAGNOSTIC_IGNORE(593)
# pragma omp for
for (int64_t mc = 0; mc < mc_max; mc++)
{
GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
}
}
- INTEL_DIAGNOSTIC_RESET
/* collecting data from threads */
for (i = 0; i < pr->grn; i++)
{
fprintf(fp, "\n *** Chemical shifts from the chemical shift index ***\n");
please_cite(fp, "Wishart98a");
- fprintf(fp, "%12s %10s %10s %10s %10s\n", "Residue", "delta Ca", "delta Ha", "delta CO",
+ fprintf(fp,
+ "%12s %10s %10s %10s %10s\n",
+ "Residue",
+ "delta Ca",
+ "delta Ha",
+ "delta CO",
"delta Cb");
for (i = 0; (i < nlist); i++)
{
co += interpolate(phi, psi, co_sd);
ha += interpolate(phi, psi, ha_sd);
}
- fprintf(fp, "%12s %10g %10g %10g %10g\n", dlist[i].name, ca / nf, ha / nf, co / nf,
- cb / nf);
+ fprintf(fp, "%12s %10g %10g %10g %10g\n", dlist[i].name, ca / nf, ha / nf, co / nf, cb / nf);
}
}
fprintf(fp, "\n");
y = inten[m][2];
z = inten[m][3];
n = x * x + y * y + z * z;
- fprintf(stderr, "%8s %8.3f %8.3f %8.3f, norm:%8.3f, d:%8.3f, e:%8.3f\n", s, x, y, z,
- std::sqrt(n), d[m], e[m]);
+ fprintf(stderr, "%8s %8.3f %8.3f %8.3f, norm:%8.3f, d:%8.3f, e:%8.3f\n", s, x, y, z, std::sqrt(n), d[m], e[m]);
}
fprintf(stderr, "\n");
}
while (get_a_line(fp.get(), line, STRLEN))
{
i = line_no;
- if (sscanf(line, "%s %d %lf %lf %lf %lf %lf %lf %lf %lf %lf", atomn, &p, &a1, &a2, &a3, &a4,
- &b1, &b2, &b3, &b4, &c)
+ if (sscanf(line, "%s %d %lf %lf %lf %lf %lf %lf %lf %lf %lf", atomn, &p, &a1, &a2, &a3, &a4, &b1, &b2, &b3, &b4, &c)
== 11)
{
gsf->atomnm[i] = gmx_strdup(atomn);
{
rearrange_atoms(red[i], &fr, index[i], isize[i], &top, FALSE, gmx_sf);
- compute_structure_factor(static_cast<structure_factor_t*>(sf), box, red[i], isize[i],
- start_q, end_q, i, sf_table);
+ compute_structure_factor(
+ static_cast<structure_factor_t*>(sf), box, red[i], isize[i], start_q, end_q, i, sf_table);
}
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
double dEvib = hwkT * (0.5 + 1.0 / (std::expm1(hwkT)));
if (debug)
{
- fprintf(debug, "i %d eigval %g omega %g hwkT %g dEvib %g\n",
- static_cast<int>(i + 1), static_cast<double>(eigval[i]), omega, hwkT, dEvib);
+ fprintf(debug,
+ "i %d eigval %g omega %g hwkT %g dEvib %g\n",
+ static_cast<int>(i + 1),
+ static_cast<double>(eigval[i]),
+ omega,
+ hwkT,
+ dEvib);
}
Evib += dEvib;
}
double dcv = std::exp(hwkT) * gmx::square(hwkT / std::expm1(hwkT));
if (debug)
{
- fprintf(debug, "i %d eigval %g omega %g hwkT %g dcv %g\n",
- static_cast<int>(i + 1), static_cast<double>(eigval[i]), omega, hwkT, dcv);
+ fprintf(debug,
+ "i %d eigval %g omega %g hwkT %g dcv %g\n",
+ static_cast<int>(i + 1),
+ static_cast<double>(eigval[i]),
+ omega,
+ hwkT,
+ dcv);
}
cv += dcv;
}
S += dS;
if (debug)
{
- fprintf(debug, "i = %5d eigval = %10g w = %10g hwkT = %10g dS = %10g\n",
- static_cast<int>(i + 1), static_cast<double>(eigval[i]), omega, hwkT, dS);
+ fprintf(debug,
+ "i = %5d eigval = %10g w = %10g hwkT = %10g dS = %10g\n",
+ static_cast<int>(i + 1),
+ static_cast<double>(eigval[i]),
+ omega,
+ hwkT,
+ dS);
}
}
else if (debug)
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+add_library(gmxlib INTERFACE)
+
add_subdirectory(nonbonded)
# The nonbonded directory contains subdirectories that are only
set(GMXLIB_SOURCES ${GMXLIB_SOURCES} ${NONBONDED_SOURCES} PARENT_SCOPE)
+# Source files have the following private module dependencies.
+target_link_libraries(gmxlib PRIVATE
+ # gmxlib
+ # math
+ # mdtypes
+ # tng_io
+ )
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(gmxlib PUBLIC
+target_include_directories(gmxlib INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(gmxlib PUBLIC
+target_link_libraries(gmxlib INTERFACE
+ legacy_api
+ )
+
+# TODO: when fileio is an OBJECT target
+#target_link_libraries(gmxlib PUBLIC legacy_api)
+#target_link_libraries(gmxlib PRIVATE common)
+
+# Module dependencies
+# fileio interfaces convey transitive dependence on these modules.
+#target_link_libraries(gmxlib PUBLIC
+target_link_libraries(gmxlib INTERFACE
+ utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(gmxlib PRIVATE tng_io)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(gmxlib PRIVATE legacy_modules)
+
# if(BUILD_TESTING)
# add_subdirectory(tests)
# endif()
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
nc->bUse = TRUE;
if (fplog)
{
- fprintf(fplog, "Using two step summing over %d groups of on average %.1f ranks\n\n", ng,
+ fprintf(fplog,
+ "Using two step summing over %d groups of on average %.1f ranks\n\n",
+ ng,
(real)n / (real)ng);
}
if (nc->rank_intra > 0)
#if !GMX_MPI
GMX_RELEASE_ASSERT(false, "Invalid call to gmx_sumd");
#else
-# if MPI_IN_PLACE_EXISTS
if (cr->nc.bUse)
{
if (cr->nc.rank_intra == 0)
{
MPI_Allreduce(MPI_IN_PLACE, r, nr, MPI_DOUBLE, MPI_SUM, cr->mpi_comm_mygroup);
}
-# else
- int i;
-
- if (nr > cr->mpb->dbuf_alloc)
- {
- cr->mpb->dbuf_alloc = nr;
- srenew(cr->mpb->dbuf, cr->mpb->dbuf_alloc);
- }
- if (cr->nc.bUse)
- {
- /* Use two step summing */
- MPI_Allreduce(r, cr->mpb->dbuf, nr, MPI_DOUBLE, MPI_SUM, cr->nc.comm_intra);
- if (cr->nc.rank_intra == 0)
- {
- /* Sum with the buffers reversed */
- MPI_Allreduce(cr->mpb->dbuf, r, nr, MPI_DOUBLE, MPI_SUM, cr->nc.comm_inter);
- }
- MPI_Bcast(r, nr, MPI_DOUBLE, 0, cr->nc.comm_intra);
- }
- else
- {
- MPI_Allreduce(r, cr->mpb->dbuf, nr, MPI_DOUBLE, MPI_SUM, cr->mpi_comm_mygroup);
- for (i = 0; i < nr; i++)
- {
- r[i] = cr->mpb->dbuf[i];
- }
- }
-# endif
#endif
}
#if !GMX_MPI
GMX_RELEASE_ASSERT(false, "Invalid call to gmx_sumf");
#else
-# if MPI_IN_PLACE_EXISTS
if (cr->nc.bUse)
{
/* Use two step summing. */
{
MPI_Allreduce(MPI_IN_PLACE, r, nr, MPI_FLOAT, MPI_SUM, cr->mpi_comm_mygroup);
}
-# else
- int i;
-
- if (nr > cr->mpb->fbuf_alloc)
- {
- cr->mpb->fbuf_alloc = nr;
- srenew(cr->mpb->fbuf, cr->mpb->fbuf_alloc);
- }
- if (cr->nc.bUse)
- {
- /* Use two step summing */
- MPI_Allreduce(r, cr->mpb->fbuf, nr, MPI_FLOAT, MPI_SUM, cr->nc.comm_intra);
- if (cr->nc.rank_intra == 0)
- {
- /* Sum with the buffers reversed */
- MPI_Allreduce(cr->mpb->fbuf, r, nr, MPI_FLOAT, MPI_SUM, cr->nc.comm_inter);
- }
- MPI_Bcast(r, nr, MPI_FLOAT, 0, cr->nc.comm_intra);
- }
- else
- {
- MPI_Allreduce(r, cr->mpb->fbuf, nr, MPI_FLOAT, MPI_SUM, cr->mpi_comm_mygroup);
- for (i = 0; i < nr; i++)
- {
- r[i] = cr->mpb->fbuf[i];
- }
- }
-# endif
#endif
}
#if !GMX_MPI
GMX_RELEASE_ASSERT(false, "Invalid call to gmx_sumi");
#else
-# if MPI_IN_PLACE_EXISTS
if (cr->nc.bUse)
{
/* Use two step summing */
{
MPI_Allreduce(MPI_IN_PLACE, r, nr, MPI_INT, MPI_SUM, cr->mpi_comm_mygroup);
}
-# else
- int i;
-
- if (nr > cr->mpb->ibuf_alloc)
- {
- cr->mpb->ibuf_alloc = nr;
- srenew(cr->mpb->ibuf, cr->mpb->ibuf_alloc);
- }
- if (cr->nc.bUse)
- {
- /* Use two step summing */
- MPI_Allreduce(r, cr->mpb->ibuf, nr, MPI_INT, MPI_SUM, cr->nc.comm_intra);
- if (cr->nc.rank_intra == 0)
- {
- /* Sum with the buffers reversed */
- MPI_Allreduce(cr->mpb->ibuf, r, nr, MPI_INT, MPI_SUM, cr->nc.comm_inter);
- }
- MPI_Bcast(r, nr, MPI_INT, 0, cr->nc.comm_intra);
- }
- else
- {
- MPI_Allreduce(r, cr->mpb->ibuf, nr, MPI_INT, MPI_SUM, cr->mpi_comm_mygroup);
- for (i = 0; i < nr; i++)
- {
- r[i] = cr->mpb->ibuf[i];
- }
- }
-# endif
#endif
}
#if !GMX_MPI
GMX_RELEASE_ASSERT(false, "Invalid call to gmx_sumli");
#else
-# if MPI_IN_PLACE_EXISTS
if (cr->nc.bUse)
{
/* Use two step summing */
{
MPI_Allreduce(MPI_IN_PLACE, r, nr, MPI_INT64_T, MPI_SUM, cr->mpi_comm_mygroup);
}
-# else
- int i;
-
- if (nr > cr->mpb->libuf_alloc)
- {
- cr->mpb->libuf_alloc = nr;
- srenew(cr->mpb->libuf, cr->mpb->libuf_alloc);
- }
- if (cr->nc.bUse)
- {
- /* Use two step summing */
- MPI_Allreduce(r, cr->mpb->libuf, nr, MPI_INT64_T, MPI_SUM, cr->nc.comm_intra);
- if (cr->nc.rank_intra == 0)
- {
- /* Sum with the buffers reversed */
- MPI_Allreduce(cr->mpb->libuf, r, nr, MPI_INT64_T, MPI_SUM, cr->nc.comm_inter);
- }
- MPI_Bcast(r, nr, MPI_INT64_T, 0, cr->nc.comm_intra);
- }
- else
- {
- MPI_Allreduce(r, cr->mpb->libuf, nr, MPI_INT64_T, MPI_SUM, cr->mpi_comm_mygroup);
- for (i = 0; i < nr; i++)
- {
- r[i] = cr->mpb->libuf[i];
- }
- }
-# endif
#endif
}
}
template<class RealType>
-static inline RealType calculateRinv6(const RealType rinvV)
+static inline RealType calculateRinv6(const RealType rInvV)
{
- RealType rinv6 = rinvV * rinvV;
- return (rinv6 * rinv6 * rinv6);
+ RealType rInv6 = rInvV * rInvV;
+ return (rInv6 * rInv6 * rInv6);
}
template<class RealType>
-static inline RealType calculateVdw6(const RealType c6, const RealType rinv6)
+static inline RealType calculateVdw6(const RealType c6, const RealType rInv6)
{
- return (c6 * rinv6);
+ return (c6 * rInv6);
}
template<class RealType>
-static inline RealType calculateVdw12(const RealType c12, const RealType rinv6)
+static inline RealType calculateVdw12(const RealType c12, const RealType rInv6)
{
- return (c12 * rinv6 * rinv6);
+ return (c12 * rInv6 * rInv6);
}
/* reaction-field electrostatics */
template<class RealType>
static inline RealType reactionFieldScalarForce(const RealType qq,
- const RealType rinv,
+ const RealType rInv,
const RealType r,
const real krf,
const real two)
{
- return (qq * (rinv - two * krf * r * r));
+ return (qq * (rInv - two * krf * r * r));
}
template<class RealType>
static inline RealType reactionFieldPotential(const RealType qq,
- const RealType rinv,
+ const RealType rInv,
const RealType r,
const real krf,
const real potentialShift)
{
- return (qq * (rinv + krf * r * r - potentialShift));
+ return (qq * (rInv + krf * r * r - potentialShift));
}
/* Ewald electrostatics */
template<class RealType>
-static inline RealType ewaldScalarForce(const RealType coulomb, const RealType rinv)
+static inline RealType ewaldScalarForce(const RealType coulomb, const RealType rInv)
{
- return (coulomb * rinv);
+ return (coulomb * rInv);
}
template<class RealType>
-static inline RealType ewaldPotential(const RealType coulomb, const RealType rinv, const real potentialShift)
+static inline RealType ewaldPotential(const RealType coulomb, const RealType rInv, const real potentialShift)
{
- return (coulomb * (rinv - potentialShift));
+ return (coulomb * (rInv - potentialShift));
}
/* cutoff LJ */
const RealType c12,
const real repulsionShift,
const real dispersionShift,
- const real onesixth,
- const real onetwelfth)
+ const real oneSixth,
+ const real oneTwelfth)
{
- return ((v12 + c12 * repulsionShift) * onetwelfth - (v6 + c6 * dispersionShift) * onesixth);
+ return ((v12 + c12 * repulsionShift) * oneTwelfth - (v6 + c6 * dispersionShift) * oneSixth);
}
/* Ewald LJ */
-static inline real ewaldLennardJonesGridSubtract(const real c6grid, const real potentialShift, const real onesixth)
+static inline real ewaldLennardJonesGridSubtract(const real c6grid, const real potentialShift, const real oneSixth)
{
- return (c6grid * potentialShift * onesixth);
+ return (c6grid * potentialShift * oneSixth);
}
/* LJ Potential switch */
using IntType = typename DataTypes::IntType;
/* FIXME: How should these be handled with SIMD? */
- constexpr real onetwelfth = 1.0 / 12.0;
- constexpr real onesixth = 1.0 / 6.0;
+ constexpr real oneTwelfth = 1.0 / 12.0;
+ constexpr real oneSixth = 1.0 / 6.0;
constexpr real zero = 0.0;
constexpr real half = 0.5;
constexpr real one = 1.0;
// Extract data from interaction_const_t
const real facel = ic->epsfac;
- const real rcoulomb = ic->rcoulomb;
+ const real rCoulomb = ic->rcoulomb;
const real krf = ic->k_rf;
const real crf = ic->c_rf;
- const real sh_lj_ewald = ic->sh_lj_ewald;
- const real rvdw = ic->rvdw;
+ const real shLjEwald = ic->sh_lj_ewald;
+ const real rVdw = ic->rvdw;
const real dispersionShift = ic->dispersion_shift.cpot;
const real repulsionShift = ic->repulsion_shift.cpot;
GMX_RELEASE_ASSERT(!(vdwInteractionTypeIsEwald && vdwModifierIsPotSwitch),
"Can not apply soft-core to switched Ewald potentials");
- real dvdl_coul = 0;
- real dvdl_vdw = 0;
+ real dvdlCoul = 0;
+ real dvdlVdw = 0;
/* Lambda factor for state A, 1-lambda*/
real LFC[NSTATES], LFV[NSTATES];
DLF[STATE_A] = -1;
DLF[STATE_B] = 1;
- real lfac_coul[NSTATES], dlfac_coul[NSTATES], lfac_vdw[NSTATES], dlfac_vdw[NSTATES];
+ real lFacCoul[NSTATES], dlFacCoul[NSTATES], lFacVdw[NSTATES], dlFacVdw[NSTATES];
constexpr real sc_r_power = 6.0_real;
for (int i = 0; i < NSTATES; i++)
{
- lfac_coul[i] = (lam_power == 2 ? (1 - LFC[i]) * (1 - LFC[i]) : (1 - LFC[i]));
- dlfac_coul[i] = DLF[i] * lam_power / sc_r_power * (lam_power == 2 ? (1 - LFC[i]) : 1);
- lfac_vdw[i] = (lam_power == 2 ? (1 - LFV[i]) * (1 - LFV[i]) : (1 - LFV[i]));
- dlfac_vdw[i] = DLF[i] * lam_power / sc_r_power * (lam_power == 2 ? (1 - LFV[i]) : 1);
+ lFacCoul[i] = (lam_power == 2 ? (1 - LFC[i]) * (1 - LFC[i]) : (1 - LFC[i]));
+ dlFacCoul[i] = DLF[i] * lam_power / sc_r_power * (lam_power == 2 ? (1 - LFC[i]) : 1);
+ lFacVdw[i] = (lam_power == 2 ? (1 - LFV[i]) * (1 - LFV[i]) : (1 - LFV[i]));
+ dlFacVdw[i] = DLF[i] * lam_power / sc_r_power * (lam_power == 2 ? (1 - LFV[i]) : 1);
}
// TODO: We should get rid of using pointers to real
const real iqB = facel * chargeB[ii];
const int ntiA = 2 * ntype * typeA[ii];
const int ntiB = 2 * ntype * typeB[ii];
- real vctot = 0;
- real vvtot = 0;
- real fix = 0;
- real fiy = 0;
- real fiz = 0;
+ real vCTot = 0;
+ real vVTot = 0;
+ real fIX = 0;
+ real fIY = 0;
+ real fIZ = 0;
for (int k = nj0; k < nj1; k++)
{
int tj[NSTATES];
const int jnr = jjnr[k];
const int j3 = 3 * jnr;
- RealType c6[NSTATES], c12[NSTATES], qq[NSTATES], Vcoul[NSTATES], Vvdw[NSTATES];
- RealType r, rinv, rp, rpm2;
- RealType alpha_vdw_eff, alpha_coul_eff, sigma6[NSTATES];
- const RealType dx = ix - x[j3];
- const RealType dy = iy - x[j3 + 1];
- const RealType dz = iz - x[j3 + 2];
- const RealType rsq = dx * dx + dy * dy + dz * dz;
- RealType FscalC[NSTATES], FscalV[NSTATES];
+ RealType c6[NSTATES], c12[NSTATES], qq[NSTATES], vCoul[NSTATES], vVdw[NSTATES];
+ RealType r, rInv, rp, rpm2;
+ RealType alphaVdwEff, alphaCoulEff, sigma6[NSTATES];
+ const RealType dX = ix - x[j3];
+ const RealType dY = iy - x[j3 + 1];
+ const RealType dZ = iz - x[j3 + 2];
+ const RealType rSq = dX * dX + dY * dY + dZ * dZ;
+ RealType fScalC[NSTATES], fScalV[NSTATES];
/* Check if this pair on the exlusions list.*/
const bool bPairIncluded = nlist->excl_fep == nullptr || nlist->excl_fep[k];
- if (rsq >= rcutoff_max2 && bPairIncluded)
+ if (rSq >= rcutoff_max2 && bPairIncluded)
{
/* We save significant time by skipping all code below.
* Note that with soft-core interactions, the actual cut-off
}
npair_within_cutoff++;
- if (rsq > rlistSquared)
+ if (rSq > rlistSquared)
{
numExcludedPairsBeyondRlist++;
}
- if (rsq > 0)
+ if (rSq > 0)
{
/* Note that unlike in the nbnxn kernels, we do not need
- * to clamp the value of rsq before taking the invsqrt
+ * to clamp the value of rSq before taking the invsqrt
* to avoid NaN in the LJ calculation, since here we do
* not calculate LJ interactions when C6 and C12 are zero.
*/
- rinv = gmx::invsqrt(rsq);
- r = rsq * rinv;
+ rInv = gmx::invsqrt(rSq);
+ r = rSq * rInv;
}
else
{
* But note that the potential is in general non-zero,
* since the soft-cored r will be non-zero.
*/
- rinv = 0;
+ rInv = 0;
r = 0;
}
if (useSoftCore)
{
- rpm2 = rsq * rsq; /* r4 */
- rp = rpm2 * rsq; /* r6 */
+ rpm2 = rSq * rSq; /* r4 */
+ rp = rpm2 * rSq; /* r6 */
}
else
{
* with not using soft-core, so we use power of 0 which gives
* the simplest math and cheapest code.
*/
- rpm2 = rinv * rinv;
+ rpm2 = rInv * rInv;
rp = 1;
}
- RealType Fscal = 0;
+ RealType fScal = 0;
qq[STATE_A] = iqA * chargeA[jnr];
qq[STATE_B] = iqB * chargeB[jnr];
/* only use softcore if one of the states has a zero endstate - softcore is for avoiding infinities!*/
if ((c12[STATE_A] > 0) && (c12[STATE_B] > 0))
{
- alpha_vdw_eff = 0;
- alpha_coul_eff = 0;
+ alphaVdwEff = 0;
+ alphaCoulEff = 0;
}
else
{
- alpha_vdw_eff = alpha_vdw;
- alpha_coul_eff = alpha_coul;
+ alphaVdwEff = alpha_vdw;
+ alphaCoulEff = alpha_coul;
}
}
for (int i = 0; i < NSTATES; i++)
{
- FscalC[i] = 0;
- FscalV[i] = 0;
- Vcoul[i] = 0;
- Vvdw[i] = 0;
+ fScalC[i] = 0;
+ fScalV[i] = 0;
+ vCoul[i] = 0;
+ vVdw[i] = 0;
- RealType rinvC, rinvV, rC, rV, rpinvC, rpinvV;
+ RealType rInvC, rInvV, rC, rV, rPInvC, rPInvV;
/* Only spend time on A or B state if it is non-zero */
if ((qq[i] != 0) || (c6[i] != 0) || (c12[i] != 0))
/* this section has to be inside the loop because of the dependence on sigma6 */
if (useSoftCore)
{
- rpinvC = one / (alpha_coul_eff * lfac_coul[i] * sigma6[i] + rp);
- pthRoot(rpinvC, &rinvC, &rC);
+ rPInvC = one / (alphaCoulEff * lFacCoul[i] * sigma6[i] + rp);
+ pthRoot(rPInvC, &rInvC, &rC);
if (scLambdasOrAlphasDiffer)
{
- rpinvV = one / (alpha_vdw_eff * lfac_vdw[i] * sigma6[i] + rp);
- pthRoot(rpinvV, &rinvV, &rV);
+ rPInvV = one / (alphaVdwEff * lFacVdw[i] * sigma6[i] + rp);
+ pthRoot(rPInvV, &rInvV, &rV);
}
else
{
/* We can avoid one expensive pow and one / operation */
- rpinvV = rpinvC;
- rinvV = rinvC;
+ rPInvV = rPInvC;
+ rInvV = rInvC;
rV = rC;
}
}
else
{
- rpinvC = 1;
- rinvC = rinv;
+ rPInvC = 1;
+ rInvC = rInv;
rC = r;
- rpinvV = 1;
- rinvV = rinv;
+ rPInvV = 1;
+ rInvV = rInv;
rV = r;
}
* and if we either include all entries in the list (no cutoff
* used in the kernel), or if we are within the cutoff.
*/
- bool computeElecInteraction = (elecInteractionTypeIsEwald && r < rcoulomb)
- || (!elecInteractionTypeIsEwald && rC < rcoulomb);
+ bool computeElecInteraction = (elecInteractionTypeIsEwald && r < rCoulomb)
+ || (!elecInteractionTypeIsEwald && rC < rCoulomb);
if ((qq[i] != 0) && computeElecInteraction)
{
if (elecInteractionTypeIsEwald)
{
- Vcoul[i] = ewaldPotential(qq[i], rinvC, sh_ewald);
- FscalC[i] = ewaldScalarForce(qq[i], rinvC);
+ vCoul[i] = ewaldPotential(qq[i], rInvC, sh_ewald);
+ fScalC[i] = ewaldScalarForce(qq[i], rInvC);
}
else
{
- Vcoul[i] = reactionFieldPotential(qq[i], rinvC, rC, krf, crf);
- FscalC[i] = reactionFieldScalarForce(qq[i], rinvC, rC, krf, two);
+ vCoul[i] = reactionFieldPotential(qq[i], rInvC, rC, krf, crf);
+ fScalC[i] = reactionFieldScalarForce(qq[i], rInvC, rC, krf, two);
}
}
* include all entries in the list (no cutoff used
* in the kernel), or if we are within the cutoff.
*/
- bool computeVdwInteraction = (vdwInteractionTypeIsEwald && r < rvdw)
- || (!vdwInteractionTypeIsEwald && rV < rvdw);
+ bool computeVdwInteraction = (vdwInteractionTypeIsEwald && r < rVdw)
+ || (!vdwInteractionTypeIsEwald && rV < rVdw);
if ((c6[i] != 0 || c12[i] != 0) && computeVdwInteraction)
{
- RealType rinv6;
+ RealType rInv6;
if (useSoftCore)
{
- rinv6 = rpinvV;
+ rInv6 = rPInvV;
}
else
{
- rinv6 = calculateRinv6(rinvV);
+ rInv6 = calculateRinv6(rInvV);
}
- RealType Vvdw6 = calculateVdw6(c6[i], rinv6);
- RealType Vvdw12 = calculateVdw12(c12[i], rinv6);
+ RealType vVdw6 = calculateVdw6(c6[i], rInv6);
+ RealType vVdw12 = calculateVdw12(c12[i], rInv6);
- Vvdw[i] = lennardJonesPotential(Vvdw6, Vvdw12, c6[i], c12[i], repulsionShift,
- dispersionShift, onesixth, onetwelfth);
- FscalV[i] = lennardJonesScalarForce(Vvdw6, Vvdw12);
+ vVdw[i] = lennardJonesPotential(
+ vVdw6, vVdw12, c6[i], c12[i], repulsionShift, dispersionShift, oneSixth, oneTwelfth);
+ fScalV[i] = lennardJonesScalarForce(vVdw6, vVdw12);
if (vdwInteractionTypeIsEwald)
{
/* Subtract the grid potential at the cut-off */
- Vvdw[i] += ewaldLennardJonesGridSubtract(nbfp_grid[tj[i]],
- sh_lj_ewald, onesixth);
+ vVdw[i] += ewaldLennardJonesGridSubtract(
+ nbfp_grid[tj[i]], shLjEwald, oneSixth);
}
if (vdwModifierIsPotSwitch)
one + d2 * d * (vdw_swV3 + d * (vdw_swV4 + d * vdw_swV5));
const RealType dsw = d2 * (vdw_swF2 + d * (vdw_swF3 + d * vdw_swF4));
- FscalV[i] = potSwitchScalarForceMod(FscalV[i], Vvdw[i], sw, rV,
- rvdw, dsw, zero);
- Vvdw[i] = potSwitchPotentialMod(Vvdw[i], sw, rV, rvdw, zero);
+ fScalV[i] = potSwitchScalarForceMod(
+ fScalV[i], vVdw[i], sw, rV, rVdw, dsw, zero);
+ vVdw[i] = potSwitchPotentialMod(vVdw[i], sw, rV, rVdw, zero);
}
}
- /* FscalC (and FscalV) now contain: dV/drC * rC
+ /* fScalC (and fScalV) now contain: dV/drC * rC
* Now we multiply by rC^-p, so it will be: dV/drC * rC^1-p
* Further down we first multiply by r^p-2 and then by
* the vector r, which in total gives: dV/drC * (r/rC)^1-p
*/
- FscalC[i] *= rpinvC;
- FscalV[i] *= rpinvV;
+ fScalC[i] *= rPInvC;
+ fScalV[i] *= rPInvV;
}
} // end for (int i = 0; i < NSTATES; i++)
/* Assemble A and B states */
for (int i = 0; i < NSTATES; i++)
{
- vctot += LFC[i] * Vcoul[i];
- vvtot += LFV[i] * Vvdw[i];
+ vCTot += LFC[i] * vCoul[i];
+ vVTot += LFV[i] * vVdw[i];
- Fscal += LFC[i] * FscalC[i] * rpm2;
- Fscal += LFV[i] * FscalV[i] * rpm2;
+ fScal += LFC[i] * fScalC[i] * rpm2;
+ fScal += LFV[i] * fScalV[i] * rpm2;
if (useSoftCore)
{
- dvdl_coul += Vcoul[i] * DLF[i]
- + LFC[i] * alpha_coul_eff * dlfac_coul[i] * FscalC[i] * sigma6[i];
- dvdl_vdw += Vvdw[i] * DLF[i]
- + LFV[i] * alpha_vdw_eff * dlfac_vdw[i] * FscalV[i] * sigma6[i];
+ dvdlCoul += vCoul[i] * DLF[i]
+ + LFC[i] * alphaCoulEff * dlFacCoul[i] * fScalC[i] * sigma6[i];
+ dvdlVdw += vVdw[i] * DLF[i]
+ + LFV[i] * alphaVdwEff * dlFacVdw[i] * fScalV[i] * sigma6[i];
}
else
{
- dvdl_coul += Vcoul[i] * DLF[i];
- dvdl_vdw += Vvdw[i] * DLF[i];
+ dvdlCoul += vCoul[i] * DLF[i];
+ dvdlVdw += vVdw[i] * DLF[i];
}
}
} // end if (bPairIncluded)
* As there is no singularity, there is no need for soft-core.
*/
const real FF = -two * krf;
- RealType VV = krf * rsq - crf;
+ RealType VV = krf * rSq - crf;
if (ii == jnr)
{
for (int i = 0; i < NSTATES; i++)
{
- vctot += LFC[i] * qq[i] * VV;
- Fscal += LFC[i] * qq[i] * FF;
- dvdl_coul += DLF[i] * qq[i] * VV;
+ vCTot += LFC[i] * qq[i] * VV;
+ fScal += LFC[i] * qq[i] * FF;
+ dvdlCoul += DLF[i] * qq[i] * VV;
}
}
- if (elecInteractionTypeIsEwald && (r < rcoulomb || !bPairIncluded))
+ if (elecInteractionTypeIsEwald && (r < rCoulomb || !bPairIncluded))
{
/* See comment in the preamble. When using Ewald interactions
* (unless we use a switch modifier) we subtract the reciprocal-space
ewitab = 4 * ewitab;
f_lr = ewtab[ewitab] + eweps * ewtab[ewitab + 1];
v_lr = (ewtab[ewitab + 2] - coulombTableScaleInvHalf * eweps * (ewtab[ewitab] + f_lr));
- f_lr *= rinv;
+ f_lr *= rInv;
/* Note that any possible Ewald shift has already been applied in
* the normal interaction part above.
for (int i = 0; i < NSTATES; i++)
{
- vctot -= LFC[i] * qq[i] * v_lr;
- Fscal -= LFC[i] * qq[i] * f_lr;
- dvdl_coul -= (DLF[i] * qq[i]) * v_lr;
+ vCTot -= LFC[i] * qq[i] * v_lr;
+ fScal -= LFC[i] * qq[i] * f_lr;
+ dvdlCoul -= (DLF[i] * qq[i]) * v_lr;
}
}
- if (vdwInteractionTypeIsEwald && (r < rvdw || !bPairIncluded))
+ 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
* r close to 0 for non-interacting pairs.
*/
- const RealType rs = rsq * rinv * vdwTableScale;
+ const RealType rs = rSq * rInv * vdwTableScale;
const IntType ri = static_cast<IntType>(rs);
const RealType frac = rs - ri;
const RealType f_lr = (1 - frac) * tab_ewald_F_lj[ri] + frac * tab_ewald_F_lj[ri + 1];
/* TODO: Currently the Ewald LJ table does not contain
* the factor 1/6, we should add this.
*/
- const RealType FF = f_lr * rinv / six;
+ const RealType FF = f_lr * rInv / six;
RealType VV =
(tab_ewald_V_lj[ri] - vdwTableScaleInvHalf * frac * (tab_ewald_F_lj[ri] + f_lr))
/ six;
for (int i = 0; i < NSTATES; i++)
{
const real c6grid = nbfp_grid[tj[i]];
- vvtot += LFV[i] * c6grid * VV;
- Fscal += LFV[i] * c6grid * FF;
- dvdl_vdw += (DLF[i] * c6grid) * VV;
+ vVTot += LFV[i] * c6grid * VV;
+ fScal += LFV[i] * c6grid * FF;
+ dvdlVdw += (DLF[i] * c6grid) * VV;
}
}
if (doForces)
{
- const real tx = Fscal * dx;
- const real ty = Fscal * dy;
- const real tz = Fscal * dz;
- fix = fix + tx;
- fiy = fiy + ty;
- fiz = fiz + tz;
+ const real tX = fScal * dX;
+ const real tY = fScal * dY;
+ const real tZ = fScal * dZ;
+ fIX = fIX + tX;
+ fIY = fIY + tY;
+ fIZ = fIZ + tZ;
/* OpenMP atomics are expensive, but this kernels is also
* expensive, so we can take this hit, instead of using
* thread-local output buffers and extra reduction.
* not throw, so no need for try/catch.
*/
#pragma omp atomic
- f[j3] -= tx;
+ f[j3] -= tX;
#pragma omp atomic
- f[j3 + 1] -= ty;
+ f[j3 + 1] -= tY;
#pragma omp atomic
- f[j3 + 2] -= tz;
+ f[j3 + 2] -= tZ;
}
} // end for (int k = nj0; k < nj1; k++)
if (doForces)
{
#pragma omp atomic
- f[ii3] += fix;
+ f[ii3] += fIX;
#pragma omp atomic
- f[ii3 + 1] += fiy;
+ f[ii3 + 1] += fIY;
#pragma omp atomic
- f[ii3 + 2] += fiz;
+ f[ii3 + 2] += fIZ;
}
if (doShiftForces)
{
#pragma omp atomic
- fshift[is3] += fix;
+ fshift[is3] += fIX;
#pragma omp atomic
- fshift[is3 + 1] += fiy;
+ fshift[is3 + 1] += fIY;
#pragma omp atomic
- fshift[is3 + 2] += fiz;
+ fshift[is3 + 2] += fIZ;
}
if (doPotential)
{
int ggid = gid[n];
#pragma omp atomic
- Vc[ggid] += vctot;
+ Vc[ggid] += vCTot;
#pragma omp atomic
- Vv[ggid] += vvtot;
+ Vv[ggid] += vVTot;
}
}
} // end for (int n = 0; n < nri; n++)
#pragma omp atomic
- dvdl[efptCOUL] += dvdl_coul;
+ dvdl[efptCOUL] += dvdlCoul;
#pragma omp atomic
- dvdl[efptVDW] += dvdl_vdw;
+ dvdl[efptVDW] += dvdlVdw;
/* Estimate flops, average for free energy stuff:
* 12 flops per outer iteration
"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);
+ numExcludedPairsBeyondRlist,
+ fr->rlist);
}
}
{
#if GMX_SIMD_HAVE_REAL && GMX_SIMD_HAVE_INT32_ARITHMETICS && GMX_USE_SIMD_KERNELS
/* FIXME: Here SimdDataTypes should be used to enable SIMD. So far, the code in nb_free_energy_kernel is not adapted to SIMD */
- return (nb_free_energy_kernel<ScalarDataTypes, useSoftCore, scLambdasOrAlphasDiffer, vdwInteractionTypeIsEwald,
- elecInteractionTypeIsEwald, vdwModifierIsPotSwitch>);
+ return (nb_free_energy_kernel<ScalarDataTypes, useSoftCore, scLambdasOrAlphasDiffer, vdwInteractionTypeIsEwald, elecInteractionTypeIsEwald, vdwModifierIsPotSwitch>);
#else
- return (nb_free_energy_kernel<ScalarDataTypes, useSoftCore, scLambdasOrAlphasDiffer, vdwInteractionTypeIsEwald,
- elecInteractionTypeIsEwald, vdwModifierIsPotSwitch>);
+ return (nb_free_energy_kernel<ScalarDataTypes, useSoftCore, scLambdasOrAlphasDiffer, vdwInteractionTypeIsEwald, elecInteractionTypeIsEwald, vdwModifierIsPotSwitch>);
#endif
}
else
{
- return (nb_free_energy_kernel<ScalarDataTypes, useSoftCore, scLambdasOrAlphasDiffer, vdwInteractionTypeIsEwald,
- elecInteractionTypeIsEwald, vdwModifierIsPotSwitch>);
+ return (nb_free_energy_kernel<ScalarDataTypes, useSoftCore, scLambdasOrAlphasDiffer, vdwInteractionTypeIsEwald, elecInteractionTypeIsEwald, vdwModifierIsPotSwitch>);
}
}
{
if (vdwModifierIsPotSwitch)
{
- return (dispatchKernelOnUseSimd<useSoftCore, scLambdasOrAlphasDiffer, vdwInteractionTypeIsEwald,
- elecInteractionTypeIsEwald, true>(useSimd));
+ return (dispatchKernelOnUseSimd<useSoftCore, scLambdasOrAlphasDiffer, vdwInteractionTypeIsEwald, elecInteractionTypeIsEwald, true>(
+ useSimd));
}
else
{
- return (dispatchKernelOnUseSimd<useSoftCore, scLambdasOrAlphasDiffer, vdwInteractionTypeIsEwald,
- elecInteractionTypeIsEwald, false>(useSimd));
+ return (dispatchKernelOnUseSimd<useSoftCore, scLambdasOrAlphasDiffer, vdwInteractionTypeIsEwald, elecInteractionTypeIsEwald, false>(
+ useSimd));
}
}
{
if (ic.softCoreParameters->alphaCoulomb == 0 && ic.softCoreParameters->alphaVdw == 0)
{
- return (dispatchKernelOnScLambdasOrAlphasDifference<false>(
- scLambdasOrAlphasDiffer, vdwInteractionTypeIsEwald, elecInteractionTypeIsEwald,
- vdwModifierIsPotSwitch, useSimd));
+ return (dispatchKernelOnScLambdasOrAlphasDifference<false>(scLambdasOrAlphasDiffer,
+ vdwInteractionTypeIsEwald,
+ elecInteractionTypeIsEwald,
+ vdwModifierIsPotSwitch,
+ useSimd));
}
else
{
- return (dispatchKernelOnScLambdasOrAlphasDifference<true>(
- scLambdasOrAlphasDiffer, vdwInteractionTypeIsEwald, elecInteractionTypeIsEwald,
- vdwModifierIsPotSwitch, useSimd));
+ return (dispatchKernelOnScLambdasOrAlphasDifference<true>(scLambdasOrAlphasDiffer,
+ vdwInteractionTypeIsEwald,
+ elecInteractionTypeIsEwald,
+ vdwModifierIsPotSwitch,
+ useSimd));
}
}
}
KernelFunction kernelFunc;
- kernelFunc = dispatchKernel(scLambdasOrAlphasDiffer, vdwInteractionTypeIsEwald,
- elecInteractionTypeIsEwald, vdwModifierIsPotSwitch, useSimd, ic);
+ kernelFunc = dispatchKernel(scLambdasOrAlphasDiffer,
+ vdwInteractionTypeIsEwald,
+ elecInteractionTypeIsEwald,
+ vdwModifierIsPotSwitch,
+ useSimd,
+ ic);
kernelFunc(nlist, xx, ff, fr, mdatoms, kernel_data, nrnb);
}
{
nrnb->n[enr] += inc;
#ifdef DEBUG_NRNB
- printf("nrnb %15s(%2d) incremented with %8d from file %s line %d\n", nbdata[enr].name, enr, inc,
- file, line);
+ printf("nrnb %15s(%2d) incremented with %8d from file %s line %d\n", nbdata[enr].name, enr, inc, file, line);
#endif
}
if (time_per_node > 0)
{
fprintf(out, "%12s %12s %12s %10s\n", "", "Core t (s)", "Wall t (s)", "(%)");
- fprintf(out, "%12s %12.3f %12.3f %10.1f\n", "Time:", time_per_thread, time_per_node,
- 100.0 * time_per_thread / time_per_node);
+ fprintf(out, "%12s %12.3f %12.3f %10.1f\n", "Time:", time_per_thread, time_per_node, 100.0 * time_per_thread / time_per_node);
/* only print day-hour-sec format if time_per_node is more than 30 min */
if (time_per_node > 30 * 60)
{
if (getenv("GMX_DETAILED_PERF_STATS") == nullptr)
{
fprintf(out, "%12s %12s %12s\n", "", "(ns/day)", "(hour/ns)");
- fprintf(out, "%12s %12.3f %12.3f\n", "Performance:", wallclocktime * 24 * 3.6 / time_per_node,
+ fprintf(out,
+ "%12s %12.3f %12.3f\n",
+ "Performance:",
+ wallclocktime * 24 * 3.6 / time_per_node,
1000 * time_per_node / (3600 * wallclocktime));
}
else
{
- fprintf(out, "%12s %12s %12s %12s %12s\n", "", "(Mnbf/s)",
- (mflop > 1000) ? "(GFlops)" : "(MFlops)", "(ns/day)", "(hour/ns)");
- fprintf(out, "%12s %12.3f %12.3f %12.3f %12.3f\n", "Performance:", nbfs / time_per_node,
- (mflop > 1000) ? (mflop / 1000) : mflop, wallclocktime * 24 * 3.6 / time_per_node,
+ fprintf(out,
+ "%12s %12s %12s %12s %12s\n",
+ "",
+ "(Mnbf/s)",
+ (mflop > 1000) ? "(GFlops)" : "(MFlops)",
+ "(ns/day)",
+ "(hour/ns)");
+ fprintf(out,
+ "%12s %12.3f %12.3f %12.3f %12.3f\n",
+ "Performance:",
+ nbfs / time_per_node,
+ (mflop > 1000) ? (mflop / 1000) : mflop,
+ wallclocktime * 24 * 3.6 / time_per_node,
1000 * time_per_node / (3600 * wallclocktime));
}
}
}
else
{
- fprintf(out, "%12s %12s %12s %14s\n", "", "(Mnbf/s)",
- (mflop > 1000) ? "(GFlops)" : "(MFlops)", "(steps/hour)");
- fprintf(out, "%12s %12.3f %12.3f %14.1f\n", "Performance:", nbfs / time_per_node,
- (mflop > 1000) ? (mflop / 1000) : mflop, nsteps * 3600.0 / time_per_node);
+ fprintf(out,
+ "%12s %12s %12s %14s\n",
+ "",
+ "(Mnbf/s)",
+ (mflop > 1000) ? "(GFlops)" : "(MFlops)",
+ "(steps/hour)");
+ fprintf(out,
+ "%12s %12.3f %12.3f %14.1f\n",
+ "Performance:",
+ nbfs / time_per_node,
+ (mflop > 1000) ? (mflop / 1000) : mflop,
+ nsteps * 3600.0 / time_per_node);
}
}
}
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2011,2013,2014,2015, by the GROMACS development team, led by
+# Copyright (c) 2011,2013,2014,2015,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.
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+# Set up the module library
+add_library(gmxpreprocess INTERFACE)
+
file(GLOB GMXPREPROCESS_SOURCES *.cpp)
set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${GMXPREPROCESS_SOURCES} PARENT_SCOPE)
+# Source files have the following private module dependencies.
+target_link_libraries(gmxpreprocess PRIVATE
+ # gmxlib
+ # math
+ # mdtypes
+ # tng_io
+ )
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(gmxpreprocess PUBLIC
+target_include_directories(gmxpreprocess INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(gmxpreprocess PUBLIC
+target_link_libraries(gmxpreprocess INTERFACE
+ legacy_api
+ )
+
+# TODO: when is an OBJECT target
+#target_link_libraries(gmxpreprocess PUBLIC legacy_api)
+#target_link_libraries(gmxpreprocess PRIVATE common)
+
+# Module dependencies
+# This module convey transitive dependence on these modules.
+#target_link_libraries(gmxpreprocess PUBLIC
+target_link_libraries(gmxpreprocess INTERFACE
+ # utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(gmxpreprocess PRIVATE tng_io)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(gmxpreprocess PRIVATE legacy_modules)
+
if(BUILD_TESTING)
add_subdirectory(tests)
endif()
}
if (jmax == -1)
{
- gmx_fatal(FARGS, "Atom %s not found in rtp database in residue %s", searchname,
+ gmx_fatal(FARGS,
+ "Atom %s not found in rtp database in residue %s",
+ searchname,
localPpResidue.resname.c_str());
}
if (kmax != strlen(searchname))
gmx_fatal(FARGS,
"Atom %s not found in rtp database in residue %s, "
"it looks a bit like %s",
- searchname, localPpResidue.resname.c_str(), *(localPpResidue.atomname[jmax]));
+ searchname,
+ localPpResidue.resname.c_str(),
+ *(localPpResidue.atomname[jmax]));
}
return jmax;
}
if (r - i > 0.01 || r - i < -0.01)
{
- gmx_fatal(FARGS, "A non-integer value (%f) was supplied for '%s' in %s", r, name,
+ gmx_fatal(FARGS,
+ "A non-integer value (%f) was supplied for '%s' in %s",
+ r,
+ name,
interaction_function[ftype].longname);
}
if (i < limit)
{
- gmx_fatal(FARGS, "Value of '%s' in %s is %d, which is smaller than the minimum of %d", name,
- interaction_function[ftype].longname, i, limit);
+ gmx_fatal(FARGS,
+ "Value of '%s' in %s is %d, which is smaller than the minimum of %d",
+ name,
+ interaction_function[ftype].longname,
+ i,
+ limit);
}
return i;
gmx_fatal(FARGS,
"Invalid geometry for flat-bottomed position restraint.\n"
"Expected number between 1 and %d. Found %d\n",
- efbposresNR - 1, newparam->fbposres.geom);
+ efbposresNR - 1,
+ newparam->fbposres.geom);
}
newparam->fbposres.r = old[1];
newparam->fbposres.k = old[2];
ffp->reppow = reppow;
enter_function(&(nbtypes[F_LJ]), static_cast<t_functype>(F_LJ), comb, reppow, ffp, nullptr, TRUE, TRUE);
- enter_function(&(nbtypes[F_BHAM]), static_cast<t_functype>(F_BHAM), comb, reppow, ffp, nullptr,
- TRUE, TRUE);
+ enter_function(
+ &(nbtypes[F_BHAM]), static_cast<t_functype>(F_BHAM), comb, reppow, ffp, nullptr, TRUE, TRUE);
for (size_t mt = 0; mt < mtop->moltype.size(); mt++)
{
if ((i != F_LJ) && (i != F_BHAM)
&& ((flags & IF_BOND) || (flags & IF_VSITE) || (flags & IF_CONSTRAINT)))
{
- enter_function(&(interactions[i]), static_cast<t_functype>(i), comb, reppow, ffp,
- &molt->ilist[i], FALSE, (i == F_POSRES || i == F_FBPOSRES));
+ enter_function(&(interactions[i]),
+ static_cast<t_functype>(i),
+ comb,
+ reppow,
+ ffp,
+ &molt->ilist[i],
+ FALSE,
+ (i == F_POSRES || i == F_FBPOSRES));
}
}
}
}
else
{
- enter_function(&(interactions[i]), static_cast<t_functype>(i), comb, reppow,
- ffp, &(*mtop->intermolecular_ilist)[i], FALSE, FALSE);
+ enter_function(&(interactions[i]),
+ static_cast<t_functype>(i),
+ comb,
+ reppow,
+ ffp,
+ &(*mtop->intermolecular_ilist)[i],
+ FALSE,
+ FALSE);
mtop->bIntermolecularInteractions = TRUE;
}
{
if (bGetMass)
{
- aps->setAtomProperty(epropMass, std::string(*atoms->resinfo[atoms->atom[i].resind].name),
- std::string(*atoms->atomname[i]), &(atoms->atom[i].m));
+ aps->setAtomProperty(epropMass,
+ std::string(*atoms->resinfo[atoms->atom[i].resind].name),
+ std::string(*atoms->atomname[i]),
+ &(atoms->atom[i].m));
}
tmass += atoms->atom[i].m;
}
fprintf(stderr,
"Range of values for B-factors too large (min %g, max %g) "
"will scale down a factor 10\n",
- bfac_min, bfac_max);
+ bfac_min,
+ bfac_max);
for (i = 0; (i < n_bfac); i++)
{
bfac[i] /= 10;
fprintf(stderr,
"Range of values for B-factors too small (min %g, max %g) "
"will scale up a factor 10\n",
- bfac_min, bfac_max);
+ bfac_min,
+ bfac_max);
for (i = 0; (i < n_bfac); i++)
{
bfac[i] *= 10;
fprintf(stderr, "B-factors range from %g to %g\n", bfac_min, bfac_max);
for (i = 1; (i < 12); i++)
{
- fprintf(out, "%-6s%5d %-4.4s%3.3s %c%4d%c %8.3f%8.3f%8.3f%6.2f%6.2f\n", "ATOM ",
- natoms + 1 + i, "CA", "LEG", space, nres + 1, space, (xmin + (i * 0.12)) * 10,
- ymin * 10, zmin * 10, 1.0, bfac_min + ((i - 1.0) * (bfac_max - bfac_min) / 10));
+ fprintf(out,
+ "%-6s%5d %-4.4s%3.3s %c%4d%c %8.3f%8.3f%8.3f%6.2f%6.2f\n",
+ "ATOM ",
+ natoms + 1 + i,
+ "CA",
+ "LEG",
+ space,
+ nres + 1,
+ space,
+ (xmin + (i * 0.12)) * 10,
+ ymin * 10,
+ zmin * 10,
+ 1.0,
+ bfac_min + ((i - 1.0) * (bfac_max - bfac_min) / 10));
}
}
for (i = 0; i < nat; i++)
{
- gmx_fprintf_pdb_atomline(out, epdbATOM, a0 + i, "C", ' ', "BOX", 'K' + i / NCUCVERT,
- r0 + i, ' ', 10 * vert[i][XX], 10 * vert[i][YY],
- 10 * vert[i][ZZ], 1.0, 0.0, "");
+ gmx_fprintf_pdb_atomline(out,
+ epdbATOM,
+ a0 + i,
+ "C",
+ ' ',
+ "BOX",
+ 'K' + i / NCUCVERT,
+ r0 + i,
+ ' ',
+ 10 * vert[i][XX],
+ 10 * vert[i][YY],
+ 10 * vert[i][ZZ],
+ 1.0,
+ 0.0,
+ "");
}
edge = compact_unitcell_edges();
{
for (i = 0; i < NCUCEDGE; i++)
{
- fprintf(out, "CONECT%5d%5d\n", a0 + j * NCUCVERT + edge[2 * i],
+ fprintf(out,
+ "CONECT%5d%5d\n",
+ a0 + j * NCUCVERT + edge[2 * i],
a0 + j * NCUCVERT + edge[2 * i + 1]);
}
}
{
for (x = 0; x <= 1; x++)
{
- gmx_fprintf_pdb_atomline(out, epdbATOM, a0 + i, "C", ' ', "BOX", 'K' + i / 8,
- r0 + i, ' ', x * 10 * box[XX][XX], y * 10 * box[YY][YY],
- z * 10 * box[ZZ][ZZ], 1.0, 0.0, "");
+ gmx_fprintf_pdb_atomline(out,
+ epdbATOM,
+ a0 + i,
+ "C",
+ ' ',
+ "BOX",
+ 'K' + i / 8,
+ r0 + i,
+ ' ',
+ x * 10 * box[XX][XX],
+ y * 10 * box[YY][YY],
+ z * 10 * box[ZZ][ZZ],
+ 1.0,
+ 0.0,
+ "");
i++;
}
}
/* Determine rotation from cross product with target vector */
cprod(principal_axis, targetvec, rotvec);
unitv(rotvec, rotvec);
- printf("Aligning %g %g %g to %g %g %g : xprod %g %g %g\n", principal_axis[XX],
- principal_axis[YY], principal_axis[ZZ], targetvec[XX], targetvec[YY], targetvec[ZZ],
- rotvec[XX], rotvec[YY], rotvec[ZZ]);
+ printf("Aligning %g %g %g to %g %g %g : xprod %g %g %g\n",
+ principal_axis[XX],
+ principal_axis[YY],
+ principal_axis[ZZ],
+ targetvec[XX],
+ targetvec[YY],
+ targetvec[ZZ],
+ rotvec[XX],
+ rotvec[YY],
+ rotvec[ZZ]);
ux = rotvec[XX];
uy = rotvec[YY];
rotmatrix[2][1] = uy * uz * (1 - costheta) + ux * sintheta;
rotmatrix[2][2] = uz * uz + (1.0 - uz * uz) * costheta;
- printf("Rotation matrix: \n%g %g %g\n%g %g %g\n%g %g %g\n", rotmatrix[0][0], rotmatrix[0][1],
- rotmatrix[0][2], rotmatrix[1][0], rotmatrix[1][1], rotmatrix[1][2], rotmatrix[2][0],
- rotmatrix[2][1], rotmatrix[2][2]);
+ printf("Rotation matrix: \n%g %g %g\n%g %g %g\n%g %g %g\n",
+ rotmatrix[0][0],
+ rotmatrix[0][1],
+ rotmatrix[0][2],
+ rotmatrix[1][0],
+ rotmatrix[1][1],
+ rotmatrix[1][2],
+ rotmatrix[2][0],
+ rotmatrix[2][1],
+ rotmatrix[2][2]);
}
static void renum_resnr(t_atoms* atoms, int isize, const int* index, int resnr_start)
{ efDAT, "-bf", "bfact", ffOPTRD } };
#define NFILE asize(fnm)
- if (!parse_common_args(&argc, argv, PCA_CAN_VIEW, NFILE, fnm, NPA, pa, asize(desc), desc,
- asize(bugs), bugs, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_VIEW, NFILE, fnm, NPA, pa, asize(desc), desc, asize(bugs), bugs, &oenv))
{
return 0;
}
if (pbcType != PbcType::No)
{
real vol = det(box);
- printf("Volume: %g nm^3, corresponds to roughly %d electrons\n", vol,
+ printf("Volume: %g nm^3, corresponds to roughly %d electrons\n",
+ vol,
100 * (static_cast<int>(vol * 4.5)));
}
/* Determine the Van der Waals radius from the force field */
if (bReadVDW)
{
- if (!aps.setAtomProperty(epropVDW, *top->atoms.resinfo[top->atoms.atom[i].resind].name,
- *top->atoms.atomname[i], &vdw))
+ if (!aps.setAtomProperty(epropVDW,
+ *top->atoms.resinfo[top->atoms.atom[i].resind].name,
+ *top->atoms.atomname[i],
+ &vdw))
{
vdw = rvdw;
}
gmx_fatal(FARGS,
"Cannot scale density with "
"zero mass (%g) or volume (%g)\n",
- mass, vol);
+ mass,
+ vol);
}
scale[XX] = scale[YY] = scale[ZZ] = std::cbrt(dens / rho);
}
}
printf("Aligning %d atoms (out of %d) to %g %g %g, center of rotation %g %g %g\n",
- numAlignmentAtoms, natom, targetvec[XX], targetvec[YY], targetvec[ZZ],
- aligncenter[XX], aligncenter[YY], aligncenter[ZZ]);
+ numAlignmentAtoms,
+ natom,
+ targetvec[XX],
+ targetvec[YY],
+ targetvec[ZZ],
+ aligncenter[XX],
+ aligncenter[YY],
+ aligncenter[ZZ]);
/*subtract out pivot point*/
for (i = 0; i < numAlignmentAtoms; i++)
{
ssize = atoms.nr;
sindex = nullptr;
}
- printf("Translating %d atoms (out of %d) by %g %g %g nm\n", ssize, natom, translation[XX],
- translation[YY], translation[ZZ]);
+ printf("Translating %d atoms (out of %d) by %g %g %g nm\n",
+ ssize,
+ natom,
+ translation[XX],
+ translation[YY],
+ translation[ZZ]);
if (sindex)
{
for (i = 0; i < ssize; i++)
{
/* Rotate */
printf("Rotating %g, %g, %g degrees around the X, Y and Z axis respectively\n",
- rotangles[XX], rotangles[YY], rotangles[ZZ]);
+ rotangles[XX],
+ rotangles[YY],
+ rotangles[ZZ]);
for (i = 0; i < DIM; i++)
{
rotangles[i] *= DEG2RAD;
}
else
{
- write_sto_conf_indexed(outfile, name, &atoms, x, bHaveV ? v : nullptr, pbcType, box,
- isize, index);
+ write_sto_conf_indexed(
+ outfile, name, &atoms, x, bHaveV ? v : nullptr, pbcType, box, isize, index);
}
sfree(grpname);
sfree(index);
{
index[i] = i;
}
- write_pdbfile_indexed(out, name, &atoms, x, pbcType, box, ' ', -1, atoms.nr, index,
- conect, outftp == efPQR);
+ write_pdbfile_indexed(
+ out, name, &atoms, x, pbcType, box, ' ', -1, atoms.nr, index, conect, outftp == efPQR);
sfree(index);
if (bLegend)
{
}
if (visbox[0] > 0)
{
- visualize_box(out, bLegend ? atoms.nr + 12 : atoms.nr,
- bLegend ? atoms.nres = 12 : atoms.nres, box, visbox);
+ visualize_box(out,
+ bLegend ? atoms.nr + 12 : atoms.nr,
+ bLegend ? atoms.nres = 12 : atoms.nres,
+ box,
+ visbox);
}
gmx_ffclose(out);
}
std::string message = gmx::formatString(
"Could not find any files ending on '%s' "
"in the force field directory '%s'",
- file_end, ffdir);
+ file_end,
+ ffdir);
GMX_THROW(gmx::InvalidInputError(message));
}
for (std::string& filename : result)
std::string message = gmx::formatString(
"No force fields found (files with name '%s' "
"in subdirectories ending on '%s')",
- filename, dirend);
+ filename,
+ dirend);
GMX_THROW(gmx::InvalidInputError(message));
}
{
// AMBER force fields with type 9 dihedrals can reach here, where we sort on
// the contents of the string that names the macro for the parameters.
- return std::lexicographical_compare(
- d1.interactionTypeName().begin(), d1.interactionTypeName().end(),
- d2.interactionTypeName().begin(), d2.interactionTypeName().end());
+ return std::lexicographical_compare(d1.interactionTypeName().begin(),
+ d1.interactionTypeName().end(),
+ d2.interactionTypeName().begin(),
+ d2.interactionTypeName().end());
}
}
int minh = 2;
int next = dihedral->second + 1;
for (int l = dihedral->second;
- (l < next && is_dihedral_on_same_bond(dihedral->first, dih[l])); l++)
+ (l < next && is_dihedral_on_same_bond(dihedral->first, dih[l]));
+ l++)
{
int nh = n_hydro(dih[l].atoms(), atoms->atomname);
if (nh < minh)
std::vector<int> ai;
for (int k = 0; (k < 4) && !bStop; k++)
{
- const int entry = search_atom(bondeds.a[k].c_str(), start, atoms, "improper",
- bAllowMissing, cyclicBondsIndex);
+ const int entry = search_atom(
+ bondeds.a[k].c_str(), start, atoms, "improper", bAllowMissing, cyclicBondsIndex);
if (entry != -1)
{
if (!dih.empty())
{
fprintf(stderr, "Before cleaning: %zu dihedrals\n", dih.size());
- dih = clean_dih(dih, improper, atoms, rtpFFDB[0].bKeepAllGeneratedDihedrals,
- rtpFFDB[0].bRemoveDihedralIfWithImproper);
+ dih = clean_dih(dih, improper, atoms, rtpFFDB[0].bKeepAllGeneratedDihedrals, rtpFFDB[0].bRemoveDihedralIfWithImproper);
}
/* Now we have unique lists of angles and dihedrals
fprintf(debug,
"Velocities were taken from a Maxwell distribution\n"
"Initial generated temperature: %12.5e (scaled to: %12.5e)\n",
- temp, tempi);
+ temp,
+ tempi);
}
}
else if (numberOfSites == 4)
{
/* angle */
- vsitetoplist->back().angle.emplace_back(s1String, s2String, s3String,
- strtod(s4, nullptr));
+ vsitetoplist->back().angle.emplace_back(
+ s1String, s2String, s3String, strtod(s4, nullptr));
/* angle */
}
else
{
gmx_fatal(FARGS,
"Need 3 or 4 values to specify bond/angle values in %s: %s\n",
- ddbname, pline);
+ ddbname,
+ pline);
}
}
break;
default:
gmx_fatal(FARGS,
- "Didnt find a case for directive %s in read_vsite_database\n", dirstr);
+ "Didnt find a case for directive %s in read_vsite_database\n",
+ dirstr);
}
}
}
});
if (foundBond == found->bond.end())
{
- gmx_fatal(FARGS, "Couldnt find bond %s-%s for residue %s in vsite database.\n",
- atom1.c_str(), atom2.c_str(), res.c_str());
+ gmx_fatal(FARGS,
+ "Couldnt find bond %s-%s for residue %s in vsite database.\n",
+ atom1.c_str(),
+ atom2.c_str(),
+ res.c_str());
}
return foundBond->value;
if (foundAngle == found->angle.end())
{
- gmx_fatal(FARGS, "Couldnt find angle %s-%s-%s for residue %s in vsite database.\n",
- atom1.c_str(), atom2.c_str(), atom3.c_str(), res.c_str());
+ gmx_fatal(FARGS,
+ "Couldnt find angle %s-%s-%s for residue %s in vsite database.\n",
+ atom1.c_str(),
+ atom2.c_str(),
+ atom3.c_str(),
+ res.c_str());
}
return foundAngle->value;
/* find heavy atom bound to this hydrogen */
heavy = NOTSET;
for (auto parm = psb->interactionTypes.begin();
- (parm != psb->interactionTypes.end()) && (heavy == NOTSET); parm++)
+ (parm != psb->interactionTypes.end()) && (heavy == NOTSET);
+ parm++)
{
if (parm->ai() == atom)
{
gmx_fatal(FARGS,
"cannot make constraint in add_vsites for %d heavy "
"atoms and %d hydrogen atoms",
- nrheavies, nrHatoms);
+ nrheavies,
+ nrHatoms);
}
my_add_param(&(plist[F_CONSTRNC]), Hatoms[i], heavies[0], NOTSET);
}
case F_VSITE3OUT:
if (nrheavies < 2)
{
- gmx_fatal(FARGS, "Not enough heavy atoms (%d) for %s (min 3)",
- nrheavies + 1, interaction_function[vsite_type[Hatoms[i]]].name);
+ gmx_fatal(FARGS,
+ "Not enough heavy atoms (%d) for %s (min 3)",
+ nrheavies + 1,
+ interaction_function[vsite_type[Hatoms[i]]].name);
}
add_vsite3_atoms(&plist[ftype], Hatoms[i], Heavy, heavies[0], heavies[1], bSwapParity);
break;
case F_VSITE4FDN:
if (nrheavies < 3)
{
- gmx_fatal(FARGS, "Not enough heavy atoms (%d) for %s (min 4)",
- nrheavies + 1, interaction_function[vsite_type[Hatoms[i]]].name);
+ gmx_fatal(FARGS,
+ "Not enough heavy atoms (%d) for %s (min 4)",
+ nrheavies + 1,
+ interaction_function[vsite_type[Hatoms[i]]].name);
}
add_vsite4_atoms(&plist[ftype], Hatoms[0], Heavy, heavies[0], heavies[1], heavies[2]);
break;
default:
- gmx_fatal(FARGS, "can't use add_vsites for interaction function %s",
+ gmx_fatal(FARGS,
+ "can't use add_vsites for interaction function %s",
interaction_function[vsite_type[Hatoms[i]]].name);
} /* switch ftype */
} /* else */
*/
rvec_sub(x[ats[atCB]], x[ats[atCG]], r_ij);
rvec_sub(x[ats[atCD2]], x[ats[atCG]], r_ik);
- calc_vsite3_param(xcom[0], ycom[0], xi[atCG], yi[atCG], xi[atCB], yi[atCB], xi[atCD2],
- yi[atCD2], &a, &b);
+ calc_vsite3_param(
+ xcom[0], ycom[0], xi[atCG], yi[atCG], xi[atCB], yi[atCB], xi[atCD2], yi[atCD2], &a, &b);
svmul(a, r_ij, t1);
svmul(b, r_ik, t2);
rvec_add(t1, t2, t1);
rvec_add(t1, x[ats[atCG]], (*newx)[atM[0]]);
- calc_vsite3_param(xcom[1], ycom[1], xi[atCG], yi[atCG], xi[atCB], yi[atCB], xi[atCD2],
- yi[atCD2], &a, &b);
+ calc_vsite3_param(
+ xcom[1], ycom[1], xi[atCG], yi[atCG], xi[atCB], yi[atCB], xi[atCD2], yi[atCD2], &a, &b);
svmul(a, r_ij, t1);
svmul(b, r_ik, t2);
rvec_add(t1, t2, t1);
{
if ((*vsite_type)[ats[i]] == F_VSITE3)
{
- calc_vsite3_param(xi[i], yi[i], xcom[0], ycom[0], xcom[1], ycom[1], xi[atCB], yi[atCB],
- &a, &b);
- add_vsite3_param(&plist[F_VSITE3], ats[i], add_shift + atM[0], add_shift + atM[1],
- ats[atCB], a, b);
+ calc_vsite3_param(
+ xi[i], yi[i], xcom[0], ycom[0], xcom[1], ycom[1], xi[atCB], yi[atCB], &a, &b);
+ add_vsite3_param(
+ &plist[F_VSITE3], ats[i], add_shift + atM[0], add_shift + atM[1], ats[atCB], a, b);
}
}
return nvsite;
/* HE1 */
if (ats[atHE1] != NOTSET)
{
- calc_vsite3_param(x[atHE1], y[atHE1], x[atCE1], y[atCE1], x[atNE2], y[atNE2], x[atCG],
- y[atCG], &a, &b);
+ calc_vsite3_param(
+ x[atHE1], y[atHE1], x[atCE1], y[atCE1], x[atNE2], y[atNE2], x[atCG], y[atCG], &a, &b);
add_vsite3_param(&plist[F_VSITE3], ats[atHE1], ats[atCE1], ats[atNE2], ats[atCG], a, b);
}
/* HE2 */
if (ats[atHE2] != NOTSET)
{
- calc_vsite3_param(x[atHE2], y[atHE2], x[atNE2], y[atNE2], x[atCE1], y[atCE1], x[atCG],
- y[atCG], &a, &b);
+ calc_vsite3_param(
+ x[atHE2], y[atHE2], x[atNE2], y[atNE2], x[atCE1], y[atCE1], x[atCG], y[atCG], &a, &b);
add_vsite3_param(&plist[F_VSITE3], ats[atHE2], ats[atNE2], ats[atCE1], ats[atCG], a, b);
}
/* ND1 */
- calc_vsite3_param(x[atND1], y[atND1], x[atNE2], y[atNE2], x[atCE1], y[atCE1], x[atCG], y[atCG],
- &a, &b);
+ calc_vsite3_param(
+ x[atND1], y[atND1], x[atNE2], y[atNE2], x[atCE1], y[atCE1], x[atCG], y[atCG], &a, &b);
add_vsite3_param(&plist[F_VSITE3], ats[atND1], ats[atNE2], ats[atCE1], ats[atCG], a, b);
/* CD2 */
- calc_vsite3_param(x[atCD2], y[atCD2], x[atCE1], y[atCE1], x[atNE2], y[atNE2], x[atCG], y[atCG],
- &a, &b);
+ calc_vsite3_param(
+ x[atCD2], y[atCD2], x[atCE1], y[atCE1], x[atNE2], y[atNE2], x[atCG], y[atCG], &a, &b);
add_vsite3_param(&plist[F_VSITE3], ats[atCD2], ats[atCE1], ats[atNE2], ats[atCG], a, b);
/* HD1 */
if (ats[atHD1] != NOTSET)
{
- calc_vsite3_param(x[atHD1], y[atHD1], x[atNE2], y[atNE2], x[atCE1], y[atCE1], x[atCG],
- y[atCG], &a, &b);
+ calc_vsite3_param(
+ x[atHD1], y[atHD1], x[atNE2], y[atNE2], x[atCE1], y[atCE1], x[atCG], y[atCG], &a, &b);
add_vsite3_param(&plist[F_VSITE3], ats[atHD1], ats[atNE2], ats[atCE1], ats[atCG], a, b);
}
/* HD2 */
if (ats[atHD2] != NOTSET)
{
- calc_vsite3_param(x[atHD2], y[atHD2], x[atCE1], y[atCE1], x[atNE2], y[atNE2], x[atCG],
- y[atCG], &a, &b);
+ calc_vsite3_param(
+ x[atHD2], y[atHD2], x[atCE1], y[atCE1], x[atNE2], y[atNE2], x[atCG], y[atCG], &a, &b);
add_vsite3_param(&plist[F_VSITE3], ats[atHD2], ats[atCE1], ats[atNE2], ats[atCG], a, b);
}
return nvsite;
/* the atnms for every residue MUST correspond to the enums in the
gen_vsites_* (one for each residue) routines! */
/* also the atom names in atnms MUST be in the same order as in the .rtp! */
- const char* atnms[resNR][MAXATOMSPERRESIDUE + 1] = {
- { "CG", /* PHE */
- "CD1", "HD1", "CD2", "HD2", "CE1", "HE1", "CE2", "HE2", "CZ", "HZ", nullptr },
- { "CB", /* TRP */
- "CG", "CD1", "HD1", "CD2", "NE1", "HE1", "CE2", "CE3", "HE3", "CZ2", "HZ2", "CZ3", "HZ3",
- "CH2", "HH2", nullptr },
- { "CG", /* TYR */
- "CD1", "HD1", "CD2", "HD2", "CE1", "HE1", "CE2", "HE2", "CZ", "OH", "HH", nullptr },
- { "CG", /* HIS */
- "ND1", "HD1", "CD2", "HD2", "CE1", "HE1", "NE2", "HE2", nullptr }
- };
+ const char* atnms[resNR][MAXATOMSPERRESIDUE + 1] = { { "CG", /* PHE */
+ "CD1",
+ "HD1",
+ "CD2",
+ "HD2",
+ "CE1",
+ "HE1",
+ "CE2",
+ "HE2",
+ "CZ",
+ "HZ",
+ nullptr },
+ { "CB", /* TRP */
+ "CG",
+ "CD1",
+ "HD1",
+ "CD2",
+ "NE1",
+ "HE1",
+ "CE2",
+ "CE3",
+ "HE3",
+ "CZ2",
+ "HZ2",
+ "CZ3",
+ "HZ3",
+ "CH2",
+ "HH2",
+ nullptr },
+ { "CG", /* TYR */
+ "CD1",
+ "HD1",
+ "CD2",
+ "HD2",
+ "CE1",
+ "HE1",
+ "CE2",
+ "HE2",
+ "CZ",
+ "OH",
+ "HH",
+ nullptr },
+ { "CG", /* HIS */
+ "ND1",
+ "HD1",
+ "CD2",
+ "HD2",
+ "CE1",
+ "HE1",
+ "NE2",
+ "HE2",
+ nullptr } };
if (debug)
{
"not enough atoms found (%d, need %d) in "
"residue %s %d while\n "
"generating aromatics virtual site construction",
- nrfound, needed, resnm, at->resinfo[resind].nr);
+ nrfound,
+ needed,
+ resnm,
+ at->resinfo[resind].nr);
}
/* Advance overall atom counter */
i++;
{
fprintf(stderr, "TRP at %d\n", o2n[ats[0]] + 1);
}
- nvsite += gen_vsites_trp(atype, &newx, &newatom, &newatomname, &o2n,
- &newvsite_type, &newcgnr, symtab, &nadd, *x, cgnr, at,
- vsite_type, plist, nrfound, ats, add_shift, vsitetop);
+ nvsite += gen_vsites_trp(atype,
+ &newx,
+ &newatom,
+ &newatomname,
+ &o2n,
+ &newvsite_type,
+ &newcgnr,
+ symtab,
+ &nadd,
+ *x,
+ cgnr,
+ at,
+ vsite_type,
+ plist,
+ nrfound,
+ ats,
+ add_shift,
+ vsitetop);
break;
case resTYR:
if (debug)
{
fprintf(stderr, "TYR at %d\n", o2n[ats[0]] + 1);
}
- nvsite += gen_vsites_tyr(atype, &newx, &newatom, &newatomname, &o2n,
- &newvsite_type, &newcgnr, symtab, &nadd, *x, cgnr, at,
- vsite_type, plist, nrfound, ats, add_shift, vsitetop);
+ nvsite += gen_vsites_tyr(atype,
+ &newx,
+ &newatom,
+ &newatomname,
+ &o2n,
+ &newvsite_type,
+ &newcgnr,
+ symtab,
+ &nadd,
+ *x,
+ cgnr,
+ at,
+ vsite_type,
+ plist,
+ nrfound,
+ ats,
+ add_shift,
+ vsitetop);
break;
case resHIS:
if (debug)
{
/* find heavy atom, count #bonds from it and #H atoms bound to it
and return H atom numbers (Hatoms) and heavy atom numbers (heavies) */
- count_bonds(i, &plist[F_BONDS], at->atomname, &nrbonds, &nrHatoms, Hatoms, &Heavy,
- &nrheavies, heavies);
+ count_bonds(i, &plist[F_BONDS], at->atomname, &nrbonds, &nrHatoms, Hatoms, &Heavy, &nrheavies, heavies);
/* get Heavy atom type */
tpHeavy = get_atype(Heavy, at, rtpFFDB, &rt);
strcpy(tpname, atype->atomNameFromAtomType(tpHeavy));
FARGS,
"Can't find dummy mass for type %s bonded to type %s in the "
"virtual site database (.vsd files). Add it to the database!\n",
- tpname, nexttpname);
+ tpname,
+ nexttpname);
}
else
{
gmx_fatal(FARGS,
"A dummy mass for type %s bonded to type %s is required, but "
"no virtual site database (.vsd) files where found.\n",
- tpname, nexttpname);
+ tpname,
+ nexttpname);
}
}
else
/* generate Heavy, H1, H2 and H3 from M1, M2 and heavies[0] */
/* note that vsite_type cannot be NOTSET, because we just set it */
- add_vsite3_atoms(&plist[(*vsite_type)[Heavy]], Heavy, heavies[0],
- add_shift + ni0, add_shift + ni0 + 1, FALSE);
+ add_vsite3_atoms(&plist[(*vsite_type)[Heavy]],
+ Heavy,
+ heavies[0],
+ add_shift + ni0,
+ add_shift + ni0 + 1,
+ FALSE);
for (int j = 0; j < nrHatoms; j++)
{
- add_vsite3_atoms(&plist[(*vsite_type)[Hatoms[j]]], Hatoms[j], heavies[0],
- add_shift + ni0, add_shift + ni0 + 1, Hat_SwapParity[j]);
+ add_vsite3_atoms(&plist[(*vsite_type)[Hatoms[j]]],
+ Hatoms[j],
+ heavies[0],
+ add_shift + ni0,
+ add_shift + ni0 + 1,
+ Hat_SwapParity[j]);
}
#undef NMASS
}
"Cannot convert atom %d %s (bound to a heavy atom "
"%s with \n"
" %d bonds and %d bound hydrogens atoms) to virtual site\n",
- i + 1, *(at->atomname[i]), tpname, nrbonds, nrHatoms);
+ i + 1,
+ *(at->atomname[i]),
+ tpname,
+ nrbonds,
+ nrHatoms);
}
if (bAddVsiteParam)
{
fprintf(debug, "Before inserting new atoms:\n");
for (int i = 0; i < at->nr; i++)
{
- fprintf(debug, "%4d %4d %4s %4d %4s %6d %-10s\n", i + 1, o2n[i] + 1,
- at->atomname[i] ? *(at->atomname[i]) : "(NULL)", at->resinfo[at->atom[i].resind].nr,
+ fprintf(debug,
+ "%4d %4d %4s %4d %4s %6d %-10s\n",
+ i + 1,
+ o2n[i] + 1,
+ at->atomname[i] ? *(at->atomname[i]) : "(NULL)",
+ at->resinfo[at->atom[i].resind].nr,
at->resinfo[at->atom[i].resind].name ? *(at->resinfo[at->atom[i].resind].name) : "(NULL)",
(*cgnr)[i],
((*vsite_type)[i] == NOTSET) ? "NOTSET" : interaction_function[(*vsite_type)[i]].name);
{
if (newatomname[i])
{
- fprintf(debug, "%4d %4s %4d %6d %-10s\n", i + 1,
- newatomname[i] ? *(newatomname[i]) : "(NULL)", newatom[i].resind, newcgnr[i],
+ fprintf(debug,
+ "%4d %4s %4d %6d %-10s\n",
+ i + 1,
+ newatomname[i] ? *(newatomname[i]) : "(NULL)",
+ newatom[i].resind,
+ newcgnr[i],
(newvsite_type[i] == NOTSET) ? "NOTSET"
: interaction_function[newvsite_type[i]].name);
}
gmx_fatal(FARGS,
"Added impossible amount of dummy masses "
"(%d on a total of %d atoms)\n",
- nadd, at->nr - nadd);
+ nadd,
+ at->nr - nadd);
}
if (debug)
fprintf(debug, "After inserting new atoms:\n");
for (int i = 0; i < at->nr; i++)
{
- fprintf(debug, "%4d %4s %4d %4s %6d %-10s\n", i + 1,
- at->atomname[i] ? *(at->atomname[i]) : "(NULL)", at->resinfo[at->atom[i].resind].nr,
+ fprintf(debug,
+ "%4d %4s %4d %4s %6d %-10s\n",
+ i + 1,
+ at->atomname[i] ? *(at->atomname[i]) : "(NULL)",
+ at->resinfo[at->atom[i].resind].nr,
at->resinfo[at->atom[i].resind].name ? *(at->resinfo[at->atom[i].resind].name) : "(NULL)",
(*cgnr)[i],
((*vsite_type)[i] == NOTSET) ? "NOTSET" : interaction_function[(*vsite_type)[i]].name);
/* find bonded heavy atom */
int a = NOTSET;
for (auto parm = psb->interactionTypes.begin();
- (parm != psb->interactionTypes.end()) && (a == NOTSET); parm++)
+ (parm != psb->interactionTypes.end()) && (a == NOTSET);
+ parm++)
{
/* if other atom is not a virtual site, it is the one we want */
if ((parm->ai() == i) && !is_vsite(vsite_type[parm->aj()]))
{ "-renumber", FALSE, etBOOL, { &bRenum }, "Renumber residues" }
};
- if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa, asize(desc), desc,
- asize(bugs), bugs, &oenv))
+ if (!parse_common_args(
+ &argc, argv, 0, NFILE, fnm, asize(pa), pa, asize(desc), desc, asize(bugs), bugs, &oenv))
{
return 0;
}
{
fprintf(debug,
"Hack '%s' %d, replacing nname '%s' with '%s' (old name '%s')\n",
- localAtomName.c_str(), pos, patch->nname.c_str(),
+ localAtomName.c_str(),
+ pos,
+ patch->nname.c_str(),
singlePatch.nname.c_str(),
patch->oname.empty() ? "" : patch->oname.c_str());
}
for (int k = 0; k < singlePatch.nr; k++)
{
expand_hackblocks_one(
- newPatch, globalPatches->at(globalPatches->size() - singlePatch.nr + k).nname,
- globalPatches, bN, bC);
+ newPatch,
+ globalPatches->at(globalPatches->size() - singlePatch.nr + k).nname,
+ globalPatches,
+ bN,
+ bC);
}
}
}
bool bFoundAll = true;
for (int m = 0; (m < patch->nctl && bFoundAll); m++)
{
- int ia = pdbasearch_atom(patch->a[m].c_str(), rnr, pdba, bCheckMissing ? "atom" : "check",
- !bCheckMissing, cyclicBondsIndex);
+ int ia = pdbasearch_atom(patch->a[m].c_str(),
+ rnr,
+ pdba,
+ bCheckMissing ? "atom" : "check",
+ !bCheckMissing,
+ cyclicBondsIndex);
if (ia < 0)
{
/* not found in original atoms, might still be in
"Atom %s not found in residue %s %d"
", rtp entry %s"
" while adding hydrogens",
- patch->a[m].c_str(), *pdba->resinfo[rnr].name,
- pdba->resinfo[rnr].nr, *pdba->resinfo[rnr].rtp);
+ patch->a[m].c_str(),
+ *pdba->resinfo[rnr].name,
+ pdba->resinfo[rnr].nr,
+ *pdba->resinfo[rnr].rtp);
}
}
}
{
if (gmx_debug_at)
{
- fprintf(debug, "Replacing %d '%s' with (old name '%s') %s\n", newi,
+ fprintf(debug,
+ "Replacing %d '%s' with (old name '%s') %s\n",
+ newi,
((*modifiedAtoms)->atomname[newi] && *(*modifiedAtoms)->atomname[newi])
? *(*modifiedAtoms)->atomname[newi]
: "",
}
if (debug)
{
- fprintf(debug, " %s %g %g", *(*modifiedAtoms)->atomname[newi],
- (*modifiedAtoms)->atom[newi].m, (*modifiedAtoms)->atom[newi].q);
+ fprintf(debug,
+ " %s %g %g",
+ *(*modifiedAtoms)->atomname[newi],
+ (*modifiedAtoms)->atom[newi].m,
+ (*modifiedAtoms)->atom[newi].q);
}
}
}
do
{
nold = nnew;
- nnew = add_h_low(initialAtoms, localAtoms, xptr, globalPatches, symtab, nterpairs, ntdb,
- ctdb, rN, rC, FALSE, cyclicBondsIndex);
+ nnew = add_h_low(
+ initialAtoms, localAtoms, xptr, globalPatches, symtab, nterpairs, ntdb, ctdb, rN, rC, FALSE, cyclicBondsIndex);
niter++;
if (niter > 100)
{
if (!bAllowMissing)
{
/* Call add_h_low once more, now only for the missing atoms check */
- add_h_low(initialAtoms, localAtoms, xptr, globalPatches, symtab, nterpairs, ntdb, ctdb, rN,
- rC, TRUE, cyclicBondsIndex);
+ add_h_low(initialAtoms, localAtoms, xptr, globalPatches, symtab, nterpairs, ntdb, ctdb, rN, rC, TRUE, cyclicBondsIndex);
}
return nnew;
gmx_fatal(FARGS, "No more replaceable solvent!");
}
- fprintf(stderr, "Replacing solvent molecule %d (atom %d) with %s\n",
- solventMoleculesForReplacement->back(), solventMoleculeAtomsToBeReplaced[0], ionname);
+ fprintf(stderr,
+ "Replacing solvent molecule %d (atom %d) with %s\n",
+ solventMoleculesForReplacement->back(),
+ solventMoleculeAtomsToBeReplaced[0],
+ ionname);
/* Replace solvent molecule charges with ion charge */
notSolventGroup->push_back(solventMoleculeAtomsToBeReplaced[0]);
// charge while the rest of the solvent molecule atoms is set to 0 charge.
atoms->atom[solventMoleculeAtomsToBeReplaced.front()].q = q;
for (auto replacedMoleculeAtom = solventMoleculeAtomsToBeReplaced.begin() + 1;
- replacedMoleculeAtom != solventMoleculeAtomsToBeReplaced.end(); ++replacedMoleculeAtom)
+ replacedMoleculeAtom != solventMoleculeAtomsToBeReplaced.end();
+ ++replacedMoleculeAtom)
{
atoms->atom[*replacedMoleculeAtom].q = 0;
}
gmx_ffclose(fpout);
gmx_fatal(FARGS,
"No line with moleculetype '%s' found the [ molecules ] section of file '%s'",
- grpname, topinout);
+ grpname,
+ topinout);
}
if (nsol_last < p_num + n_num)
{
gmx_fatal(FARGS,
"The last entry for moleculetype '%s' in the [ molecules ] section of file '%s' "
"has less solvent molecules (%d) than were replaced (%d)",
- grpname, topinout, nsol_last, p_num + n_num);
+ grpname,
+ topinout,
+ nsol_last,
+ p_num + n_num);
}
/* Print all the molecule entries */
{
printf("Replacing %d solute molecules in topology file (%s) "
" by %d %s and %d %s ions.\n",
- p_num + n_num, topinout, p_num, p_name, n_num, n_name);
+ p_num + n_num,
+ topinout,
+ p_num,
+ p_name,
+ n_num,
+ n_name);
nsol_last -= p_num + n_num;
if (nsol_last > 0)
{
if (numIndicesToAdd > 0)
{
invertedGroup.resize(invertedGroup.size() + numIndicesToAdd);
- std::iota(std::end(invertedGroup) - numIndicesToAdd, std::end(invertedGroup),
- firstToAddToInvertedGroup);
+ std::iota(std::end(invertedGroup) - numIndicesToAdd, std::end(invertedGroup), firstToAddToInvertedGroup);
}
}
{ efTOP, "-p", "topol", ffOPTRW } };
#define NFILE asize(fnm)
- if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa, asize(desc), desc,
- asize(bugs), bugs, &oenv))
+ if (!parse_common_args(
+ &argc, argv, 0, NFILE, fnm, asize(pa), pa, asize(desc), desc, asize(bugs), bugs, &oenv))
{
if (oenv != nullptr)
{
gmx_fatal(FARGS,
"Can't neutralize this system using -nq %d and"
" -pq %d.\n",
- n_q, p_q);
+ n_q,
+ p_q);
}
while (qdelta != 0)
gmx_fatal(FARGS,
"The solvent group %s is not continuous: "
"index[%d]=%d, index[%d]=%d",
- grpname, int(i), solventGroup[i - 1] + 1, int(i + 1), solventGroup[i] + 1);
+ grpname,
+ int(i),
+ solventGroup[i - 1] + 1,
+ int(i + 1),
+ solventGroup[i] + 1);
}
}
nsa = 1;
}
if (solventGroup.size() % nsa != 0)
{
- gmx_fatal(FARGS, "Your solvent group size (%td) is not a multiple of %d",
- gmx::ssize(solventGroup), nsa);
+ gmx_fatal(FARGS,
+ "Your solvent group size (%td) is not a multiple of %d",
+ gmx::ssize(solventGroup),
+ nsa);
}
nw = solventGroup.size() / nsa;
fprintf(stderr, "Number of (%d-atomic) solvent molecules: %d\n", nsa, nw);
// Randomly shuffle the solvent molecules that shall be replaced by ions
// then pick molecules from the back of the list as replacement candidates
gmx::DefaultRandomEngine rng(seed);
- std::shuffle(std::begin(solventMoleculesForReplacement),
- std::end(solventMoleculesForReplacement), rng);
+ std::shuffle(
+ std::begin(solventMoleculesForReplacement), std::end(solventMoleculesForReplacement), rng);
/* Now loop over the ions that have to be placed */
while (p_num-- > 0)
{
- insert_ion(nsa, &solventMoleculesForReplacement, repl, solventGroup, x, &pbc, 1, p_q,
- p_name, &atoms, rmin, ¬SolventGroup);
+ insert_ion(
+ nsa, &solventMoleculesForReplacement, repl, solventGroup, x, &pbc, 1, p_q, p_name, &atoms, rmin, ¬SolventGroup);
}
while (n_num-- > 0)
{
- insert_ion(nsa, &solventMoleculesForReplacement, repl, solventGroup, x, &pbc, -1, n_q,
- n_name, &atoms, rmin, ¬SolventGroup);
+ insert_ion(
+ nsa, &solventMoleculesForReplacement, repl, solventGroup, x, &pbc, -1, n_q, n_name, &atoms, rmin, ¬SolventGroup);
}
fprintf(stderr, "\n");
{
fprintf(out, "; distance restraints for %s of %s\n\n", indexGroupNames, title);
fprintf(out, "[ distance_restraints ]\n");
- fprintf(out, ";%4s %5s %1s %5s %10s %10s %10s %10s %10s\n", "i", "j", "?", "label",
- "funct", "lo", "up1", "up2", "weight");
+ fprintf(out,
+ ";%4s %5s %1s %5s %10s %10s %10s %10s %10s\n",
+ "i",
+ "j",
+ "?",
+ "label",
+ "funct",
+ "lo",
+ "up1",
+ "up2",
+ "weight");
}
for (i = k = 0; i < igrp; i++)
{
}
lo = std::max(0.0_real, d - dd);
hi = d + dd;
- fprintf(out, "%5d %5d %1d %5d %10d %10g %10g %10g %10g\n", indexGroups[i] + 1,
- indexGroups[j] + 1, 1, k, 1, lo, hi, hi + disre_up2, 1.0);
+ fprintf(out,
+ "%5d %5d %1d %5d %10d %10g %10g %10g %10g\n",
+ indexGroups[i] + 1,
+ indexGroups[j] + 1,
+ 1,
+ k,
+ 1,
+ lo,
+ hi,
+ hi + disre_up2,
+ 1.0);
}
}
}
std::string inc_fn = dval.substr(i0, len);
/* Open include file and store it as a child in the handle structure */
- int status = cpp_open_file(inc_fn.c_str(), &(handle->child), nullptr, &handle->defines,
- &handle->includes);
+ int status = cpp_open_file(
+ inc_fn.c_str(), &(handle->child), nullptr, &handle->defines, &handle->includes);
if (status != eCPP_OK)
{
handle->child = nullptr;
status = eCPP_NR;
}
- sprintf(buf, "%s - File %s, line %d\nLast line read:\n'%s'", ecpp[status],
+ sprintf(buf,
+ "%s - File %s, line %d\nLast line read:\n'%s'",
+ ecpp[status],
(handle && !handle->fn.empty()) ? handle->fn.c_str() : "unknown",
- (handle) ? handle->line_nr : -1, !handle->line.empty() ? handle->line.c_str() : "");
+ (handle) ? handle->line_nr : -1,
+ !handle->line.empty() ? handle->line.c_str() : "");
return gmx_strdup(buf);
}
int PreprocessingAtomTypes::atomTypeFromName(const std::string& str) const
{
/* Atom types are always case sensitive */
- auto found = std::find_if(impl_->types.begin(), impl_->types.end(),
- [&str](const auto& type) { return str == *type.name_; });
+ auto found = std::find_if(impl_->types.begin(), impl_->types.end(), [&str](const auto& type) {
+ return str == *type.name_;
+ });
if (found == impl_->types.end())
{
return NOTSET;
void PreprocessingAtomTypes::printTypes(FILE* out)
{
fprintf(out, "[ %s ]\n", dir2str(Directive::d_atomtypes));
- fprintf(out, "; %6s %8s %8s %8s %12s %12s\n", "type", "mass", "charge", "particle", "c6",
+ fprintf(out,
+ "; %6s %8s %8s %8s %12s %12s\n",
+ "type",
+ "mass",
+ "charge",
+ "particle",
+ "c6",
"c12");
for (auto& entry : impl_->types)
{
- fprintf(out, "%8s %8.3f %8.3f %8s %12e %12e\n", *(entry.name_), entry.atom_.m,
- entry.atom_.q, "A", entry.nb_.c0(), entry.nb_.c1());
+ fprintf(out,
+ "%8s %8.3f %8.3f %8s %12e %12e\n",
+ *(entry.name_),
+ entry.atom_.m,
+ entry.atom_.q,
+ "A",
+ entry.nb_.c0(),
+ entry.nb_.c1());
}
fprintf(out, "\n");
const t_atoms* atoms = &moltype.atoms;
for (int i = 0; (i < atoms->nr); i++)
{
- atoms->atom[i].type = search_atomtypes(this, &nat, typelist, atoms->atom[i].type,
- plist[ftype].interactionTypes, ftype);
- atoms->atom[i].typeB = search_atomtypes(this, &nat, typelist, atoms->atom[i].typeB,
- plist[ftype].interactionTypes, ftype);
+ atoms->atom[i].type = search_atomtypes(
+ this, &nat, typelist, atoms->atom[i].type, plist[ftype].interactionTypes, ftype);
+ atoms->atom[i].typeB = search_atomtypes(
+ this, &nat, typelist, atoms->atom[i].typeB, plist[ftype].interactionTypes, ftype);
}
}
{
if (wall_atomtype[i] >= 0)
{
- wall_atomtype[i] = search_atomtypes(this, &nat, typelist, wall_atomtype[i],
- plist[ftype].interactionTypes, ftype);
+ wall_atomtype[i] = search_atomtypes(
+ this, &nat, typelist, wall_atomtype[i], plist[ftype].interactionTypes, ftype);
}
}
{
int mj = typelist[j];
const InteractionOfType& interactionType = plist[ftype].interactionTypes[ntype * mi + mj];
- nbsnew.emplace_back(interactionType.atoms(), interactionType.forceParam(),
+ nbsnew.emplace_back(interactionType.atoms(),
+ interactionType.forceParam(),
interactionType.interactionTypeName());
}
new_types.push_back(impl_->types[mi]);
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2011,2014,2015,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2011,2014,2015,2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <cstdio>
+#include <memory>
#include <string>
-#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/real.h"
struct gmx_mtop_t;
private:
class Impl;
//! Pimpl that holds the data.
- gmx::PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
#endif
int PreprocessingBondAtomType::bondAtomTypeFromName(const std::string& str) const
{
/* Atom types are always case sensitive */
- auto found =
- std::find_if(impl_->typeNames.begin(), impl_->typeNames.end(),
- [&str](const auto& type) { return str == const_cast<const char*>(*type); });
+ auto found = std::find_if(impl_->typeNames.begin(), impl_->typeNames.end(), [&str](const auto& type) {
+ return str == const_cast<const char*>(*type);
+ });
if (found == impl_->typeNames.end())
{
return NOTSET;
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2011,2014,2015,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2011,2014,2015,2018,2019,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <cstdio>
+#include <memory>
#include <string>
-#include "gromacs/utility/classhelpers.h"
-
struct t_symtab;
/*! \libinternal \brief
private:
class Impl;
//! Pimpl that holds the data.
- gmx::PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
#endif
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/mdlib/calc_verletbuf.h"
#include "gromacs/mdlib/compute_io.h"
#include "gromacs/mdlib/constr.h"
+#include "gromacs/mdlib/md_support.h"
#include "gromacs/mdlib/perf_est.h"
#include "gromacs/mdlib/vsite.h"
#include "gromacs/mdrun/mdmodules.h"
GMX_LOG(logger.warning)
.asParagraph()
.appendTextFormatted(
- "atom name %d in %s and %s does not match (%s - %s)", i + 1,
- fn1, fn2, *(tat->atomname[j]), *(at->atomname[i]));
+ "atom name %d in %s and %s does not match (%s - %s)",
+ i + 1,
+ fn1,
+ fn2,
+ *(tat->atomname[j]),
+ *(at->atomname[i]));
}
else if (nmismatch == c_maxNumberOfMismatches)
{
"oscillational period of %.1e ps, which is less than %d times the time step of "
"%.1e ps.\n"
"%s",
- *w_moltype->name, w_a1 + 1, *w_moltype->atoms.atomname[w_a1], w_a2 + 1,
- *w_moltype->atoms.atomname[w_a2], std::sqrt(w_period2),
- bWarn ? min_steps_warn : min_steps_note, dt,
+ *w_moltype->name,
+ w_a1 + 1,
+ *w_moltype->atoms.atomname[w_a1],
+ w_a2 + 1,
+ *w_moltype->atoms.atomname[w_a2],
+ std::sqrt(w_period2),
+ bWarn ? min_steps_warn : min_steps_note,
+ dt,
bWater ? "Maybe you asked for fexible water."
: "Maybe you forgot to change the constraints mdp option.");
if (bWarn)
bool ffParametrizedWithHBondConstraints;
/* TOPOLOGY processing */
- sys->name = do_top(bVerbose, topfile, topppfile, opts, bZero, &(sys->symtab), interactions,
- comb, reppow, fudgeQQ, atypes, mi, intermolecular_interactions, ir,
- &molblock, &ffParametrizedWithHBondConstraints, wi, logger);
+ sys->name = do_top(bVerbose,
+ topfile,
+ topppfile,
+ opts,
+ bZero,
+ &(sys->symtab),
+ interactions,
+ comb,
+ reppow,
+ fudgeQQ,
+ atypes,
+ mi,
+ intermolecular_interactions,
+ ir,
+ &molblock,
+ &ffParametrizedWithHBondConstraints,
+ wi,
+ logger);
sys->molblock.clear();
gmx_fatal(FARGS,
"number of coordinates in coordinate file (%s, %d)\n"
" does not match topology (%s, %d)",
- confin, state->natoms, topfile, sys->natoms);
+ confin,
+ state->natoms,
+ topfile,
+ sys->natoms);
}
/* It would be nice to get rid of the copies below, but we don't know
* a priori if the number of atoms in confin matches what we expect.
"%d non-matching atom name%s\n"
"atom names from %s will be used\n"
"atom names from %s will be ignored\n",
- nmismatch, (nmismatch == 1) ? "" : "s", topfile, confin);
+ nmismatch,
+ (nmismatch == 1) ? "" : "s",
+ topfile,
+ confin);
warning(wi, warningMessage.c_str());
}
GMX_LOG(logger.info).asParagraph().appendTextFormatted("Using frame at t = %g ps", use_time);
GMX_LOG(logger.info).asParagraph().appendTextFormatted("Starting time for run is %g ps", ir->init_t);
- if ((ir->epc != epcNO || ir->etc == etcNOSEHOOVER) && ener)
+ if ((ir->epc != PressureCoupling::No || ir->etc == TemperatureCoupling::NoseHoover) && ener)
{
get_enx_state(ener, use_time, sys->groups, ir, state);
preserve_box_shape(ir, state->box_rel, state->boxv);
std::string warningMessage = gmx::formatString(
"The number of atoms in %s (%d) does not match the number of atoms in the topology "
"(%d). Will assume that the first %d atoms in the topology and %s match.",
- fn, natoms, mtop->natoms, std::min(mtop->natoms, natoms), fn);
+ fn,
+ natoms,
+ mtop->natoms,
+ std::min(mtop->natoms, natoms),
+ fn);
warning(wi, warningMessage.c_str());
}
gmx_fatal(FARGS,
"Position restraint atom index (%d) in moltype '%s' is larger than "
"number of atoms in %s (%d).\n",
- ai + 1, *molinfo[molb.type].name, fn, natoms);
+ ai + 1,
+ *molinfo[molb.type].name,
+ fn,
+ natoms);
}
hadAtom[ai] = TRUE;
if (rc_scaling == erscCOM)
gmx_fatal(FARGS,
"Position restraint atom index (%d) in moltype '%s' is larger than "
"number of atoms in %s (%d).\n",
- ai + 1, *molinfo[molb.type].name, fn, natoms);
+ ai + 1,
+ *molinfo[molb.type].name,
+ fn,
+ natoms);
}
if (rc_scaling == erscCOM && !hadAtom[ai])
{
.asParagraph()
.appendTextFormatted(
"The center of mass of the position restraint coord's is %6.3f %6.3f %6.3f",
- com[XX], com[YY], com[ZZ]);
+ com[XX],
+ com[YY],
+ com[ZZ]);
}
if (rc_scaling != erscNO)
for (i = 0; i < 2 * grid_spacing; i++)
{
- spline1d(dx, &(tmp_grid[2 * grid_spacing * i]), 2 * grid_spacing, tmp_u.data(),
+ spline1d(dx,
+ &(tmp_grid[2 * grid_spacing * i]),
+ 2 * grid_spacing,
+ tmp_u.data(),
&(tmp_t2[2 * grid_spacing * i]));
}
for (k = 0; k < 2 * grid_spacing; k++)
{
- interpolate1d(xmin, dx, &(tmp_grid[2 * grid_spacing * k]),
- &(tmp_t2[2 * grid_spacing * k]), psi, &tmp_yy[k], &tmp_y1[k]);
+ interpolate1d(xmin,
+ dx,
+ &(tmp_grid[2 * grid_spacing * k]),
+ &(tmp_t2[2 * grid_spacing * k]),
+ psi,
+ &tmp_yy[k],
+ &tmp_y1[k]);
}
spline1d(dx, tmp_yy.data(), 2 * grid_spacing, tmp_u.data(), tmp_u2.data());
"Molecule type '%s' has %d constraints.\n"
"For stability and efficiency there should not be more constraints than "
"internal number of degrees of freedom: %d.\n",
- *mi[molb.type].name, count_mol, nrdf_internal(&mi[molb.type].atoms));
+ *mi[molb.type].name,
+ count_mol,
+ nrdf_internal(&mi[molb.type].atoms));
warning(wi, warningMessage.c_str());
}
count += molb.nmol * count_mol;
.appendTextFormatted(
"Atom %d '%s' in moleculetype '%s' is not bound by a potential or "
"constraint to any other atom in the same moleculetype.",
- a + 1, *atoms->atomname[a], *molt->name);
+ a + 1,
+ *atoms->atomname[a],
+ *molt->name);
}
numDanglingAtoms++;
}
"issues in a simulation, this often means that the user forgot to add a "
"bond/potential/constraint or put multiple molecules in the same moleculetype "
"definition by mistake. Run with -v to get information for each atom.",
- *molt->name, numDanglingAtoms);
+ *molt->name,
+ numDanglingAtoms);
warning_note(wi, warningMessage.c_str());
}
}
"hydrogens) or use integrator = %s or decrease one or more tolerances: "
"verlet-buffer-tolerance <= %g, LINCS iterations >= %d, LINCS order "
">= %d or SHAKE tolerance <= %g",
- ei_names[eiSD1], bufferToleranceThreshold, lincsIterationThreshold,
- lincsOrderThreshold, shakeToleranceThreshold);
+ ei_names[eiSD1],
+ bufferToleranceThreshold,
+ lincsIterationThreshold,
+ lincsOrderThreshold,
+ shakeToleranceThreshold);
}
else
{
.asParagraph()
.appendTextFormatted(
"Determining Verlet buffer for a tolerance of %g kJ/mol/ps at %g K",
- ir->verletbuf_tol, buffer_temp);
+ ir->verletbuf_tol,
+ buffer_temp);
/* Calculate the buffer size for simple atom vs atoms list */
VerletbufListSetup listSetup1x1;
listSetup1x1.cluster_size_i = 1;
listSetup1x1.cluster_size_j = 1;
- const real rlist_1x1 = calcVerletBufferSize(*mtop, det(box), *ir, ir->nstlist, ir->nstlist - 1,
- buffer_temp, listSetup1x1);
+ const real rlist_1x1 = calcVerletBufferSize(
+ *mtop, det(box), *ir, ir->nstlist, ir->nstlist - 1, buffer_temp, listSetup1x1);
/* Set the pair-list buffer size in ir */
VerletbufListSetup listSetup4x4 = verletbufGetSafeListSetup(ListSetupType::CpuNoSimd);
- ir->rlist = calcVerletBufferSize(*mtop, det(box), *ir, ir->nstlist, ir->nstlist - 1,
- buffer_temp, listSetup4x4);
+ ir->rlist = calcVerletBufferSize(
+ *mtop, det(box), *ir, ir->nstlist, ir->nstlist - 1, buffer_temp, listSetup4x4);
const int n_nonlin_vsite = gmx::countNonlinearVsites(*mtop);
if (n_nonlin_vsite > 0)
GMX_LOG(logger.info)
.asParagraph()
.appendTextFormatted(
- "Calculated rlist for %dx%d atom pair-list as %.3f nm, buffer size %.3f nm", 1,
- 1, rlist_1x1, rlist_1x1 - std::max(ir->rvdw, ir->rcoulomb));
+ "Calculated rlist for %dx%d atom pair-list as %.3f nm, buffer size %.3f nm",
+ 1,
+ 1,
+ rlist_1x1,
+ rlist_1x1 - std::max(ir->rvdw, ir->rcoulomb));
GMX_LOG(logger.info)
.asParagraph()
.appendTextFormatted(
"Set rlist, assuming %dx%d atom pair-list, to %.3f nm, buffer size %.3f nm",
- listSetup4x4.cluster_size_i, listSetup4x4.cluster_size_j, ir->rlist,
+ listSetup4x4.cluster_size_i,
+ listSetup4x4.cluster_size_j,
+ ir->rlist,
ir->rlist - std::max(ir->rvdw, ir->rcoulomb));
GMX_LOG(logger.info)
"The pair-list cut-off (%g nm) is longer than half the shortest box vector or "
"longer than the smallest box diagonal element (%g nm). Increase the box size or "
"decrease nstlist or increase verlet-buffer-tolerance.",
- ir->rlist, std::sqrt(max_cutoff2(ir->pbcType, box)));
+ ir->rlist,
+ std::sqrt(max_cutoff2(ir->pbcType, box)));
}
}
"Then a coordinate file is read and velocities can be generated",
"from a Maxwellian distribution if requested.",
"[THISMODULE] also reads parameters for [gmx-mdrun] ",
- "(eg. number of MD steps, time step, cut-off), and others such as",
- "NEMD parameters, which are corrected so that the net acceleration",
- "is zero.",
+ "(eg. number of MD steps, time step, cut-off).",
"Eventually a binary file is produced that can serve as the sole input",
"file for the MD program.[PAR]",
}
t_state state;
- new_status(fn, opt2fn_null("-pp", NFILE, fnm), opt2fn("-c", NFILE, fnm), opts, ir, bZero,
- bGenVel, bVerbose, &state, &atypes, &sys, &mi, &intermolecular_interactions,
- interactions, &comb, &reppow, &fudgeQQ, opts->bMorse, wi, logger);
+ new_status(fn,
+ opt2fn_null("-pp", NFILE, fnm),
+ opt2fn("-c", NFILE, fnm),
+ opts,
+ ir,
+ bZero,
+ bGenVel,
+ bVerbose,
+ &state,
+ &atypes,
+ &sys,
+ &mi,
+ &intermolecular_interactions,
+ interactions,
+ &comb,
+ &reppow,
+ &fudgeQQ,
+ opts->bMorse,
+ wi,
+ logger);
if (debug)
{
{
if (ir->eI == eiCG || ir->eI == eiLBFGS)
{
- std::string warningMessage =
- gmx::formatString("Can not do %s with %s, use %s", EI(ir->eI),
- econstr_names[econtSHAKE], econstr_names[econtLINCS]);
+ std::string warningMessage = gmx::formatString("Can not do %s with %s, use %s",
+ EI(ir->eI),
+ econstr_names[econtSHAKE],
+ econstr_names[econtLINCS]);
warning_error(wi, warningMessage);
}
if (ir->bPeriodicMols)
{
std::string warningMessage =
gmx::formatString("Can not do periodic molecules with %s, use %s",
- econstr_names[econtSHAKE], econstr_names[econtLINCS]);
+ econstr_names[econtSHAKE],
+ econstr_names[econtLINCS]);
warning_error(wi, warningMessage);
}
}
- if (EI_SD(ir->eI) && ir->etc != etcNO)
+ if (EI_SD(ir->eI) && ir->etc != TemperatureCoupling::No)
{
warning_note(wi, "Temperature coupling is ignored with SD integrators.");
}
if (nint_ftype(&sys, mi, F_POSRES) > 0 || nint_ftype(&sys, mi, F_FBPOSRES) > 0)
{
- if (ir->epc == epcPARRINELLORAHMAN || ir->epc == epcMTTK)
+ if (ir->epc == PressureCoupling::ParrinelloRahman || ir->epc == PressureCoupling::Mttk)
{
std::string warningMessage = gmx::formatString(
"You are combining position restraints with %s pressure coupling, which can "
"lead to instabilities. If you really want to combine position restraints with "
"pressure coupling, we suggest to use %s pressure coupling instead.",
- EPCOUPLTYPE(ir->epc), EPCOUPLTYPE(epcBERENDSEN));
+ enumValueToString(ir->epc),
+ enumValueToString(PressureCoupling::Berendsen));
warning_note(wi, warningMessage);
}
}
GMX_LOG(logger.info).asParagraph().appendText(message);
}
- gen_posres(&sys, mi, fn, fnB, ir->refcoord_scaling, ir->pbcType, ir->posres_com,
- ir->posres_comB, wi, logger);
+ gen_posres(&sys, mi, fn, fnB, ir->refcoord_scaling, ir->pbcType, ir->posres_com, ir->posres_comB, wi, logger);
}
/* If we are using CMAP, setup the pre-interpolation grid */
if (interactions[F_CMAP].ncmap() > 0)
{
- init_cmap_grid(&sys.ffparams.cmap_grid, interactions[F_CMAP].cmapAngles,
+ init_cmap_grid(&sys.ffparams.cmap_grid,
+ interactions[F_CMAP].cmapAngles,
interactions[F_CMAP].cmakeGridSpacing);
- setup_cmap(interactions[F_CMAP].cmakeGridSpacing, interactions[F_CMAP].cmapAngles,
- interactions[F_CMAP].cmap, &sys.ffparams.cmap_grid);
+ setup_cmap(interactions[F_CMAP].cmakeGridSpacing,
+ interactions[F_CMAP].cmapAngles,
+ interactions[F_CMAP].cmap,
+ &sys.ffparams.cmap_grid);
}
set_wall_atomtype(&atypes, opts, ir, wi, logger);
}
const int ntype = atypes.size();
- convertInteractionsOfType(ntype, interactions, mi, intermolecular_interactions.get(), comb,
- reppow, fudgeQQ, &sys);
+ convertInteractionsOfType(
+ ntype, interactions, mi, intermolecular_interactions.get(), comb, reppow, fudgeQQ, &sys);
if (debug)
{
{
real buffer_temp;
- if (EI_MD(ir->eI) && ir->etc == etcNO)
+ if (EI_MD(ir->eI) && ir->etc == TemperatureCoupling::No)
{
if (bGenVel)
{
buffer_temp = get_max_reference_temp(ir, wi);
}
- if (EI_MD(ir->eI) && ir->etc == etcNO && buffer_temp == 0)
+ if (EI_MD(ir->eI) && ir->etc == TemperatureCoupling::No && buffer_temp == 0)
{
/* NVE with initial T=0: we add a fixed ratio to rlist.
* Since we don't actually use verletbuf_tol, we set it to -1
* Note that we can't warn when nsteps=0, since we don't
* know how many steps the user intends to run.
*/
- if (EI_MD(ir->eI) && ir->etc == etcNO && ir->nstlist > 1 && ir->nsteps > 0)
+ if (EI_MD(ir->eI) && ir->etc == TemperatureCoupling::No && ir->nstlist > 1 && ir->nsteps > 0)
{
const real driftTolerance = 0.01;
/* We use 2 DOF per atom = 2kT pot+kin energy,
"NVE simulation of length %g ps, which can give a final drift of "
"%d%%. For conserving energy to %d%% when using constraints, you "
"might need to set verlet-buffer-tolerance to %.1e.",
- ir->verletbuf_tol, ir->nsteps * ir->delta_t,
+ ir->verletbuf_tol,
+ ir->nsteps * ir->delta_t,
gmx::roundToInt(ir->verletbuf_tol / totalEnergyDriftPerAtomPerPicosecond * 100),
gmx::roundToInt(100 * driftTolerance),
driftTolerance * totalEnergyDriftPerAtomPerPicosecond);
.asParagraph()
.appendTextFormatted("getting data from old trajectory ...");
}
- cont_status(ftp2fn(efTRN, NFILE, fnm), ftp2fn_null(efEDR, NFILE, fnm), bNeedVel, bGenVel,
- fr_time, ir, &state, &sys, oenv, logger);
+ cont_status(ftp2fn(efTRN, NFILE, fnm),
+ ftp2fn_null(efEDR, NFILE, fnm),
+ bNeedVel,
+ bGenVel,
+ fr_time,
+ ir,
+ &state,
+ &sys,
+ oenv,
+ logger);
}
if (ir->pbcType == PbcType::XY && ir->nwall != 2)
wi, "Some of the Fourier grid sizes are set, but all of them need to be set.");
}
const int minGridSize = minimalPmeGridSize(ir->pme_order);
- calcFftGrid(stdout, scaledBox, ir->fourier_spacing, minGridSize, &(ir->nkx), &(ir->nky),
- &(ir->nkz));
+ calcFftGrid(stdout, scaledBox, ir->fourier_spacing, minGridSize, &(ir->nkx), &(ir->nky), &(ir->nkz));
if (ir->nkx < minGridSize || ir->nky < minGridSize || ir->nkz < minGridSize)
{
warning_error(wi,
if (ir->bDoAwh)
{
tensor compressibility = { { 0 } };
- if (ir->epc != epcNO)
+ if (ir->epc != PressureCoupling::No)
{
copy_mat(ir->compress, compressibility);
}
setStateDependentAwhParams(
- ir->awhParams, *ir->pull, pull, state.box, ir->pbcType, compressibility, &ir->opts,
+ ir->awhParams,
+ *ir->pull,
+ pull,
+ state.box,
+ ir->pbcType,
+ compressibility,
+ &ir->opts,
ir->efep != efepNO ? ir->fepvals->all_lambda[efptFEP][ir->fepvals->init_fep_state] : 0,
- sys, wi);
+ sys,
+ wi);
}
if (ir->bPull)
if (ir->bRot)
{
- set_reference_positions(ir->rot, state.x.rvec_array(), state.box,
- opt2fn("-ref", NFILE, fnm), opt2bSet("-ref", NFILE, fnm), wi);
+ set_reference_positions(ir->rot,
+ state.x.rvec_array(),
+ state.box,
+ opt2fn("-ref", NFILE, fnm),
+ opt2bSet("-ref", NFILE, fnm),
+ wi);
}
/* reset_multinr(sys); */
std::make_unique<gmx::KeyValueTreeObject>(internalParameterBuilder.build());
}
+ if (ir->comm_mode != ecmNO)
+ {
+ const int nstglobalcomm = computeGlobalCommunicationPeriod(ir);
+ if (ir->nstcomm % nstglobalcomm != 0)
+ {
+ warning_note(
+ wi,
+ gmx::formatString(
+ "COM removal frequency is set to (%d).\n"
+ "Other settings require a global communication frequency of %d.\n"
+ "Note that this will require additional global communication steps,\n"
+ "which will reduce performance when using multiple ranks.\n"
+ "Consider setting nstcomm to a multiple of %d.",
+ ir->nstcomm,
+ nstglobalcomm,
+ nstglobalcomm));
+ }
+ }
+
if (bVerbose)
{
GMX_LOG(logger.info).asParagraph().appendTextFormatted("writing run input file...");
hack->tp = tp;
if ((tp < 1) || (tp >= maxcontrol))
{
- gmx_fatal(FARGS, "Error in hdb file %s:\nH-type should be in 1-%d. Offending line:\n%s", fn,
- maxcontrol - 1, line);
+ gmx_fatal(FARGS,
+ "Error in hdb file %s:\nH-type should be in 1-%d. Offending line:\n%s",
+ fn,
+ maxcontrol - 1,
+ line);
}
hack->nctl = ns - 3;
gmx_fatal(FARGS,
"Error in hdb file %s:\nWrong number of control atoms (%d instead of %d) on "
"line:\n%s\n",
- fn, hack->nctl, ncontrol[hack->tp], line);
+ fn,
+ hack->nctl,
+ ncontrol[hack->tp],
+ line);
}
for (int i = 0; (i < hack->nctl); i++)
{
gmx_fatal(FARGS,
"Expected %d lines of hydrogens, found only %d "
"while reading Hydrogen Database %s residue %s",
- nab, i - 1, block->name.c_str(), hfn);
+ nab,
+ i - 1,
+ block->name.c_str(),
+ hfn);
}
if (nullptr == fgets(buf, STRLEN, in))
{
if (!globalPatches->empty())
{
/* Sort the list for searching later */
- std::sort(globalPatches->begin(), globalPatches->end(),
+ std::sort(globalPatches->begin(),
+ globalPatches->end(),
[](const MoleculePatchDatabase& a1, const MoleculePatchDatabase& a2) {
- return std::lexicographical_compare(
- a1.name.begin(), a1.name.end(), a2.name.begin(), a2.name.end(),
- [](const char& c1, const char& c2) {
- return std::toupper(c1) < std::toupper(c2);
- });
+ return std::lexicographical_compare(a1.name.begin(),
+ a1.name.end(),
+ a2.name.begin(),
+ a2.name.end(),
+ [](const char& c1, const char& c2) {
+ return std::toupper(c1) < std::toupper(c2);
+ });
});
}
}
gmx::ArrayRef<const MoleculePatchDatabase>::iterator
search_h_db(gmx::ArrayRef<const MoleculePatchDatabase> globalPatches, const char* key)
{
- return std::find_if(
- globalPatches.begin(), globalPatches.end(),
- [&key](const MoleculePatchDatabase& a) { return gmx::equalCaseInsensitive(key, a.name); });
+ return std::find_if(globalPatches.begin(), globalPatches.end(), [&key](const MoleculePatchDatabase& a) {
+ return gmx::equalCaseInsensitive(key, a.name);
+ });
}
None,
Count
};
-static const gmx::EnumerationArray<RotationType, const char*> c_rotationTypeNames = { { "xyz", "z",
- "none" } };
+static const gmx::EnumerationArray<RotationType, const char*> c_rotationTypeNames = {
+ { "xyz", "z", "none" }
+};
static void center_molecule(gmx::ArrayRef<RVec> x)
{
// Skip a position if ntry trials were not successful.
if (trial >= firstTrial + ntry)
{
- fprintf(stderr, " skipped position (%.3f, %.3f, %.3f)\n", rpos[XX][mol],
- rpos[YY][mol], rpos[ZZ][mol]);
+ fprintf(stderr,
+ " skipped position (%.3f, %.3f, %.3f)\n",
+ rpos[XX][mol],
+ rpos[YY][mol],
+ rpos[ZZ][mol]);
++mol;
++failed;
firstTrial = trial;
generate_trial_conf(x_insrt, offset_x, enum_rot, &rng, &x_n);
gmx::AnalysisNeighborhoodPositions pos(*x);
gmx::AnalysisNeighborhoodSearch search = nb.initSearch(&pbc, pos);
- if (isInsertionAllowed(&search, exclusionDistances, x_n, exclusionDistances_insrt, *atoms,
- removableAtoms, &remover))
+ if (isInsertionAllowed(
+ &search, exclusionDistances, x_n, exclusionDistances_insrt, *atoms, removableAtoms, &remover))
{
x->insert(x->end(), x_n.begin(), x_n.end());
- exclusionDistances.insert(exclusionDistances.end(), exclusionDistances_insrt.begin(),
+ exclusionDistances.insert(exclusionDistances.end(),
+ exclusionDistances_insrt.begin(),
exclusionDistances_insrt.end());
builder.mergeAtoms(atoms_insrt);
++mol;
remover.removeMarkedAtoms(atoms);
if (atoms->nr < originalAtomCount)
{
- fprintf(stderr, "Replaced %d residues (%d atoms)\n", originalResidueCount - atoms->nres,
+ fprintf(stderr,
+ "Replaced %d residues (%d atoms)\n",
+ originalResidueCount - atoms->nres,
originalAtomCount - atoms->nr);
}
bool bTprFileWasRead;
rvec* temporaryX = nullptr;
fprintf(stderr, "Reading solute configuration\n");
- readConfAndTopology(inputConfFile_.c_str(), &bTprFileWasRead, &top_, &pbcType_, &temporaryX,
- nullptr, box_);
+ readConfAndTopology(
+ inputConfFile_.c_str(), &bTprFileWasRead, &top_, &pbcType_, &temporaryX, nullptr, box_);
x_.assign(temporaryX, temporaryX + top_.natoms);
sfree(temporaryX);
if (top_.natoms == 0)
PbcType pbcType_dummy;
matrix box_dummy;
rvec* temporaryX;
- readConfAndTopology(insertConfFile_.c_str(), &bTprFileWasRead, &topInserted, &pbcType_dummy,
- &temporaryX, nullptr, box_dummy);
+ readConfAndTopology(
+ insertConfFile_.c_str(), &bTprFileWasRead, &topInserted, &pbcType_dummy, &temporaryX, nullptr, box_dummy);
xInserted.assign(temporaryX, temporaryX + topInserted.natoms);
sfree(temporaryX);
atomsInserted = gmx_mtop_global_atoms(&topInserted);
/* add nmol_ins molecules of atoms_ins
in random orientation at random place */
- insert_mols(nmolIns_, nmolTry_, seed_, defaultDistance_, scaleFactor_, &atoms, &top_.symtab,
- &x_, removableAtoms, atomsInserted, xInserted, pbcTypeForOutput, box_,
- positionFile_, deltaR_, enumRot_);
+ insert_mols(nmolIns_,
+ nmolTry_,
+ seed_,
+ defaultDistance_,
+ scaleFactor_,
+ &atoms,
+ &top_.symtab,
+ &x_,
+ removableAtoms,
+ atomsInserted,
+ xInserted,
+ pbcTypeForOutput,
+ box_,
+ positionFile_,
+ deltaR_,
+ enumRot_);
/* write new configuration to file confout */
fprintf(stderr, "Writing generated configuration to %s\n", outputConfFile_.c_str());
- write_sto_conf(outputConfFile_.c_str(), *top_.name, &atoms, as_rvec_array(x_.data()), nullptr,
- pbcTypeForOutput, box_);
+ write_sto_conf(
+ outputConfFile_.c_str(), *top_.name, &atoms, as_rvec_array(x_.data()), nullptr, pbcTypeForOutput, box_);
/* print size of generated configuration */
fprintf(stderr, "\nOutput configuration contains %d atoms in %d residues\n", atoms.nr, atoms.nres);
for (int i = 0; i < a->nr; ++i)
{
real value;
- if (!aps->setAtomProperty(epropVDW, std::string(*(a->resinfo[a->atom[i].resind].name)),
- std::string(*(a->atomname[i])), &value))
+ if (!aps->setAtomProperty(epropVDW,
+ std::string(*(a->resinfo[a->atom[i].resind].name)),
+ std::string(*(a->atomname[i])),
+ &value))
{
value = defaultDistance;
}
fprintf(fp, "; nm2type database\n");
for (i = 0; (i < nnm); i++)
{
- fprintf(fp, "%-8s %-8s %8.4f %8.4f %-4d", nm2t[i].elem, nm2t[i].type, nm2t[i].q, nm2t[i].m,
- nm2t[i].nbonds);
+ fprintf(fp, "%-8s %-8s %8.4f %8.4f %-4d", nm2t[i].elem, nm2t[i].type, nm2t[i].q, nm2t[i].m, nm2t[i].nbonds);
for (j = 0; (j < nm2t[i].nbonds); j++)
{
fprintf(fp, " %-5s %6.4f", nm2t[i].bond[j], nm2t[i].blen[j]);
{
atoms->atom[i].qB = alpha;
atoms->atom[i].m = atoms->atom[i].mB = mm;
- k = atype->addType(tab, atoms->atom[i], type, InteractionOfType({}, {}),
- atoms->atom[i].type, atomnr);
+ k = atype->addType(
+ tab, atoms->atom[i], type, InteractionOfType({}, {}), atoms->atom[i].type, atomnr);
}
atoms->atom[i].type = k;
atoms->atom[i].typeB = k;
}
else
{
- fprintf(stderr, "Can not find forcefield for atom %s-%d with %d bonds\n",
- *atoms->atomname[i], i + 1, nb);
+ fprintf(stderr,
+ "Can not find forcefield for atom %s-%d with %d bonds\n",
+ *atoms->atomname[i],
+ i + 1,
+ nb);
}
}
sfree(bbb);
const char* get_histp(int resnr, gmx::ArrayRef<const RtpRename> rr)
{
- const char* expl[ehisNR] = { "H on ND1 only", "H on NE2 only", "H on ND1 and NE2",
- "Coupled to Heme" };
+ const char* expl[ehisNR] = {
+ "H on ND1 only", "H on NE2 only", "H on ND1 and NE2", "Coupled to Heme"
+ };
return select_res(ehisNR, resnr, hh, expl, "HISTIDINE", rr);
}
{
if (nc != 2 && nc != 5)
{
- gmx_fatal(FARGS, "Residue renaming database '%s' has %d columns instead of %d or %d",
- fname, ncol, 2, 5);
+ gmx_fatal(FARGS,
+ "Residue renaming database '%s' has %d columns instead of %d or %d",
+ fname,
+ ncol,
+ 2,
+ 5);
}
ncol = nc;
}
gmx_fatal(FARGS,
"A line in residue renaming database '%s' has %d columns, while previous "
"lines have %d columns",
- fname, nc, ncol);
+ fname,
+ nc,
+ ncol);
}
if (nc == 2)
if (newName[0] == '-')
{
- gmx_fatal(FARGS, "In the chosen force field there is no residue type for '%s'%s", name,
+ gmx_fatal(FARGS,
+ "In the chosen force field there is no residue type for '%s'%s",
+ name,
bStart ? (bEnd ? " as a standalone (starting & ending) residue" : " as a starting terminus")
: (bEnd ? " as an ending terminus" : ""));
}
GMX_LOG(logger.info)
.asParagraph()
.appendTextFormatted("Changing rtp entry of residue %d %s to '%s'",
- pdba->resinfo[r].nr, *pdba->resinfo[r].name,
+ pdba->resinfo[r].nr,
+ *pdba->resinfo[r].name,
newName.c_str());
}
pdba->resinfo[r].rtp = put_symtab(symtab, newName.c_str());
.appendTextFormatted(
"Replaced %d residue%s named %s to the default %s. Use interactive "
"selection of protonated residues if that is what you need.",
- numMatchesFound, numMatchesFound > 1 ? "s" : "", oldnm, newnm);
+ numMatchesFound,
+ numMatchesFound > 1 ? "s" : "",
+ oldnm,
+ newnm);
}
}
.appendTextFormatted("Occupancy for atom %s%d-%s is %f rather than 1",
*atoms->resinfo[atoms->atom[i].resind].name,
atoms->resinfo[atoms->atom[i].resind].nr,
- *atoms->atomname[i], atoms->pdbinfo[i].occup);
+ *atoms->atomname[i],
+ atoms->pdbinfo[i].occup);
}
if (atoms->pdbinfo[i].occup == 0)
{
"there were %d atoms with zero occupancy and %d atoms with "
" occupancy unequal to one (out of %d atoms). Check your pdb "
"file.",
- nzero, nnotone, atoms->nr);
+ nzero,
+ nnotone,
+ atoms->nr);
}
else
{
"\n"
"[ position_restraints ]\n"
"; %4s%6s%8s%8s%8s\n",
- "atom", "type", "fx", "fy", "fz");
+ "atom",
+ "type",
+ "fx",
+ "fy",
+ "fz");
for (i = 0; (i < pdba->nr); i++)
{
if (!is_hydrogen(*pdba->atomname[i]) && !is_dummymass(*pdba->atomname[i]))
atomnm = *pdba->atomname[i];
const PreprocessResidue* localPpResidue = &restp_chain[pdba->atom[i].resind];
auto found =
- std::find_if(localPpResidue->atomname.begin(), localPpResidue->atomname.end(),
+ std::find_if(localPpResidue->atomname.begin(),
+ localPpResidue->atomname.end(),
[&atomnm](char** it) { return gmx::equalCaseInsensitive(atomnm, *it); });
if (found == localPpResidue->atomname.end())
{
std::string buf = gmx::formatString(
"Atom %s in residue %s %d was not found in rtp entry %s with %d atoms\n"
"while sorting atoms.\n%s",
- atomnm, *pdba->resinfo[pdba->atom[i].resind].name,
- pdba->resinfo[pdba->atom[i].resind].nr, localPpResidue->resname.c_str(),
+ atomnm,
+ *pdba->resinfo[pdba->atom[i].resind].name,
+ pdba->resinfo[pdba->atom[i].resind].nr,
+ localPpResidue->resname.c_str(),
localPpResidue->natom(),
is_hydrogen(atomnm)
? "\nFor a hydrogen, this can be a different protonation state, or it\n"
GMX_LOG(logger.info)
.asParagraph()
.appendTextFormatted("deleting duplicate atom %4s %s%4d%c",
- *pdba->atomname[i], *ri->name, ri->nr, ri->ic);
+ *pdba->atomname[i],
+ *ri->name,
+ ri->nr,
+ ri->ic);
if (ri->chainid && (ri->chainid != ' '))
{
printf(" ch %c", ri->chainid);
gmx_fatal(FARGS,
"The chain covering the range %s--%s does not have a consistent chain ID. "
"The first residue has ID '%c', while residue %s has ID '%c'.",
- startResidueString.c_str(), endResidueString.c_str(), chainID0,
- residueString.c_str(), chainID);
+ startResidueString.c_str(),
+ endResidueString.c_str(),
+ chainID0,
+ residueString.c_str(),
+ chainID);
}
// At this point all residues have the same ID. If they are also non-blank
"file in the GROMACS library directory. If there are other molecules "
"such as ligands, they should not have the same chain ID as the "
"adjacent protein chain since it's a separate molecule.",
- startResidueString.c_str(), endResidueString.c_str(), restype0.c_str(),
- residueString.c_str(), restype.c_str());
+ startResidueString.c_str(),
+ endResidueString.c_str(),
+ restype0.c_str(),
+ residueString.c_str(),
+ restype.c_str());
}
}
}
GMX_LOG(logger.info)
.asParagraph()
.appendTextFormatted("Identified residue %s%d as a starting terminus.",
- *pdba->resinfo[i].name, pdba->resinfo[i].nr);
+ *pdba->resinfo[i].name,
+ pdba->resinfo[i].nr);
*r_start = i;
}
else if (gmx::equalCaseInsensitive(*startrestype, "Ion"))
.appendTextFormatted(
"Residue %s%d has type 'Ion', assuming it is not linked into a "
"chain.",
- *pdba->resinfo[i].name, pdba->resinfo[i].nr);
+ *pdba->resinfo[i].name,
+ pdba->resinfo[i].nr);
}
if (ionNotes == 4)
{
"be catastrophic if they should in fact be linked. Please "
"check your structure, "
"and add %s to residuetypes.dat if this was not correct.",
- *pdba->resinfo[i].name, pdba->resinfo[i].nr, *pdba->resinfo[i].name);
+ *pdba->resinfo[i].name,
+ pdba->resinfo[i].nr,
+ *pdba->resinfo[i].name);
}
else
{
"and add all "
"necessary residue names to residuetypes.dat if this was not "
"correct.",
- *pdba->resinfo[i].name, pdba->resinfo[i].nr);
+ *pdba->resinfo[i].name,
+ pdba->resinfo[i].nr);
}
}
if (startWarnings == 4)
.appendTextFormatted(
"Residue %s%d has type 'Ion', assuming it is not linked into a "
"chain.",
- *pdba->resinfo[i].name, pdba->resinfo[i].nr);
+ *pdba->resinfo[i].name,
+ pdba->resinfo[i].nr);
}
if (ionNotes == 4)
{
"linked. Please check your structure, and add %s to "
"residuetypes.dat "
"if this was not correct.",
- *pdba->resinfo[i].name, pdba->resinfo[i].nr, restype->c_str(),
- *pdba->resinfo[*r_start].name, pdba->resinfo[*r_start].nr,
- startrestype->c_str(), *pdba->resinfo[i].name);
+ *pdba->resinfo[i].name,
+ pdba->resinfo[i].nr,
+ restype->c_str(),
+ *pdba->resinfo[*r_start].name,
+ pdba->resinfo[*r_start].nr,
+ startrestype->c_str(),
+ *pdba->resinfo[i].name);
}
if (endWarnings == 4)
{
GMX_LOG(logger.info)
.asParagraph()
.appendTextFormatted("Identified residue %s%d as a ending terminus.",
- *pdba->resinfo[*r_end].name, pdba->resinfo[*r_end].nr);
+ *pdba->resinfo[*r_end].name,
+ pdba->resinfo[*r_end].nr);
}
}
"Split the chain (and introduce termini) between residue %s%d (chain id '%c', atom %d %s)\
"
"and residue %s%d (chain id '%c', atom %d %s) ? [n/y]",
- prev_resname, prev_resnum, prev_chainid, prev_atomnum,
- prev_atomname, this_resname, this_resnum, this_chainid,
- this_atomnum, this_atomname);
+ prev_resname,
+ prev_resnum,
+ prev_chainid,
+ prev_atomnum,
+ prev_atomname,
+ this_resname,
+ this_resnum,
+ this_chainid,
+ this_atomnum,
+ this_atomname);
if (nullptr == fgets(select, STRLEN - 1, stdin))
{
Aromatics,
Count
};
-const gmx::EnumerationArray<VSitesType, const char*> c_vsitesTypeNames = { { "none", "hydrogens",
- "aromatics" } };
+const gmx::EnumerationArray<VSitesType, const char*> c_vsitesTypeNames = {
+ { "none", "hydrogens", "aromatics" }
+};
enum class WaterType : int
{
Interactive,
Count
};
-const gmx::EnumerationArray<MergeType, const char*> c_mergeTypeNames = { { "no", "all",
- "interactive" } };
+const gmx::EnumerationArray<MergeType, const char*> c_mergeTypeNames = {
+ { "no", "all", "interactive" }
+};
} // namespace
}
/* Force field selection, interactive or direct */
- choose_ff(strcmp(ff_.c_str(), "select") == 0 ? nullptr : ff_.c_str(), forcefield_,
- sizeof(forcefield_), ffdir_, sizeof(ffdir_), loggerOwner_->logger());
+ choose_ff(strcmp(ff_.c_str(), "select") == 0 ? nullptr : ff_.c_str(),
+ forcefield_,
+ sizeof(forcefield_),
+ ffdir_,
+ sizeof(ffdir_),
+ loggerOwner_->logger());
if (strlen(forcefield_) > 0)
{
PbcType pbcType;
t_atoms pdba_all;
rvec* pdbx;
- int natom = read_pdball(inputConfFile_.c_str(), bOutputSet_, outFile_.c_str(), &title, &pdba_all,
- &pdbx, &pbcType, box, bRemoveH_, &symtab, &rt, watres, &aps, bVerbose_);
+ int natom = read_pdball(inputConfFile_.c_str(),
+ bOutputSet_,
+ outFile_.c_str(),
+ &title,
+ &pdba_all,
+ &pdbx,
+ &pbcType,
+ box,
+ bRemoveH_,
+ &symtab,
+ &rt,
+ watres,
+ &aps,
+ bVerbose_);
if (natom == 0)
{
"%s) and chain starting with "
"residue %s%d (chain id '%c', atom %d %s) into a single "
"moleculetype (keeping termini)? [n/y]",
- prev_resname, prev_resnum, prev_chainid, prev_atomnum,
- prev_atomname, this_resname, this_resnum, this_chainid,
- this_atomnum, this_atomname);
+ prev_resname,
+ prev_resnum,
+ prev_chainid,
+ prev_atomnum,
+ prev_atomname,
+ this_resname,
+ this_resnum,
+ this_chainid,
+ this_atomnum,
+ this_atomname);
if (nullptr == fgets(select, STRLEN - 1, stdin))
{
.appendTextFormatted(
"There are %d chains and %d blocks of water and "
"%d residues with %d atoms",
- numChains - nwaterchain, nwaterchain, pdba_all.nres, natom);
+ numChains - nwaterchain,
+ nwaterchain,
+ pdba_all.nres,
+ natom);
GMX_LOG(logger.info)
.asParagraph()
{
GMX_LOG(logger.info)
.asParagraph()
- .appendTextFormatted(" %d '%c' %5d %6d %s\n", i + 1,
- chains[i].chainid ? chains[i].chainid : '-', chains[i].pdba->nres,
- chains[i].pdba->nr, chains[i].bAllWat ? "(only water)" : "");
+ .appendTextFormatted(" %d '%c' %5d %6d %s\n",
+ i + 1,
+ chains[i].chainid ? chains[i].chainid : '-',
+ chains[i].pdba->nres,
+ chains[i].pdba->nr,
+ chains[i].bAllWat ? "(only water)" : "");
}
check_occupancy(&pdba_all, inputConfFile_.c_str(), bVerbose_, logger);
GMX_LOG(logger.info)
.asParagraph()
.appendTextFormatted("Processing chain %d '%c' (%d atoms, %d residues)",
- chain + 1, cc->chainid, natom, nres);
+ chain + 1,
+ cc->chainid,
+ natom,
+ nres);
}
else
{
GMX_LOG(logger.info)
.asParagraph()
- .appendTextFormatted("Processing chain %d (%d atoms, %d residues)", chain + 1,
- natom, nres);
- }
-
- process_chain(logger, pdba, x, bUnA_, bUnA_, bUnA_, bLysMan_, bAspMan_, bGluMan_, bHisMan_,
- bArgMan_, bGlnMan_, angle_, distance_, &symtab, rtprename);
+ .appendTextFormatted(
+ "Processing chain %d (%d atoms, %d residues)", chain + 1, natom, nres);
+ }
+
+ process_chain(logger,
+ pdba,
+ x,
+ bUnA_,
+ bUnA_,
+ bUnA_,
+ bLysMan_,
+ bAspMan_,
+ bGluMan_,
+ bHisMan_,
+ bArgMan_,
+ bGlnMan_,
+ angle_,
+ distance_,
+ &symtab,
+ rtprename);
cc->chainstart[cc->nterpairs] = pdba->nres;
j = 0;
for (int i = 0; i < cc->nterpairs; i++)
{
- find_nc_ter(pdba, cc->chainstart[i], cc->chainstart[i + 1], &(cc->r_start[j]),
- &(cc->r_end[j]), &rt, logger);
+ find_nc_ter(
+ pdba, cc->chainstart[i], cc->chainstart[i + 1], &(cc->r_start[j]), &(cc->r_end[j]), &rt, logger);
if (cc->r_start[j] >= 0 && cc->r_end[j] >= 0)
{
- if (checkChainCyclicity(pdba, pdbx, cc->r_start[j], cc->r_end[j], rtpFFDB,
- rtprename, long_bond_dist_, short_bond_dist_))
+ if (checkChainCyclicity(
+ pdba, pdbx, cc->r_start[j], cc->r_end[j], rtpFFDB, rtprename, long_bond_dist_, short_bond_dist_))
{
cc->cyclicBondsIndex.push_back(cc->r_start[j]);
cc->cyclicBondsIndex.push_back(cc->r_end[j]);
{
if (bTerMan_ && !tdblist.empty())
{
- sprintf(select, "Select start terminus type for %s-%d",
- *pdba->resinfo[cc->r_start[i]].name, pdba->resinfo[cc->r_start[i]].nr);
+ sprintf(select,
+ "Select start terminus type for %s-%d",
+ *pdba->resinfo[cc->r_start[i]].name,
+ pdba->resinfo[cc->r_start[i]].nr);
cc->ntdb.push_back(choose_ter(tdblist, select));
}
else
cc->ntdb.push_back(tdblist[0]);
}
- printf("Start terminus %s-%d: %s\n", *pdba->resinfo[cc->r_start[i]].name,
- pdba->resinfo[cc->r_start[i]].nr, (cc->ntdb[i])->name.c_str());
+ printf("Start terminus %s-%d: %s\n",
+ *pdba->resinfo[cc->r_start[i]].name,
+ pdba->resinfo[cc->r_start[i]].nr,
+ (cc->ntdb[i])->name.c_str());
tdblist.clear();
}
}
{
if (bTerMan_ && !tdblist.empty())
{
- sprintf(select, "Select end terminus type for %s-%d",
- *pdba->resinfo[cc->r_end[i]].name, pdba->resinfo[cc->r_end[i]].nr);
+ sprintf(select,
+ "Select end terminus type for %s-%d",
+ *pdba->resinfo[cc->r_end[i]].name,
+ pdba->resinfo[cc->r_end[i]].nr);
cc->ctdb.push_back(choose_ter(tdblist, select));
}
else
{
cc->ctdb.push_back(tdblist[0]);
}
- printf("End terminus %s-%d: %s\n", *pdba->resinfo[cc->r_end[i]].name,
- pdba->resinfo[cc->r_end[i]].nr, (cc->ctdb[i])->name.c_str());
+ printf("End terminus %s-%d: %s\n",
+ *pdba->resinfo[cc->r_end[i]].name,
+ pdba->resinfo[cc->r_end[i]].nr,
+ (cc->ctdb[i])->name.c_str());
tdblist.clear();
}
}
std::vector<MoleculePatchDatabase> hb_chain;
/* lookup hackblocks and rtp for all residues */
std::vector<PreprocessResidue> restp_chain;
- get_hackblocks_rtp(&hb_chain, &restp_chain, rtpFFDB, pdba->nres, pdba->resinfo, cc->nterpairs,
- &symtab, cc->ntdb, cc->ctdb, cc->r_start, cc->r_end, bAllowMissing_, logger);
+ get_hackblocks_rtp(&hb_chain,
+ &restp_chain,
+ rtpFFDB,
+ pdba->nres,
+ pdba->resinfo,
+ cc->nterpairs,
+ &symtab,
+ cc->ntdb,
+ cc->ctdb,
+ cc->r_start,
+ cc->r_end,
+ bAllowMissing_,
+ logger);
/* ideally, now we would not need the rtp itself anymore, but do
everything using the hb and restp arrays. Unfortunately, that
requires some re-thinking of code in gen_vsite.c, which I won't
.asParagraph()
.appendTextFormatted(
"Generating any missing hydrogen atoms and/or adding termini.");
- add_h(&pdba, &localAtoms[chain], &x, ah, &symtab, cc->nterpairs, cc->ntdb, cc->ctdb,
- cc->r_start, cc->r_end, bAllowMissing_, cc->cyclicBondsIndex);
+ add_h(&pdba,
+ &localAtoms[chain],
+ &x,
+ ah,
+ &symtab,
+ cc->nterpairs,
+ cc->ntdb,
+ cc->ctdb,
+ cc->r_start,
+ cc->r_end,
+ bAllowMissing_,
+ cc->cyclicBondsIndex);
GMX_LOG(logger.info)
.asParagraph()
.appendTextFormatted("Now there are %d residues with %d atoms", pdba->nres, pdba->nr);
top_file2 = top_file;
}
- pdb2top(top_file2, posre_fn.c_str(), molname.c_str(), pdba, &x, &atype, &symtab, rtpFFDB,
- restp_chain, hb_chain, bAllowMissing_, bVsites_, bVsiteAromatics_, ffdir_, mHmult_,
- ssbonds, long_bond_dist_, short_bond_dist_, bDeuterate_, bChargeGroups_, bCmap_,
- bRenumRes_, bRTPresname_, cc->cyclicBondsIndex, logger);
+ pdb2top(top_file2,
+ posre_fn.c_str(),
+ molname.c_str(),
+ pdba,
+ &x,
+ &atype,
+ &symtab,
+ rtpFFDB,
+ restp_chain,
+ hb_chain,
+ bAllowMissing_,
+ bVsites_,
+ bVsiteAromatics_,
+ ffdir_,
+ mHmult_,
+ ssbonds,
+ long_bond_dist_,
+ short_bond_dist_,
+ bDeuterate_,
+ bChargeGroups_,
+ bCmap_,
+ bRenumRes_,
+ bRTPresname_,
+ cc->cyclicBondsIndex,
+ logger);
if (!cc->bAllWat)
{
"The topology file '%s' for the selected water "
"model '%s' can not be found in the force field "
"directory. Select a different water model.",
- waterFile.c_str(), watermodel_);
+ waterFile.c_str(),
+ watermodel_);
GMX_THROW(InconsistentInputError(message));
}
}
GMX_LOG(logger.info)
.asParagraph()
.appendTextFormatted("Including chain %d in system: %d atoms %d residues",
- i + 1, chains[i].pdba->nr, chains[i].pdba->nres);
+ i + 1,
+ chains[i].pdba->nr,
+ chains[i].pdba->nres);
}
for (int j = 0; (j < chains[i].pdba->nr); j++)
{
{
make_new_box(atoms->nr, gmx::as_rvec_array(x.data()), box, box_space, false);
}
- write_sto_conf(outputConfFile_.c_str(), title, atoms, gmx::as_rvec_array(x.data()), nullptr,
- pbcType, box);
+ write_sto_conf(
+ outputConfFile_.c_str(), title, atoms, gmx::as_rvec_array(x.data()), nullptr, pbcType, box);
done_symtab(&symtab);
done_atom(&pdba_all);
{
GMX_LOG(logger.info)
.asParagraph()
- .appendTextFormatted("The %s force field and the %s water model are used.", ffname_,
- watermodel_);
+ .appendTextFormatted(
+ "The %s force field and the %s water model are used.", ffname_, watermodel_);
sfree(watermodel_);
}
else
GMX_LOG(logger.warning)
.asParagraph()
.appendTextFormatted("atom %s is missing in residue %s %d in the pdb file",
- name, *(at->resinfo[resind].name), at->resinfo[resind].nr);
+ name,
+ *(at->resinfo[resind].name),
+ at->resinfo[resind].nr);
if (name[0] == 'H' || name[0] == 'h')
{
GMX_LOG(logger.warning)
"You might need to add atom %s to the hydrogen database of "
"building block %s "
"in the file %s.hdb (see the manual)",
- name, *(at->resinfo[resind].rtp), rp->filebase.c_str());
+ name,
+ *(at->resinfo[resind].rtp),
+ rp->filebase.c_str());
}
}
}
"Force field '%s' occurs in %d places. pdb2gmx is using the one in "
"the current directory. Use interactive selection "
"(not the -ff option) if you would prefer a different one.",
- ffsel, nfound);
+ ffsel,
+ nfound);
}
else
{
"the current directory.\n"
"Run without the -ff switch and select the force "
"field interactively.",
- ffsel, nfound);
+ ffsel,
+ nfound);
GMX_THROW(gmx::InconsistentInputError(message));
}
}
"to point to the desired force field first, and/or "
"rename or move the force field directory present "
"in the current working directory.",
- ffs[sel].c_str(), fflib_forcefield_dir_ext());
+ ffs[sel].c_str(),
+ fflib_forcefield_dir_ext());
GMX_THROW(gmx::NotImplementedError(message));
}
}
if (ffs[sel].length() >= static_cast<size_t>(ff_maxlen))
{
std::string message = gmx::formatString("Length of force field name (%d) >= maxlen (%d)",
- static_cast<int>(ffs[sel].length()), ff_maxlen);
+ static_cast<int>(ffs[sel].length()),
+ ff_maxlen);
GMX_THROW(gmx::InvalidInputError(message));
}
strcpy(forcefield, ffs[sel].c_str());
if (ffpath.length() >= static_cast<size_t>(ffdir_maxlen))
{
std::string message = gmx::formatString("Length of force field dir (%d) >= maxlen (%d)",
- static_cast<int>(ffpath.length()), ffdir_maxlen);
+ static_cast<int>(ffpath.length()),
+ ffdir_maxlen);
GMX_THROW(gmx::InvalidInputError(message));
}
strcpy(ffdir, ffpath.c_str());
int aj = search_res_atom(bond.secondAtom.c_str(), rj, atoms, "special bond", bAllowMissing);
if ((ai == -1) || (aj == -1))
{
- gmx_fatal(FARGS, "Trying to make impossible special bond (%s-%s)!",
- bond.firstAtom.c_str(), bond.secondAtom.c_str());
+ gmx_fatal(FARGS,
+ "Trying to make impossible special bond (%s-%s)!",
+ bond.firstAtom.c_str(),
+ bond.secondAtom.c_str());
}
add_param(ps, ai, aj, {}, nullptr);
}
{
GMX_LOG(logger.warning)
.asParagraph()
- .appendTextFormatted("Long Bond (%d-%d = %g nm)", ai + 1, aj + 1,
- std::sqrt(dist2));
+ .appendTextFormatted(
+ "Long Bond (%d-%d = %g nm)", ai + 1, aj + 1, std::sqrt(dist2));
}
else if (dist2 < short_bond_dist2)
{
GMX_LOG(logger.warning)
.asParagraph()
- .appendTextFormatted("Short Bond (%d-%d = %g nm)", ai + 1, aj + 1,
- std::sqrt(dist2));
+ .appendTextFormatted(
+ "Short Bond (%d-%d = %g nm)", ai + 1, aj + 1, std::sqrt(dist2));
}
add_param(psb, ai, aj, {}, patch.s.c_str());
}
static void check_restp_types(const PreprocessResidue& r0, const PreprocessResidue& r1)
{
- check_restp_type("all dihedrals", static_cast<int>(r0.bKeepAllGeneratedDihedrals),
+ check_restp_type("all dihedrals",
+ static_cast<int>(r0.bKeepAllGeneratedDihedrals),
static_cast<int>(r1.bKeepAllGeneratedDihedrals));
check_restp_type("nrexcl", r0.nrexcl, r1.nrexcl);
- check_restp_type("HH14", static_cast<int>(r0.bGenerateHH14Interactions),
+ check_restp_type("HH14",
+ static_cast<int>(r0.bGenerateHH14Interactions),
static_cast<int>(r1.bGenerateHH14Interactions));
- check_restp_type("remove dihedrals", static_cast<int>(r0.bRemoveDihedralIfWithImproper),
+ check_restp_type("remove dihedrals",
+ static_cast<int>(r0.bRemoveDihedralIfWithImproper),
static_cast<int>(r1.bRemoveDihedralIfWithImproper));
for (int i = 0; i < ebtsNR; i++)
if (patch->nr != 0)
{
/* find atom in restp */
- auto found = std::find_if(posres->atomname.begin(), posres->atomname.end(),
- [&patch](char** name) {
- return (patch->oname.empty() && patch->a[0] == *name)
- || (patch->oname == *name);
- });
+ auto found = std::find_if(
+ posres->atomname.begin(), posres->atomname.end(), [&patch](char** name) {
+ return (patch->oname.empty() && patch->a[0] == *name)
+ || (patch->oname == *name);
+ });
if (found == posres->atomname.end())
{
"atom %s not found in buiding block %d%s "
"while combining tdb and rtp",
patch->oname.empty() ? patch->a[0].c_str() : patch->oname.c_str(),
- pos + 1, *resinfo[pos].rtp);
+ pos + 1,
+ *resinfo[pos].rtp);
}
}
else
/* This atom still has the old name, rename it */
std::string newnm = patch->nname;
auto found = std::find_if(
- localPpResidue->atomname.begin(), localPpResidue->atomname.end(),
+ localPpResidue->atomname.begin(),
+ localPpResidue->atomname.end(),
[&newnm](char** name) { return gmx::equalCaseInsensitive(newnm, *name); });
if (found == localPpResidue->atomname.end())
{
*/
bool bFoundInAdd = false;
for (auto rtpModification = singlePatch.hack.begin();
- rtpModification != singlePatch.hack.end(); rtpModification++)
+ rtpModification != singlePatch.hack.end();
+ rtpModification++)
{
int k = std::distance(localPpResidue->atomname.begin(), found);
std::string start_at;
}
else
{
- start_at = gmx::formatString("%s%d", singlePatch.hack[k].nname.c_str(),
- anmnr - 1);
+ start_at = gmx::formatString(
+ "%s%d", singlePatch.hack[k].nname.c_str(), anmnr - 1);
}
- auto found2 =
- std::find_if(localPpResidue->atomname.begin(),
- localPpResidue->atomname.end(), [&start_at](char** name) {
- return gmx::equalCaseInsensitive(start_at, *name);
- });
+ auto found2 = std::find_if(localPpResidue->atomname.begin(),
+ localPpResidue->atomname.end(),
+ [&start_at](char** name) {
+ return gmx::equalCaseInsensitive(start_at, *name);
+ });
if (found2 == localPpResidue->atomname.end())
{
gmx_fatal(FARGS,
"Could not find atom '%s' in residue building block '%s' to "
"add atom '%s' to",
- start_at.c_str(), localPpResidue->resname.c_str(), newnm.c_str());
+ start_at.c_str(),
+ localPpResidue->resname.c_str(),
+ newnm.c_str());
}
/* We can add the atom after atom start_nr */
- add_atom_to_restp(localPpResidue, symtab,
+ add_atom_to_restp(localPpResidue,
+ symtab,
std::distance(localPpResidue->atomname.begin(), found2),
&(*patch));
"Could not find an 'add' entry for atom named '%s' corresponding to "
"the 'replace' entry from atom name '%s' to '%s' for tdb or hdb "
"database of residue type '%s'",
- newnm.c_str(), patch->oname.c_str(), patch->nname.c_str(),
+ newnm.c_str(),
+ patch->oname.c_str(),
+ patch->nname.c_str(),
localPpResidue->resname.c_str());
}
}
{
GMX_LOG(logger.info)
.asParagraph()
- .appendTextFormatted("Renaming atom '%s' in residue '%s' %d to '%s'", oldnm,
- localPpResidue->resname.c_str(), resnr, newnm.c_str());
+ .appendTextFormatted("Renaming atom '%s' in residue '%s' %d to '%s'",
+ oldnm,
+ localPpResidue->resname.c_str(),
+ resnr,
+ newnm.c_str());
}
/* Rename the atom in pdba */
pdba->atomname[atind] = put_symtab(symtab, newnm.c_str());
* in the rtp entry of this residue.
*/
auto found3 = std::find_if(
- localPpResidue->atomname.begin(), localPpResidue->atomname.end(),
+ localPpResidue->atomname.begin(),
+ localPpResidue->atomname.end(),
[&oldnm](char** name) { return gmx::equalCaseInsensitive(oldnm, *name); });
if (found3 == localPpResidue->atomname.end())
{
{
GMX_LOG(logger.info)
.asParagraph()
- .appendTextFormatted("Deleting atom '%s' in residue '%s' %d", oldnm,
- localPpResidue->resname.c_str(), resnr);
+ .appendTextFormatted("Deleting atom '%s' in residue '%s' %d",
+ oldnm,
+ localPpResidue->resname.c_str(),
+ resnr);
}
/* We should free the atom name,
* but it might be used multiple times in the symtab.
const char* oldnm = *pdba->atomname[i];
PreprocessResidue* localPpResidue = &usedPpResidues[pdba->atom[i].resind];
auto found = std::find_if(
- localPpResidue->atomname.begin(), localPpResidue->atomname.end(),
- [&oldnm](char** name) { return gmx::equalCaseInsensitive(oldnm, *name); });
+ localPpResidue->atomname.begin(), localPpResidue->atomname.end(), [&oldnm](char** name) {
+ return gmx::equalCaseInsensitive(oldnm, *name);
+ });
if (found == localPpResidue->atomname.end())
{
/* Not found yet, check if we have to rename this atom */
- if (match_atomnames_with_rtp_atom(pdba, x, symtab, i, localPpResidue,
- globalPatches[pdba->atom[i].resind], bVerbose, logger))
+ if (match_atomnames_with_rtp_atom(
+ pdba, x, symtab, i, localPpResidue, globalPatches[pdba->atom[i].resind], bVerbose, logger))
{
/* We deleted this atom, decrease the atom counter by 1. */
i--;
if (bAddCMAP)
{
- add_cmap_param(psb, cmap_atomid[0], cmap_atomid[1], cmap_atomid[2], cmap_atomid[3],
- cmap_atomid[4], b.s.c_str());
+ add_cmap_param(psb,
+ cmap_atomid[0],
+ cmap_atomid[1],
+ cmap_atomid[2],
+ cmap_atomid[3],
+ cmap_atomid[4],
+ b.s.c_str());
}
}
ResidueType rt;
/* Make bonds */
- at2bonds(&(plist[F_BONDS]), globalPatches, atoms, *x, long_bond_dist, short_bond_dist,
- cyclicBondsIndex, logger);
+ at2bonds(&(plist[F_BONDS]), globalPatches, atoms, *x, long_bond_dist, short_bond_dist, cyclicBondsIndex, logger);
/* specbonds: disulphide bonds & heme-his */
do_ssbonds(&(plist[F_BONDS]), atoms, ssbonds, bAllowMissing);
gmx_fatal(FARGS,
"There were %d missing atoms in molecule %s, if you want to use this "
"incomplete topology anyhow, use the option -missing",
- nmissat, molname);
+ nmissat,
+ molname);
}
}
.appendTextFormatted(
"There are %4zu dihedrals, %4zu impropers, %4zu angles\n"
" %4zu pairs, %4zu bonds and %4zu virtual sites",
- plist[F_PDIHS].size(), plist[F_IDIHS].size(), plist[F_ANGLES].size(),
- plist[F_LJ14].size(), plist[F_BONDS].size(),
+ plist[F_PDIHS].size(),
+ plist[F_IDIHS].size(),
+ plist[F_ANGLES].size(),
+ plist[F_LJ14].size(),
+ plist[F_BONDS].size(),
plist[F_VSITE2].size() + plist[F_VSITE3].size() + plist[F_VSITE3FD].size()
+ plist[F_VSITE3FAD].size() + plist[F_VSITE3OUT].size()
+ plist[F_VSITE4FD].size() + plist[F_VSITE4FDN].size());
{
bts[i] = usedPpResidues[0].rb[i].type;
}
- write_top(top_file, posre_fn, molname, atoms, bRTPresname, bts, plist, excls, atype, cgnr,
+ write_top(top_file,
+ posre_fn,
+ molname,
+ atoms,
+ bRTPresname,
+ bts,
+ plist,
+ excls,
+ atype,
+ cgnr,
usedPpResidues[0].nrexcl);
}
{
if (0 != strcmp(bondtype, "atom"))
{
- snprintf(message_buffer, 1024,
+ snprintf(message_buffer,
+ 1024,
"Residue %d named %s of a molecule in the input file was mapped\n"
"to an entry in the topology database, but the atom %s used in\n"
"an interaction of type %s in that entry is not found in the\n"
"input file. Perhaps your atom and/or residue naming needs to be\n"
"fixed.\n",
- resind + 1, resname, atomname, bondtype);
+ resind + 1,
+ resname,
+ atomname,
+ bondtype);
}
else
{
- snprintf(message_buffer, 1024,
+ snprintf(message_buffer,
+ 1024,
"Residue %d named %s of a molecule in the input file was mapped\n"
"to an entry in the topology database, but the atom %s used in\n"
"that entry is not found in the input file. Perhaps your atom\n"
"and/or residue naming needs to be fixed.\n",
- resind + 1, resname, atomname);
+ resind + 1,
+ resname,
+ atomname);
}
if (bAllowMissing)
{
}
if (!(bNext && at[start].resind == at[natoms - 1].resind))
{
- atom_not_found(FARGS, type, at[start].resind, *atoms->resinfo[resind].name, bondtype,
- bAllowMissing);
+ atom_not_found(FARGS, type, at[start].resind, *atoms->resinfo[resind].name, bondtype, bAllowMissing);
}
}
else
}
if (start > 0)
{
- atom_not_found(FARGS, type, at[start].resind, *atoms->resinfo[resind].name, bondtype,
- bAllowMissing);
+ atom_not_found(FARGS, type, at[start].resind, *atoms->resinfo[resind].name, bondtype, bAllowMissing);
}
}
return -1;
#include <algorithm>
#include <memory>
+#include <numeric>
#include <string>
#include "gromacs/applied_forces/awh/read_params.h"
struct gmx_inputrec_strings
{
- char tcgrps[STRLEN], tau_t[STRLEN], ref_t[STRLEN], acc[STRLEN], accgrps[STRLEN], freeze[STRLEN],
- frdim[STRLEN], energy[STRLEN], user1[STRLEN], user2[STRLEN], vcm[STRLEN],
- x_compressed_groups[STRLEN], couple_moltype[STRLEN], orirefitgrp[STRLEN],
- egptable[STRLEN], egpexcl[STRLEN], wall_atomtype[STRLEN], wall_density[STRLEN],
- deform[STRLEN], QMMM[STRLEN], imd_grp[STRLEN];
+ char tcgrps[STRLEN], tau_t[STRLEN], ref_t[STRLEN], freeze[STRLEN], frdim[STRLEN],
+ energy[STRLEN], user1[STRLEN], user2[STRLEN], vcm[STRLEN], x_compressed_groups[STRLEN],
+ couple_moltype[STRLEN], orirefitgrp[STRLEN], egptable[STRLEN], egpexcl[STRLEN],
+ wall_atomtype[STRLEN], wall_density[STRLEN], deform[STRLEN], QMMM[STRLEN], imd_grp[STRLEN];
char fep_lambda[efptNR][STRLEN];
char lambda_weights[STRLEN];
std::vector<std::string> pullGroupNames;
}
}
-static int lcd(int n1, int n2)
-{
- int d, i;
-
- d = 1;
- for (i = 2; (i <= n1 && i <= n2); i++)
- {
- if (n1 % i == 0 && n2 % i == 0)
- {
- d = i;
- }
- }
-
- return d;
-}
-
//! Convert legacy mdp entries to modern ones.
static void process_interaction_modifier(int* eintmod)
{
}
}
-static void checkMtsRequirement(const t_inputrec& ir, const char* param, const int nstValue, warninp_t wi)
-{
- GMX_RELEASE_ASSERT(ir.mtsLevels.size() >= 2, "Need at least two levels for MTS");
- const int mtsFactor = ir.mtsLevels.back().stepFactor;
- if (nstValue % mtsFactor != 0)
- {
- auto message = gmx::formatString(
- "With MTS, %s = %d should be a multiple of mts-factor = %d", param, nstValue, mtsFactor);
- warning_error(wi, message.c_str());
- }
-}
-
-static void setupMtsLevels(gmx::ArrayRef<gmx::MtsLevel> mtsLevels,
- const t_inputrec& ir,
- const t_gromppopts& opts,
- warninp_t wi)
-{
- /* MD-VV has no MTS support yet.
- * SD1 needs different scaling coefficients for the different MTS forces
- * and the different forces are currently not available in ForceBuffers.
- */
- if (ir.eI != eiMD)
- {
- auto message = gmx::formatString(
- "Multiple time stepping is only supported with integrator %s", ei_names[eiMD]);
- warning_error(wi, message.c_str());
- }
- if (opts.numMtsLevels != 2)
- {
- warning_error(wi, "Only mts-levels = 2 is supported");
- }
- else
- {
- const std::vector<std::string> inputForceGroups = gmx::splitString(opts.mtsLevel2Forces);
- auto& forceGroups = mtsLevels[1].forceGroups;
- for (const auto& inputForceGroup : inputForceGroups)
- {
- bool found = false;
- int nameIndex = 0;
- for (const auto& forceGroupName : gmx::mtsForceGroupNames)
- {
- if (gmx::equalCaseInsensitive(inputForceGroup, forceGroupName))
- {
- forceGroups.set(nameIndex);
- found = true;
- }
- nameIndex++;
- }
- if (!found)
- {
- auto message =
- gmx::formatString("Unknown MTS force group '%s'", inputForceGroup.c_str());
- warning_error(wi, message.c_str());
- }
- }
-
- if (mtsLevels[1].stepFactor <= 1)
- {
- gmx_fatal(FARGS, "mts-factor should be larger than 1");
- }
-
- // Make the level 0 use the complement of the force groups of group 1
- mtsLevels[0].forceGroups = ~mtsLevels[1].forceGroups;
- mtsLevels[0].stepFactor = 1;
-
- if ((EEL_FULL(ir.coulombtype) || EVDW_PME(ir.vdwtype))
- && !mtsLevels[1].forceGroups[static_cast<int>(gmx::MtsForceGroups::LongrangeNonbonded)])
- {
- warning_error(wi,
- "With long-range electrostatics and/or LJ treatment, the long-range part "
- "has to be part of the mts-level2-forces");
- }
-
- if (ir.nstcalcenergy > 0)
- {
- checkMtsRequirement(ir, "nstcalcenergy", ir.nstcalcenergy, wi);
- }
- checkMtsRequirement(ir, "nstenergy", ir.nstenergy, wi);
- checkMtsRequirement(ir, "nstlog", ir.nstlog, wi);
- if (ir.efep != efepNO)
- {
- checkMtsRequirement(ir, "nstdhdl", ir.fepvals->nstdhdl, wi);
- }
-
- if (ir.bPull)
- {
- const int pullMtsLevel = gmx::forceGroupMtsLevel(ir.mtsLevels, gmx::MtsForceGroups::Pull);
- if (ir.pull->nstxout % ir.mtsLevels[pullMtsLevel].stepFactor != 0)
- {
- warning_error(wi, "pull-nstxout should be a multiple of mts-factor");
- }
- if (ir.pull->nstfout % ir.mtsLevels[pullMtsLevel].stepFactor != 0)
- {
- warning_error(wi, "pull-nstfout should be a multiple of mts-factor");
- }
- }
- }
-}
-
void check_ir(const char* mdparin,
const gmx::MdModulesNotifier& mdModulesNotifier,
t_inputrec* ir,
set_warning_line(wi, mdparin, -1);
+ /* We cannot check MTS requirements with an invalid MTS setup
+ * and we will already have generated errors with an invalid MTS setup.
+ */
+ if (gmx::haveValidMtsSetup(*ir))
+ {
+ std::vector<std::string> errorMessages = gmx::checkMtsRequirements(*ir);
+
+ for (const auto& errorMessage : errorMessages)
+ {
+ warning_error(wi, errorMessage.c_str());
+ }
+ }
+
if (ir->coulombtype == eelRF_NEC_UNSUPPORTED)
{
sprintf(warn_buf, "%s electrostatics is no longer supported", eel_names[eelRF_NEC_UNSUPPORTED]);
sprintf(warn_buf,
"Replacing vdwtype=%s by the equivalent combination of vdwtype=%s and "
"vdw_modifier=%s",
- evdw_names[ir->vdwtype], evdw_names[evdwCUT], eintmod_names[ir->vdw_modifier]);
+ evdw_names[ir->vdwtype],
+ evdw_names[evdwCUT],
+ eintmod_names[ir->vdw_modifier]);
warning_note(wi, warn_buf);
ir->vdwtype = evdwCUT;
}
else
{
- sprintf(warn_buf, "Unsupported combination of vdwtype=%s and vdw_modifier=%s",
- evdw_names[ir->vdwtype], eintmod_names[ir->vdw_modifier]);
+ sprintf(warn_buf,
+ "Unsupported combination of vdwtype=%s and vdw_modifier=%s",
+ evdw_names[ir->vdwtype],
+ eintmod_names[ir->vdw_modifier]);
warning_error(wi, warn_buf);
}
}
if (EEL_USER(ir->coulombtype))
{
- sprintf(warn_buf, "Coulomb type %s is not supported with the verlet scheme",
+ sprintf(warn_buf,
+ "Coulomb type %s is not supported with the verlet scheme",
eel_names[ir->coulombtype]);
warning_error(wi, warn_buf);
}
/* GENERAL INTEGRATOR STUFF */
if (!EI_MD(ir->eI))
{
- if (ir->etc != etcNO)
+ if (ir->etc != TemperatureCoupling::No)
{
if (EI_RANDOM(ir->eI))
{
"Setting tcoupl from '%s' to 'no'. %s handles temperature coupling "
"implicitly. See the documentation for more information on which "
"parameters affect temperature for %s.",
- etcoupl_names[ir->etc], ei_names[ir->eI], ei_names[ir->eI]);
+ enumValueToString(ir->etc),
+ ei_names[ir->eI],
+ ei_names[ir->eI]);
}
else
{
sprintf(warn_buf,
"Setting tcoupl from '%s' to 'no'. Temperature coupling does not apply to "
"%s.",
- etcoupl_names[ir->etc], ei_names[ir->eI]);
+ enumValueToString(ir->etc),
+ ei_names[ir->eI]);
}
warning_note(wi, warn_buf);
}
- ir->etc = etcNO;
+ ir->etc = TemperatureCoupling::No;
}
if (ir->eI == eiVVAK)
{
sprintf(warn_buf,
"Integrator method %s is implemented primarily for validation purposes; for "
"molecular dynamics, you should probably be using %s or %s",
- ei_names[eiVVAK], ei_names[eiMD], ei_names[eiVV]);
+ ei_names[eiVVAK],
+ ei_names[eiMD],
+ ei_names[eiVV]);
warning_note(wi, warn_buf);
}
if (!EI_DYNAMICS(ir->eI))
{
- if (ir->epc != epcNO)
+ if (ir->epc != PressureCoupling::No)
{
sprintf(warn_buf,
"Setting pcoupl from '%s' to 'no'. Pressure coupling does not apply to %s.",
- epcoupl_names[ir->epc], ei_names[ir->eI]);
+ enumValueToString(ir->epc),
+ ei_names[ir->eI]);
warning_note(wi, warn_buf);
}
- ir->epc = epcNO;
+ ir->epc = PressureCoupling::No;
}
if (EI_DYNAMICS(ir->eI))
{
*/
if (ir->nstlist > 0)
{
- ir->nstcalcenergy = lcd(ir->nstenergy, ir->nstlist);
+ ir->nstcalcenergy = std::gcd(ir->nstenergy, ir->nstlist);
}
else
{
min_name = nstdh;
}
/* If the user sets nstenergy small, we should respect that */
- sprintf(warn_buf, "Setting nstcalcenergy (%d) equal to %s (%d)", ir->nstcalcenergy,
- min_name, min_nst);
+ sprintf(warn_buf, "Setting nstcalcenergy (%d) equal to %s (%d)", ir->nstcalcenergy, min_name, min_nst);
warning_note(wi, warn_buf);
ir->nstcalcenergy = min_nst;
}
- if (ir->epc != epcNO)
+ if (ir->epc != PressureCoupling::No)
{
if (ir->nstpcouple < 0)
{
if (ir->bExpanded)
{
/* nstexpanded should be a multiple of nstcalcenergy */
- check_nst("nstcalcenergy", ir->nstcalcenergy, "nstexpanded",
- &ir->expandedvals->nstexpanded, wi);
+ check_nst("nstcalcenergy", ir->nstcalcenergy, "nstexpanded", &ir->expandedvals->nstexpanded, wi);
}
/* for storing exact averages nstenergy should be
* a multiple of nstcalcenergy
bool bAllTempZero = TRUE;
for (i = 0; i < fep->n_lambda; i++)
{
- sprintf(err_buf, "Entry %d for %s must be between 0 and 1, instead is %g", i,
- efpt_names[efptTEMPERATURE], fep->all_lambda[efptTEMPERATURE][i]);
+ sprintf(err_buf,
+ "Entry %d for %s must be between 0 and 1, instead is %g",
+ i,
+ efpt_names[efptTEMPERATURE],
+ fep->all_lambda[efptTEMPERATURE][i]);
CHECK((fep->all_lambda[efptTEMPERATURE][i] < 0) || (fep->all_lambda[efptTEMPERATURE][i] > 1));
if (fep->all_lambda[efptTEMPERATURE][i] > 0)
{
/* check compatability of the temperature coupling with simulated tempering */
- if (ir->etc == etcNOSEHOOVER)
+ if (ir->etc == TemperatureCoupling::NoseHoover)
{
sprintf(warn_buf,
"Nose-Hoover based temperature control such as [%s] my not be "
"entirelyconsistent with simulated tempering",
- etcoupl_names[ir->etc]);
+ enumValueToString(ir->etc));
warning_note(wi, warn_buf);
}
sprintf(err_buf,
"Higher simulated tempering temperature (%g) must be >= than the simulated "
"tempering lower temperature (%g)",
- ir->simtempvals->simtemp_high, ir->simtempvals->simtemp_low);
+ ir->simtempvals->simtemp_high,
+ ir->simtempvals->simtemp_low);
CHECK(ir->simtempvals->simtemp_high <= ir->simtempvals->simtemp_low);
- sprintf(err_buf, "Higher simulated tempering temperature (%g) must be >= zero",
+ sprintf(err_buf,
+ "Higher simulated tempering temperature (%g) must be >= zero",
ir->simtempvals->simtemp_high);
CHECK(ir->simtempvals->simtemp_high <= 0);
- sprintf(err_buf, "Lower simulated tempering temperature (%g) must be >= zero",
+ sprintf(err_buf,
+ "Lower simulated tempering temperature (%g) must be >= zero",
ir->simtempvals->simtemp_low);
CHECK(ir->simtempvals->simtemp_low <= 0);
}
fep->delta_lambda);
CHECK(fep->delta_lambda > 0 && ((fep->init_fep_state > 0) || (fep->init_lambda > 0)));
- sprintf(err_buf, "Can't use positive delta-lambda (%g) with expanded ensemble simulations",
+ sprintf(err_buf,
+ "Can't use positive delta-lambda (%g) with expanded ensemble simulations",
fep->delta_lambda);
CHECK(fep->delta_lambda > 0 && (ir->efep == efepEXPANDED));
if (fep->n_lambda == 0)
{
/* Clear output in case of no states:*/
- sprintf(err_buf, "init-lambda-state set to %d: no lambda states are defined.",
- fep->init_fep_state);
+ sprintf(err_buf, "init-lambda-state set to %d: no lambda states are defined.", fep->init_fep_state);
CHECK((fep->init_fep_state >= 0) && (fep->n_lambda == 0));
}
else
{
- sprintf(err_buf, "initial thermodynamic state %d does not exist, only goes to %d",
- fep->init_fep_state, fep->n_lambda - 1);
+ sprintf(err_buf,
+ "initial thermodynamic state %d does not exist, only goes to %d",
+ fep->init_fep_state,
+ fep->n_lambda - 1);
CHECK((fep->init_fep_state >= fep->n_lambda));
}
sprintf(err_buf,
"init-lambda=%g while init-lambda-state=%d. Lambda state must be set either with "
"init-lambda-state or with init-lambda, but not both",
- fep->init_lambda, fep->init_fep_state);
+ fep->init_lambda,
+ fep->init_fep_state);
CHECK((fep->init_fep_state >= 0) && (fep->init_lambda >= 0));
{
for (i = 0; i < fep->n_lambda; i++)
{
- sprintf(err_buf, "Entry %d for %s must be between 0 and 1, instead is %g", i,
- efpt_names[j], fep->all_lambda[j][i]);
+ sprintf(err_buf,
+ "Entry %d for %s must be between 0 and 1, instead is %g",
+ i,
+ efpt_names[j],
+ fep->all_lambda[j][i]);
CHECK((fep->all_lambda[j][i] < 0) || (fep->all_lambda[j][i] > 1));
}
}
"For state %d, vdw-lambdas (%f) is changing with vdw softcore, while "
"coul-lambdas (%f) is nonzero without coulomb softcore: this will lead to "
"crashes, and is not supported.",
- i, fep->all_lambda[efptVDW][i], fep->all_lambda[efptCOUL][i]);
+ i,
+ fep->all_lambda[efptVDW][i],
+ fep->all_lambda[efptCOUL][i]);
CHECK((fep->sc_alpha > 0)
&& (((fep->all_lambda[efptCOUL][i] > 0.0) && (fep->all_lambda[efptCOUL][i] < 1.0))
&& ((fep->all_lambda[efptVDW][i] > 0.0) && (fep->all_lambda[efptVDW][i] < 1.0))));
"energy conservation, but usually other effects dominate. With a common sigma "
"value of %g nm the fraction of the particle-particle potential at the cut-off "
"at lambda=%g is around %.1e, while ewald-rtol is %.1e.",
- fep->sc_r_power, sigma, lambda, r_sc - 1.0, ir->ewald_rtol);
+ fep->sc_r_power,
+ sigma,
+ lambda,
+ r_sc - 1.0,
+ ir->ewald_rtol);
warning_note(wi, warn_buf);
}
sprintf(err_buf,
"weight-equil-number-all-lambda (%d) is ignored if lmc-weights-equil is not equal "
"to %s",
- expand->equil_n_at_lam, elmceq_names[elmceqNUMATLAM]);
+ expand->equil_n_at_lam,
+ elmceq_names[elmceqNUMATLAM]);
CHECK((expand->equil_n_at_lam > 0) && (expand->elmceq != elmceqNUMATLAM));
sprintf(err_buf,
"weight-equil-number-samples (%d) is ignored if lmc-weights-equil is not equal to "
"%s",
- expand->equil_samples, elmceq_names[elmceqSAMPLES]);
+ expand->equil_samples,
+ elmceq_names[elmceqSAMPLES]);
CHECK((expand->equil_samples > 0) && (expand->elmceq != elmceqSAMPLES));
sprintf(err_buf,
"weight-equil-number-steps (%d) is ignored if lmc-weights-equil is not equal to %s",
- expand->equil_steps, elmceq_names[elmceqSTEPS]);
+ expand->equil_steps,
+ elmceq_names[elmceqSTEPS]);
CHECK((expand->equil_steps > 0) && (expand->elmceq != elmceqSTEPS));
sprintf(err_buf,
"weight-equil-wl-delta (%d) is ignored if lmc-weights-equil is not equal to %s",
- expand->equil_samples, elmceq_names[elmceqWLDELTA]);
+ expand->equil_samples,
+ elmceq_names[elmceqWLDELTA]);
CHECK((expand->equil_wl_delta > 0) && (expand->elmceq != elmceqWLDELTA));
sprintf(err_buf,
"weight-equil-count-ratio (%f) is ignored if lmc-weights-equil is not equal to %s",
- expand->equil_ratio, elmceq_names[elmceqRATIO]);
+ expand->equil_ratio,
+ elmceq_names[elmceqRATIO]);
CHECK((expand->equil_ratio > 0) && (expand->elmceq != elmceqRATIO));
sprintf(err_buf,
"weight-equil-number-all-lambda (%d) must be a positive integer if "
"lmc-weights-equil=%s",
- expand->equil_n_at_lam, elmceq_names[elmceqNUMATLAM]);
+ expand->equil_n_at_lam,
+ elmceq_names[elmceqNUMATLAM]);
CHECK((expand->equil_n_at_lam <= 0) && (expand->elmceq == elmceqNUMATLAM));
sprintf(err_buf,
"weight-equil-number-samples (%d) must be a positive integer if "
"lmc-weights-equil=%s",
- expand->equil_samples, elmceq_names[elmceqSAMPLES]);
+ expand->equil_samples,
+ elmceq_names[elmceqSAMPLES]);
CHECK((expand->equil_samples <= 0) && (expand->elmceq == elmceqSAMPLES));
sprintf(err_buf,
"weight-equil-number-steps (%d) must be a positive integer if lmc-weights-equil=%s",
- expand->equil_steps, elmceq_names[elmceqSTEPS]);
+ expand->equil_steps,
+ elmceq_names[elmceqSTEPS]);
CHECK((expand->equil_steps <= 0) && (expand->elmceq == elmceqSTEPS));
- sprintf(err_buf, "weight-equil-wl-delta (%f) must be > 0 if lmc-weights-equil=%s",
- expand->equil_wl_delta, elmceq_names[elmceqWLDELTA]);
+ sprintf(err_buf,
+ "weight-equil-wl-delta (%f) must be > 0 if lmc-weights-equil=%s",
+ expand->equil_wl_delta,
+ elmceq_names[elmceqWLDELTA]);
CHECK((expand->equil_wl_delta <= 0) && (expand->elmceq == elmceqWLDELTA));
- sprintf(err_buf, "weight-equil-count-ratio (%f) must be > 0 if lmc-weights-equil=%s",
- expand->equil_ratio, elmceq_names[elmceqRATIO]);
+ sprintf(err_buf,
+ "weight-equil-count-ratio (%f) must be > 0 if lmc-weights-equil=%s",
+ expand->equil_ratio,
+ elmceq_names[elmceqRATIO]);
CHECK((expand->equil_ratio <= 0) && (expand->elmceq == elmceqRATIO));
- sprintf(err_buf, "lmc-weights-equil=%s only possible when lmc-stats = %s or lmc-stats %s",
- elmceq_names[elmceqWLDELTA], elamstats_names[elamstatsWL], elamstats_names[elamstatsWWL]);
+ sprintf(err_buf,
+ "lmc-weights-equil=%s only possible when lmc-stats = %s or lmc-stats %s",
+ elmceq_names[elmceqWLDELTA],
+ elamstats_names[elamstatsWL],
+ elamstats_names[elamstatsWWL]);
CHECK((expand->elmceq == elmceqWLDELTA) && (!EWL(expand->elamstats)));
sprintf(err_buf, "lmc-repeats (%d) must be greater than 0", expand->lmc_repeats);
sprintf(err_buf,
"init-lambda-state (%d) must be zero if lmc-forced-nstart (%d)> 0 and lmc-move != "
"'no'",
- fep->init_fep_state, expand->lmc_forced_nstart);
+ fep->init_fep_state,
+ expand->lmc_forced_nstart);
CHECK((fep->init_fep_state != 0) && (expand->lmc_forced_nstart > 0)
&& (expand->elmcmove != elmcmoveNO));
sprintf(err_buf, "lmc-forced-nstart (%d) must not be negative", expand->lmc_forced_nstart);
CHECK((expand->lmc_forced_nstart < 0));
- sprintf(err_buf, "init-lambda-state (%d) must be in the interval [0,number of lambdas)",
+ sprintf(err_buf,
+ "init-lambda-state (%d) must be in the interval [0,number of lambdas)",
fep->init_fep_state);
CHECK((fep->init_fep_state < 0) || (fep->init_fep_state >= fep->n_lambda));
{
sprintf(err_buf,
"nst-transition-matrix (%d) must be an integer multiple of nstlog (%d)",
- expand->nstTij, ir->nstlog);
+ expand->nstTij,
+ ir->nstlog);
CHECK((expand->nstTij % ir->nstlog) != 0);
}
}
{
if (ir->pbcType == PbcType::No)
{
- if (ir->epc != epcNO)
+ if (ir->epc != PressureCoupling::No)
{
warning(wi, "Turning off pressure coupling for vacuum system");
- ir->epc = epcNO;
+ ir->epc = PressureCoupling::No;
}
}
else
{
- sprintf(err_buf, "Can not have pressure coupling with pbc=%s",
+ sprintf(err_buf,
+ "Can not have pressure coupling with pbc=%s",
c_pbcTypeNames[ir->pbcType].c_str());
- CHECK(ir->epc != epcNO);
+ CHECK(ir->epc != PressureCoupling::No);
}
sprintf(err_buf, "Can not have Ewald with pbc=%s", c_pbcTypeNames[ir->pbcType].c_str());
CHECK(EEL_FULL(ir->coulombtype));
- sprintf(err_buf, "Can not have dispersion correction with pbc=%s",
+ sprintf(err_buf,
+ "Can not have dispersion correction with pbc=%s",
c_pbcTypeNames[ir->pbcType].c_str());
CHECK(ir->eDispCorr != edispcNO);
}
"with coulombtype = %s or coulombtype = %s\n"
"without periodic boundary conditions (pbc = %s) and\n"
"rcoulomb and rvdw set to zero",
- eel_names[eelCUT], eel_names[eelUSER], c_pbcTypeNames[PbcType::No].c_str());
+ eel_names[eelCUT],
+ eel_names[eelUSER],
+ c_pbcTypeNames[PbcType::No].c_str());
CHECK(((ir->coulombtype != eelCUT) && (ir->coulombtype != eelUSER))
|| (ir->pbcType != PbcType::No) || (ir->rcoulomb != 0.0) || (ir->rvdw != 0.0));
}
/* TEMPERATURE COUPLING */
- if (ir->etc == etcYES)
+ if (ir->etc == TemperatureCoupling::Yes)
{
- ir->etc = etcBERENDSEN;
+ ir->etc = TemperatureCoupling::Berendsen;
warning_note(wi,
"Old option for temperature coupling given: "
"changing \"yes\" to \"Berendsen\"\n");
}
- if ((ir->etc == etcNOSEHOOVER) || (ir->epc == epcMTTK))
+ if ((ir->etc == TemperatureCoupling::NoseHoover) || (ir->epc == PressureCoupling::Mttk))
{
if (ir->opts.nhchainlength < 1)
{
warning(wi, warn_buf);
}
- if (ir->etc == etcNOSEHOOVER && !EI_VV(ir->eI) && ir->opts.nhchainlength > 1)
+ if (ir->etc == TemperatureCoupling::NoseHoover && !EI_VV(ir->eI) && ir->opts.nhchainlength > 1)
{
warning_note(
wi,
if (ETC_ANDERSEN(ir->etc))
{
- sprintf(err_buf, "%s temperature control not supported for integrator %s.",
- etcoupl_names[ir->etc], ei_names[ir->eI]);
+ sprintf(err_buf,
+ "%s temperature control not supported for integrator %s.",
+ enumValueToString(ir->etc),
+ ei_names[ir->eI]);
CHECK(!(EI_VV(ir->eI)));
- if (ir->nstcomm > 0 && (ir->etc == etcANDERSEN))
+ if (ir->nstcomm > 0 && (ir->etc == TemperatureCoupling::Andersen))
{
sprintf(warn_buf,
"Center of mass removal not necessary for %s. All velocities of coupled "
"groups are rerandomized periodically, so flying ice cube errors will not "
"occur.",
- etcoupl_names[ir->etc]);
+ enumValueToString(ir->etc));
warning_note(wi, warn_buf);
}
sprintf(err_buf,
"nstcomm must be 1, not %d for %s, as velocities of atoms in coupled groups are "
"randomized every time step",
- ir->nstcomm, etcoupl_names[ir->etc]);
- CHECK(ir->nstcomm > 1 && (ir->etc == etcANDERSEN));
+ ir->nstcomm,
+ enumValueToString(ir->etc));
+ CHECK(ir->nstcomm > 1 && (ir->etc == TemperatureCoupling::Andersen));
}
- if (ir->etc == etcBERENDSEN)
+ if (ir->etc == TemperatureCoupling::Berendsen)
{
sprintf(warn_buf,
"The %s thermostat does not generate the correct kinetic energy distribution. You "
"might want to consider using the %s thermostat.",
- ETCOUPLTYPE(ir->etc), ETCOUPLTYPE(etcVRESCALE));
+ enumValueToString(ir->etc),
+ enumValueToString(TemperatureCoupling::VRescale));
warning_note(wi, warn_buf);
}
- if ((ir->etc == etcNOSEHOOVER || ETC_ANDERSEN(ir->etc)) && ir->epc == epcBERENDSEN)
+ if ((ir->etc == TemperatureCoupling::NoseHoover || ETC_ANDERSEN(ir->etc))
+ && ir->epc == PressureCoupling::Berendsen)
{
sprintf(warn_buf,
"Using Berendsen pressure coupling invalidates the "
}
/* PRESSURE COUPLING */
- if (ir->epc == epcISOTROPIC)
+ if (ir->epc == PressureCoupling::Isotropic)
{
- ir->epc = epcBERENDSEN;
+ ir->epc = PressureCoupling::Berendsen;
warning_note(wi,
"Old option for pressure coupling given: "
"changing \"Isotropic\" to \"Berendsen\"\n");
}
- if (ir->epc != epcNO)
+ if (ir->epc != PressureCoupling::No)
{
dt_pcoupl = ir->nstpcouple * ir->delta_t;
sprintf(warn_buf,
"For proper integration of the %s barostat, tau-p (%g) should be at least %d "
"times larger than nstpcouple*dt (%g)",
- EPCOUPLTYPE(ir->epc), ir->tau_p, pcouple_min_integration_steps(ir->epc), dt_pcoupl);
+ enumValueToString(ir->epc),
+ ir->tau_p,
+ pcouple_min_integration_steps(ir->epc),
+ dt_pcoupl);
warning(wi, warn_buf);
}
sprintf(err_buf,
"compressibility must be > 0 when using pressure"
" coupling %s\n",
- EPCOUPLTYPE(ir->epc));
+ enumValueToString(ir->epc));
CHECK(ir->compress[XX][XX] < 0 || ir->compress[YY][YY] < 0 || ir->compress[ZZ][ZZ] < 0
|| (trace(ir->compress) == 0 && ir->compress[YY][XX] <= 0 && ir->compress[ZZ][XX] <= 0
&& ir->compress[ZZ][YY] <= 0));
- if (epcPARRINELLORAHMAN == ir->epc && opts->bGenVel)
+ if (PressureCoupling::ParrinelloRahman == ir->epc && opts->bGenVel)
{
sprintf(warn_buf,
"You are generating velocities so I am assuming you "
"equilibrating first with Berendsen pressure coupling. If "
"you are not equilibrating the system, you can probably "
"ignore this warning.",
- epcoupl_names[ir->epc]);
+ enumValueToString(ir->epc));
warning(wi, warn_buf);
}
}
if (!EI_VV(ir->eI))
{
- if (ir->epc == epcMTTK)
+ if (ir->epc == PressureCoupling::Mttk)
{
warning_error(wi, "MTTK pressure coupling requires a Velocity-verlet integrator");
}
sprintf(warn_buf,
"coulombtype = %s is only for testing purposes and can lead to serious "
"artifacts, advice: use coulombtype = %s",
- eel_names[ir->coulombtype], eel_names[eelRF_ZERO]);
+ eel_names[ir->coulombtype],
+ eel_names[eelRF_ZERO]);
warning(wi, warn_buf);
}
CHECK((ir->epsilon_rf < ir->epsilon_r && ir->epsilon_rf != 0) || (ir->epsilon_r == 0));
if (ir->epsilon_rf == ir->epsilon_r)
{
- sprintf(warn_buf, "Using epsilon-rf = epsilon-r with %s does not make sense",
+ sprintf(warn_buf,
+ "Using epsilon-rf = epsilon-r with %s does not make sense",
eel_names[ir->coulombtype]);
warning(wi, warn_buf);
}
"The switching range should be 5%% or less (currently %.2f%% using a switching "
"range of %4f-%4f) for accurate electrostatic energies, energy conservation "
"will be good regardless, since ewald_rtol = %g.",
- percentage, ir->rcoulomb_switch, ir->rcoulomb, ir->ewald_rtol);
+ percentage,
+ ir->rcoulomb_switch,
+ ir->rcoulomb,
+ ir->ewald_rtol);
warning(wi, warn_buf);
}
}
if (ir->coulombtype == eelPMESWITCH || ir->coulombtype == eelPMEUSER
|| ir->coulombtype == eelPMEUSERSWITCH)
{
- sprintf(err_buf, "With coulombtype = %s, rcoulomb must be <= rlist",
- eel_names[ir->coulombtype]);
+ sprintf(err_buf, "With coulombtype = %s, rcoulomb must be <= rlist", eel_names[ir->coulombtype]);
CHECK(ir->rcoulomb > ir->rlist);
}
}
if (ir->pme_order < orderMin || ir->pme_order > orderMax)
{
- sprintf(warn_buf, "With coulombtype = %s, you should have %d <= pme-order <= %d",
- eel_names[ir->coulombtype], orderMin, orderMax);
+ sprintf(warn_buf,
+ "With coulombtype = %s, you should have %d <= pme-order <= %d",
+ eel_names[ir->coulombtype],
+ orderMin,
+ orderMax);
warning_error(wi, warn_buf);
}
}
{
if (ir->ewald_geometry == eewg3D)
{
- sprintf(warn_buf, "With pbc=%s you should use ewald-geometry=%s",
- c_pbcTypeNames[ir->pbcType].c_str(), eewg_names[eewg3DC]);
+ sprintf(warn_buf,
+ "With pbc=%s you should use ewald-geometry=%s",
+ c_pbcTypeNames[ir->pbcType].c_str(),
+ eewg_names[eewg3DC]);
warning(wi, warn_buf);
}
/* This check avoids extra pbc coding for exclusion corrections */
}
if ((ir->ewald_geometry == eewg3DC) && (ir->pbcType != PbcType::XY) && EEL_FULL(ir->coulombtype))
{
- sprintf(warn_buf, "With %s and ewald_geometry = %s you should use pbc = %s",
- eel_names[ir->coulombtype], eewg_names[eewg3DC], c_pbcTypeNames[PbcType::XY].c_str());
+ sprintf(warn_buf,
+ "With %s and ewald_geometry = %s you should use pbc = %s",
+ eel_names[ir->coulombtype],
+ eewg_names[eewg3DC],
+ c_pbcTypeNames[PbcType::XY].c_str());
warning(wi, warn_buf);
}
if ((ir->epsilon_surface != 0) && EEL_FULL(ir->coulombtype))
"You are applying a switch function to vdw forces or potentials from %g to %g "
"nm, which is more than half the interaction range, whereas switch functions "
"are intended to act only close to the cut-off.",
- ir->rvdw_switch, ir->rvdw);
+ ir->rvdw_switch,
+ ir->rvdw);
warning_note(wi, warn_buf);
}
}
{
if (!(ir->vdw_modifier == eintmodNONE || ir->vdw_modifier == eintmodPOTSHIFT))
{
- sprintf(err_buf, "With vdwtype = %s, the only supported modifiers are %s and %s",
- evdw_names[ir->vdwtype], eintmod_names[eintmodPOTSHIFT], eintmod_names[eintmodNONE]);
+ sprintf(err_buf,
+ "With vdwtype = %s, the only supported modifiers are %s and %s",
+ evdw_names[ir->vdwtype],
+ eintmod_names[eintmodPOTSHIFT],
+ eintmod_names[eintmodNONE]);
warning_error(wi, err_buf);
}
}
{
gmx_fatal(FARGS, "AdResS simulations are no longer supported");
}
+
+ // cosine acceleration is only supported in leap-frog
+ if (ir->cos_accel != 0.0 && ir->eI != eiMD)
+ {
+ warning_error(wi, "cos-acceleration is only supported by integrator = md");
+ }
}
/* interpret a number of doubles from a string and put them in an array,
}
catch (gmx::GromacsException&)
{
- warning_error(wi, "Invalid value " + values[i]
- + " in string in mdp file. Expected a real number.");
+ warning_error(wi,
+ "Invalid value " + values[i]
+ + " in string in mdp file. Expected a real number.");
}
}
}
gmx_fatal(FARGS,
"Number of lambdas (%d) for FEP type %s not equal to number of other types "
"(%d)",
- nfep[i], efpt_names[i], max_n_lambda);
+ nfep[i],
+ efpt_names[i],
+ max_n_lambda);
}
}
/* we don't print out dhdl if the temperature is changing, since we can't correctly define dhdl in this case */
}
else if (nweights != fep->n_lambda)
{
- gmx_fatal(FARGS, "Number of weights (%d) is not equal to number of lambda values (%d)",
- nweights, fep->n_lambda);
+ gmx_fatal(FARGS,
+ "Number of weights (%d) is not equal to number of lambda values (%d)",
+ nweights,
+ fep->n_lambda);
}
if ((expand->nstexpanded < 0) && (ir->efep != efepNO))
{
auto message = gmx::formatString(
"Invalid value for mdp option %s. %s should only consist of integers separated "
"by spaces.",
- name, name);
+ name,
+ name);
warning_error(wi, message);
}
++i;
auto message = gmx::formatString(
"Invalid value for mdp option %s. %s should only consist of real numbers "
"separated by spaces.",
- name, name);
+ name,
+ name);
warning_error(wi, message);
}
++i;
}
}
-static void convertRvecs(warninp_t wi, gmx::ArrayRef<const std::string> inputs, const char* name, rvec* outputs)
-{
- int i = 0, d = 0;
- for (const auto& input : inputs)
- {
- try
- {
- outputs[i][d] = gmx::fromString<real>(input);
- }
- catch (gmx::GromacsException&)
- {
- auto message = gmx::formatString(
- "Invalid value for mdp option %s. %s should only consist of real numbers "
- "separated by spaces.",
- name, name);
- warning_error(wi, message);
- }
- ++d;
- if (d == DIM)
- {
- d = 0;
- ++i;
- }
- }
-}
-
static void do_wall_params(t_inputrec* ir, char* wall_atomtype, char* wall_density, t_gromppopts* opts, warninp_t wi)
{
opts->wall_atomtype[0] = nullptr;
auto wallAtomTypes = gmx::splitString(wall_atomtype);
if (wallAtomTypes.size() != size_t(ir->nwall))
{
- gmx_fatal(FARGS, "Expected %d elements for wall_atomtype, found %zu", ir->nwall,
+ gmx_fatal(FARGS,
+ "Expected %d elements for wall_atomtype, found %zu",
+ ir->nwall,
wallAtomTypes.size());
}
GMX_RELEASE_ASSERT(ir->nwall < 3, "Invalid number of walls");
auto wallDensity = gmx::splitString(wall_density);
if (wallDensity.size() != size_t(ir->nwall))
{
- gmx_fatal(FARGS, "Expected %d elements for wall-density, found %zu", ir->nwall,
+ gmx_fatal(FARGS,
+ "Expected %d elements for wall-density, found %zu",
+ ir->nwall,
wallDensity.size());
}
convertReals(wi, wallDensity, "wall-density", ir->wall_density);
expand->bWLoneovert = (get_eeenum(inp, "wl-oneovert", yesno_names, wi) != 0);
}
+template<typename EnumType>
+EnumType getEnum(std::vector<t_inpfile>* inp, const char* name, warninp_t wi)
+{
+ // If we there's no valid option, we'll use the first enum entry as default.
+ // Note, this assumes the enum is zero based, which is also assumed by
+ // EnumerationWrapper and EnumerationArray.
+ const auto defaultEnumValue = EnumType::Default;
+ const auto& defaultName = enumValueToString(defaultEnumValue);
+ // Get index of option in input
+ const auto ii = get_einp(inp, name);
+ if (ii == -1)
+ {
+ // If the option wasn't set, we use the first enum entry as default
+ inp->back().value_.assign(defaultName);
+ return defaultEnumValue;
+ }
+
+ // Check if option string can be mapped to a valid enum value
+ const auto* optionString = (*inp)[ii].value_.c_str();
+ for (auto enumValue : gmx::EnumerationWrapper<EnumType>{})
+ {
+ if (gmx_strcasecmp_min(enumValueToString(enumValue), optionString) == 0)
+ {
+ return enumValue;
+ }
+ }
+
+ // If we get here, the option set is invalid. Print error.
+ std::string errorMessage = gmx::formatString(
+ "Invalid enum '%s' for variable %s, using '%s'\n", optionString, name, defaultName);
+ errorMessage += gmx::formatString("Next time, use one of:");
+ for (auto enumValue : gmx::EnumerationWrapper<EnumType>{})
+ {
+ errorMessage += gmx::formatString(" '%s'", enumValueToString(enumValue));
+ }
+ if (wi != nullptr)
+ {
+ warning_error(wi, errorMessage);
+ }
+ else
+ {
+ fprintf(stderr, "%s\n", errorMessage.c_str());
+ }
+ (*inp)[ii].value_.assign(defaultName);
+ return defaultEnumValue;
+}
+
/*! \brief Return whether an end state with the given coupling-lambda
* value describes fully-interacting VDW.
*
ir->useMts = (get_eeenum(&inp, "mts", yesno_names, wi) != 0);
if (ir->useMts)
{
- opts->numMtsLevels = get_eint(&inp, "mts-levels", 2, wi);
- ir->mtsLevels.resize(2);
- gmx::MtsLevel& mtsLevel = ir->mtsLevels[1];
- opts->mtsLevel2Forces = setStringEntry(&inp, "mts-level2-forces", "longrange-nonbonded");
- mtsLevel.stepFactor = get_eint(&inp, "mts-level2-factor", 2, wi);
+ gmx::GromppMtsOpts& mtsOpts = opts->mtsOpts;
+ mtsOpts.numLevels = get_eint(&inp, "mts-levels", 2, wi);
+ mtsOpts.level2Forces = setStringEntry(&inp, "mts-level2-forces", "longrange-nonbonded");
+ mtsOpts.level2Factor = get_eint(&inp, "mts-level2-factor", 2, wi);
// We clear after reading without dynamics to not force the user to remove MTS mdp options
if (!EI_DYNAMICS(ir->eI))
{
ir->useMts = false;
- ir->mtsLevels.clear();
}
}
printStringNoNewline(&inp, "mode for center of mass motion removal");
printStringNoNewline(&inp, "cut-off lengths");
ir->rcoulomb_switch = get_ereal(&inp, "rcoulomb-switch", 0.0, wi);
ir->rcoulomb = get_ereal(&inp, "rcoulomb", 1.0, wi);
- printStringNoNewline(&inp,
- "Relative dielectric constant for the medium and the reaction field");
+ printStringNoNewline(&inp, "Relative dielectric constant for the medium and the reaction field");
ir->epsilon_r = get_ereal(&inp, "epsilon-r", 1.0, wi);
ir->epsilon_rf = get_ereal(&inp, "epsilon-rf", 0.0, wi);
printStringNoNewline(&inp, "Method for doing Van der Waals");
/* Coupling stuff */
printStringNewline(&inp, "OPTIONS FOR WEAK COUPLING ALGORITHMS");
printStringNoNewline(&inp, "Temperature coupling");
- ir->etc = get_eeenum(&inp, "tcoupl", etcoupl_names, wi);
+ ir->etc = getEnum<TemperatureCoupling>(&inp, "tcoupl", wi);
ir->nsttcouple = get_eint(&inp, "nsttcouple", -1, wi);
ir->opts.nhchainlength = get_eint(&inp, "nh-chain-length", 10, wi);
ir->bPrintNHChains = (get_eeenum(&inp, "print-nose-hoover-chain-variables", yesno_names, wi) != 0);
setStringEntry(&inp, "tau-t", inputrecStrings->tau_t, nullptr);
setStringEntry(&inp, "ref-t", inputrecStrings->ref_t, nullptr);
printStringNoNewline(&inp, "pressure coupling");
- ir->epc = get_eeenum(&inp, "pcoupl", epcoupl_names, wi);
+ ir->epc = getEnum<PressureCoupling>(&inp, "pcoupl", wi);
ir->epct = get_eeenum(&inp, "pcoupltype", epcoupltype_names, wi);
ir->nstpcouple = get_eint(&inp, "nstpcouple", -1, wi);
printStringNoNewline(&inp, "Time constant (ps), compressibility (1/bar) and reference P (bar)");
/* Non-equilibrium MD stuff */
printStringNewline(&inp, "Non-equilibrium MD stuff");
- setStringEntry(&inp, "acc-grps", inputrecStrings->accgrps, nullptr);
- setStringEntry(&inp, "accelerate", inputrecStrings->acc, nullptr);
setStringEntry(&inp, "freezegrps", inputrecStrings->freeze, nullptr);
setStringEntry(&inp, "freezedim", inputrecStrings->frdim, nullptr);
ir->cos_accel = get_ereal(&inp, "cos-acceleration", 0, wi);
{
dumdub[m][i] = 0.0;
}
- if (ir->epc)
+ if (ir->epc != PressureCoupling::No)
{
switch (ir->epct)
{
dumdub[m][YY] = dumdub[m][XX];
break;
case epctANISOTROPIC:
- if (sscanf(dumstr[m], "%lf%lf%lf%lf%lf%lf", &(dumdub[m][XX]), &(dumdub[m][YY]),
- &(dumdub[m][ZZ]), &(dumdub[m][3]), &(dumdub[m][4]), &(dumdub[m][5]))
+ if (sscanf(dumstr[m],
+ "%lf%lf%lf%lf%lf%lf",
+ &(dumdub[m][XX]),
+ &(dumdub[m][YY]),
+ &(dumdub[m][ZZ]),
+ &(dumdub[m][3]),
+ &(dumdub[m][4]),
+ &(dumdub[m][5]))
!= 6)
{
warning_error(
}
break;
default:
- gmx_fatal(FARGS, "Pressure coupling type %s not implemented yet",
+ gmx_fatal(FARGS,
+ "Pressure coupling type %s not implemented yet",
epcoupltype_names[ir->epct]);
}
}
}
double gmx_unused canary;
- int ndeform = sscanf(inputrecStrings->deform, "%lf %lf %lf %lf %lf %lf %lf", &(dumdub[0][0]),
- &(dumdub[0][1]), &(dumdub[0][2]), &(dumdub[0][3]), &(dumdub[0][4]),
- &(dumdub[0][5]), &canary);
+ int ndeform = sscanf(inputrecStrings->deform,
+ "%lf %lf %lf %lf %lf %lf %lf",
+ &(dumdub[0][0]),
+ &(dumdub[0][1]),
+ &(dumdub[0][2]),
+ &(dumdub[0][3]),
+ &(dumdub[0][4]),
+ &(dumdub[0][5]),
+ &canary);
if (strlen(inputrecStrings->deform) > 0 && ndeform != 6)
{
ir->deform[YY][XX] = dumdub[0][3];
ir->deform[ZZ][XX] = dumdub[0][4];
ir->deform[ZZ][YY] = dumdub[0][5];
- if (ir->epc != epcNO)
+ if (ir->epc != PressureCoupling::No)
{
for (i = 0; i < 3; i++)
{
/* Set up MTS levels, this needs to happen before checking AWH parameters */
if (ir->useMts)
{
- setupMtsLevels(ir->mtsLevels, *ir, *opts, wi);
+ std::vector<std::string> errorMessages;
+ ir->mtsLevels = gmx::setupMtsLevels(opts->mtsOpts, &errorMessages);
+
+ for (const auto& errorMessage : errorMessages)
+ {
+ warning_error(wi, errorMessage.c_str());
+ }
}
if (ir->bDoAwh)
const int ognr = cbuf[aj];
if (ognr != NOGID)
{
- gmx_fatal(FARGS, "Atom %d in multiple %s groups (%d and %d)", aj + 1, title,
- ognr + 1, i + 1);
+ gmx_fatal(FARGS, "Atom %d in multiple %s groups (%d and %d)", aj + 1, title, ognr + 1, i + 1);
}
else
{
{
if (bVerbose)
{
- fprintf(stderr, "Making dummy/rest group for %s containing %d elements\n", title,
- natoms - ntot);
+ fprintf(stderr, "Making dummy/rest group for %s containing %d elements\n", title, natoms - ntot);
}
/* Add group name "rest" */
grps->emplace_back(restnm);
nrdf_tc[i] = 0;
}
for (gmx::index i = 0;
- i < gmx::ssize(groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval]) + 1; i++)
+ i < gmx::ssize(groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval]) + 1;
+ i++)
{
nrdf_vcm[i] = 0;
clear_ivec(dof_vcm[i]);
* Note that we do not and should not include the rest group here.
*/
for (gmx::index j = 0;
- j < gmx::ssize(groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval]); j++)
+ j < gmx::ssize(groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval]);
+ j++)
{
switch (ir->comm_mode)
{
}
for (gmx::index i = 0;
- i < gmx::ssize(groups.groups[SimulationAtomGroupType::TemperatureCoupling]); i++)
+ i < gmx::ssize(groups.groups[SimulationAtomGroupType::TemperatureCoupling]);
+ i++)
{
/* Count the number of atoms of TC group i for every VCM group */
for (gmx::index j = 0;
- j < gmx::ssize(groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval]) + 1; j++)
+ j < gmx::ssize(groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval]) + 1;
+ j++)
{
na_vcm[j] = 0;
}
nrdf_uc = nrdf_tc[i];
nrdf_tc[i] = 0;
for (gmx::index j = 0;
- j < gmx::ssize(groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval]) + 1; j++)
+ j < gmx::ssize(groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval]) + 1;
+ j++)
{
if (nrdf_vcm[j] > nrdf_vcm_sub[j])
{
{
opts->nrdf[i] = 0;
}
- fprintf(stderr, "Number of degrees of freedom in T-Coupling group %s is %.2f\n",
- gnames[groups.groups[SimulationAtomGroupType::TemperatureCoupling][i]], opts->nrdf[i]);
+ fprintf(stderr,
+ "Number of degrees of freedom in T-Coupling group %s is %.2f\n",
+ gnames[groups.groups[SimulationAtomGroupType::TemperatureCoupling][i]],
+ opts->nrdf[i]);
}
sfree(nrdf2);
if (swapg->nat > 0)
{
- fprintf(stderr, "%s group '%s' contains %d atoms.\n",
- ig < 3 ? eSwapFixedGrp_names[ig] : "Swap", swap->grp[ig].molname, swapg->nat);
+ fprintf(stderr,
+ "%s group '%s' contains %d atoms.\n",
+ ig < 3 ? eSwapFixedGrp_names[ig] : "Swap",
+ swap->grp[ig].molname,
+ swapg->nat);
snew(swapg->ind, swapg->nat);
for (i = 0; i < swapg->nat; i++)
{
fprintf(stderr,
"Group '%s' with %d atoms can be activated for interactive molecular dynamics "
"(IMD).\n",
- IMDgname, IMDgroup->nat);
+ IMDgname,
+ IMDgroup->nat);
snew(IMDgroup->ind, IMDgroup->nat);
for (i = 0; i < IMDgroup->nat; i++)
{
"removal group(s), due to limitations in the code these still contribute to the "
"mass of the COM along frozen dimensions and therefore the COMM correction will be "
"too small.",
- numPartiallyFrozenVcmAtoms, DIM);
+ numPartiallyFrozenVcmAtoms,
+ DIM);
warning(wi, warningText.c_str());
}
if (numNonVcmAtoms > 0)
gmx_fatal(FARGS,
"Invalid T coupling input: %zu groups, %zu ref-t values and "
"%zu tau-t values",
- temperatureCouplingGroupNames.size(), temperatureCouplingReferenceValues.size(),
+ temperatureCouplingGroupNames.size(),
+ temperatureCouplingReferenceValues.size(),
temperatureCouplingTauValues.size());
}
const bool useReferenceTemperature = integratorHasReferenceTemperature(ir);
- do_numbering(natoms, groups, temperatureCouplingGroupNames, defaultIndexGroups, gnames,
- SimulationAtomGroupType::TemperatureCoupling, restnm,
- useReferenceTemperature ? egrptpALL : egrptpALL_GENREST, bVerbose, wi);
+ do_numbering(natoms,
+ groups,
+ temperatureCouplingGroupNames,
+ defaultIndexGroups,
+ gnames,
+ SimulationAtomGroupType::TemperatureCoupling,
+ restnm,
+ useReferenceTemperature ? egrptpALL : egrptpALL_GENREST,
+ bVerbose,
+ wi);
nr = groups->groups[SimulationAtomGroupType::TemperatureCoupling].size();
ir->opts.ngtc = nr;
snew(ir->opts.nrdf, nr);
warning_error(wi, warn_buf);
}
- if (ir->etc != etcVRESCALE && ir->opts.tau_t[i] == 0)
+ if (ir->etc != TemperatureCoupling::VRescale && ir->opts.tau_t[i] == 0)
{
warning_note(
wi,
tau_min = std::min(tau_min, ir->opts.tau_t[i]);
}
}
- if (ir->etc != etcNO && ir->nsttcouple == -1)
+ if (ir->etc != TemperatureCoupling::No && ir->nsttcouple == -1)
{
ir->nsttcouple = ir_optimal_nsttcouple(ir);
}
if (EI_VV(ir->eI))
{
- if ((ir->etc == etcNOSEHOOVER) && (ir->epc == epcBERENDSEN))
+ if ((ir->etc == TemperatureCoupling::NoseHoover) && (ir->epc == PressureCoupling::Berendsen))
{
gmx_fatal(FARGS,
"Cannot do Nose-Hoover temperature with Berendsen pressure control with "
"md-vv; use either vrescale temperature with berendsen pressure or "
"Nose-Hoover temperature with MTTK pressure");
}
- if (ir->epc == epcMTTK)
+ if (ir->epc == PressureCoupling::Mttk)
{
- if (ir->etc != etcNOSEHOOVER)
+ if (ir->etc != TemperatureCoupling::NoseHoover)
{
gmx_fatal(FARGS,
"Cannot do MTTK pressure coupling without Nose-Hoover temperature "
sprintf(warn_buf,
"For proper integration of the %s thermostat, tau-t (%g) should be at "
"least %d times larger than nsttcouple*dt (%g)",
- ETCOUPLTYPE(ir->etc), tau_min, nstcmin, ir->nsttcouple * ir->delta_t);
+ enumValueToString(ir->etc),
+ tau_min,
+ nstcmin,
+ ir->nsttcouple * ir->delta_t);
warning(wi, warn_buf);
}
}
}
if (!simulatedAnnealingGroupNames.empty() && gmx::ssize(simulatedAnnealingGroupNames) != nr)
{
- gmx_fatal(FARGS, "Wrong number of annealing values: %zu (for %d groups)\n",
- simulatedAnnealingGroupNames.size(), nr);
+ gmx_fatal(FARGS,
+ "Wrong number of annealing values: %zu (for %d groups)\n",
+ simulatedAnnealingGroupNames.size(),
+ nr);
}
else
{
auto simulatedAnnealingPoints = gmx::splitString(inputrecStrings->anneal_npoints);
if (simulatedAnnealingPoints.size() != simulatedAnnealingGroupNames.size())
{
- gmx_fatal(FARGS, "Found %zu annealing-npoints values for %zu groups\n",
- simulatedAnnealingPoints.size(), simulatedAnnealingGroupNames.size());
+ gmx_fatal(FARGS,
+ "Found %zu annealing-npoints values for %zu groups\n",
+ simulatedAnnealingPoints.size(),
+ simulatedAnnealingGroupNames.size());
}
convertInts(wi, simulatedAnnealingPoints, "annealing points", ir->opts.anneal_npoints);
size_t numSimulatedAnnealingFields = 0;
if (simulatedAnnealingTimes.size() != numSimulatedAnnealingFields)
{
- gmx_fatal(FARGS, "Found %zu annealing-time values, wanted %zu\n",
- simulatedAnnealingTimes.size(), numSimulatedAnnealingFields);
+ gmx_fatal(FARGS,
+ "Found %zu annealing-time values, wanted %zu\n",
+ simulatedAnnealingTimes.size(),
+ numSimulatedAnnealingFields);
}
auto simulatedAnnealingTemperatures = gmx::splitString(inputrecStrings->anneal_temp);
if (simulatedAnnealingTemperatures.size() != numSimulatedAnnealingFields)
{
- gmx_fatal(FARGS, "Found %zu annealing-temp values, wanted %zu\n",
- simulatedAnnealingTemperatures.size(), numSimulatedAnnealingFields);
+ gmx_fatal(FARGS,
+ "Found %zu annealing-temp values, wanted %zu\n",
+ simulatedAnnealingTemperatures.size(),
+ numSimulatedAnnealingFields);
}
std::vector<real> allSimulatedAnnealingTimes(numSimulatedAnnealingFields);
std::vector<real> allSimulatedAnnealingTemperatures(numSimulatedAnnealingFields);
- convertReals(wi, simulatedAnnealingTimes, "anneal-time",
- allSimulatedAnnealingTimes.data());
- convertReals(wi, simulatedAnnealingTemperatures, "anneal-temp",
+ convertReals(wi, simulatedAnnealingTimes, "anneal-time", allSimulatedAnnealingTimes.data());
+ convertReals(wi,
+ simulatedAnnealingTemperatures,
+ "anneal-temp",
allSimulatedAnnealingTemperatures.data());
for (i = 0, k = 0; i < nr; i++)
{
gmx_fatal(FARGS,
"Annealing timepoints out of order: t=%f comes after "
"t=%f\n",
- ir->opts.anneal_time[i][j], ir->opts.anneal_time[i][j - 1]);
+ ir->opts.anneal_time[i][j],
+ ir->opts.anneal_time[i][j - 1]);
}
}
if (ir->opts.anneal_temp[i][j] < 0)
{
- gmx_fatal(FARGS, "Found negative temperature in annealing: %f\n",
+ gmx_fatal(FARGS,
+ "Found negative temperature in annealing: %f\n",
ir->opts.anneal_temp[i][j]);
}
k++;
if (ir->opts.annealing[i] != eannNO)
{
j = groups->groups[SimulationAtomGroupType::TemperatureCoupling][i];
- fprintf(stderr, "Simulated annealing for group %s: %s, %d timepoints\n",
- *(groups->groupNames[j]), eann_names[ir->opts.annealing[i]],
+ fprintf(stderr,
+ "Simulated annealing for group %s: %s, %d timepoints\n",
+ *(groups->groupNames[j]),
+ eann_names[ir->opts.annealing[i]],
ir->opts.anneal_npoints[i]);
fprintf(stderr, "Time (ps) Temperature (K)\n");
/* All terms except the last one */
for (j = 0; j < (ir->opts.anneal_npoints[i] - 1); j++)
{
- fprintf(stderr, "%9.1f %5.1f\n", ir->opts.anneal_time[i][j],
+ fprintf(stderr,
+ "%9.1f %5.1f\n",
+ ir->opts.anneal_time[i][j],
ir->opts.anneal_temp[i][j]);
}
j = ir->opts.anneal_npoints[i] - 1;
if (ir->opts.annealing[i] == eannSINGLE)
{
- fprintf(stderr, "%9.1f- %5.1f\n", ir->opts.anneal_time[i][j],
+ fprintf(stderr,
+ "%9.1f- %5.1f\n",
+ ir->opts.anneal_time[i][j],
ir->opts.anneal_temp[i][j]);
}
else
{
- fprintf(stderr, "%9.1f %5.1f\n", ir->opts.anneal_time[i][j],
+ fprintf(stderr,
+ "%9.1f %5.1f\n",
+ ir->opts.anneal_time[i][j],
ir->opts.anneal_temp[i][j]);
if (std::fabs(ir->opts.anneal_temp[i][j] - ir->opts.anneal_temp[i][0]) > GMX_REAL_EPS)
{
{
for (int i = 1; i < ir->pull->ngroup; i++)
{
- const int gid = search_string(inputrecStrings->pullGroupNames[i].c_str(),
- defaultIndexGroups->nr, gnames);
+ const int gid = search_string(
+ inputrecStrings->pullGroupNames[i].c_str(), defaultIndexGroups->nr, gnames);
GMX_ASSERT(defaultIndexGroups, "Must have initialized default index groups");
atomGroupRangeValidation(natoms, gid, *defaultIndexGroups);
}
*defaultIndexGroups, gmx::arrayRefFromArray(gnames, defaultIndexGroups->nr));
notifier.preProcessingNotifications_.notify(defaultIndexGroupsAndNames);
- auto accelerations = gmx::splitString(inputrecStrings->acc);
- auto accelerationGroupNames = gmx::splitString(inputrecStrings->accgrps);
- if (accelerationGroupNames.size() * DIM != accelerations.size())
- {
- gmx_fatal(FARGS, "Invalid Acceleration input: %zu groups and %zu acc. values",
- accelerationGroupNames.size(), accelerations.size());
- }
- do_numbering(natoms, groups, accelerationGroupNames, defaultIndexGroups, gnames,
- SimulationAtomGroupType::Acceleration, restnm, egrptpALL_GENREST, bVerbose, wi);
- nr = groups->groups[SimulationAtomGroupType::Acceleration].size();
- snew(ir->opts.acc, nr);
- ir->opts.ngacc = nr;
-
- convertRvecs(wi, accelerations, "anneal-time", ir->opts.acc);
-
auto freezeDims = gmx::splitString(inputrecStrings->frdim);
auto freezeGroupNames = gmx::splitString(inputrecStrings->freeze);
if (freezeDims.size() != DIM * freezeGroupNames.size())
{
- gmx_fatal(FARGS, "Invalid Freezing input: %zu groups and %zu freeze values",
- freezeGroupNames.size(), freezeDims.size());
- }
- do_numbering(natoms, groups, freezeGroupNames, defaultIndexGroups, gnames,
- SimulationAtomGroupType::Freeze, restnm, egrptpALL_GENREST, bVerbose, wi);
+ gmx_fatal(FARGS,
+ "Invalid Freezing input: %zu groups and %zu freeze values",
+ freezeGroupNames.size(),
+ freezeDims.size());
+ }
+ do_numbering(natoms,
+ groups,
+ freezeGroupNames,
+ defaultIndexGroups,
+ gnames,
+ SimulationAtomGroupType::Freeze,
+ restnm,
+ egrptpALL_GENREST,
+ bVerbose,
+ wi);
nr = groups->groups[SimulationAtomGroupType::Freeze].size();
ir->opts.ngfrz = nr;
snew(ir->opts.nFreeze, nr);
}
auto energyGroupNames = gmx::splitString(inputrecStrings->energy);
- do_numbering(natoms, groups, energyGroupNames, defaultIndexGroups, gnames,
- SimulationAtomGroupType::EnergyOutput, restnm, egrptpALL_GENREST, bVerbose, wi);
+ do_numbering(natoms,
+ groups,
+ energyGroupNames,
+ defaultIndexGroups,
+ gnames,
+ SimulationAtomGroupType::EnergyOutput,
+ restnm,
+ egrptpALL_GENREST,
+ bVerbose,
+ wi);
add_wall_energrps(groups, ir->nwall, symtab);
ir->opts.ngener = groups->groups[SimulationAtomGroupType::EnergyOutput].size();
auto vcmGroupNames = gmx::splitString(inputrecStrings->vcm);
- do_numbering(natoms, groups, vcmGroupNames, defaultIndexGroups, gnames,
- SimulationAtomGroupType::MassCenterVelocityRemoval, restnm,
- vcmGroupNames.empty() ? egrptpALL_GENREST : egrptpPART, bVerbose, wi);
+ do_numbering(natoms,
+ groups,
+ vcmGroupNames,
+ defaultIndexGroups,
+ gnames,
+ SimulationAtomGroupType::MassCenterVelocityRemoval,
+ restnm,
+ vcmGroupNames.empty() ? egrptpALL_GENREST : egrptpPART,
+ bVerbose,
+ wi);
if (ir->comm_mode != ecmNO)
{
calc_nrdf(mtop, ir, gnames);
auto user1GroupNames = gmx::splitString(inputrecStrings->user1);
- do_numbering(natoms, groups, user1GroupNames, defaultIndexGroups, gnames,
- SimulationAtomGroupType::User1, restnm, egrptpALL_GENREST, bVerbose, wi);
+ do_numbering(natoms,
+ groups,
+ user1GroupNames,
+ defaultIndexGroups,
+ gnames,
+ SimulationAtomGroupType::User1,
+ restnm,
+ egrptpALL_GENREST,
+ bVerbose,
+ wi);
auto user2GroupNames = gmx::splitString(inputrecStrings->user2);
- do_numbering(natoms, groups, user2GroupNames, defaultIndexGroups, gnames,
- SimulationAtomGroupType::User2, restnm, egrptpALL_GENREST, bVerbose, wi);
+ do_numbering(natoms,
+ groups,
+ user2GroupNames,
+ defaultIndexGroups,
+ gnames,
+ SimulationAtomGroupType::User2,
+ restnm,
+ egrptpALL_GENREST,
+ bVerbose,
+ wi);
auto compressedXGroupNames = gmx::splitString(inputrecStrings->x_compressed_groups);
- do_numbering(natoms, groups, compressedXGroupNames, defaultIndexGroups, gnames,
- SimulationAtomGroupType::CompressedPositionOutput, restnm, egrptpONE, bVerbose, wi);
+ do_numbering(natoms,
+ groups,
+ compressedXGroupNames,
+ defaultIndexGroups,
+ gnames,
+ SimulationAtomGroupType::CompressedPositionOutput,
+ restnm,
+ egrptpONE,
+ bVerbose,
+ wi);
auto orirefFitGroupNames = gmx::splitString(inputrecStrings->orirefitgrp);
- do_numbering(natoms, groups, orirefFitGroupNames, defaultIndexGroups, gnames,
- SimulationAtomGroupType::OrientationRestraintsFit, restnm, egrptpALL_GENREST,
- bVerbose, wi);
+ do_numbering(natoms,
+ groups,
+ orirefFitGroupNames,
+ defaultIndexGroups,
+ gnames,
+ SimulationAtomGroupType::OrientationRestraintsFit,
+ restnm,
+ egrptpALL_GENREST,
+ bVerbose,
+ wi);
/* MiMiC QMMM input processing */
auto qmGroupNames = gmx::splitString(inputrecStrings->QMMM);
gmx_fatal(FARGS, "Currently, having more than one QM group in MiMiC is not supported");
}
/* group rest, if any, is always MM! */
- do_numbering(natoms, groups, qmGroupNames, defaultIndexGroups, gnames,
- SimulationAtomGroupType::QuantumMechanics, restnm, egrptpALL_GENREST, bVerbose, wi);
+ do_numbering(natoms,
+ groups,
+ qmGroupNames,
+ defaultIndexGroups,
+ gnames,
+ SimulationAtomGroupType::QuantumMechanics,
+ restnm,
+ egrptpALL_GENREST,
+ bVerbose,
+ wi);
ir->opts.ngQM = qmGroupNames.size();
/* end of MiMiC QMMM input */
if ((ir->expandedvals->nstexpanded < 0) && ir->bSimTemp)
{
ir->expandedvals->nstexpanded = 2 * static_cast<int>(ir->opts.tau_t[0] / ir->delta_t);
- warning(wi, gmx::formatString(
- "the value for nstexpanded was not specified for "
- " expanded ensemble simulated tempering. It is set to 2*tau_t (%d) "
- "by default, but it is recommended to set it to an explicit value!",
- ir->expandedvals->nstexpanded));
+ warning(wi,
+ gmx::formatString(
+ "the value for nstexpanded was not specified for "
+ " expanded ensemble simulated tempering. It is set to 2*tau_t (%d) "
+ "by default, but it is recommended to set it to an explicit value!",
+ ir->expandedvals->nstexpanded));
}
for (i = 0; (i < defaultIndexGroups->nr); i++)
{
gmx_fatal(FARGS,
" Invalid geometry for flat-bottom position restraint.\n"
"Expected nr between 1 and %d. Found %d\n",
- efbposresNR - 1, pr->fbposres.geom);
+ efbposresNR - 1,
+ pr->fbposres.geom);
}
}
}
if (sscanf(ptr, "%lf%lf", &dbl, &canary) != 1)
{
- gmx_fatal(FARGS,
- "Could not parse a single floating-point number from GMX_LJCOMB_TOL (%s)", ptr);
+ gmx_fatal(
+ FARGS, "Could not parse a single floating-point number from GMX_LJCOMB_TOL (%s)", ptr);
}
tol = dbl;
}
{
bool bLBRulesPossible, bC6ParametersWorkWithGeometricRules, bC6ParametersWorkWithLBRules;
- check_combination_rule_differences(mtop, 0, &bC6ParametersWorkWithGeometricRules,
- &bC6ParametersWorkWithLBRules, &bLBRulesPossible);
+ check_combination_rule_differences(
+ mtop, 0, &bC6ParametersWorkWithGeometricRules, &bC6ParametersWorkWithLBRules, &bLBRulesPossible);
if (ir->ljpme_combination_rule == eljpmeLB)
{
if (!bC6ParametersWorkWithLBRules || !bLBRulesPossible)
void triple_check(const char* mdparin, t_inputrec* ir, gmx_mtop_t* sys, warninp_t wi)
{
// Not meeting MTS requirements should have resulted in a fatal error, so we can assert here
- gmx::assertMtsRequirements(*ir);
+ GMX_ASSERT(gmx::checkMtsRequirements(*ir).empty(), "All MTS requirements should be met here");
char err_buf[STRLEN];
int i, m, c, nmol;
- bool bCharge, bAcc;
- real * mgrp, mt;
- rvec acc;
+ bool bCharge;
gmx_mtop_atomloop_block_t aloopb;
ivec AbsRef;
char warn_buf[STRLEN];
}
if (ir->cutoff_scheme == ecutsVERLET && ir->verletbuf_tol > 0 && ir->nstlist > 1
- && ((EI_MD(ir->eI) || EI_SD(ir->eI)) && (ir->etc == etcVRESCALE || ir->etc == etcBERENDSEN)))
+ && ((EI_MD(ir->eI) || EI_SD(ir->eI))
+ && (ir->etc == TemperatureCoupling::VRescale || ir->etc == TemperatureCoupling::Berendsen)))
{
/* Check if a too small Verlet buffer might potentially
* cause more drift than the thermostat can couple off.
"of %g and a tau_t of %g, your temperature might be off by up to %.1f%%. "
"To ensure the error is below %.1f%%, decrease verlet-buffer-tolerance to "
"%.0e or decrease tau_t.",
- ir->verletbuf_tol, T, tau, 100 * max_T_error, 100 * T_error_suggest,
+ ir->verletbuf_tol,
+ T,
+ tau,
+ 100 * max_T_error,
+ 100 * T_error_suggest,
ir->verletbuf_tol * T_error_suggest / max_T_error);
warning(wi, warn_buf);
}
sprintf(err_buf,
"all tau_t must be positive using Andersen temperature control, "
"tau_t[%d]=%10.6f",
- i, ir->opts.tau_t[i]);
+ i,
+ ir->opts.tau_t[i]);
CHECK(ir->opts.tau_t[i] < 0);
}
- if (ir->etc == etcANDERSENMASSIVE && ir->comm_mode != ecmNO)
+ if (ir->etc == TemperatureCoupling::AndersenMassive && ir->comm_mode != ecmNO)
{
for (i = 0; i < ir->opts.ngtc; i++)
{
"multiple of nstcomm (%d), as velocities of atoms in coupled groups are "
"randomized every time step. The input tau_t (%8.3f) leads to %d steps per "
"randomization",
- i, etcoupl_names[ir->etc], ir->nstcomm, ir->opts.tau_t[i], nsteps);
+ i,
+ enumValueToString(ir->etc),
+ ir->nstcomm,
+ ir->opts.tau_t[i],
+ nsteps);
CHECK(nsteps % ir->nstcomm != 0);
}
}
"rounding errors can lead to build up of kinetic energy of the center of mass");
}
- if (ir->epc == epcPARRINELLORAHMAN && ir->etc == etcNOSEHOOVER)
+ if (ir->epc == PressureCoupling::ParrinelloRahman && ir->etc == TemperatureCoupling::NoseHoover)
{
real tau_t_max = 0;
for (int g = 0; g < ir->opts.ngtc; g++)
std::string message = gmx::formatString(
"With %s T-coupling and %s p-coupling, "
"%s (%g) should be at least twice as large as %s (%g) to avoid resonances",
- etcoupl_names[ir->etc], epcoupl_names[ir->epc], "tau-p", ir->tau_p, "tau-t",
+ enumValueToString(ir->etc),
+ enumValueToString(ir->epc),
+ "tau-p",
+ ir->tau_p,
+ "tau-t",
tau_t_max);
warning(wi, message.c_str());
}
}
/* Check for pressure coupling with absolute position restraints */
- if (ir->epc != epcNO && ir->refcoord_scaling == erscNO)
+ if (ir->epc != PressureCoupling::No && ir->refcoord_scaling == erscNO)
{
absolute_reference(ir, sys, TRUE, AbsRef);
{
"You are using full electrostatics treatment %s for a system without charges.\n"
"This costs a lot of performance for just processing zeros, consider using %s "
"instead.\n",
- EELTYPE(ir->coulombtype), EELTYPE(eelCUT));
+ EELTYPE(ir->coulombtype),
+ EELTYPE(eelCUT));
warning(wi, err_buf);
}
}
"constant by hand.");
}
- bAcc = FALSE;
- for (int i = 0; (i < gmx::ssize(sys->groups.groups[SimulationAtomGroupType::Acceleration])); i++)
- {
- for (m = 0; (m < DIM); m++)
- {
- if (fabs(ir->opts.acc[i][m]) > 1e-6)
- {
- bAcc = TRUE;
- }
- }
- }
- if (bAcc)
- {
- clear_rvec(acc);
- snew(mgrp, sys->groups.groups[SimulationAtomGroupType::Acceleration].size());
- for (const AtomProxy atomP : AtomRange(*sys))
- {
- const t_atom& local = atomP.atom();
- int i = atomP.globalAtomNumber();
- mgrp[getGroupType(sys->groups, SimulationAtomGroupType::Acceleration, i)] += local.m;
- }
- mt = 0.0;
- for (i = 0; (i < gmx::ssize(sys->groups.groups[SimulationAtomGroupType::Acceleration])); i++)
- {
- for (m = 0; (m < DIM); m++)
- {
- acc[m] += ir->opts.acc[i][m] * mgrp[i];
- }
- mt += mgrp[i];
- }
- for (m = 0; (m < DIM); m++)
- {
- if (fabs(acc[m]) > 1e-6)
- {
- const char* dim[DIM] = { "X", "Y", "Z" };
- fprintf(stderr, "Net Acceleration in %s direction, will %s be corrected\n", dim[m],
- ir->nstcomm != 0 ? "" : "not");
- if (ir->nstcomm != 0 && m < ndof_com(ir))
- {
- acc[m] /= mt;
- for (i = 0;
- (i < gmx::ssize(sys->groups.groups[SimulationAtomGroupType::Acceleration])); i++)
- {
- ir->opts.acc[i][m] -= acc[m];
- }
- }
- }
- }
- sfree(mgrp);
- }
-
if (ir->efep != efepNO && ir->fepvals->sc_alpha != 0
&& !gmx_within_tol(sys->ffparams.reppow, 12.0, 10 * GMX_DOUBLE_EPS))
{
{
for (m = 0; m <= i; m++)
{
- if ((ir->epc != epcNO && ir->compress[i][m] != 0) || ir->deform[i][m] != 0)
+ if ((ir->epc != PressureCoupling::No && ir->compress[i][m] != 0) || ir->deform[i][m] != 0)
{
for (c = 0; c < ir->pull->ncoord; c++)
{
gmx_fatal(FARGS,
"Can not have dynamic box while using pull geometry '%s' "
"(dim %c)",
- EPULLGEOM(ir->pull->coord[c].eGeom), 'x' + m);
+ EPULLGEOM(ir->pull->coord[c].eGeom),
+ 'x' + m);
}
}
}
if ((ir->eConstrAlg == econtLINCS) && bHasNormalConstraints)
{
/* If we have Lincs constraints: */
- if (ir->eI == eiMD && ir->etc == etcNO && ir->eConstrAlg == econtLINCS && ir->nLincsIter == 1)
+ if (ir->eI == eiMD && ir->etc == TemperatureCoupling::No && ir->eConstrAlg == econtLINCS
+ && ir->nLincsIter == 1)
{
sprintf(warn_buf,
"For energy conservation with LINCS, lincs_iter should be 2 or larger.\n");
ei_names[ir->eI]);
warning_note(wi, warn_buf);
}
- if (ir->epc == epcMTTK)
+ if (ir->epc == PressureCoupling::Mttk)
{
warning_error(wi, "MTTK not compatible with lincs -- use shake instead.");
}
}
- if (bHasAnyConstraints && ir->epc == epcMTTK)
+ if (bHasAnyConstraints && ir->epc == PressureCoupling::Mttk)
{
warning_error(wi, "Constraints are not implemented with MTTK pressure control.");
}
#include "gromacs/fileio/readinp.h"
#include "gromacs/math/vectypes.h"
+#include "gromacs/mdtypes/multipletimestepping.h"
#include "gromacs/utility/arrayref.h"
#include "gromacs/utility/real.h"
struct t_gromppopts
{
- int warnings = 0;
- int nshake = 0;
- char* include = nullptr;
- char* define = nullptr;
- bool bGenVel = false;
- bool bGenPairs = false;
- real tempi = 0;
- int seed = 0;
- int numMtsLevels = 0;
- std::string mtsLevel2Forces;
- bool bOrire = false;
- bool bMorse = false;
- char* wall_atomtype[2] = { nullptr, nullptr };
- char* couple_moltype = nullptr;
- int couple_lam0 = 0;
- int couple_lam1 = 0;
- bool bCoupleIntra = false;
+ int warnings = 0;
+ int nshake = 0;
+ char* include = nullptr;
+ char* define = nullptr;
+ bool bGenVel = false;
+ bool bGenPairs = false;
+ real tempi = 0;
+ int seed = 0;
+ gmx::GromppMtsOpts mtsOpts;
+ bool bOrire = false;
+ bool bMorse = false;
+ char* wall_atomtype[2] = { nullptr, nullptr };
+ char* couple_moltype = nullptr;
+ int couple_lam0 = 0;
+ int couple_lam1 = 0;
+ bool bCoupleIntra = false;
};
/*! \brief Initialise object to hold strings parsed from an .mdp file */
gmx_fatal(FARGS,
"Pulling of type %s can not be combined with geometry %s. Consider using pull "
"type %s.",
- epull_names[pcrd->eType], epullg_names[pcrd->eGeom], epull_names[epullUMBRELLA]);
+ epull_names[pcrd->eType],
+ epullg_names[pcrd->eGeom],
+ epull_names[epullUMBRELLA]);
}
if (pcrd->eType == epullEXTERNAL)
sprintf(buf,
"The use of pull type '%s' for pull coordinate %d requires that the name of "
"the module providing the potential external is set with the option %s%d%s",
- epull_names[pcrd->eType], coord_index_for_output, "pull-coord",
- coord_index_for_output, "-potential-provider");
+ epull_names[pcrd->eType],
+ coord_index_for_output,
+ "pull-coord",
+ coord_index_for_output,
+ "-potential-provider");
warning_error(wi, buf);
}
sprintf(buf,
"The use of pull type '%s' for pull coordinate %d requires that the pull rate "
"is zero",
- epull_names[pcrd->eType], coord_index_for_output);
+ epull_names[pcrd->eType],
+ coord_index_for_output);
warning_error(wi, buf);
}
"With pull type '%s' and geometry '%s', the distance component along the "
"cylinder axis between atoms in the cylinder group and the COM of the pull "
"group should be smaller than half the box length",
- epull_names[pcrd->eType], epullg_names[pcrd->eGeom]);
+ epull_names[pcrd->eType],
+ epullg_names[pcrd->eGeom]);
warning_note(wi, buf);
}
}
"This may work, since you have set pull-coord-start to 'yes' which modifies "
"this value, but only for certain starting distances. "
"If this is a mistake you may want to use geometry %s instead.",
- pcrd->init, EPULLGEOM(pcrd->eGeom), EPULLGEOM(epullgDIR));
+ pcrd->init,
+ EPULLGEOM(pcrd->eGeom),
+ EPULLGEOM(epullgDIR));
warning(wi, buf);
}
}
"allowed range [0, 180] degrees for geometry (%s). "
"This may work, since you have set pull-coord-start to 'yes' which modifies "
"this value, but only for certain starting angles.",
- pcrd->init, EPULLGEOM(pcrd->eGeom));
+ pcrd->init,
+ EPULLGEOM(pcrd->eGeom));
warning(wi, buf);
}
}
"allowed range [-180, 180] degrees for geometry (%s). "
"This may work, since you have set pull-coord-start to 'yes' which modifies "
"this value, but only for certain starting angles.",
- pcrd->init, EPULLGEOM(pcrd->eGeom));
+ pcrd->init,
+ EPULLGEOM(pcrd->eGeom));
warning(wi, buf);
}
}
{
if (dnorm2(vec) == 0)
{
- gmx_fatal(FARGS, "With pull geometry %s the pull vector can not be 0,0,0",
+ gmx_fatal(FARGS,
+ "With pull geometry %s the pull vector can not be 0,0,0",
epullg_names[pcrd->eGeom]);
}
for (int d = 0; d < DIM; d++)
gmx_fatal(FARGS,
"pull-coord-vec has non-zero %c-component while pull_dim for the "
"%c-dimension is set to N",
- 'x' + d, 'x' + d);
+ 'x' + d,
+ 'x' + d);
}
}
"A pull vector is given (%g %g %g) but will not be used with geometry %s. If "
"you really want to use this "
"vector, consider using geometry %s instead.",
- vec[0], vec[1], vec[2], EPULLGEOM(pcrd->eGeom),
+ vec[0],
+ vec[1],
+ vec[2],
+ EPULLGEOM(pcrd->eGeom),
pcrd->eGeom == epullgANGLE ? EPULLGEOM(epullgANGLEAXIS) : EPULLGEOM(epullgDIR));
warning(wi, buf);
}
default: pullCoord.ngroup = 2; break;
}
- nscan = sscanf(groups, "%d %d %d %d %d %d %d", &pullCoord.group[0], &pullCoord.group[1],
- &pullCoord.group[2], &pullCoord.group[3], &pullCoord.group[4],
- &pullCoord.group[5], &idum);
+ nscan = sscanf(groups,
+ "%d %d %d %d %d %d %d",
+ &pullCoord.group[0],
+ &pullCoord.group[1],
+ &pullCoord.group[2],
+ &pullCoord.group[3],
+ &pullCoord.group[4],
+ &pullCoord.group[5],
+ &idum);
if (nscan != pullCoord.ngroup)
{
auto message =
gmx::formatString("%s should contain %d pull group indices with geometry %s",
- buf, pullCoord.ngroup, epullg_names[pullCoord.eGeom]);
+ buf,
+ pullCoord.ngroup,
+ epullg_names[pullCoord.eGeom]);
set_warning_line(wi, nullptr, -1);
warning_error(wi, message);
}
/* Quit with a fatal error to avoid invalid memory access */
gmx_fatal(FARGS,
"%s contains an invalid pull group %d, you should have %d <= group <= %d",
- buf, pullCoord.group[g], 0, pull->ngroup - 1);
+ buf,
+ pullCoord.group[g],
+ 0,
+ pull->ngroup - 1);
}
}
gmx_fatal(FARGS,
"Number of weights (%ld) for pull group %d '%s' does not match the number of "
"atoms (%ld)",
- gmx::ssize(pullGroup.weight), g, pullGroupNames[g].c_str(),
+ gmx::ssize(pullGroup.weight),
+ g,
+ pullGroupNames[g].c_str(),
gmx::ssize(pullGroup.ind));
}
gmx_fatal(FARGS,
"Pull group index in pull-coord%d-groups out of range, should be between %d "
"and %d",
- c + 1, 0, int(pullGroups.size()) + 1);
+ c + 1,
+ 0,
+ int(pullGroups.size()) + 1);
}
if (pcrd.group[0] == pcrd.group[1])
for (int g = 0; g < pull->ngroup; g++)
{
bool groupObeysPbc = pullCheckPbcWithinGroup(
- *pull_work, gmx::arrayRefFromArray(reinterpret_cast<gmx::RVec*>(x), mtop->natoms),
- pbc, g, c_pullGroupSmallGroupThreshold);
+ *pull_work,
+ gmx::arrayRefFromArray(reinterpret_cast<gmx::RVec*>(x), mtop->natoms),
+ pbc,
+ g,
+ c_pullGroupSmallGroupThreshold);
if (!groupObeysPbc)
{
char buf[STRLEN];
"atom should be chosen as pbcatom. Pull group %d is larger than that and "
"does not have "
"a specific atom selected as reference atom.",
- c_pullGroupSmallGroupThreshold, g);
+ c_pullGroupSmallGroupThreshold,
+ g);
warning_error(wi, buf);
}
else if (!pull->bSetPbcRefToPrevStepCOM)
"other "
"atoms in the group is larger than %g times half the box size. "
"Set the pull-pbc-ref-prev-step-com option to yes.",
- pull->group[g].pbcatom + 1, g, c_pullGroupSmallGroupThreshold);
+ pull->group[g].pbcatom + 1,
+ g,
+ c_pullGroupSmallGroupThreshold);
warning_error(wi, buf);
}
}
if (groupObeysPbc)
{
groupObeysPbc = pullCheckPbcWithinGroup(
- *pull_work, gmx::arrayRefFromArray(reinterpret_cast<gmx::RVec*>(x), mtop->natoms),
- pbc, g, c_pullGroupPbcMargin);
+ *pull_work,
+ gmx::arrayRefFromArray(reinterpret_cast<gmx::RVec*>(x), mtop->natoms),
+ pbc,
+ g,
+ c_pullGroupPbcMargin);
if (!groupObeysPbc)
{
char buf[STRLEN];
"size from the PBC atom (%d). "
"If atoms are or will more beyond half the box size from the PBC atom, the "
"COM will be ill defined.",
- g, c_pullGroupPbcMargin, pull->group[g].pbcatom + 1);
+ g,
+ c_pullGroupPbcMargin,
+ pull->group[g].pbcatom + 1);
set_warning_line(wi, nullptr, -1);
warning(wi, buf);
}
gmx_fatal(FARGS,
"The initial pull distance (%g) needs to be non-negative with geometry "
"%s. If you want a signed distance, use geometry %s instead.",
- pcrd->init, EPULLGEOM(pcrd->eGeom), EPULLGEOM(epullgDIR));
+ pcrd->init,
+ EPULLGEOM(pcrd->eGeom),
+ EPULLGEOM(epullgDIR));
}
/* TODO: With a positive init but a negative rate things could still
sprintf(warn_buf, "rot-vec%d = 0", g);
warning_error(wi, warn_buf);
}
- fprintf(stderr, "%s Group %d (%s) normalized rot. vector: %f %f %f\n", RotStr, g,
- erotg_names[rotg->eType], vec[0], vec[1], vec[2]);
+ fprintf(stderr,
+ "%s Group %d (%s) normalized rot. vector: %f %f %f\n",
+ RotStr,
+ g,
+ erotg_names[rotg->eType],
+ vec[0],
+ vec[1],
+ vec[2]);
for (m = 0; m < DIM; m++)
{
rotg->inputVec[m] = vec[m];
warning_error(wi, warn_buf);
}
printStringNoNewline(
- inp,
- "For fit type 'potential', distance in degrees between two consecutive angles");
+ inp, "For fit type 'potential', distance in degrees between two consecutive angles");
sprintf(buf, "rot-potfit-step%d", g);
rotg->PotAngle_step = get_ereal(inp, buf, 0.25, wi);
}
gmx_fatal(FARGS,
"%s The file containing the reference positions was not found.\n"
"Expected the file '%s' for group %d.\n",
- RotStr, reffile, g);
+ RotStr,
+ reffile,
+ g);
}
if (gmx_fexist(reffile))
gmx_fatal(FARGS,
"Number of atoms in file %s (%d) does not match the number of atoms in "
"rotation group (%d)!\n",
- reffile, header.natoms, rotg->nat);
+ reffile,
+ header.natoms,
+ rotg->nat);
}
- gmx_trr_read_single_frame(reffile, &header.step, &header.t, &header.lambda, f_box,
- &header.natoms, rotg->x_ref, nullptr, nullptr);
+ gmx_trr_read_single_frame(
+ reffile, &header.step, &header.t, &header.lambda, f_box, &header.natoms, rotg->x_ref, nullptr, nullptr);
/* Check whether the box is unchanged and output a warning if not: */
check_box_unchanged(f_box, box, reffile, wi);
if (rotg->nat > 0)
{
- fprintf(stderr, "Rotation group %d '%s' has %d atoms\n", g, rotateGroupNames[g].c_str(),
- rotg->nat);
+ fprintf(stderr, "Rotation group %d '%s' has %d atoms\n", g, rotateGroupNames[g].c_str(), rotg->nat);
snew(rotg->ind, rotg->nat);
for (i = 0; i < rotg->nat; i++)
{
{
gmx_fatal(FARGS, "Incorrect atomtype (%d)", tp);
}
- fprintf(out, "%6s %6s %8.3f %6d\n", *(rtpDBEntry.atomname[j]), tpnm,
- rtpDBEntry.atom[j].q, rtpDBEntry.cgnr[j]);
+ fprintf(out,
+ "%6s %6s %8.3f %6d\n",
+ *(rtpDBEntry.atomname[j]),
+ tpnm,
+ rtpDBEntry.atom[j].q,
+ rtpDBEntry.cgnr[j]);
}
}
gmx_fatal(FARGS,
"Atom type %s (residue %s) not found in atomtype "
"database",
- buf1, r0->resname.c_str());
+ buf1,
+ r0->resname.c_str());
}
r0->atom.back().type = j;
r0->atom.back().m = atype->atomMassFromAtomType(j);
fprintf(out,
"; bonds angles dihedrals impropers all_dihedrals nr_exclusions HH14 "
"remove_dih\n");
- fprintf(out, " %5d %6d %9d %9d %14d %14d %14d %14d\n\n", rtpDBEntry[0].rb[0].type,
- rtpDBEntry[0].rb[1].type, rtpDBEntry[0].rb[2].type, rtpDBEntry[0].rb[3].type,
- static_cast<int>(rtpDBEntry[0].bKeepAllGeneratedDihedrals), rtpDBEntry[0].nrexcl,
+ fprintf(out,
+ " %5d %6d %9d %9d %14d %14d %14d %14d\n\n",
+ rtpDBEntry[0].rb[0].type,
+ rtpDBEntry[0].rb[1].type,
+ rtpDBEntry[0].rb[2].type,
+ rtpDBEntry[0].rb[3].type,
+ static_cast<int>(rtpDBEntry[0].bKeepAllGeneratedDihedrals),
+ rtpDBEntry[0].nrexcl,
static_cast<int>(rtpDBEntry[0].bGenerateHH14Interactions),
static_cast<int>(rtpDBEntry[0].bRemoveDihedralIfWithImproper));
}
"remove_dih");
GMX_LOG(logger.info)
.asParagraph()
- .appendTextFormatted(
- " %5d %6d %9d %9d %14d %14d %14d %14d", rtpDBEntry[0].rb[0].type,
- rtpDBEntry[0].rb[1].type, rtpDBEntry[0].rb[2].type, rtpDBEntry[0].rb[3].type,
- static_cast<int>(rtpDBEntry[0].bKeepAllGeneratedDihedrals),
- rtpDBEntry[0].nrexcl, static_cast<int>(rtpDBEntry[0].bGenerateHH14Interactions),
- static_cast<int>(rtpDBEntry[0].bRemoveDihedralIfWithImproper));
+ .appendTextFormatted(" %5d %6d %9d %9d %14d %14d %14d %14d",
+ rtpDBEntry[0].rb[0].type,
+ rtpDBEntry[0].rb[1].type,
+ rtpDBEntry[0].rb[2].type,
+ rtpDBEntry[0].rb[3].type,
+ static_cast<int>(rtpDBEntry[0].bKeepAllGeneratedDihedrals),
+ rtpDBEntry[0].nrexcl,
+ static_cast<int>(rtpDBEntry[0].bGenerateHH14Interactions),
+ static_cast<int>(rtpDBEntry[0].bRemoveDihedralIfWithImproper));
}
if (gmx::equalCaseInsensitive("bondedtypes", header, 5))
{
get_a_line(in, line, STRLEN);
- if ((nparam = sscanf(line, "%d %d %d %d %d %d %d %d", &header_settings.rb[ebtsBONDS].type,
+ if ((nparam = sscanf(line,
+ "%d %d %d %d %d %d %d %d",
+ &header_settings.rb[ebtsBONDS].type,
&header_settings.rb[ebtsANGLES].type,
- &header_settings.rb[ebtsPDIHS].type, &header_settings.rb[ebtsIDIHS].type,
- &dum1, &header_settings.nrexcl, &dum2, &dum3))
+ &header_settings.rb[ebtsPDIHS].type,
+ &header_settings.rb[ebtsIDIHS].type,
+ &dum1,
+ &header_settings.nrexcl,
+ &dum2,
+ &dum3))
< 4)
{
- gmx_fatal(FARGS, "need 4 to 8 parameters in the header of .rtp file %s at line:\n%s\n",
- rrdb.c_str(), line);
+ gmx_fatal(FARGS,
+ "need 4 to 8 parameters in the header of .rtp file %s at line:\n%s\n",
+ rrdb.c_str(),
+ line);
}
header_settings.bKeepAllGeneratedDihedrals = (dum1 != 0);
header_settings.bGenerateHH14Interactions = (dum2 != 0);
gmx_fatal(FARGS, "No atoms found in .rtp file in residue %s\n", res->resname.c_str());
}
- auto found = std::find_if(rtpDBEntry->begin(), rtpDBEntry->end() - 1,
- [&res](const PreprocessResidue& entry) {
- return gmx::equalCaseInsensitive(entry.resname, res->resname);
- });
+ auto found = std::find_if(
+ rtpDBEntry->begin(), rtpDBEntry->end() - 1, [&res](const PreprocessResidue& entry) {
+ return gmx::equalCaseInsensitive(entry.resname, res->resname);
+ });
if (found != rtpDBEntry->end() - 1)
{
if (found >= oldArrayEnd)
{
- gmx_fatal(FARGS, "Found a second entry for '%s' in '%s'", res->resname.c_str(),
- rrdb.c_str());
+ gmx_fatal(FARGS, "Found a second entry for '%s' in '%s'", res->resname.c_str(), rrdb.c_str());
}
if (bAllowOverrideRTP)
{
.appendTextFormatted(
"Found another rtp entry for '%s' in '%s',"
" ignoring this entry and keeping the one from '%s.rtp'",
- res->resname.c_str(), rrdb.c_str(), found->filebase.c_str());
+ res->resname.c_str(),
+ rrdb.c_str(),
+ found->filebase.c_str());
/* We should free all the data for this entry.
* The current code gives a lot of dangling pointers.
*/
gmx_fatal(FARGS,
"Found rtp entries for '%s' in both '%s' and '%s'. If you want the first "
"definition to override the second one, set the -rtpo option of pdb2gmx.",
- res->resname.c_str(), found->filebase.c_str(), rrdb.c_str());
+ res->resname.c_str(),
+ found->filebase.c_str(),
+ rrdb.c_str());
}
}
}
std::sort(rtpDBEntry->begin(), rtpDBEntry->end(), [](const PreprocessResidue& a, const PreprocessResidue& b) {
return std::lexicographical_compare(
- a.resname.begin(), a.resname.end(), b.resname.begin(), b.resname.end(),
+ a.resname.begin(),
+ a.resname.end(),
+ b.resname.begin(),
+ b.resname.end(),
[](const char& c1, const char& c2) { return std::toupper(c1) < std::toupper(c2); });
});
}
if (nbest > 1)
{
- gmx_fatal(FARGS, "Residue '%s' not found in residue topology database, looks a bit like %s",
- key.c_str(), bestbuf.c_str());
+ gmx_fatal(FARGS,
+ "Residue '%s' not found in residue topology database, looks a bit like %s",
+ key.c_str(),
+ bestbuf.c_str());
}
else if (besti == -1)
{
.appendTextFormatted(
"'%s' not found in residue topology database, "
"trying to use '%s'",
- key.c_str(), rtpDBEntry[besti].resname.c_str());
+ key.c_str(),
+ rtpDBEntry[besti].resname.c_str());
}
return rtpDBEntry[besti].resname;
gmx::ArrayRef<const PreprocessResidue>::const_iterator
getDatabaseEntry(const std::string& rtpname, gmx::ArrayRef<const PreprocessResidue> rtpDBEntry)
{
- auto found = std::find_if(rtpDBEntry.begin(), rtpDBEntry.end(),
- [&rtpname](const PreprocessResidue& entry) {
- return gmx::equalCaseInsensitive(rtpname, entry.resname);
- });
+ auto found = std::find_if(
+ rtpDBEntry.begin(), rtpDBEntry.end(), [&rtpname](const PreprocessResidue& entry) {
+ return gmx::equalCaseInsensitive(rtpname, entry.resname);
+ });
if (found == rtpDBEntry.end())
{
/* This should never happen, since searchResidueDatabase should have been called
{
numAtomsInMolType++;
}
- molTypes.emplace_back(MoleculeType{ *atoms->resinfo[atoms->atom[i].resind].name,
- numAtomsInMolType, 1 });
+ molTypes.emplace_back(MoleculeType{
+ *atoms->resinfo[atoms->atom[i].resind].name, numAtomsInMolType, 1 });
}
else
{
}
}
- fprintf(stderr, "Found %zu%s molecule type%s:\n", molTypes.size(),
- molTypes.size() == 1 ? "" : " different", molTypes.size() == 1 ? "" : "s");
+ fprintf(stderr,
+ "Found %zu%s molecule type%s:\n",
+ molTypes.size(),
+ molTypes.size() == 1 ? "" : " different",
+ molTypes.size() == 1 ? "" : "s");
for (const auto& molType : molTypes)
{
- fprintf(stderr, "%7s (%4d atoms): %5d residues\n", molType.name.c_str(), molType.numAtoms,
- molType.numMolecules);
+ fprintf(stderr, "%7s (%4d atoms): %5d residues\n", molType.name.c_str(), molType.numAtoms, molType.numMolecules);
}
/* if we have only 1 moleculetype, we don't have to sort */
}
nmol *= n_box[i];
}
- fprintf(stderr, "Will generate new solvent configuration of %dx%dx%d boxes\n", n_box[XX],
- n_box[YY], n_box[ZZ]);
+ fprintf(stderr, "Will generate new solvent configuration of %dx%dx%d boxes\n", n_box[XX], n_box[YY], n_box[ZZ]);
// Create arrays for storing the generated system (cannot be done in-place
// in case the target box is smaller than the original in one dimension,
remover.removeMarkedElements(r);
const int originalAtomCount = atoms->nr;
remover.removeMarkedAtoms(atoms);
- fprintf(stderr, "Removed %d solvent atoms due to solvent-solvent overlap\n",
- originalAtomCount - atoms->nr);
+ fprintf(stderr, "Removed %d solvent atoms due to solvent-solvent overlap\n", originalAtomCount - atoms->nr);
}
/*! \brief
remover.removeMarkedElements(r);
const int originalAtomCount = atoms->nr;
remover.removeMarkedAtoms(atoms);
- fprintf(stderr, "Removed %d solvent atoms more than %f nm from solute.\n",
- originalAtomCount - atoms->nr, rshell);
+ fprintf(stderr,
+ "Removed %d solvent atoms more than %f nm from solute.\n",
+ originalAtomCount - atoms->nr,
+ rshell);
}
/*! \brief
remover.removeMarkedElements(r);
const int originalAtomCount = atoms->nr;
remover.removeMarkedAtoms(atoms);
- fprintf(stderr, "Removed %d solvent atoms due to solute-solvent overlap\n",
- originalAtomCount - atoms->nr);
+ fprintf(stderr, "Removed %d solvent atoms due to solute-solvent overlap\n", originalAtomCount - atoms->nr);
}
/*! \brief
fprintf(stderr, "Reading solvent configuration\n");
bool bTprFileWasRead;
rvec *temporaryX = nullptr, *temporaryV = nullptr;
- readConfAndTopology(gmx::findLibraryFile(filename).c_str(), &bTprFileWasRead, &topSolvent,
- &pbcTypeSolvent, &temporaryX, &temporaryV, boxSolvent);
+ readConfAndTopology(gmx::findLibraryFile(filename).c_str(),
+ &bTprFileWasRead,
+ &topSolvent,
+ &pbcTypeSolvent,
+ &temporaryX,
+ &temporaryV,
+ boxSolvent);
t_atoms* atomsSolvent;
snew(atomsSolvent, 1);
*atomsSolvent = gmx_mtop_global_atoms(&topSolvent);
{
if (rshell > 0.0)
{
- removeSolventOutsideShell(atomsSolvent, &xSolvent, &vSolvent, &exclusionDistances_solvt,
- pbc, *x, rshell);
+ removeSolventOutsideShell(
+ atomsSolvent, &xSolvent, &vSolvent, &exclusionDistances_solvt, pbc, *x, rshell);
}
- removeSolventOverlappingWithSolute(atomsSolvent, &xSolvent, &vSolvent,
- &exclusionDistances_solvt, pbc, *x, exclusionDistances);
+ removeSolventOverlappingWithSolute(
+ atomsSolvent, &xSolvent, &vSolvent, &exclusionDistances_solvt, pbc, *x, exclusionDistances);
}
if (max_sol > 0 && atomsSolvent->nres > max_sol)
gmx::AtomsBuilder builder(atoms, symtab);
builder.mergeAtoms(*sortedAtomsSolvent);
}
- fprintf(stderr, "Generated solvent containing %d atoms in %d residues\n", atomsSolvent->nr,
+ fprintf(stderr,
+ "Generated solvent containing %d atoms in %d residues\n",
+ atomsSolvent->nr,
atomsSolvent->nres);
if (newatoms)
mtot = 0;
for (i = 0; (i < atoms->nr); i++)
{
- aps->setAtomProperty(epropMass, std::string(*atoms->resinfo[atoms->atom[i].resind].name),
- std::string(*atoms->atomname[i]), &mm);
+ aps->setAtomProperty(epropMass,
+ std::string(*atoms->resinfo[atoms->atom[i].resind].name),
+ std::string(*atoms->atomname[i]),
+ &mm);
mtot += mm;
}
fprintf(stdout,
"Adding line for %d solvent molecules with resname (%s) to "
"topology file (%s)\n",
- resCount, currRes.c_str(), topinout);
+ resCount,
+ currRes.c_str(),
+ topinout);
fprintf(fpout, "%-15s %5d\n", currRes.c_str(), resCount);
currRes = *atoms->resinfo[i].name;
resCount = 1;
fprintf(stdout,
"Adding line for %d solvent molecules with resname (%s) to "
"topology file (%s)\n",
- resCount, currRes.c_str(), topinout);
+ resCount,
+ currRes.c_str(),
+ topinout);
fprintf(fpout, "%-15s %5d\n", currRes.c_str(), resCount);
}
gmx_ffclose(fpout);
{ "-vel", FALSE, etBOOL, { &bReadV }, "Keep velocities from input solute and solvent" },
};
- if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa, asize(desc), desc,
- asize(bugs), bugs, &oenv))
+ if (!parse_common_args(
+ &argc, argv, 0, NFILE, fnm, asize(pa), pa, asize(desc), desc, asize(bugs), bugs, &oenv))
{
return 0;
}
fprintf(stderr, "Reading solute configuration%s\n", bReadV ? " and velocities" : "");
bool bTprFileWasRead;
rvec *temporaryX = nullptr, *temporaryV = nullptr;
- readConfAndTopology(conf_prot, &bTprFileWasRead, &top, &pbcType, &temporaryX,
- bReadV ? &temporaryV : nullptr, box);
+ readConfAndTopology(
+ conf_prot, &bTprFileWasRead, &top, &pbcType, &temporaryX, bReadV ? &temporaryV : nullptr, box);
*atoms = gmx_mtop_global_atoms(&top);
x.assign(temporaryX, temporaryX + top.natoms);
sfree(temporaryX);
"or give explicit -box command line option");
}
- add_solv(solventFileName, atoms, &top.symtab, &x, &v, pbcTypeForOutput, box, &aps,
- defaultDistance, scaleFactor, r_shell, max_sol);
+ add_solv(solventFileName, atoms, &top.symtab, &x, &v, pbcTypeForOutput, box, &aps, defaultDistance, scaleFactor, r_shell, max_sol);
/* write new configuration 1 to file confout */
confout = ftp2fn(efSTO, NFILE, fnm);
fprintf(stderr, "Writing generated configuration to %s\n", confout);
const char* outputTitle = (bProt ? *top.name : "Generated by gmx solvate");
- write_sto_conf(confout, outputTitle, atoms, as_rvec_array(x.data()),
- !v.empty() ? as_rvec_array(v.data()) : nullptr, pbcTypeForOutput, box);
+ write_sto_conf(confout,
+ outputTitle,
+ atoms,
+ as_rvec_array(x.data()),
+ !v.empty() ? as_rvec_array(v.data()) : nullptr,
+ pbcTypeForOutput,
+ box);
/* print size of generated configuration */
fprintf(stderr, "\nOutput configuration contains %d atoms in %d residues\n", atoms->nr, atoms->nres);
int nlines = get_lines(sbfile, &lines);
for (int i = 0; (i < nlines); i++)
{
- if (sscanf(lines[i], "%s%s%d%s%s%d%lf%s%s", r1buf, a1buf, &nb1, r2buf, a2buf, &nb2, &length,
- nr1buf, nr2buf)
+ if (sscanf(lines[i], "%s%s%d%s%s%d%lf%s%s", r1buf, a1buf, &nb1, r2buf, a2buf, &nb2, &length, nr1buf, nr2buf)
!= 9)
{
fprintf(stderr, "Invalid line '%s' in %s\n", lines[i], sbfile);
{
sfree(lines);
}
- fprintf(stderr, "%zu out of %d lines of %s converted successfully\n", specialBonds.size(),
- nlines, sbfile);
+ fprintf(stderr, "%zu out of %d lines of %s converted successfully\n", specialBonds.size(), nlines, sbfile);
return specialBonds;
}
{
if (bVerbose)
{
- printf("Using rtp entry %s for %s %d\n", newres, *pdba->resinfo[resind].name,
+ printf("Using rtp entry %s for %s %d\n",
+ newres,
+ *pdba->resinfo[resind].name,
pdba->resinfo[resind].nr);
}
/* this used to free *resname, which messes up the symtab! */
int e = std::min(b + MAXCOL, nspec - 1);
for (int i = b; (i < e); i++)
{
- sprintf(buf, "%s%d", *pdba->resinfo[pdba->atom[specialBondAtomIdxs[i]].resind].name,
+ sprintf(buf,
+ "%s%d",
+ *pdba->resinfo[pdba->atom[specialBondAtomIdxs[i]].resind].name,
pdba->resinfo[specialBondResIdxs[i]].nr);
fprintf(stderr, "%8s", buf);
}
e = std::min(b + MAXCOL, nspec - 1);
for (int i = b; (i < e); i++)
{
- std::string buf = gmx::formatString("%s%d", *pdba->atomname[specialBondAtomIdxs[i]],
- specialBondAtomIdxs[i] + 1);
+ std::string buf = gmx::formatString(
+ "%s%d", *pdba->atomname[specialBondAtomIdxs[i]], specialBondAtomIdxs[i] + 1);
fprintf(stderr, "%8s", buf.c_str());
}
fprintf(stderr, "\n");
for (int i = b + 1; (i < nspec); i++)
{
std::string buf = gmx::formatString(
- "%s%d", *pdba->resinfo[pdba->atom[specialBondAtomIdxs[i]].resind].name,
+ "%s%d",
+ *pdba->resinfo[pdba->atom[specialBondAtomIdxs[i]].resind].name,
pdba->resinfo[specialBondResIdxs[i]].nr);
fprintf(stderr, "%8s", buf.c_str());
- buf = gmx::formatString("%s%d", *pdba->atomname[specialBondAtomIdxs[i]],
- specialBondAtomIdxs[i] + 1);
+ buf = gmx::formatString(
+ "%s%d", *pdba->atomname[specialBondAtomIdxs[i]], specialBondAtomIdxs[i] + 1);
fprintf(stderr, "%8s", buf.c_str());
int e2 = std::min(i, e);
for (int j = b; (j < e2); j++)
if (bonds.size() < specialBondAtomIdxs.size()
&& is_bond(specialBonds, pdba, ai, aj, d[i][j], &index_sb, &bSwap))
{
- fprintf(stderr, "%s %s-%d %s-%d and %s-%d %s-%d%s", bInteractive ? "Link" : "Linking",
+ fprintf(stderr,
+ "%s %s-%d %s-%d and %s-%d %s-%d%s",
+ bInteractive ? "Link" : "Linking",
*pdba->resinfo[pdba->atom[ai].resind].name,
- pdba->resinfo[specialBondResIdxs[i]].nr, *pdba->atomname[ai], ai + 1,
+ pdba->resinfo[specialBondResIdxs[i]].nr,
+ *pdba->atomname[ai],
+ ai + 1,
*pdba->resinfo[pdba->atom[aj].resind].name,
- pdba->resinfo[specialBondResIdxs[j]].nr, *pdba->atomname[aj], aj + 1,
+ pdba->resinfo[specialBondResIdxs[j]].nr,
+ *pdba->atomname[aj],
+ aj + 1,
bInteractive ? " (y/n) ?" : "...\n");
bool bDoit = bInteractive ? yesno() : true;
/* rename residues */
if (bSwap)
{
- rename_1res(pdba, specialBondResIdxs[i],
- specialBonds[index_sb].newSecondResidue.c_str(), bVerbose);
- rename_1res(pdba, specialBondResIdxs[j],
- specialBonds[index_sb].newFirstResidue.c_str(), bVerbose);
+ rename_1res(pdba,
+ specialBondResIdxs[i],
+ specialBonds[index_sb].newSecondResidue.c_str(),
+ bVerbose);
+ rename_1res(pdba,
+ specialBondResIdxs[j],
+ specialBonds[index_sb].newFirstResidue.c_str(),
+ bVerbose);
}
else
{
- rename_1res(pdba, specialBondResIdxs[i],
- specialBonds[index_sb].newFirstResidue.c_str(), bVerbose);
- rename_1res(pdba, specialBondResIdxs[j],
- specialBonds[index_sb].newSecondResidue.c_str(), bVerbose);
+ rename_1res(pdba,
+ specialBondResIdxs[i],
+ specialBonds[index_sb].newFirstResidue.c_str(),
+ bVerbose);
+ rename_1res(pdba,
+ specialBondResIdxs[j],
+ specialBonds[index_sb].newSecondResidue.c_str(),
+ bVerbose);
}
}
}
gmx_fatal(FARGS,
"Reading Termini Database: expected %d or %d items of atom data in stead of %d "
"on line\n%s",
- 3, 4, nr, line);
+ 3,
+ 4,
+ nr,
+ line);
}
i = 0;
if (!bAdd)
{
fprintf(out, "[ %s ]\n", modification.name.c_str());
- if (std::any_of(modification.hack.begin(), modification.hack.end(),
- [](const auto& mod) { return mod.type() == MoleculePatchType::Replace; }))
+ if (std::any_of(modification.hack.begin(), modification.hack.end(), [](const auto& mod) {
+ return mod.type() == MoleculePatchType::Replace;
+ }))
{
fprintf(out, "[ %s ]\n", kw_names[ekwRepl - ebtsNR - 1]);
for (const auto& hack : modification.hack)
}
}
}
- if (std::any_of(modification.hack.begin(), modification.hack.end(),
- [](const auto& mod) { return mod.type() == MoleculePatchType::Add; }))
+ if (std::any_of(modification.hack.begin(), modification.hack.end(), [](const auto& mod) {
+ return mod.type() == MoleculePatchType::Add;
+ }))
{
fprintf(out, "[ %s ]\n", kw_names[ekwAdd - ebtsNR - 1]);
for (const auto& hack : modification.hack)
}
}
}
- if (std::any_of(modification.hack.begin(), modification.hack.end(),
- [](const auto& mod) { return mod.type() == MoleculePatchType::Delete; }))
+ if (std::any_of(modification.hack.begin(), modification.hack.end(), [](const auto& mod) {
+ return mod.type() == MoleculePatchType::Delete;
+ }))
{
fprintf(out, "[ %s ]\n", kw_names[ekwDel - ebtsNR - 1]);
for (const auto& hack : modification.hack)
gmx_fatal(FARGS,
"Reading Termini Database '%s': "
"expected atom name on line\n%s",
- fn, line);
+ fn,
+ line);
}
hack->oname = buf;
/* we only replace or delete one atom at a time */
if (kwnr == ekwRepl || kwnr == ekwAdd)
{
hack->atom.emplace_back();
- read_atom(line + n, kwnr == ekwAdd, &hack->nname, &hack->atom.back(), atype,
- &hack->cgnr);
+ read_atom(line + n, kwnr == ekwAdd, &hack->nname, &hack->atom.back(), atype, &hack->cgnr);
if (hack->nname.empty())
{
if (!hack->oname.empty())
gmx_fatal(FARGS,
"Reading Termini Database '%s': don't know which name the "
"new atom should have on line\n%s",
- fn, line);
+ fn,
+ line);
}
}
}
gmx_fatal(FARGS,
"Reading Termini Database '%s': expected %d atom names (found "
"%d) on line\n%s",
- fn, btsNiatoms[kwnr], j - 1, line);
+ fn,
+ btsNiatoms[kwnr],
+ j - 1,
+ line);
}
n += ni;
}
for (const auto& modification : tb)
{
bool bIsZwitterion = (0 == gmx_wcmatch("*ZWITTERION*", modification->name.c_str()));
- printf("%2d: %s%s\n", i, modification->name.c_str(),
+ printf("%2d: %s%s\n",
+ i,
+ modification->name.c_str(),
bIsZwitterion ? " (only use with zwitterions containing exactly one residue)" : "");
i++;
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2013,2014,2015,2016,2019, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016,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.
gmx::test::TestReferenceChecker rootChecker(this->rootChecker());
rootChecker.checkString(args.toString(), "CommandLine");
- ASSERT_EQ(0, gmx::test::CommandLineTestHelper::runModuleFactory(
- &gmx::InsertMoleculesInfo::create, &cmdline));
+ ASSERT_EQ(0,
+ gmx::test::CommandLineTestHelper::runModuleFactory(
+ &gmx::InsertMoleculesInfo::create, &cmdline));
checkOutputFiles();
}
TEST_F(InsertMoleculesTest, InsertsMoleculesIntoFixedPositions)
{
const char* const cmdline[] = { "insert-molecules", "-box", "4", "-seed", "1997" };
- const char* const positions[] = { "0.0 0.0 0.0", "1.0 2.0 3.0", "0.99 2.01 3.0",
- "2.0 1.0 2.0" };
+ const char* const positions[] = {
+ "0.0 0.0 0.0", "1.0 2.0 3.0", "0.99 2.01 3.0", "2.0 1.0 2.0"
+ };
setInputFile("-ci", "x0.gro");
setInputFileContents("-ip", "dat", positions);
runTest(CommandLine(cmdline));
TextWriter::writeFileFromString(inputMdpFilename, inputMdpFileContents);
- get_ir(inputMdpFilename.c_str(), outputMdpFilename.c_str(), &mdModules_, &ir_, &opts_,
- WriteMdpHeader::no, wi_);
+ get_ir(inputMdpFilename.c_str(), outputMdpFilename.c_str(), &mdModules_, &ir_, &opts_, WriteMdpHeader::no, wi_);
check_ir(inputMdpFilename.c_str(), mdModules_.notifier(), &ir_, &opts_, wi_);
// Now check
dh_hist_spacing = 0.1
; Non-equilibrium MD stuff
-acc-grps =
-accelerate =
freezegrps =
freezedim =
cos-acceleration = 0
dh_hist_spacing = 0.1
; Non-equilibrium MD stuff
-acc-grps =
-accelerate =
freezegrps =
freezedim =
cos-acceleration = 0
dh_hist_spacing = 0.1
; Non-equilibrium MD stuff
-acc-grps =
-accelerate =
freezegrps =
freezedim =
cos-acceleration = 0
dh_hist_spacing = 0.1
; Non-equilibrium MD stuff
-acc-grps =
-accelerate =
freezegrps =
freezedim =
cos-acceleration = 0
dh_hist_spacing = 0.1
; Non-equilibrium MD stuff
-acc-grps =
-accelerate =
freezegrps =
freezedim =
cos-acceleration = 0
dh_hist_spacing = 0.1
; Non-equilibrium MD stuff
-acc-grps =
-accelerate =
freezegrps =
freezedim =
cos-acceleration = 0
dh_hist_spacing = 0.1
; Non-equilibrium MD stuff
-acc-grps =
-accelerate =
freezegrps =
freezedim =
cos-acceleration = 0
dh_hist_spacing = 0.1
; Non-equilibrium MD stuff
-acc-grps =
-accelerate =
freezegrps =
freezedim =
cos-acceleration = 0
dh_hist_spacing = 0.1
; Non-equilibrium MD stuff
-acc-grps =
-accelerate =
freezegrps =
freezedim =
cos-acceleration = 0
{
int ni = harmonic->ai();
int nj = harmonic->aj();
- real edis = search_e_diss(n2m, t2m,
+ real edis = search_e_diss(n2m,
+ t2m,
atype->atomNameFromAtomType(mol.atoms.atom[ni].type),
atype->atomNameFromAtomType(mol.atoms.atom[nj].type));
if (edis != 0)
}
int newHarmonics = mol.interactions[bb].size();
- fprintf(stderr, "Converted %d out of %d %s to morse bonds for mol %d\n",
- nrharm - newHarmonics, nrharm, interaction_function[bb].name, i);
+ fprintf(stderr,
+ "Converted %d out of %d %s to morse bonds for mol %d\n",
+ nrharm - newHarmonics,
+ nrharm,
+ interaction_function[bb].name,
+ i);
}
}
i++;
/* Must correspond to the Directive enum in grompp_impl.h */
static gmx::EnumerationArray<Directive, const char*> directive_names = {
- { "defaults", "atomtypes", "bondtypes", "constrainttypes", "pairtypes", "angletypes",
- "dihedraltypes", "nonbond_params", "implicit_genborn_params", "implicit_surface_params",
+ { "defaults",
+ "atomtypes",
+ "bondtypes",
+ "constrainttypes",
+ "pairtypes",
+ "angletypes",
+ "dihedraltypes",
+ "nonbond_params",
+ "implicit_genborn_params",
+ "implicit_surface_params",
"cmaptypes",
/* All the directives above can not appear after moleculetype */
- "moleculetype", "atoms", "virtual_sites1", "virtual_sites2", "virtual_sites3",
- "virtual_sites4", "virtual_sitesn", "bonds", "exclusions", "pairs", "pairs_nb", "angles",
- "dihedrals", "constraints", "settles", "polarization", "water_polarization",
- "thole_polarization", "system", "molecules", "position_restraints", "angle_restraints",
- "angle_restraints_z", "distance_restraints", "orientation_restraints", "dihedral_restraints",
- "cmap", "intermolecular_interactions", "maxdirs", "invalid", "none" }
+ "moleculetype",
+ "atoms",
+ "virtual_sites1",
+ "virtual_sites2",
+ "virtual_sites3",
+ "virtual_sites4",
+ "virtual_sitesn",
+ "bonds",
+ "exclusions",
+ "pairs",
+ "pairs_nb",
+ "angles",
+ "dihedrals",
+ "constraints",
+ "settles",
+ "polarization",
+ "water_polarization",
+ "thole_polarization",
+ "system",
+ "molecules",
+ "position_restraints",
+ "angle_restraints",
+ "angle_restraints_z",
+ "distance_restraints",
+ "orientation_restraints",
+ "dihedral_restraints",
+ "cmap",
+ "intermolecular_interactions",
+ "maxdirs",
+ "invalid",
+ "none" }
};
int ifunc_index(Directive d, int type)
// be in the same place that was valid in old versions (ie. child
// directive of [atomtypes]) but any relevant case will
// satisfy that.
- set_nec(&(necessary[Directive::d_implicit_genborn_params]), Directive::d_atomtypes,
- Directive::d_none);
- set_nec(&(necessary[Directive::d_implicit_surface_params]), Directive::d_atomtypes,
- Directive::d_none);
+ set_nec(&(necessary[Directive::d_implicit_genborn_params]), Directive::d_atomtypes, Directive::d_none);
+ set_nec(&(necessary[Directive::d_implicit_surface_params]), Directive::d_atomtypes, Directive::d_none);
set_nec(&(necessary[Directive::d_cmaptypes]), Directive::d_atomtypes, Directive::d_none);
set_nec(&(necessary[Directive::d_moleculetype]), Directive::d_atomtypes, Directive::d_none);
set_nec(&(necessary[Directive::d_atoms]), Directive::d_moleculetype, Directive::d_none);
set_nec(&(necessary[Directive::d_vsites4]), Directive::d_atoms, Directive::d_none);
set_nec(&(necessary[Directive::d_vsitesn]), Directive::d_atoms, Directive::d_none);
set_nec(&(necessary[Directive::d_bonds]), Directive::d_atoms, Directive::d_none);
- set_nec(&(necessary[Directive::d_exclusions]), Directive::d_bonds, Directive::d_constraints,
- Directive::d_settles, Directive::d_none);
+ set_nec(&(necessary[Directive::d_exclusions]),
+ Directive::d_bonds,
+ Directive::d_constraints,
+ Directive::d_settles,
+ Directive::d_none);
set_nec(&(necessary[Directive::d_pairs]), Directive::d_atoms, Directive::d_none);
set_nec(&(necessary[Directive::d_pairs_nb]), Directive::d_atoms, Directive::d_none);
set_nec(&(necessary[Directive::d_angles]), Directive::d_atoms, Directive::d_none);
set_nec(&(necessary[Directive::d_orientation_restraints]), Directive::d_atoms, Directive::d_none);
set_nec(&(necessary[Directive::d_dihedral_restraints]), Directive::d_atoms, Directive::d_none);
set_nec(&(necessary[Directive::d_cmap]), Directive::d_atoms, Directive::d_none);
- set_nec(&(necessary[Directive::d_intermolecular_interactions]), Directive::d_molecules,
+ set_nec(&(necessary[Directive::d_intermolecular_interactions]),
+ Directive::d_molecules,
Directive::d_none);
}
*DS = nullptr;
if (((m <= 0.0) || (mB <= 0.0)) && ((pt == eptAtom) || (pt == eptNucleus)))
{
ri = atoms->atom[i].resind;
- sprintf(buf, "atom %s (Res %s-%d) has mass %g (state A) / %g (state B)\n",
- *(atoms->atomname[i]), *(atoms->resinfo[ri].name), atoms->resinfo[ri].nr, m, mB);
+ sprintf(buf,
+ "atom %s (Res %s-%d) has mass %g (state A) / %g (state B)\n",
+ *(atoms->atomname[i]),
+ *(atoms->resinfo[ri].name),
+ atoms->resinfo[ri].nr,
+ m,
+ mB);
warning_error(wi, buf);
}
else if (((m != 0) || (mB != 0)) && (pt == eptVSite))
"virtual site %s (Res %s-%d) has non-zero mass %g (state A) / %g (state "
"B)\n"
" Check your topology.\n",
- *(atoms->atomname[i]), *(atoms->resinfo[ri].name), atoms->resinfo[ri].nr, m, mB);
+ *(atoms->atomname[i]),
+ *(atoms->resinfo[ri].name),
+ atoms->resinfo[ri].nr,
+ m,
+ mB);
warning_error(wi, buf);
/* The following statements make LINCS break! */
/* atoms->atom[i].m=0; */
{
/* we should print here which directives should have
been present, and which actually are */
- gmx_fatal(FARGS, "%s\nInvalid order for directive %s",
- cpp_error(&handle, eCPP_SYNTAX), dir2str(newd));
+ gmx_fatal(FARGS,
+ "%s\nInvalid order for directive %s",
+ cpp_error(&handle, eCPP_SYNTAX),
+ dir2str(newd));
/* d = Directive::d_invalid; */
}
case Directive::d_defaults:
if (bReadDefaults)
{
- gmx_fatal(FARGS, "%s\nFound a second defaults directive.\n",
+ gmx_fatal(FARGS,
+ "%s\nFound a second defaults directive.\n",
cpp_error(&handle, eCPP_SYNTAX));
}
bReadDefaults = TRUE;
- nscan = sscanf(pline, "%s%s%s%lf%lf%lf", nb_str, comb_str, genpairs,
- &fLJ, &fQQ, &fPOW);
+ nscan = sscanf(
+ pline, "%s%s%s%lf%lf%lf", nb_str, comb_str, genpairs, &fLJ, &fQQ, &fPOW);
if (nscan < 2)
{
too_few(wi);
break;
case Directive::d_atomtypes:
- push_at(symtab, atypes, &bondAtomType, pline, nb_funct, &nbparam,
- bGenPairs ? &pair : nullptr, wi);
+ push_at(symtab,
+ atypes,
+ &bondAtomType,
+ pline,
+ nb_funct,
+ &nbparam,
+ bGenPairs ? &pair : nullptr,
+ wi);
break;
case Directive::d_bondtypes: // Intended to fall through
|| opts->couple_lam1 == ecouplamNONE
|| opts->couple_lam1 == ecouplamQ))
{
- dcatt = add_atomtype_decoupled(symtab, atypes, &nbparam,
- bGenPairs ? &pair : nullptr);
+ dcatt = add_atomtype_decoupled(
+ symtab, atypes, &nbparam, bGenPairs ? &pair : nullptr);
}
ntype = atypes->size();
ncombs = (ntype * (ntype + 1)) / 2;
- generate_nbparams(*combination_rule, nb_funct,
- &(interactions[nb_funct]), atypes, wi);
+ generate_nbparams(
+ *combination_rule, nb_funct, &(interactions[nb_funct]), atypes, wi);
ncopy = copy_nbparams(nbparam, nb_funct, &(interactions[nb_funct]), ntype);
GMX_LOG(logger.info)
.asParagraph()
.appendTextFormatted(
"Generated %d of the %d non-bonded parameter "
"combinations",
- ncombs - ncopy, ncombs);
+ ncombs - ncopy,
+ ncombs);
free_nbparam(nbparam, ntype);
if (bGenPairs)
{
- gen_pairs((interactions[nb_funct]), &(interactions[F_LJ14]),
- fudgeLJ, *combination_rule);
+ gen_pairs((interactions[nb_funct]),
+ &(interactions[F_LJ14]),
+ fudgeLJ,
+ *combination_rule);
ncopy = copy_nbparams(pair, nb_funct, &(interactions[F_LJ14]), ntype);
GMX_LOG(logger.info)
.asParagraph()
.appendTextFormatted(
"Generated %d of the %d 1-4 parameter "
"combinations",
- ncombs - ncopy, ncombs);
+ ncombs - ncopy,
+ ncombs);
free_nbparam(pair, ntype);
}
/* Copy GBSA parameters to atomtype array? */
GMX_RELEASE_ASSERT(
mi0,
"Need to have a valid MoleculeInformation object to work on");
- push_bond(d, interactions, mi0->interactions, &(mi0->atoms), atypes,
- pline, FALSE, bGenPairs, *fudgeQQ, bZero, &bWarn_copy_A_B, wi);
+ push_bond(d,
+ interactions,
+ mi0->interactions,
+ &(mi0->atoms),
+ atypes,
+ pline,
+ FALSE,
+ bGenPairs,
+ *fudgeQQ,
+ bZero,
+ &bWarn_copy_A_B,
+ wi);
break;
case Directive::d_pairs_nb:
GMX_RELEASE_ASSERT(
mi0,
"Need to have a valid MoleculeInformation object to work on");
- push_bond(d, interactions, mi0->interactions, &(mi0->atoms), atypes,
- pline, FALSE, FALSE, 1.0, bZero, &bWarn_copy_A_B, wi);
+ push_bond(d,
+ interactions,
+ mi0->interactions,
+ &(mi0->atoms),
+ atypes,
+ pline,
+ FALSE,
+ FALSE,
+ 1.0,
+ bZero,
+ &bWarn_copy_A_B,
+ wi);
break;
case Directive::d_vsites1:
GMX_RELEASE_ASSERT(
mi0,
"Need to have a valid MoleculeInformation object to work on");
- push_bond(d, interactions, mi0->interactions, &(mi0->atoms), atypes,
- pline, TRUE, bGenPairs, *fudgeQQ, bZero, &bWarn_copy_A_B, wi);
+ push_bond(d,
+ interactions,
+ mi0->interactions,
+ &(mi0->atoms),
+ atypes,
+ pline,
+ TRUE,
+ bGenPairs,
+ *fudgeQQ,
+ bZero,
+ &bWarn_copy_A_B,
+ wi);
break;
case Directive::d_cmap:
GMX_RELEASE_ASSERT(
.asParagraph()
.appendTextFormatted(
"Excluding %d bonded neighbours molecule type '%s'",
- mi0->nrexcl, *mi0->name);
+ mi0->nrexcl,
+ *mi0->name);
sum_q(&mi0->atoms, nrcopies, &qt, &qBt);
if (!mi0->bProcessed)
{
if (bCouple)
{
- convert_moltype_couple(mi0, dcatt, *fudgeQQ, opts->couple_lam0,
- opts->couple_lam1, opts->bCoupleIntra,
- nb_funct, &(interactions[nb_funct]), wi);
+ convert_moltype_couple(mi0,
+ dcatt,
+ *fudgeQQ,
+ opts->couple_lam0,
+ opts->couple_lam1,
+ opts->bCoupleIntra,
+ nb_funct,
+ &(interactions[nb_funct]),
+ wi);
}
stupid_fill_block(&mi0->mols, mi0->atoms.nr, TRUE);
mi0->bProcessed = TRUE;
}
GMX_LOG(logger.info)
.asParagraph()
- .appendTextFormatted("Coupling %d copies of molecule type '%s'", nmol_couple,
- opts->couple_moltype);
+ .appendTextFormatted(
+ "Coupling %d copies of molecule type '%s'", nmol_couple, opts->couple_moltype);
}
/* this is not very clean, but fixes core dump on empty system name */
}
if (fabs(qBt) > 1e-4 && !gmx_within_tol(qBt, qt, 1e-6))
{
- sprintf(warn_buf, "State B has non-zero total charge: %.6f\n%s\n", qBt,
- floating_point_arithmetic_tip);
+ sprintf(warn_buf, "State B has non-zero total charge: %.6f\n%s\n", qBt, floating_point_arithmetic_tip);
warning_note(wi, warn_buf);
}
if (usingFullRangeElectrostatics && (fabs(qt) > 1e-4 || fabs(qBt) > 1e-4))
{
GMX_LOG(logger.info).asParagraph().appendTextFormatted("processing topology...");
}
- title = read_topol(topfile, tmpfile, opts->define, opts->include, symtab, atypes, molinfo,
- intermolecular_interactions, interactions, combination_rule, repulsion_power,
- opts, fudgeQQ, molblock, ffParametrizedWithHBondConstraints,
- ir->efep != efepNO, bZero, EEL_FULL(ir->coulombtype), wi, logger);
+ title = read_topol(topfile,
+ tmpfile,
+ opts->define,
+ opts->include,
+ symtab,
+ atypes,
+ molinfo,
+ intermolecular_interactions,
+ interactions,
+ combination_rule,
+ repulsion_power,
+ opts,
+ fudgeQQ,
+ molblock,
+ ffParametrizedWithHBondConstraints,
+ ir->efep != efepNO,
+ bZero,
+ EEL_FULL(ir->coulombtype),
+ wi,
+ logger);
if ((*combination_rule != eCOMB_GEOMETRIC) && (ir->vdwtype == evdwUSER))
{
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
snew(atom, 1);
/* First assign input line to temporary array */
- nfields = sscanf(line, "%s%s%s%s%s%s%s%s%s%s%s%s", tmpfield[0], tmpfield[1], tmpfield[2],
- tmpfield[3], tmpfield[4], tmpfield[5], tmpfield[6], tmpfield[7], tmpfield[8],
- tmpfield[9], tmpfield[10], tmpfield[11]);
+ nfields = sscanf(line,
+ "%s%s%s%s%s%s%s%s%s%s%s%s",
+ tmpfield[0],
+ tmpfield[1],
+ tmpfield[2],
+ tmpfield[3],
+ tmpfield[4],
+ tmpfield[5],
+ tmpfield[6],
+ tmpfield[7],
+ tmpfield[8],
+ tmpfield[9],
+ tmpfield[10],
+ tmpfield[11]);
/* Comments on optional fields in the atomtypes section:
*
{
if (have_bonded_type)
{
- nread = sscanf(line, "%s%s%d%lf%lf%s%lf%lf", type, btype, &atomnr, &m, &q,
- ptype, &c[0], &c[1]);
+ nread = sscanf(
+ line, "%s%s%d%lf%lf%s%lf%lf", type, btype, &atomnr, &m, &q, ptype, &c[0], &c[1]);
if (nread < 8)
{
too_few(wi);
{
if (have_bonded_type)
{
- nread = sscanf(line, "%s%s%d%lf%lf%s%lf%lf%lf", type, btype, &atomnr, &m, &q,
- ptype, &c[0], &c[1], &c[2]);
+ nread = sscanf(
+ line, "%s%s%d%lf%lf%s%lf%lf%lf", type, btype, &atomnr, &m, &q, ptype, &c[0], &c[1], &c[2]);
if (nread < 9)
{
too_few(wi);
else
{
/* have_atomic_number && !have_bonded_type */
- nread = sscanf(line, "%s%d%lf%lf%s%lf%lf%lf", type, &atomnr, &m, &q, ptype,
- &c[0], &c[1], &c[2]);
+ nread = sscanf(
+ line, "%s%d%lf%lf%s%lf%lf%lf", type, &atomnr, &m, &q, ptype, &c[0], &c[1], &c[2]);
if (nread < 8)
{
too_few(wi);
if (have_bonded_type)
{
/* !have_atomic_number && have_bonded_type */
- nread = sscanf(line, "%s%s%lf%lf%s%lf%lf%lf", type, btype, &m, &q, ptype, &c[0],
- &c[1], &c[2]);
+ nread = sscanf(
+ line, "%s%s%lf%lf%s%lf%lf%lf", type, btype, &m, &q, ptype, &c[0], &c[1], &c[2]);
if (nread < 8)
{
too_few(wi);
"to suppress this warning with -maxwarn.",
type);
warning(wi, message);
- if ((nr = at->setType(nr, symtab, *atom, type, interactionType, batype_nr, atomnr)) == NOTSET)
+ if ((at->setType(nr, symtab, *atom, type, interactionType, batype_nr, atomnr)) == NOTSET)
{
auto message = gmx::formatString("Replacing atomtype %s failed", type);
warning_error_and_exit(wi, message, FARGS);
GMX_ASSERT(nrfp <= MAXFORCEPARAM,
"This is ensured in other places, but we need this assert to keep the clang "
"analyzer happy");
- const bool identicalParameters = std::equal(
- bt->interactionTypes[i].forceParam().begin(),
- bt->interactionTypes[i].forceParam().begin() + nrfp, b.forceParam().begin());
+ const bool identicalParameters = std::equal(bt->interactionTypes[i].forceParam().begin(),
+ bt->interactionTypes[i].forceParam().begin() + nrfp,
+ b.forceParam().begin());
if (!bAllowRepeat || identicalParameters)
{
nrfpA = interaction_function[ftype].nrfpA;
strcpy(f1, formnl[nral]);
strcat(f1, formlf);
- if ((nn = sscanf(line, f1, &c[0], &c[1], &c[2], &c[3], &c[4], &c[5], &c[6], &c[7], &c[8], &c[9],
- &c[10], &c[11], &c[12]))
+ if ((nn = sscanf(
+ line, f1, &c[0], &c[1], &c[2], &c[3], &c[4], &c[5], &c[6], &c[7], &c[8], &c[9], &c[10], &c[11], &c[12]))
!= nrfp)
{
if (nn == nrfpA)
strcat(f1, formlf[nrfp - 1]);
/* Check number of parameters given */
- if ((nn = sscanf(line, f1, &c[0], &c[1], &c[2], &c[3], &c[4], &c[5], &c[6], &c[7], &c[8], &c[9],
- &c[10], &c[11]))
+ if ((nn = sscanf(
+ line, f1, &c[0], &c[1], &c[2], &c[3], &c[4], &c[5], &c[6], &c[7], &c[8], &c[9], &c[10], &c[11]))
!= nrfp)
{
if (nn == nrfpA)
{
auto message =
gmx::formatString("Error in reading cmap parameter for angle %s %s %s %s %s",
- alc[0], alc[1], alc[2], alc[3], alc[4]);
+ alc[0],
+ alc[1],
+ alc[2],
+ alc[3],
+ alc[4]);
warning_error(wi, message);
}
}
/* Check for the correct number of atoms (again) */
if (bt[F_CMAP].nct() != nct)
{
- auto message = gmx::formatString("Incorrect number of atom types (%d) in cmap type %d\n",
- nct, bt[F_CMAP].cmapAngles);
+ auto message = gmx::formatString(
+ "Incorrect number of atom types (%d) in cmap type %d\n", nct, bt[F_CMAP].cmapAngles);
warning_error(wi, message);
}
std::vector<int> atomTypes =
auto message = gmx::formatString(
"Atoms in the .top are not numbered consecutively from 1 (rather, "
"atomnr = %d, while at->nr = %d)",
- atomnr, at->nr);
+ atomnr,
+ at->nr);
warning_error_and_exit(wi, message, FARGS);
}
}
}
- push_atom_now(symtab, at, atomnr, atypes->atomNumberFromAtomType(type), type, ctype, ptype,
- resnumberic, resname, name, m0, q0, typeB, typeB == type ? ctype : ctypeB, mB, qB, wi);
+ push_atom_now(symtab,
+ at,
+ atomnr,
+ atypes->atomNumberFromAtomType(type),
+ type,
+ ctype,
+ ptype,
+ resnumberic,
+ resname,
+ name,
+ m0,
+ q0,
+ typeB,
+ typeB == type ? ctype : ctypeB,
+ mB,
+ qB,
+ wi);
}
void push_molt(t_symtab* symtab, std::vector<MoleculeInformation>* mol, char* line, warninp* wi)
}
/* Test if this moleculetype overwrites another */
- const auto found = std::find_if(mol->begin(), mol->end(),
- [&type](const auto& m) { return strcmp(*(m.name), type) == 0; });
+ const auto found = std::find_if(
+ mol->begin(), mol->end(), [&type](const auto& m) { return strcmp(*(m.name), type) == 0; });
if (found != mol->end())
{
auto message = gmx::formatString("moleculetype %s is redefined", type);
if (!bFound)
{
auto foundParameter =
- std::find_if(bt[ftype].interactionTypes.begin(), bt[ftype].interactionTypes.end(),
+ std::find_if(bt[ftype].interactionTypes.begin(),
+ bt[ftype].interactionTypes.end(),
[¶mAtoms, &at, &bB](const auto& param) {
return findIfAllNBAtomsMatch(param.atoms(), paramAtoms, at, bB);
});
/* If we did not find a matching type for this cmap torsion */
if (!bFound)
{
- auto message = gmx::formatString("Unknown cmap torsion between atoms %d %d %d %d %d", p->ai() + 1,
- p->aj() + 1, p->ak() + 1, p->al() + 1, p->am() + 1);
+ auto message = gmx::formatString("Unknown cmap torsion between atoms %d %d %d %d %d",
+ p->ai() + 1,
+ p->aj() + 1,
+ p->ak() + 1,
+ p->al() + 1,
+ p->am() + 1);
warning_error_and_exit(wi, message, FARGS);
}
{
if (bB)
{
- return natom_match(currentParamFromParameterArray, at->atom[parameterToAdd.ai()].typeB,
- at->atom[parameterToAdd.aj()].typeB, at->atom[parameterToAdd.ak()].typeB,
- at->atom[parameterToAdd.al()].typeB, atypes);
+ return natom_match(currentParamFromParameterArray,
+ at->atom[parameterToAdd.ai()].typeB,
+ at->atom[parameterToAdd.aj()].typeB,
+ at->atom[parameterToAdd.ak()].typeB,
+ at->atom[parameterToAdd.al()].typeB,
+ atypes);
}
else
{
- return natom_match(currentParamFromParameterArray, at->atom[parameterToAdd.ai()].type,
- at->atom[parameterToAdd.aj()].type, at->atom[parameterToAdd.ak()].type,
- at->atom[parameterToAdd.al()].type, atypes);
+ return natom_match(currentParamFromParameterArray,
+ at->atom[parameterToAdd.ai()].type,
+ at->atom[parameterToAdd.aj()].type,
+ at->atom[parameterToAdd.ak()].type,
+ at->atom[parameterToAdd.al()].type,
+ atypes);
}
}
auto pos = bt[ftype].interactionTypes.begin();
while (pos != bt[ftype].interactionTypes.end() && nmatch_max < 4)
{
- pos = std::find_if(bt[ftype].interactionTypes.begin(), bt[ftype].interactionTypes.end(),
+ pos = std::find_if(bt[ftype].interactionTypes.begin(),
+ bt[ftype].interactionTypes.end(),
[&p, &at, &atypes, &bB, &nmatch_max](const auto& param) {
return (findNumberOfDihedralAtomMatches(param, p, at, atypes, bB)
> nmatch_max);
else /* Not a dihedral */
{
gmx::ArrayRef<const int> atomParam = p.atoms();
- auto found = std::find_if(
- bt[ftype].interactionTypes.begin(), bt[ftype].interactionTypes.end(),
- [&atomParam, &at, &atypes, &bB](const auto& param) {
- return findIfAllParameterAtomsMatch(param.atoms(), atomParam, at, atypes, bB);
- });
+ auto found = std::find_if(bt[ftype].interactionTypes.begin(),
+ bt[ftype].interactionTypes.end(),
+ [&atomParam, &at, &atypes, &bB](const auto& param) {
+ return findIfAllParameterAtomsMatch(
+ param.atoms(), atomParam, at, atypes, bB);
+ });
if (found != bt[ftype].interactionTypes.end())
{
nparam_found = 1;
"This probably means that you have inserted topology section \"%s\"\n"
"in a part belonging to a different molecule than you intended to.\n"
"In that case move the \"%s\" section to the right molecule.",
- aa[i], dir2str(d), at->nr, dir2str(d), dir2str(d));
+ aa[i],
+ dir2str(d),
+ at->nr,
+ dir2str(d),
+ dir2str(d));
warning_error_and_exit(wi, message, FARGS);
}
for (int j = i + 1; (j < nral); j++)
strcpy(format, asformat[nral_fmt - 1]);
strcat(format, ccformat);
- nread = sscanf(line, format, &cc[0], &cc[1], &cc[2], &cc[3], &cc[4], &cc[5], &cc[6], &cc[7],
- &cc[8], &cc[9], &cc[10], &cc[11], &cc[12]);
+ nread = sscanf(line,
+ format,
+ &cc[0],
+ &cc[1],
+ &cc[2],
+ &cc[3],
+ &cc[4],
+ &cc[5],
+ &cc[6],
+ &cc[7],
+ &cc[8],
+ &cc[9],
+ &cc[10],
+ &cc[11],
+ &cc[12]);
if ((nread == NRFPA(ftype)) && (NRFPB(ftype) != 0))
{
auto message = gmx::formatString(
"Incorrect number of parameters - found %d, expected %d "
"or %d for %s (after the function type).",
- nread, NRFPA(ftype), NRFP(ftype), interaction_function[ftype].longname);
+ nread,
+ NRFPA(ftype),
+ NRFP(ftype),
+ interaction_function[ftype].longname);
warning_error_and_exit(wi, message, FARGS);
}
{
if (bZero)
{
- fprintf(stderr, "NOTE: No default %s types, using zeroes\n",
+ fprintf(stderr,
+ "NOTE: No default %s types, using zeroes\n",
interaction_function[ftype].longname);
}
else
if ((ftype == F_PDIHS || ftype == F_ANGRES || ftype == F_ANGRESZ) && paramValue[5] != paramValue[2])
{
auto message = gmx::formatString("%s multiplicity can not be perturbed %f!=%f",
- interaction_function[ftype].longname, paramValue[2],
+ interaction_function[ftype].longname,
+ paramValue[2],
paramValue[5]);
warning_error_and_exit(wi, message, FARGS);
}
{
auto message = gmx::formatString("%s table number can not be perturbed %d!=%d",
interaction_function[ftype].longname,
- gmx::roundToInt(param.c0()), gmx::roundToInt(param.c0()));
+ gmx::roundToInt(param.c0()),
+ gmx::roundToInt(param.c0()));
warning_error_and_exit(wi, message, FARGS);
}
"This probably means that you have inserted topology section \"%s\"\n"
"in a part belonging to a different molecule than you intended to.\n"
"In that case move the \"%s\" section to the right molecule.",
- aa[i], dir2str(d), at->nr, dir2str(d), dir2str(d));
+ aa[i],
+ dir2str(d),
+ at->nr,
+ dir2str(d),
+ dir2str(d));
warning_error_and_exit(wi, message, FARGS);
}
else
{
/* This is essentially the same check as in default_cmap_params() done one more time */
- auto message = gmx::formatString(
- "Unable to assign a cmap type to torsion %d %d %d %d and %d\n", param.ai() + 1,
- param.aj() + 1, param.ak() + 1, param.al() + 1, param.am() + 1);
+ auto message =
+ gmx::formatString("Unable to assign a cmap type to torsion %d %d %d %d and %d\n",
+ param.ai() + 1,
+ param.aj() + 1,
+ param.ak() + 1,
+ param.al() + 1,
+ param.am() + 1);
warning_error_and_exit(wi, message, FARGS);
}
}
auto message = gmx::formatString(
"No weight or negative weight found for vsiten "
"constructing atom %d (atom index %d)",
- nj + 1, atc[nj] + 1);
+ nj + 1,
+ atc[nj] + 1);
warning_error_and_exit(wi, message, FARGS);
}
break;
"For moleculetype '%s' in [ system ] %d case insensitive "
"matches, but %d case sensitive matches were found. Check "
"the case of the characters in the moleculetypes.",
- type, nrci, nrcs);
+ type,
+ nrci,
+ nrcs);
warning_error_and_exit(wi, message, FARGS);
}
if (nrci == 1)
for (const auto& param : paramp1)
{
- std::vector<real> forceParam = { fudgeQQ, atoms->atom[param.ai()].q,
- atoms->atom[param.aj()].q, param.c0(), param.c1() };
+ std::vector<real> forceParam = {
+ fudgeQQ, atoms->atom[param.ai()].q, atoms->atom[param.aj()].q, param.c0(), param.c1()
+ };
paramnew.emplace_back(InteractionOfType(param.atoms(), forceParam, ""));
}
}
std::vector<int> atoms = { i, j };
std::vector<real> forceParam = {
- atom[i].q, atom[j].q, nbp->interactionTypes[ntype * atom[i].type + atom[j].type].c0(),
+ atom[i].q,
+ atom[j].q,
+ nbp->interactionTypes[ntype * atom[i].type + atom[j].type].c0(),
nbp->interactionTypes[ntype * atom[i].type + atom[j].type].c1()
};
add_param_to_list(&mol->interactions[F_LJC_PAIRS_NB], InteractionOfType(atoms, forceParam));
"charges and/or atom types set in the topology file as well "
"as through the mdp option '%s'. You can not use both "
"these methods simultaneously.",
- i + 1, mol_name, "couple-moltype");
+ i + 1,
+ mol_name,
+ "couple-moltype");
warning_error_and_exit(wi, message, FARGS);
}
#ifdef DEBUG
GMX_LOG(logger.info)
.asParagraph()
- .appendTextFormatted("Angle: %d-%d-%d", ang->ai(),
- ang->aj(), ang->ak());
+ .appendTextFormatted(
+ "Angle: %d-%d-%d", ang->ai(), ang->aj(), ang->ak());
#endif
int numhydrogens = count_hydrogens(info, 3, ang->atoms());
if ((nshake == eshALLANGLES) || (numhydrogens > 1)
GMX_LOG(logger.info)
.asParagraph()
.appendTextFormatted("p: %d, q: %d, dist: %12.5e",
- atomNumbers[0], atomNumbers[1],
+ atomNumbers[0],
+ atomNumbers[1],
forceParm[0]);
#endif
add_param_to_list(&(plist[F_CONSTR]),
as = dir2str(Directive::d_atoms);
fprintf(out, "[ %s ]\n", as);
- fprintf(out, "; %4s %10s %6s %7s%6s %6s %10s %10s %6s %10s %10s\n", "nr", "type", "resnr",
- "residue", "atom", "cgnr", "charge", "mass", "typeB", "chargeB", "massB");
+ fprintf(out,
+ "; %4s %10s %6s %7s%6s %6s %10s %10s %6s %10s %10s\n",
+ "nr",
+ "type",
+ "resnr",
+ "residue",
+ "atom",
+ "cgnr",
+ "charge",
+ "mass",
+ "typeB",
+ "chargeB",
+ "massB");
qtot = 0;
if ((i == 0 || ri != at->atom[i - 1].resind) && at->resinfo[ri].rtp != nullptr)
{
qres = get_residue_charge(at, i);
- fprintf(out, "; residue %3d %-3s rtp %-4s q ", at->resinfo[ri].nr,
- *at->resinfo[ri].name, *at->resinfo[ri].rtp);
+ fprintf(out,
+ "; residue %3d %-3s rtp %-4s q ",
+ at->resinfo[ri].nr,
+ *at->resinfo[ri].name,
+ *at->resinfo[ri].rtp);
if (fabs(qres) < 0.001)
{
fprintf(out, " %s", "0.0");
/* This is true by construction, but static analysers don't know */
GMX_ASSERT(!bRTPresname || at->resinfo[at->atom[i].resind].rtp,
"-rtpres did not have residue name available");
- fprintf(out, "%6d %10s %6d%c %5s %6s %6d %10g %10g", i + 1, tpnmA, at->resinfo[ri].nr,
+ fprintf(out,
+ "%6d %10s %6d%c %5s %6s %6d %10g %10g",
+ i + 1,
+ tpnmA,
+ at->resinfo[ri].nr,
at->resinfo[ri].ic,
bRTPresname ? *(at->resinfo[at->atom[i].resind].rtp)
: *(at->resinfo[at->atom[i].resind].name),
- *(at->atomname[i]), cgnr[i], at->atom[i].q, at->atom[i].m);
+ *(at->atomname[i]),
+ cgnr[i],
+ at->atom[i].q,
+ at->atom[i].m);
if (PERTURBED(at->atom[i]))
{
tpB = at->atom[i].typeB;
fprintf(fp, "angles:");
for (const auto& angle : angles)
{
- fprintf(fp, " %d-%d-%d (%g)", angle.ai() + 1, angle.aj() + 1, angle.ak() + 1,
- angle.parameterValue());
+ fprintf(fp, " %d-%d-%d (%g)", angle.ai() + 1, angle.aj() + 1, angle.ak() + 1, angle.parameterValue());
}
fprintf(fp, "\n");
}
fprintf(fp, "idihs:");
for (const auto& idih : idihs)
{
- fprintf(fp, " %d-%d-%d-%d (%g)", idih.ai() + 1, idih.aj() + 1, idih.ak() + 1,
- idih.al() + 1, idih.parameterValue());
+ fprintf(fp,
+ " %d-%d-%d-%d (%g)",
+ idih.ai() + 1,
+ idih.aj() + 1,
+ idih.ak() + 1,
+ idih.al() + 1,
+ idih.parameterValue());
}
fprintf(fp, "\n");
}
/* check if this is part of a NH3 , NH2-umbrella or CH3 group,
* i.e. if atom k and l are dummy masses (MNH* or MCH3*) */
bXH3 = ((gmx::equalCaseInsensitive(get_atomtype_name_AB(&at->atom[vsite->ak()], atypes), "MNH", 3))
- && (gmx::equalCaseInsensitive(get_atomtype_name_AB(&at->atom[vsite->al()], atypes),
- "MNH", 3)))
- || ((gmx::equalCaseInsensitive(get_atomtype_name_AB(&at->atom[vsite->ak()], atypes),
- "MCH3", 4))
- && (gmx::equalCaseInsensitive(get_atomtype_name_AB(&at->atom[vsite->al()], atypes),
- "MCH3", 4)));
+ && (gmx::equalCaseInsensitive(
+ get_atomtype_name_AB(&at->atom[vsite->al()], atypes), "MNH", 3)))
+ || ((gmx::equalCaseInsensitive(
+ get_atomtype_name_AB(&at->atom[vsite->ak()], atypes), "MCH3", 4))
+ && (gmx::equalCaseInsensitive(
+ get_atomtype_name_AB(&at->atom[vsite->al()], atypes), "MCH3", 4)));
bjk = get_bond_length(bonds, vsite->aj(), vsite->ak());
bjl = get_bond_length(bonds, vsite->aj(), vsite->al());
/* check if this is part of a NH2-umbrella, NH3 or CH3 group,
* i.e. if atom k and l are dummy masses (MNH* or MCH3*) */
bXH3 = ((gmx::equalCaseInsensitive(get_atomtype_name_AB(&at->atom[vsite->ak()], atypes), "MNH", 3))
- && (gmx::equalCaseInsensitive(get_atomtype_name_AB(&at->atom[vsite->al()], atypes),
- "MNH", 3)))
- || ((gmx::equalCaseInsensitive(get_atomtype_name_AB(&at->atom[vsite->ak()], atypes),
- "MCH3", 4))
- && (gmx::equalCaseInsensitive(get_atomtype_name_AB(&at->atom[vsite->al()], atypes),
- "MCH3", 4)));
+ && (gmx::equalCaseInsensitive(
+ get_atomtype_name_AB(&at->atom[vsite->al()], atypes), "MNH", 3)))
+ || ((gmx::equalCaseInsensitive(
+ get_atomtype_name_AB(&at->atom[vsite->ak()], atypes), "MCH3", 4))
+ && (gmx::equalCaseInsensitive(
+ get_atomtype_name_AB(&at->atom[vsite->al()], atypes), "MCH3", 4)));
/* check if construction parity must be swapped */
bSwapParity = (vsite->c1() == -1);
.asParagraph()
.appendTextFormatted(
"virtual site %d: angle ijk = %f, angle ijl = %f, angle ijm = %f",
- vsite->ai() + 1, RAD2DEG * aijk, RAD2DEG * aijl, RAD2DEG * aijm);
+ vsite->ai() + 1,
+ RAD2DEG * aijk,
+ RAD2DEG * aijl,
+ RAD2DEG * aijm);
gmx_fatal(FARGS,
"invalid construction in calc_vsite4fd for atom %d: "
"cosakl=%f, cosakm=%f\n",
- vsite->ai() + 1, cosakl, cosakm);
+ vsite->ai() + 1,
+ cosakl,
+ cosakm);
}
sinakl = std::sqrt(1 - gmx::square(cosakl));
sinakm = std::sqrt(1 - gmx::square(cosakm));
.asParagraph()
.appendTextFormatted(
"virtual site %d: angle ijk = %f, angle ijl = %f, angle ijm = %f",
- vsite->ai() + 1, RAD2DEG * aijk, RAD2DEG * aijl, RAD2DEG * aijm);
+ vsite->ai() + 1,
+ RAD2DEG * aijk,
+ RAD2DEG * aijl,
+ RAD2DEG * aijm);
gmx_fatal(FARGS,
"invalid construction in calc_vsite4fdn for atom %d: "
"pl=%f, pm=%f\n",
- vsite->ai() + 1, pl, pm);
+ vsite->ai() + 1,
+ pl,
+ pm);
}
a = pk / pl;
fprintf(debug,
"Found %zu bonds, %zu angles and %zu idihs "
"for virtual site %d (%s)\n",
- allVsiteBondeds.bonds.size(), allVsiteBondeds.angles.size(),
- allVsiteBondeds.dihedrals.size(), param.ai() + 1,
+ allVsiteBondeds.bonds.size(),
+ allVsiteBondeds.angles.size(),
+ allVsiteBondeds.dihedrals.size(),
+ param.ai() + 1,
interaction_function[ftype].longname);
- print_bad(debug, allVsiteBondeds.bonds, allVsiteBondeds.angles,
+ print_bad(debug,
+ allVsiteBondeds.bonds,
+ allVsiteBondeds.angles,
allVsiteBondeds.dihedrals);
} /* debug */
switch (ftype)
{
case F_VSITE3:
- bERROR = calc_vsite3_param(atypes, ¶m, atoms, allVsiteBondeds.bonds,
- allVsiteBondeds.angles);
+ bERROR = calc_vsite3_param(
+ atypes, ¶m, atoms, allVsiteBondeds.bonds, allVsiteBondeds.angles);
break;
case F_VSITE3FD:
- bERROR = calc_vsite3fd_param(¶m, allVsiteBondeds.bonds,
- allVsiteBondeds.angles);
+ bERROR = calc_vsite3fd_param(
+ ¶m, allVsiteBondeds.bonds, allVsiteBondeds.angles);
break;
case F_VSITE3FAD:
- bERROR = calc_vsite3fad_param(¶m, allVsiteBondeds.bonds,
- allVsiteBondeds.angles);
+ bERROR = calc_vsite3fad_param(
+ ¶m, allVsiteBondeds.bonds, allVsiteBondeds.angles);
break;
case F_VSITE3OUT:
- bERROR = calc_vsite3out_param(atypes, ¶m, atoms, allVsiteBondeds.bonds,
- allVsiteBondeds.angles);
+ bERROR = calc_vsite3out_param(
+ atypes, ¶m, atoms, allVsiteBondeds.bonds, allVsiteBondeds.angles);
break;
case F_VSITE4FD:
- bERROR = calc_vsite4fd_param(¶m, allVsiteBondeds.bonds,
- allVsiteBondeds.angles, logger);
+ bERROR = calc_vsite4fd_param(
+ ¶m, allVsiteBondeds.bonds, allVsiteBondeds.angles, logger);
break;
case F_VSITE4FDN:
- bERROR = calc_vsite4fdn_param(¶m, allVsiteBondeds.bonds,
- allVsiteBondeds.angles, logger);
+ bERROR = calc_vsite4fdn_param(
+ ¶m, allVsiteBondeds.bonds, allVsiteBondeds.angles, logger);
break;
default:
gmx_fatal(FARGS,
"Automatic parameter generation not supported "
"for %s atom %d",
- interaction_function[ftype].longname, param.ai() + 1);
+ interaction_function[ftype].longname,
+ param.ai() + 1);
bERROR = TRUE;
} /* switch */
if (bERROR)
gmx_fatal(FARGS,
"Automatic parameter generation not supported "
"for %s atom %d for this bonding configuration",
- interaction_function[ftype].longname, param.ai() + 1);
+ interaction_function[ftype].longname,
+ param.ai() + 1);
}
} /* if bSet */
i++;
{
GMX_LOG(logger.info)
.asParagraph()
- .appendTextFormatted("doing %d %s virtual sites", (nrd / (nra + 1)),
+ .appendTextFormatted("doing %d %s virtual sites",
+ (nrd / (nra + 1)),
interaction_function[ftype].longname);
}
.asParagraph()
.appendTextFormatted(
"ERROR: Cannot have constraint (%d-%d) with virtual site (%d)",
- param.ai() + 1, param.aj() + 1, atom + 1);
+ param.ai() + 1,
+ param.aj() + 1,
+ atom + 1);
n++;
}
}
if (interaction_function[ftype].flags & IF_CONSTRAINT)
{
for (auto entry = plist[ftype].interactionTypes.begin();
- (entry != plist[ftype].interactionTypes.end()) && !bPresent; entry++)
+ (entry != plist[ftype].interactionTypes.end()) && !bPresent;
+ entry++)
{
/* all constraints until one matches */
bPresent = (((entry->ai() == at1) && (entry->aj() == at2))
{
GMX_LOG(logger.info)
.asParagraph()
- .appendTextFormatted("Removed %4d %15ss with virtual sites, %zu left", nremoved,
- interaction_function[cftype].longname, ps->size());
+ .appendTextFormatted("Removed %4d %15ss with virtual sites, %zu left",
+ nremoved,
+ interaction_function[cftype].longname,
+ ps->size());
}
if (nconverted)
{
.asParagraph()
.appendTextFormatted(
"Converted %4d %15ss with virtual sites to connections, %zu left",
- nconverted, interaction_function[cftype].longname, ps->size());
+ nconverted,
+ interaction_function[cftype].longname,
+ ps->size());
}
if (nOut)
{
"bond-length\n"
" If the constructions were generated by pdb2gmx ignore "
"this warning",
- nOut, interaction_function[cftype].longname,
+ nOut,
+ interaction_function[cftype].longname,
interaction_function[F_VSITE3OUT].longname);
}
}
GMX_LOG(logger.info)
.asParagraph()
.appendTextFormatted("Removed %4zu %15ss with virtual sites, %zu left",
- oldSize - ps->size(), interaction_function[cftype].longname,
+ oldSize - ps->size(),
+ interaction_function[cftype].longname,
ps->size());
}
}
GMX_LOG(logger.info)
.asParagraph()
.appendTextFormatted("Removed %4zu %15ss with virtual sites, %zu left",
- oldSize - ps->size(), interaction_function[cftype].longname,
+ oldSize - ps->size(),
+ interaction_function[cftype].longname,
ps->size());
}
}
int aj = dihedral.aj();
int ak = dihedral.ak();
int al = dihedral.al();
- real ph = RAD2DEG
- * dih_angle(x[ai], x[aj], x[ak], x[al], bPBC ? &pbc : nullptr, r_ij, r_kj, r_kl,
- m, n, &t1, &t2, &t3);
+ real ph =
+ RAD2DEG
+ * dih_angle(x[ai], x[aj], x[ak], x[al], bPBC ? &pbc : nullptr, r_ij, r_kj, r_kl, m, n, &t1, &t2, &t3);
dihedral.setForceParameter(0, ph);
}
}
};
const char* bugs[] = {
"The atom type selection is primitive. Virtually no chemical knowledge is used",
- "Periodic boundary conditions screw up the bonding", "No improper dihedrals are generated",
+ "Periodic boundary conditions screw up the bonding",
+ "No improper dihedrals are generated",
"The atoms to atomtype translation table is incomplete ([TT]atomname2type.n2t[tt] file in",
"the data directory). Please extend it and send the results back to the GROMACS crew."
};
{ "-kp", FALSE, etREAL, { &kp }, "Dihedral angle force constant (kJ/mol/rad^2)" }
};
- if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa, asize(desc), desc,
- asize(bugs), bugs, &oenv))
+ if (!parse_common_args(
+ &argc, argv, 0, NFILE, fnm, asize(pa), pa, asize(desc), desc, asize(bugs), bugs, &oenv))
{
return 0;
}
/* Force field selection, interactive or direct */
- choose_ff(strcmp(ff, "select") == 0 ? nullptr : ff, forcefield, sizeof(forcefield), ffdir,
- sizeof(ffdir), logger);
+ choose_ff(strcmp(ff, "select") == 0 ? nullptr : ff, forcefield, sizeof(forcefield), ffdir, sizeof(ffdir), logger);
bOPLS = (strcmp(forcefield, "oplsaa") == 0);
.appendTextFormatted(
"There are %4zu %s dihedrals, %4zu impropers, %4zu angles\n"
" %4zu pairs, %4zu bonds and %4d atoms\n",
- plist[F_PDIHS].size(), bOPLS ? "Ryckaert-Bellemans" : "proper", plist[F_IDIHS].size(),
- plist[F_ANGLES].size(), plist[F_LJ14].size(), plist[F_BONDS].size(), atoms->nr);
+ plist[F_PDIHS].size(),
+ bOPLS ? "Ryckaert-Bellemans" : "proper",
+ plist[F_IDIHS].size(),
+ plist[F_ANGLES].size(),
+ plist[F_LJ14].size(),
+ plist[F_BONDS].size(),
+ atoms->nr);
calc_angles_dihs(&plist[F_ANGLES], &plist[F_PDIHS], x, bPBC, box);
fp = ftp2FILE(efTOP, NFILE, fnm, "w");
print_top_header(fp, ftp2fn(efTOP, NFILE, fnm), TRUE, ffdir, 1.0);
- write_top(fp, nullptr, mymol.name.c_str(), atoms, FALSE, bts, plist, excls, &atypes, cgnr,
+ write_top(fp,
+ nullptr,
+ mymol.name.c_str(),
+ atoms,
+ FALSE,
+ bts,
+ plist,
+ excls,
+ &atypes,
+ cgnr,
rtp_header_settings.nrexcl);
print_top_mols(fp, mymol.name.c_str(), ffdir, nullptr, {}, gmx::arrayRefFromArray(&mymol, 1));
}
if (na != 3)
{
- gmx_fatal(FARGS, "Expected a residue name and two atom names in file '%s', not '%s'",
- filename.c_str(), line);
+ gmx_fatal(FARGS,
+ "Expected a residue name and two atom names in file '%s', not '%s'",
+ filename.c_str(),
+ line);
}
srenew(xl, n + 1);
const char* ptr0 = xlatom[i].replace;
if (bVerbose)
{
- printf("Renaming atom '%s' in residue %d %s to '%s'\n", *atoms->atomname[a],
- atoms->resinfo[resind].nr, *atoms->resinfo[resind].name, ptr0);
+ printf("Renaming atom '%s' in residue %d %s to '%s'\n",
+ *atoms->atomname[a],
+ atoms->resinfo[resind].nr,
+ *atoms->resinfo[resind].name,
+ ptr0);
}
atoms->atomname[a] = put_symtab(symtab, ptr0);
bRenamed = TRUE;
# the incidence of textual clashes when adding/moving files that
# otherwise make the end of the list a hotspot.
+add_library(gpu_utils INTERFACE)
+
gmx_add_libgromacs_sources(
clfftinitializer.cpp
device_stream_manager.cpp
)
endif()
+# Source files have the following private module dependencies.
+target_link_libraries(gpu_utils PRIVATE
+# gmxlib
+# math
+# mdtypes
+# tng_io
+ )
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(gpu_utils PUBLIC
+target_include_directories(gpu_utils INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(gpu_utils PUBLIC
+target_link_libraries(gpu_utils INTERFACE
+ legacy_api
+ )
+
+# TODO: when gpu_utils is an OBJECT target
+#target_link_libraries(gpu_utils PUBLIC legacy_api)
+#target_link_libraries(gpu_utils PRIVATE common)
+
+# Module dependencies
+# gpu_utils interfaces convey transitive dependence on these modules.
+#target_link_libraries(gpu_utils PUBLIC
+target_link_libraries(gpu_utils INTERFACE
+# utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(gpu_utils PRIVATE tng_io)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(gpu_utils PRIVATE legacy_modules)
+
if (BUILD_TESTING)
add_subdirectory(tests)
endif()
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "config.h"
+#include <mutex>
+
#include "gromacs/utility/basedefinitions.h"
#include "gromacs/utility/exceptions.h"
-#include "gromacs/utility/mutex.h"
#include "gromacs/utility/stringutil.h"
#if GMX_GPU_OPENCL
* initialize it more than once. */
//! @{
bool g_clfftInitialized = false;
-gmx::Mutex g_clfftMutex;
+std::mutex g_clfftMutex;
//! @}
#endif
ClfftInitializer::ClfftInitializer()
{
#if GMX_GPU_OPENCL
- gmx::lock_guard<gmx::Mutex> guard(g_clfftMutex);
+ std::lock_guard<std::mutex> guard(g_clfftMutex);
clfftSetupData fftSetup;
int initErrorCode = clfftInitSetupData(&fftSetup);
if (initErrorCode != 0)
ClfftInitializer::~ClfftInitializer()
{
#if GMX_GPU_OPENCL
- gmx::lock_guard<gmx::Mutex> guard(g_clfftMutex);
+ std::lock_guard<std::mutex> guard(g_clfftMutex);
if (g_clfftInitialized)
{
clfftTeardown();
*/
static inline std::string getDeviceErrorString(const cudaError_t deviceError)
{
- return formatString("CUDA error #%d (%s): %s.", deviceError, cudaGetErrorName(deviceError),
+ return formatString("CUDA error #%d (%s): %s.",
+ deviceError,
+ cudaGetErrorName(deviceError),
cudaGetErrorString(deviceError));
}
{
dim3 blockSize(config.blockSize[0], config.blockSize[1], config.blockSize[2]);
dim3 gridSize(config.gridSize[0], config.gridSize[1], config.gridSize[2]);
- cudaLaunchKernel((void*)kernel, gridSize, blockSize, const_cast<void**>(kernelArgs.data()),
- config.sharedMemorySize, deviceStream.stream());
+ cudaLaunchKernel((void*)kernel,
+ gridSize,
+ blockSize,
+ const_cast<void**>(kernelArgs.data()),
+ config.sharedMemorySize,
+ deviceStream.stream());
gmx::ensureNoPendingDeviceError("GPU kernel (" + std::string(kernelName)
+ ") failed to launch.");
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2020, by the GROMACS development team, led by
+ * Copyright (c) 2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "config.h"
+#include <memory>
+
#if GMX_GPU_OPENCL
# include "gromacs/gpu_utils/gmxopencl.h"
#endif
#if GMX_GPU_SYCL
# include "gromacs/gpu_utils/gmxsycl.h"
#endif
+
#include "gromacs/gpu_utils/gpu_utils.h"
#include "gromacs/hardware/device_management.h"
#include "gromacs/utility/classhelpers.h"
{
GMX_THROW(gmx::InternalError(gmx::formatString(
"Failed to create OpenCL context on device %s (OpenCL error ID %d).",
- deviceInfo.device_name, clError)));
+ deviceInfo.device_name,
+ clError)));
}
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2020, by the GROMACS development team, led by
+ * Copyright (c) 2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "config.h"
+#include <memory>
+
#if GMX_GPU_CUDA
# include <cuda_runtime.h>
#elif GMX_GPU_SYCL
# include "gromacs/gpu_utils/gmxsycl.h"
#endif
+
#include "gromacs/utility/classhelpers.h"
struct DeviceInformation;
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
#ifndef GMX_GPU_UTILS_GPUSTREAMMANAGER_H
#define GMX_GPU_UTILS_GPUSTREAMMANAGER_H
+#include <memory>
#include <string>
-#include "gromacs/utility/classhelpers.h"
-
class DeviceContext;
struct DeviceInformation;
class DeviceStream;
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
{
GMX_THROW(gmx::InternalError(gmx::formatString(
"Failed to create OpenCL command queue on GPU %s (OpenCL error ID %d).",
- deviceInfo.device_name, clError)));
+ deviceInfo.device_name,
+ clError)));
}
}
switch (transferKind)
{
case GpuApiCallBehavior::Async:
- GMX_ASSERT(isHostMemoryPinned(hostBuffer),
- "Source host buffer was not pinned for CUDA");
- stat = cudaMemcpyAsync(*((ValueType**)buffer) + startingOffset, hostBuffer, bytes,
- cudaMemcpyHostToDevice, deviceStream.stream());
+ GMX_ASSERT(isHostMemoryPinned(hostBuffer), "Source host buffer was not pinned for CUDA");
+ stat = cudaMemcpyAsync(*((ValueType**)buffer) + startingOffset,
+ hostBuffer,
+ bytes,
+ cudaMemcpyHostToDevice,
+ deviceStream.stream());
GMX_RELEASE_ASSERT(
stat == cudaSuccess,
("Asynchronous H2D copy failed. " + gmx::getDeviceErrorString(stat)).c_str());
break;
case GpuApiCallBehavior::Sync:
- stat = cudaMemcpy(*((ValueType**)buffer) + startingOffset, hostBuffer, bytes,
- cudaMemcpyHostToDevice);
+ stat = cudaMemcpy(
+ *((ValueType**)buffer) + startingOffset, hostBuffer, bytes, cudaMemcpyHostToDevice);
GMX_RELEASE_ASSERT(
stat == cudaSuccess,
("Synchronous H2D copy failed. " + gmx::getDeviceErrorString(stat)).c_str());
case GpuApiCallBehavior::Async:
GMX_ASSERT(isHostMemoryPinned(hostBuffer),
"Destination host buffer was not pinned for CUDA");
- stat = cudaMemcpyAsync(hostBuffer, *((ValueType**)buffer) + startingOffset, bytes,
- cudaMemcpyDeviceToHost, deviceStream.stream());
+ stat = cudaMemcpyAsync(hostBuffer,
+ *((ValueType**)buffer) + startingOffset,
+ bytes,
+ cudaMemcpyDeviceToHost,
+ deviceStream.stream());
GMX_RELEASE_ASSERT(
stat == cudaSuccess,
("Asynchronous D2H copy failed. " + gmx::getDeviceErrorString(stat)).c_str());
break;
case GpuApiCallBehavior::Sync:
- stat = cudaMemcpy(hostBuffer, *((ValueType**)buffer) + startingOffset, bytes,
- cudaMemcpyDeviceToHost);
+ stat = cudaMemcpy(
+ hostBuffer, *((ValueType**)buffer) + startingOffset, bytes, cudaMemcpyDeviceToHost);
GMX_RELEASE_ASSERT(
stat == cudaSuccess,
("Synchronous D2H copy failed. " + gmx::getDeviceErrorString(stat)).c_str());
const size_t bytes = numValues * sizeof(ValueType);
const char pattern = 0;
- cudaError_t stat = cudaMemsetAsync(*((ValueType**)buffer) + startingOffset, pattern, bytes,
- deviceStream.stream());
+ cudaError_t stat = cudaMemsetAsync(
+ *((ValueType**)buffer) + startingOffset, pattern, bytes, deviceStream.stream());
GMX_RELEASE_ASSERT(stat == cudaSuccess,
("Couldn't clear the device buffer. " + gmx::getDeviceErrorString(stat)).c_str());
}
GMX_ASSERT(buffer, "needs a buffer pointer");
void* hostPtr = nullptr;
cl_int clError;
- *buffer = clCreateBuffer(deviceContext.context(), CL_MEM_READ_WRITE,
- numValues * sizeof(ValueType), hostPtr, &clError);
+ *buffer = clCreateBuffer(
+ deviceContext.context(), CL_MEM_READ_WRITE, numValues * sizeof(ValueType), hostPtr, &clError);
GMX_RELEASE_ASSERT(clError == CL_SUCCESS,
- gmx::formatString("clCreateBuffer failure (OpenCL error %d: %s)", clError,
+ gmx::formatString("clCreateBuffer failure (OpenCL error %d: %s)",
+ clError,
ocl_get_error_string(clError).c_str())
.c_str());
}
cl_int clError = clReleaseMemObject(*buffer);
GMX_RELEASE_ASSERT(clError == CL_SUCCESS,
gmx::formatString("clReleaseMemObject failed (OpenCL error %d: %s)",
- clError, ocl_get_error_string(clError).c_str())
+ clError,
+ ocl_get_error_string(clError).c_str())
.c_str());
}
}
switch (transferKind)
{
case GpuApiCallBehavior::Async:
- clError = clEnqueueWriteBuffer(deviceStream.stream(), *buffer, CL_FALSE, offset, bytes,
- hostBuffer, 0, nullptr, timingEvent);
+ clError = clEnqueueWriteBuffer(
+ deviceStream.stream(), *buffer, CL_FALSE, offset, bytes, hostBuffer, 0, nullptr, timingEvent);
GMX_RELEASE_ASSERT(
clError == CL_SUCCESS,
- gmx::formatString("Asynchronous H2D copy failed (OpenCL error %d: %s)", clError,
+ gmx::formatString("Asynchronous H2D copy failed (OpenCL error %d: %s)",
+ clError,
ocl_get_error_string(clError).c_str())
.c_str());
break;
case GpuApiCallBehavior::Sync:
- clError = clEnqueueWriteBuffer(deviceStream.stream(), *buffer, CL_TRUE, offset, bytes,
- hostBuffer, 0, nullptr, timingEvent);
+ clError = clEnqueueWriteBuffer(
+ deviceStream.stream(), *buffer, CL_TRUE, offset, bytes, hostBuffer, 0, nullptr, timingEvent);
GMX_RELEASE_ASSERT(
clError == CL_SUCCESS,
- gmx::formatString("Synchronous H2D copy failed (OpenCL error %d: %s)", clError,
+ gmx::formatString("Synchronous H2D copy failed (OpenCL error %d: %s)",
+ clError,
ocl_get_error_string(clError).c_str())
.c_str());
break;
switch (transferKind)
{
case GpuApiCallBehavior::Async:
- clError = clEnqueueReadBuffer(deviceStream.stream(), *buffer, CL_FALSE, offset, bytes,
- hostBuffer, 0, nullptr, timingEvent);
+ clError = clEnqueueReadBuffer(
+ deviceStream.stream(), *buffer, CL_FALSE, offset, bytes, hostBuffer, 0, nullptr, timingEvent);
GMX_RELEASE_ASSERT(
clError == CL_SUCCESS,
- gmx::formatString("Asynchronous D2H copy failed (OpenCL error %d: %s)", clError,
+ gmx::formatString("Asynchronous D2H copy failed (OpenCL error %d: %s)",
+ clError,
ocl_get_error_string(clError).c_str())
.c_str());
break;
case GpuApiCallBehavior::Sync:
- clError = clEnqueueReadBuffer(deviceStream.stream(), *buffer, CL_TRUE, offset, bytes,
- hostBuffer, 0, nullptr, timingEvent);
+ clError = clEnqueueReadBuffer(
+ deviceStream.stream(), *buffer, CL_TRUE, offset, bytes, hostBuffer, 0, nullptr, timingEvent);
GMX_RELEASE_ASSERT(
clError == CL_SUCCESS,
- gmx::formatString("Synchronous D2H copy failed (OpenCL error %d: %s)", clError,
+ gmx::formatString("Synchronous D2H copy failed (OpenCL error %d: %s)",
+ clError,
ocl_get_error_string(clError).c_str())
.c_str());
break;
const cl_uint numWaitEvents = 0;
const cl_event* waitEvents = nullptr;
cl_event commandEvent;
- cl_int clError = clEnqueueFillBuffer(deviceStream.stream(), *buffer, &pattern, sizeof(pattern),
- offset, bytes, numWaitEvents, waitEvents, &commandEvent);
+ cl_int clError = clEnqueueFillBuffer(
+ deviceStream.stream(), *buffer, &pattern, sizeof(pattern), offset, bytes, numWaitEvents, waitEvents, &commandEvent);
GMX_RELEASE_ASSERT(clError == CL_SUCCESS,
gmx::formatString("Couldn't clear the device buffer (OpenCL error %d: %s)",
- clError, ocl_get_error_string(clError).c_str())
+ clError,
+ ocl_get_error_string(clError).c_str())
.c_str());
}
cl_int clError;
*deviceBuffer = clCreateBuffer(deviceContext.context(),
CL_MEM_READ_ONLY | CL_MEM_HOST_WRITE_ONLY | CL_MEM_COPY_HOST_PTR,
- bytes, const_cast<ValueType*>(hostBuffer), &clError);
+ bytes,
+ const_cast<ValueType*>(hostBuffer),
+ &clError);
GMX_RELEASE_ASSERT(clError == CL_SUCCESS,
gmx::formatString("Constant memory allocation failed (OpenCL error %d: %s)",
- clError, ocl_get_error_string(clError).c_str())
+ clError,
+ ocl_get_error_string(clError).c_str())
.c_str());
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2020, by the GROMACS development team, led by
+ * Copyright (c) 2020,2021, 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.
* \inlibraryapi
*/
+#include <utility>
+
#include "gromacs/gpu_utils/device_context.h"
#include "gromacs/gpu_utils/device_stream.h"
#include "gromacs/gpu_utils/devicebuffer_datatype.h"
}
}
+
+namespace gmx::internal
+{
+/*! \brief Helper function to clear device buffer.
+ *
+ * Not applicable to GROMACS's float3 (a.k.a. gmx::RVec) and other custom types.
+ * From SYCL specs: "T must be a scalar value or a SYCL vector type."
+ */
+template<typename ValueType>
+cl::sycl::event fillSyclBufferWithNull(cl::sycl::buffer<ValueType, 1>& buffer,
+ size_t startingOffset,
+ size_t numValues,
+ cl::sycl::queue queue)
+{
+ using cl::sycl::access::mode;
+ const cl::sycl::range<1> range(numValues);
+ const cl::sycl::id<1> offset(startingOffset);
+ const ValueType pattern = ValueType(0); // SYCL vectors support initialization by scalar
+
+ return queue.submit([&](cl::sycl::handler& cgh) {
+ auto d_bufferAccessor =
+ cl::sycl::accessor<ValueType, 1, mode::discard_write>{ buffer, cgh, range, offset };
+ cgh.fill(d_bufferAccessor, pattern);
+ });
+}
+
+//! \brief Helper function to clear device buffer of type float3.
+template<>
+inline cl::sycl::event fillSyclBufferWithNull(cl::sycl::buffer<float3, 1>& buffer,
+ size_t startingOffset,
+ size_t numValues,
+ cl::sycl::queue queue)
+{
+ cl::sycl::buffer<float, 1> bufferAsFloat = buffer.reinterpret<float, 1>(buffer.get_count() * DIM);
+ return fillSyclBufferWithNull<float>(
+ bufferAsFloat, startingOffset * DIM, numValues * DIM, std::move(queue));
+}
+} // namespace gmx::internal
+
/*! \brief
* Clears the device buffer asynchronously.
*
GMX_ASSERT(checkDeviceBuffer(*buffer, startingOffset + numValues),
"buffer too small or not initialized");
- const ValueType pattern{};
cl::sycl::buffer<ValueType>& syclBuffer = *(buffer->buffer_);
- cl::sycl::event ev = deviceStream.stream().submit([&](cl::sycl::handler& cgh) {
- auto d_bufferAccessor = cl::sycl::accessor<ValueType, 1, cl::sycl::access::mode::discard_write>{
- syclBuffer, cgh, cl::sycl::range(numValues), cl::sycl::id(startingOffset)
- };
- cgh.fill(d_bufferAccessor, pattern);
- });
+ gmx::internal::fillSyclBufferWithNull<ValueType>(
+ syclBuffer, startingOffset, numValues, deviceStream.stream());
}
/*! \brief Create a texture object for an array of type ValueType.
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2020, by the GROMACS development team, led by
+ * Copyright (c) 2020,2021, 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.
* \brief
* Wraps the complexity of including SYCL in GROMACS.
*
- * SYCL headers use symbol DIM as a template parameter, which gets broken by macro DIM defined
+ * The __SYCL_COMPILER_VERSION macro is used to identify Intel DPCPP compiler.
+ * See https://github.com/intel/llvm/pull/2998 for better proposal.
+ *
+ * Intel SYCL headers use symbol DIM as a template parameter, which gets broken by macro DIM defined
* in gromacs/math/vectypes.h. Here, we include the SYCL header while temporary undefining this macro.
+ * See https://github.com/intel/llvm/issues/2981.
+ *
+ * Different compilers, at the time of writing, have different names for some of the proposed features
+ * of the SYCL2020 standard. For uniformity, they are all aliased in our custom sycl_2020 namespace.
*
* \inlibraryapi
*/
#ifndef GMX_GPU_UTILS_GMXSYCL_H
#define GMX_GPU_UTILS_GMXSYCL_H
+/* Some versions of Intel ICPX compiler (at least 2021.1.1 and 2021.1.2) fail to unroll a loop
+ * in sycl::accessor::__init, and emit -Wpass-failed=transform-warning. This is a useful
+ * warning, but mostly noise right now. Probably related to using shared memory accessors.
+ * The unroll directive was introduced in https://github.com/intel/llvm/pull/2449. */
+#if defined(__INTEL_LLVM_COMPILER)
+# include <CL/sycl/version.hpp>
+# define DISABLE_UNROLL_WARNINGS \
+ ((__SYCL_COMPILER_VERSION >= 20201113) && (__SYCL_COMPILER_VERSION <= 20201214))
+#else
+# define DISABLE_UNROLL_WARNINGS 0
+#endif
+
+#if DISABLE_UNROLL_WARNINGS
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wpass-failed"
+#endif
#ifdef DIM
# if DIM != 3
# include <CL/sycl.hpp>
#endif
+#if DISABLE_UNROLL_WARNINGS
+# pragma clang diagnostic pop
+#endif
+
+#undef DISABLE_UNROLL_WARNINGS
+
+/* Exposing Intel-specific extensions in a manner compatible with SYCL2020 provisional spec.
+ * Despite ICPX (up to 2021.1.2 at the least) having SYCL_LANGUAGE_VERSION=202001,
+ * some parts of the spec are still in custom sycl::ONEAPI namespace (sycl::intel in beta versions),
+ * and some functions have different names. To make things easier to upgrade
+ * in the future, this thin layer is added.
+ * */
+namespace sycl_2020
+{
+namespace detail
+{
+#if defined(__SYCL_COMPILER_VERSION) // Intel DPCPP compiler
+// Confirmed to work for 2021.1-beta10 (20201005), 2021.1.1 (20201113), 2021.1.2 (20201214).
+namespace origin = cl::sycl::ONEAPI;
+#elif defined(__HIPSYCL__)
+namespace origin = cl::sycl;
+#else
+# error "Unsupported version of SYCL compiler"
+#endif
+} // namespace detail
+
+using detail::origin::memory_order;
+using detail::origin::memory_scope;
+using detail::origin::plus;
+using detail::origin::sub_group;
+
+#if defined(__SYCL_COMPILER_VERSION) // Intel DPCPP compiler
+using detail::origin::atomic_ref;
+template<typename... Args>
+bool group_any_of(Args&&... args)
+{
+ return detail::origin::any_of(std::forward<Args>(args)...);
+}
+template<typename... Args>
+auto group_reduce(Args&&... args) -> decltype(detail::origin::reduce(std::forward<Args>(args)...))
+{
+ return detail::origin::reduce(std::forward<Args>(args)...);
+}
+#elif defined(__HIPSYCL__)
+// No atomic_ref in hipSYCL yet (2021-01-29)
+using detail::origin::group_any_of;
+using detail::origin::group_reduce;
+#else
+# error "Unsupported SYCL compiler"
+#endif
+
+} // namespace sycl_2020
+
#endif
.appendTextFormatted(
"GPU peer access not enabled between GPUs %d and %d due to unexpected "
"return value from %s. %s",
- gpuA, gpuB, cudaCallName, gmx::getDeviceErrorString(stat).c_str());
+ gpuA,
+ gpuB,
+ cudaCallName,
+ gmx::getDeviceErrorString(stat).c_str());
}
}
.appendTextFormatted(
"GPU peer access not enabled due to unexpected return value from "
"cudaSetDevice(%d). %s",
- gpuA, gmx::getDeviceErrorString(stat).c_str());
+ gpuA,
+ gmx::getDeviceErrorString(stat).c_str());
return;
}
for (unsigned int j = 0; j < gpuIdsToUse.size(); j++)
cl_ulong start_ns, end_ns;
cl_int gmx_unused cl_error;
- cl_error = clGetEventProfilingInfo(events_[i], CL_PROFILING_COMMAND_START,
- sizeof(cl_ulong), &start_ns, nullptr);
+ cl_error = clGetEventProfilingInfo(
+ events_[i], CL_PROFILING_COMMAND_START, sizeof(cl_ulong), &start_ns, nullptr);
GMX_ASSERT(CL_SUCCESS == cl_error,
gmx::formatString("GPU timing update failure (OpenCL error %d: %s).",
- cl_error, ocl_get_error_string(cl_error).c_str())
+ cl_error,
+ ocl_get_error_string(cl_error).c_str())
.c_str());
- cl_error = clGetEventProfilingInfo(events_[i], CL_PROFILING_COMMAND_END,
- sizeof(cl_ulong), &end_ns, nullptr);
+ cl_error = clGetEventProfilingInfo(
+ events_[i], CL_PROFILING_COMMAND_END, sizeof(cl_ulong), &end_ns, nullptr);
GMX_ASSERT(CL_SUCCESS == cl_error,
gmx::formatString("GPU timing update failure (OpenCL error %d: %s).",
- cl_error, ocl_get_error_string(cl_error).c_str())
+ cl_error,
+ ocl_get_error_string(cl_error).c_str())
.c_str());
milliseconds += (end_ns - start_ns) / 1000000.0;
}
// assume that sizeof(char) is one byte.
std::array<char, 1024> deviceName;
size_t deviceNameLength;
- cl_int cl_error = clGetDeviceInfo(deviceId, CL_DEVICE_NAME, deviceName.size(),
- deviceName.data(), &deviceNameLength);
+ cl_int cl_error = clGetDeviceInfo(
+ deviceId, CL_DEVICE_NAME, deviceName.size(), deviceName.data(), &deviceNameLength);
if (cl_error != CL_SUCCESS)
{
GMX_THROW(InternalError(formatString("Could not get OpenCL device name, error was %s",
(symbols), by permitting only alphanumeric characters from the
current locale. We assume these work well enough in a
filename. */
- std::copy_if(deviceName.begin(), deviceName.begin() + deviceNameLength,
- std::back_inserter(cacheFilename), isalnum);
+ std::copy_if(deviceName.begin(),
+ deviceName.begin() + deviceNameLength,
+ std::back_inserter(cacheFilename),
+ isalnum);
cacheFilename += ".bin";
return cacheFilename;
/* Create program from pre-built binary */
cl_int cl_error;
- cl_program program = clCreateProgramWithBinary(context, 1, &deviceId, &fileSize,
- const_cast<const unsigned char**>(&binary),
- nullptr, &cl_error);
+ cl_program program = clCreateProgramWithBinary(
+ context, 1, &deviceId, &fileSize, const_cast<const unsigned char**>(&binary), nullptr, &cl_error);
if (cl_error != CL_SUCCESS)
{
GMX_THROW(InternalError("Could not create OpenCL program from the cache file " + filename
buildLogGuard.reset(buildLog);
/* Get the actual compilation log */
- cl_error = clGetProgramBuildInfo(program, deviceId, CL_PROGRAM_BUILD_LOG, buildLogSize,
- buildLog, nullptr);
+ cl_error = clGetProgramBuildInfo(
+ program, deviceId, CL_PROGRAM_BUILD_LOG, buildLogSize, buildLog, nullptr);
if (cl_error != CL_SUCCESS)
{
GMX_THROW(InternalError("Could not get OpenCL program build log, error was "
size_t getKernelWarpSize(cl_kernel kernel, cl_device_id deviceId)
{
size_t warpSize = 0;
- cl_int cl_error =
- clGetKernelWorkGroupInfo(kernel, deviceId, CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE,
- sizeof(warpSize), &warpSize, nullptr);
+ cl_int cl_error = clGetKernelWorkGroupInfo(
+ kernel, deviceId, CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE, sizeof(warpSize), &warpSize, nullptr);
if (cl_error != CL_SUCCESS)
{
GMX_THROW(InternalError("Could not query OpenCL preferred workgroup size, error was "
// Failing to read from the cache is not a critical error
formatExceptionMessageToFile(fplog, e);
}
- fprintf(fplog, "OpenCL binary cache file %s is present, will load kernels.\n",
+ fprintf(fplog,
+ "OpenCL binary cache file %s is present, will load kernels.\n",
cacheFilename.c_str());
}
else
/* Write log first, and then throw exception that the user know what is
the issue even if the build fails. */
- writeOclBuildLog(fplog, program, deviceId, kernelFilename, preprocessorOptions,
- buildStatus != CL_SUCCESS);
+ writeOclBuildLog(fplog, program, deviceId, kernelFilename, preprocessorOptions, buildStatus != CL_SUCCESS);
if (buildStatus != CL_SUCCESS)
{
{
globalWorkSize[i] = config.gridSize[i] * config.blockSize[i];
}
- cl_int clError = clEnqueueNDRangeKernel(deviceStream.stream(), kernel, workDimensions,
- globalWorkOffset, globalWorkSize, config.blockSize,
- waitListSize, waitList, timingEvent);
+ cl_int clError = clEnqueueNDRangeKernel(deviceStream.stream(),
+ kernel,
+ workDimensions,
+ globalWorkOffset,
+ globalWorkSize,
+ config.blockSize,
+ waitListSize,
+ waitList,
+ timingEvent);
if (CL_SUCCESS != clError)
{
const std::string errorMessage = "GPU kernel (" + std::string(kernelName)
std::iota(valuesIn.begin(), valuesIn.end(), c_initialValue<TypeParam>);
- copyToDeviceBuffer(&buffer, valuesIn.data(), 0, numValues, deviceStream,
- GpuApiCallBehavior::Sync, nullptr);
- copyFromDeviceBuffer(valuesOut.data(), &buffer, 0, numValues, deviceStream,
- GpuApiCallBehavior::Sync, nullptr);
+ copyToDeviceBuffer(
+ &buffer, valuesIn.data(), 0, numValues, deviceStream, GpuApiCallBehavior::Sync, nullptr);
+ copyFromDeviceBuffer(
+ valuesOut.data(), &buffer, 0, numValues, deviceStream, GpuApiCallBehavior::Sync, nullptr);
EXPECT_THAT(valuesOut, Pointwise(Eq(), valuesIn)) << "Changed after H2D and D2H copy.";
freeDeviceBuffer(&buffer);
}
std::iota(valuesIn.begin(), valuesIn.end(), c_initialValue<TypeParam>);
// Fill the buffer with two copies of valuesIn, one after the other.
- copyToDeviceBuffer(&buffer, valuesIn.data(), 0, numValues, deviceStream,
- GpuApiCallBehavior::Sync, nullptr);
- copyToDeviceBuffer(&buffer, valuesIn.data(), numValues, numValues, deviceStream,
- GpuApiCallBehavior::Sync, nullptr);
+ copyToDeviceBuffer(
+ &buffer, valuesIn.data(), 0, numValues, deviceStream, GpuApiCallBehavior::Sync, nullptr);
+ copyToDeviceBuffer(
+ &buffer, valuesIn.data(), numValues, numValues, deviceStream, GpuApiCallBehavior::Sync, nullptr);
// Do the same copying on the CPU, so we can test it works
// correctly.
valuesIn.insert(valuesIn.end(), valuesIn.begin(), valuesIn.end());
- copyFromDeviceBuffer(valuesOut.data(), &buffer, 0, 2 * numValues, deviceStream,
- GpuApiCallBehavior::Sync, nullptr);
+ copyFromDeviceBuffer(
+ valuesOut.data(), &buffer, 0, 2 * numValues, deviceStream, GpuApiCallBehavior::Sync, nullptr);
EXPECT_THAT(valuesOut, Pointwise(Eq(), valuesIn)) << "Changed after H2D and D2H copy.";
SCOPED_TRACE("Checking the copy respects the output range");
// all but one of the old values.
valuesIn.erase(valuesIn.begin());
valuesIn.push_back(valuesIn.back());
- copyFromDeviceBuffer(valuesOut.data(), &buffer, 1, 2 * numValues - 1, deviceStream,
- GpuApiCallBehavior::Sync, nullptr);
+ copyFromDeviceBuffer(
+ valuesOut.data(), &buffer, 1, 2 * numValues - 1, deviceStream, GpuApiCallBehavior::Sync, nullptr);
EXPECT_THAT(valuesOut, Pointwise(Eq(), valuesIn)) << "Changed after H2D and D2H copy.";
}
}
DeviceStreamManager manager(deviceInfo, havePpDomainDecomposition, simulationWork, useTiming);
expectValidStreams(&manager, { DeviceStreamType::NonBondedLocal });
- expectInvalidStreams(&manager, { DeviceStreamType::NonBondedNonLocal,
- DeviceStreamType::Pme, DeviceStreamType::PmePpTransfer,
- DeviceStreamType::UpdateAndConstraints });
+ expectInvalidStreams(&manager,
+ { DeviceStreamType::NonBondedNonLocal,
+ DeviceStreamType::Pme,
+ DeviceStreamType::PmePpTransfer,
+ DeviceStreamType::UpdateAndConstraints });
}
{
bool havePpDomainDecomposition = true;
DeviceStreamManager manager(deviceInfo, havePpDomainDecomposition, simulationWork, useTiming);
- expectValidStreams(&manager, { DeviceStreamType::NonBondedLocal,
- DeviceStreamType::NonBondedNonLocal });
- expectInvalidStreams(&manager, { DeviceStreamType::Pme, DeviceStreamType::PmePpTransfer,
- DeviceStreamType::UpdateAndConstraints });
+ expectValidStreams(
+ &manager, { DeviceStreamType::NonBondedLocal, DeviceStreamType::NonBondedNonLocal });
+ expectInvalidStreams(&manager,
+ { DeviceStreamType::Pme,
+ DeviceStreamType::PmePpTransfer,
+ DeviceStreamType::UpdateAndConstraints });
}
{
bool havePpDomainDecomposition = false;
DeviceStreamManager manager(deviceInfo, havePpDomainDecomposition, simulationWork, useTiming);
- expectValidStreams(&manager, { DeviceStreamType::Pme, DeviceStreamType::NonBondedLocal,
- DeviceStreamType::PmePpTransfer,
- DeviceStreamType::UpdateAndConstraints });
+ expectValidStreams(&manager,
+ { DeviceStreamType::Pme,
+ DeviceStreamType::NonBondedLocal,
+ DeviceStreamType::PmePpTransfer,
+ DeviceStreamType::UpdateAndConstraints });
expectInvalidStreams(&manager, { DeviceStreamType::NonBondedNonLocal });
}
bool havePpDomainDecomposition = true;
DeviceStreamManager manager(deviceInfo, havePpDomainDecomposition, simulationWork, useTiming);
- expectValidStreams(&manager, { DeviceStreamType::Pme, DeviceStreamType::NonBondedLocal,
- DeviceStreamType::NonBondedNonLocal, DeviceStreamType::PmePpTransfer,
- DeviceStreamType::UpdateAndConstraints });
+ expectValidStreams(&manager,
+ { DeviceStreamType::Pme,
+ DeviceStreamType::NonBondedLocal,
+ DeviceStreamType::NonBondedNonLocal,
+ DeviceStreamType::PmePpTransfer,
+ DeviceStreamType::UpdateAndConstraints });
}
{
bool havePpDomainDecomposition = false;
DeviceStreamManager manager(deviceInfo, havePpDomainDecomposition, simulationWork, useTiming);
- expectValidStreams(&manager, { DeviceStreamType::NonBondedLocal,
- DeviceStreamType::UpdateAndConstraints });
- expectInvalidStreams(&manager, { DeviceStreamType::NonBondedNonLocal,
- DeviceStreamType::Pme, DeviceStreamType::PmePpTransfer });
+ expectValidStreams(
+ &manager, { DeviceStreamType::NonBondedLocal, DeviceStreamType::UpdateAndConstraints });
+ expectInvalidStreams(&manager,
+ { DeviceStreamType::NonBondedNonLocal,
+ DeviceStreamType::Pme,
+ DeviceStreamType::PmePpTransfer });
}
{
bool havePpDomainDecomposition = true;
DeviceStreamManager manager(deviceInfo, havePpDomainDecomposition, simulationWork, useTiming);
- expectValidStreams(&manager, { DeviceStreamType::NonBondedLocal, DeviceStreamType::NonBondedNonLocal,
- DeviceStreamType::UpdateAndConstraints });
+ expectValidStreams(&manager,
+ { DeviceStreamType::NonBondedLocal,
+ DeviceStreamType::NonBondedNonLocal,
+ DeviceStreamType::UpdateAndConstraints });
expectInvalidStreams(&manager, { DeviceStreamType::Pme, DeviceStreamType::PmePpTransfer });
}
bool havePpDomainDecomposition = false;
DeviceStreamManager manager(deviceInfo, havePpDomainDecomposition, simulationWork, useTiming);
- expectValidStreams(&manager, { DeviceStreamType::Pme, DeviceStreamType::NonBondedLocal,
- DeviceStreamType::PmePpTransfer,
- DeviceStreamType::UpdateAndConstraints });
+ expectValidStreams(&manager,
+ { DeviceStreamType::Pme,
+ DeviceStreamType::NonBondedLocal,
+ DeviceStreamType::PmePpTransfer,
+ DeviceStreamType::UpdateAndConstraints });
expectInvalidStreams(&manager, { DeviceStreamType::NonBondedNonLocal });
}
bool havePpDomainDecomposition = true;
DeviceStreamManager manager(deviceInfo, havePpDomainDecomposition, simulationWork, useTiming);
- expectValidStreams(&manager, { DeviceStreamType::Pme, DeviceStreamType::NonBondedLocal,
- DeviceStreamType::NonBondedNonLocal, DeviceStreamType::PmePpTransfer,
- DeviceStreamType::UpdateAndConstraints });
+ expectValidStreams(&manager,
+ { DeviceStreamType::Pme,
+ DeviceStreamType::NonBondedLocal,
+ DeviceStreamType::NonBondedNonLocal,
+ DeviceStreamType::PmePpTransfer,
+ DeviceStreamType::UpdateAndConstraints });
}
}
}
{
if (status != CL_SUCCESS)
{
- GMX_THROW(InternalError(formatString("Failure while %s, error was %s", message,
- ocl_get_error_string(status).c_str())));
+ GMX_THROW(InternalError(formatString(
+ "Failure while %s, error was %s", message, ocl_get_error_string(status).c_str())));
}
}
auto devicePointer = clCreateBuffer(context, CL_MEM_READ_WRITE, input.size(), nullptr, &status);
throwUponFailure(status, "creating buffer");
- status = clEnqueueWriteBuffer(commandQueue, devicePointer, CL_TRUE, 0, input.size(),
- input.data(), 0, nullptr, nullptr);
+ status = clEnqueueWriteBuffer(
+ commandQueue, devicePointer, CL_TRUE, 0, input.size(), input.data(), 0, nullptr, nullptr);
throwUponFailure(status, "transferring host to device");
- status = clEnqueueReadBuffer(commandQueue, devicePointer, CL_TRUE, 0, output.size(),
- output.data(), 0, nullptr, nullptr);
+ status = clEnqueueReadBuffer(
+ commandQueue, devicePointer, CL_TRUE, 0, output.size(), output.data(), 0, nullptr, nullptr);
throwUponFailure(status, "transferring device to host");
status = clReleaseMemObject(devicePointer);
DeviceBuffer<RVec> d_rVecInput;
allocateDeviceBuffer(&d_rVecInput, numElements, deviceContext);
- copyToDeviceBuffer(&d_rVecInput, h_rVecInput.data(), 0, numElements, deviceStream,
- GpuApiCallBehavior::Sync, nullptr);
+ copyToDeviceBuffer(
+ &d_rVecInput, h_rVecInput.data(), 0, numElements, deviceStream, GpuApiCallBehavior::Sync, nullptr);
DeviceBuffer<float3> d_float3Output;
allocateDeviceBuffer(&d_float3Output, numElements * DIM, deviceContext);
kernelLaunchConfig.sharedMemorySize = 0;
auto kernelPtr = convertRVecToFloat3OnDevice_kernel;
- const auto kernelArgs = prepareGpuKernelArguments(kernelPtr, kernelLaunchConfig,
- &d_float3Output, &d_rVecInput, &numElements);
- launchGpuKernel(kernelPtr, kernelLaunchConfig, deviceStream, nullptr,
- "convertRVecToFloat3OnDevice_kernel", kernelArgs);
-
- copyFromDeviceBuffer(h_float3Output.data(), &d_float3Output, 0, numElements, deviceStream,
- GpuApiCallBehavior::Sync, nullptr);
+ const auto kernelArgs = prepareGpuKernelArguments(
+ kernelPtr, kernelLaunchConfig, &d_float3Output, &d_rVecInput, &numElements);
+ launchGpuKernel(kernelPtr,
+ kernelLaunchConfig,
+ deviceStream,
+ nullptr,
+ "convertRVecToFloat3OnDevice_kernel",
+ kernelArgs);
+
+ copyFromDeviceBuffer(
+ h_float3Output.data(), &d_float3Output, 0, numElements, deviceStream, GpuApiCallBehavior::Sync, nullptr);
saveFloat3InRVecFormat(h_rVecOutput, h_float3Output.data(), numElements);
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+add_library(hardware INTERFACE)
gmx_add_libgromacs_sources(
cpuinfo.cpp
detecthardware.cpp
)
endif()
+# Source files have the following private module dependencies.
+target_link_libraries(hardware PRIVATE
+ )
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(hardware PUBLIC
+target_include_directories(hardware INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(hardware PUBLIC
+target_link_libraries(hardware INTERFACE
+ legacy_api
+ )
+
+# TODO: when hardware is an OBJECT target
+#target_link_libraries(hardware PUBLIC legacy_api)
+#target_link_libraries(hardware PRIVATE common)
+
+# Module dependencies
+# hardware interfaces convey transitive dependence on these modules.
+#target_link_libraries(hardware PUBLIC
+target_link_libraries(hardware INTERFACE
+ utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(hardware PRIVATE tng_io)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(hardware PRIVATE legacy_modules)
+
if (BUILD_TESTING)
add_subdirectory(tests)
endif()
for (std::size_t i = 0; i < uniqueSortedV.size(); i++)
{
unsigned int val = uniqueSortedV[i];
- std::replace_if(v->begin(), v->end(), [val](unsigned int& c) -> bool { return c == val; },
+ std::replace_if(v->begin(),
+ v->end(),
+ [val](unsigned int& c) -> bool { return c == val; },
static_cast<unsigned int>(i));
}
}
{
result.features_.insert(CpuInfo::Feature::X86_Hygon);
}
- detectX86Features(&result.brandString_, &result.family_, &result.model_, &result.stepping_,
- &result.features_);
+ detectX86Features(
+ &result.brandString_, &result.family_, &result.model_, &result.stepping_, &result.features_);
result.logicalProcessors_ = detectX86LogicalProcessors();
}
else
// On Linux we might be able to find information in /proc/cpuinfo. If vendor or brand
// is set to a known value this routine will not overwrite it.
- detectProcCpuInfo(&result.vendor_, &result.brandString_, &result.family_, &result.model_,
- &result.stepping_, &result.features_);
+ detectProcCpuInfo(&result.vendor_,
+ &result.brandString_,
+ &result.family_,
+ &result.model_,
+ &result.stepping_,
+ &result.features_);
}
if (!result.logicalProcessors_.empty())
bool cpuIsX86Nehalem(const CpuInfo& cpuInfo)
{
- return (cpuInfo.vendor() == gmx::CpuInfo::Vendor::Intel && cpuInfo.family() == 6
+ return (cpuInfo.vendor() == CpuInfo::Vendor::Intel && cpuInfo.family() == 6
&& (cpuInfo.model() == 0x2E || cpuInfo.model() == 0x1A || cpuInfo.model() == 0x1E
|| cpuInfo.model() == 0x2F || cpuInfo.model() == 0x2C || cpuInfo.model() == 0x25));
}
+bool cpuIsAmdZen1(const CpuInfo& cpuInfo)
+{
+ /* Both Zen/Zen+/Zen2 have family==23
+ * Model numbers for Zen:
+ * 1) Naples, Whitehaven, Summit Ridge, and Snowy Owl;
+ * 17) Raven Ridge.
+ * Model numbers for Zen+:
+ * 8) Pinnacle Ridge;
+ * 24) Picasso.
+ * Hygon got license for Zen1, but not Zen2 (https://www.tomshardware.com/news/amd-zen-china-x86-ip-license,39573.html)
+ */
+ return (cpuInfo.vendor() == CpuInfo::Vendor::Amd && cpuInfo.family() == 23
+ && (cpuInfo.model() == 1 || cpuInfo.model() == 17 || cpuInfo.model() == 8
+ || cpuInfo.model() == 24))
+ || (cpuInfo.vendor() == CpuInfo::Vendor::Hygon);
+}
+
} // namespace gmx
#ifdef GMX_CPUINFO_STANDALONE
*/
bool cpuIsX86Nehalem(const CpuInfo& cpuInfo);
+/*! \brief Return true if the CPU is a first generation AMD Zen (produced by AMD or Hygon)
+ *
+ * \param cpuInfo Object with cpu information
+ *
+ * \returns True if running on a first generation AMD Zen
+ */
+bool cpuIsAmdZen1(const CpuInfo& cpuInfo);
+
} // namespace gmx
#endif // GMX_HARDWARE_CPUINFO_H
* - family=23 with the below listed models;
* - Hygon as vendor.
*/
- const bool cpuIsAmdZen1 = ((cpuInfo.vendor() == CpuInfo::Vendor::Amd && cpuInfo.family() == 23
- && (cpuInfo.model() == 1 || cpuInfo.model() == 17
- || cpuInfo.model() == 8 || cpuInfo.model() == 24))
- || cpuInfo.vendor() == CpuInfo::Vendor::Hygon);
+ const bool cpuIsAmdZen1 = gmx::cpuIsAmdZen1(cpuInfo);
int numCompatibleDevices = getCompatibleDevices(hardwareInfo->deviceInfoList).size();
#if GMX_LIB_MPI
countsLocal[3] = numCompatibleDevices;
}
- MPI_Allreduce(countsLocal.data(), countsReduced.data(), countsLocal.size(), MPI_INT,
- MPI_SUM, MPI_COMM_WORLD);
+ MPI_Allreduce(countsLocal.data(), countsReduced.data(), countsLocal.size(), MPI_INT, MPI_SUM, MPI_COMM_WORLD);
}
constexpr int numElementsMax = 11;
maxMinLocal[9] = -maxMinLocal[4];
maxMinLocal[10] = (cpuIsAmdZen1 ? 1 : 0);
- MPI_Allreduce(maxMinLocal.data(), maxMinReduced.data(), maxMinLocal.size(), MPI_INT,
- MPI_MAX, MPI_COMM_WORLD);
+ MPI_Allreduce(maxMinLocal.data(), maxMinReduced.data(), maxMinLocal.size(), MPI_INT, MPI_MAX, MPI_COMM_WORLD);
}
hardwareInfo->nphysicalnode = countsReduced[0];
GMX_LOG(mdlog.info)
.appendTextFormatted(
"Note: %d CPUs configured, but only %d were detected to be online.\n",
- countConfigured, countFromDetection);
+ countConfigured,
+ countFromDetection);
if (c_architecture == Architecture::X86 && countConfigured == 2 * countFromDetection)
{
* missing, so that is suppressed.
*/
static const gmx::EnumerationArray<DeviceStatus, const char*> c_deviceStateString = {
- "compatible", "nonexistent", "incompatible",
+ "compatible",
+ "nonexistent",
+ "incompatible",
// clang-format off
// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
"incompatible (please recompile with correct GMX" "_OPENCL_NB_CLUSTER_SIZE of 4)",
// clang-format on
- "incompatible (please use CUDA build for NVIDIA Volta GPUs or newer)", "non-functional",
+ "incompatible (please use CUDA build for NVIDIA Volta GPUs or newer)",
+ "non-functional",
"unavailable"
};
"might be rare, or some architectures were disabled in the build. \n"
"Consult the install guide for how to use the GMX_CUDA_TARGET_SM and "
"GMX_CUDA_TARGET_COMPUTE CMake variables to add this architecture. \n",
- gmx::getProgramContext().displayName(), deviceId, deviceProp.major, deviceProp.minor);
+ gmx::getProgramContext().displayName(),
+ deviceId,
+ deviceProp.major,
+ deviceProp.minor);
}
return stat;
cu_err = cudaSetDevice(deviceInfo.id);
if (cu_err != cudaSuccess)
{
- fprintf(stderr, "Error while switching to device #%d. %s\n", deviceInfo.id,
+ fprintf(stderr,
+ "Error while switching to device #%d. %s\n",
+ deviceInfo.id,
gmx::getDeviceErrorString(cu_err).c_str());
return DeviceStatus::NonFunctional;
}
// launchGpuKernel error is not fatal and should continue with marking the device bad
fprintf(stderr,
"Error occurred while running dummy kernel sanity check on device #%d:\n %s\n",
- deviceInfo.id, formatExceptionMessageToString(ex).c_str());
+ deviceInfo.id,
+ formatExceptionMessageToString(ex).c_str());
return DeviceStatus::NonFunctional;
}
if (!gpuExists)
{
- return gmx::formatString("#%d: %s, stat: %s", deviceInfo.id, "N/A",
- c_deviceStateString[deviceInfo.status]);
+ return gmx::formatString(
+ "#%d: %s, stat: %s", deviceInfo.id, "N/A", c_deviceStateString[deviceInfo.status]);
}
else
{
return gmx::formatString("#%d: NVIDIA %s, compute cap.: %d.%d, ECC: %3s, stat: %s",
- deviceInfo.id, deviceInfo.prop.name, deviceInfo.prop.major,
- deviceInfo.prop.minor, deviceInfo.prop.ECCEnabled ? "yes" : " no",
+ deviceInfo.id,
+ deviceInfo.prop.name,
+ deviceInfo.prop.major,
+ deviceInfo.prop.minor,
+ deviceInfo.prop.ECCEnabled ? "yes" : " no",
c_deviceStateString[deviceInfo.status]);
}
}
bool deviceIdIsCompatible(const std::vector<std::unique_ptr<DeviceInformation>>& deviceInfoList,
const int deviceId)
{
- auto foundIt = std::find_if(deviceInfoList.begin(), deviceInfoList.end(),
+ auto foundIt = std::find_if(deviceInfoList.begin(),
+ deviceInfoList.end(),
[deviceId](auto& deviceInfo) { return deviceInfo->id == deviceId; });
if (foundIt == deviceInfoList.end())
{
GMX_THROW(gmx::RangeError(gmx::formatString(
- "Device ID %d did not correspond to any of the %zu detected device(s)", deviceId,
+ "Device ID %d did not correspond to any of the %zu detected device(s)",
+ deviceId,
deviceInfoList.size())));
}
return (*foundIt)->status == DeviceStatus::Compatible;
static const unsigned int ccMajorBad = 7; // Volta and Turing
unsigned int ccMajor;
cl_device_id devId = deviceInfo.oclDeviceId;
- const cl_int err = clGetDeviceInfo(devId, CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV,
- sizeof(ccMajor), &ccMajor, nullptr);
+ const cl_int err = clGetDeviceInfo(
+ devId, CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV, sizeof(ccMajor), &ccMajor, nullptr);
if (err != CL_SUCCESS)
{
return true; // Err on a side of trusting the user to know what they are doing.
// the device which has the following format:
// OpenCL<space><major_version.minor_version><space><vendor-specific information>
unsigned int deviceVersionMinor, deviceVersionMajor;
- const int valuesScanned = std::sscanf(deviceInfo.device_version, "OpenCL %u.%u",
- &deviceVersionMajor, &deviceVersionMinor);
- const bool versionLargeEnough =
+ const int valuesScanned = std::sscanf(
+ deviceInfo.device_version, "OpenCL %u.%u", &deviceVersionMajor, &deviceVersionMinor);
+ const bool versionLargeEnough =
((valuesScanned == 2)
&& ((deviceVersionMajor > minVersionMajor)
|| (deviceVersionMajor == minVersionMajor && deviceVersionMinor >= minVersionMinor)));
{
if (message != nullptr)
{
- return gmx::formatString("%s did %ssucceed %d: %s", message,
- ((status != CL_SUCCESS) ? "not " : ""), status,
+ return gmx::formatString("%s did %ssucceed %d: %s",
+ message,
+ ((status != CL_SUCCESS) ? "not " : ""),
+ status,
ocl_get_error_string(status).c_str());
}
else
{
return gmx::formatString("%sOpenCL error encountered %d: %s",
- ((status != CL_SUCCESS) ? "" : "No "), status,
+ ((status != CL_SUCCESS) ? "" : "No "),
+ status,
ocl_get_error_string(status).c_str());
}
}
clSetKernelArg(kernel, 0, sizeof(void*), nullptr);
const size_t localWorkSize = 1, globalWorkSize = 1;
- if ((status = clEnqueueNDRangeKernel(commandQueue, kernel, 1, nullptr, &globalWorkSize,
- &localWorkSize, 0, nullptr, nullptr))
+ if ((status = clEnqueueNDRangeKernel(
+ commandQueue, kernel, 1, nullptr, &globalWorkSize, &localWorkSize, 0, nullptr, nullptr))
!= CL_SUCCESS)
{
errorMessage->assign(makeOpenClInternalErrorString("clEnqueueNDRangeKernel", status));
GMX_RELEASE_ASSERT(
status == CL_SUCCESS,
gmx::formatString("An unexpected value was returned from clGetPlatformIDs %d: %s",
- status, ocl_get_error_string(status).c_str())
+ status,
+ ocl_get_error_string(status).c_str())
.c_str());
bool foundPlatform = (numPlatforms > 0);
if (!foundPlatform && errorMessage != nullptr)
/* If requesting req_dev_type devices fails, just go to the next platform */
if (CL_SUCCESS
- != clGetDeviceIDs(ocl_platform_ids[i], req_dev_type, numDevices, ocl_device_ids,
- &ocl_device_count))
+ != clGetDeviceIDs(ocl_platform_ids[i], req_dev_type, numDevices, ocl_device_ids, &ocl_device_count))
{
continue;
}
deviceInfoList[device_index]->oclDeviceId = ocl_device_ids[j];
deviceInfoList[device_index]->device_name[0] = 0;
- clGetDeviceInfo(ocl_device_ids[j], CL_DEVICE_NAME,
+ clGetDeviceInfo(ocl_device_ids[j],
+ CL_DEVICE_NAME,
sizeof(deviceInfoList[device_index]->device_name),
- deviceInfoList[device_index]->device_name, nullptr);
+ deviceInfoList[device_index]->device_name,
+ nullptr);
deviceInfoList[device_index]->device_version[0] = 0;
- clGetDeviceInfo(ocl_device_ids[j], CL_DEVICE_VERSION,
+ clGetDeviceInfo(ocl_device_ids[j],
+ CL_DEVICE_VERSION,
sizeof(deviceInfoList[device_index]->device_version),
- deviceInfoList[device_index]->device_version, nullptr);
+ deviceInfoList[device_index]->device_version,
+ nullptr);
deviceInfoList[device_index]->vendorName[0] = 0;
- clGetDeviceInfo(ocl_device_ids[j], CL_DEVICE_VENDOR,
+ clGetDeviceInfo(ocl_device_ids[j],
+ CL_DEVICE_VENDOR,
sizeof(deviceInfoList[device_index]->vendorName),
- deviceInfoList[device_index]->vendorName, nullptr);
+ deviceInfoList[device_index]->vendorName,
+ nullptr);
deviceInfoList[device_index]->compute_units = 0;
- clGetDeviceInfo(ocl_device_ids[j], CL_DEVICE_MAX_COMPUTE_UNITS,
+ clGetDeviceInfo(ocl_device_ids[j],
+ CL_DEVICE_MAX_COMPUTE_UNITS,
sizeof(deviceInfoList[device_index]->compute_units),
- &(deviceInfoList[device_index]->compute_units), nullptr);
+ &(deviceInfoList[device_index]->compute_units),
+ nullptr);
deviceInfoList[device_index]->adress_bits = 0;
- clGetDeviceInfo(ocl_device_ids[j], CL_DEVICE_ADDRESS_BITS,
+ clGetDeviceInfo(ocl_device_ids[j],
+ CL_DEVICE_ADDRESS_BITS,
sizeof(deviceInfoList[device_index]->adress_bits),
- &(deviceInfoList[device_index]->adress_bits), nullptr);
+ &(deviceInfoList[device_index]->adress_bits),
+ nullptr);
deviceInfoList[device_index]->deviceVendor =
getDeviceVendor(deviceInfoList[device_index]->vendorName);
- clGetDeviceInfo(ocl_device_ids[j], CL_DEVICE_MAX_WORK_ITEM_SIZES, 3 * sizeof(size_t),
- &deviceInfoList[device_index]->maxWorkItemSizes, nullptr);
+ clGetDeviceInfo(ocl_device_ids[j],
+ CL_DEVICE_MAX_WORK_ITEM_SIZES,
+ 3 * sizeof(size_t),
+ &deviceInfoList[device_index]->maxWorkItemSizes,
+ nullptr);
- clGetDeviceInfo(ocl_device_ids[j], CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(size_t),
- &deviceInfoList[device_index]->maxWorkGroupSize, nullptr);
+ clGetDeviceInfo(ocl_device_ids[j],
+ CL_DEVICE_MAX_WORK_GROUP_SIZE,
+ sizeof(size_t),
+ &deviceInfoList[device_index]->maxWorkGroupSize,
+ nullptr);
deviceInfoList[device_index]->status =
gmx::checkGpu(device_index, *deviceInfoList[device_index]);
if (!gpuExists)
{
- return gmx::formatString("#%d: %s, status: %s", deviceInfo.id, "N/A",
- c_deviceStateString[deviceInfo.status]);
+ return gmx::formatString(
+ "#%d: %s, status: %s", deviceInfo.id, "N/A", c_deviceStateString[deviceInfo.status]);
}
else
{
return gmx::formatString("#%d: name: %s, vendor: %s, device version: %s, status: %s",
- deviceInfo.id, deviceInfo.device_name, deviceInfo.vendorName,
- deviceInfo.device_version, c_deviceStateString[deviceInfo.status]);
+ deviceInfo.id,
+ deviceInfo.device_name,
+ deviceInfo.vendorName,
+ deviceInfo.device_version,
+ c_deviceStateString[deviceInfo.status]);
}
}
{
if (errorMessage != nullptr)
{
- errorMessage->assign(gmx::formatString(
- "Unable to run dummy kernel on device %s: %s",
- syclDevice.get_info<cl::sycl::info::device::name>().c_str(), e.what()));
+ errorMessage->assign(
+ gmx::formatString("Unable to run dummy kernel on device %s: %s",
+ syclDevice.get_info<cl::sycl::info::device::name>().c_str(),
+ e.what()));
}
return false;
}
if (!deviceExists)
{
- return gmx::formatString("#%d: %s, status: %s", deviceInfo.id, "N/A",
- c_deviceStateString[deviceInfo.status]);
+ return gmx::formatString(
+ "#%d: %s, status: %s", deviceInfo.id, "N/A", c_deviceStateString[deviceInfo.status]);
}
else
{
return gmx::formatString(
- "#%d: name: %s, vendor: %s, device version: %s, status: %s", deviceInfo.id,
+ "#%d: name: %s, vendor: %s, device version: %s, status: %s",
+ deviceInfo.id,
deviceInfo.syclDevice.get_info<cl::sycl::info::device::name>().c_str(),
deviceInfo.syclDevice.get_info<cl::sycl::info::device::vendor>().c_str(),
deviceInfo.syclDevice.get_info<cl::sycl::info::device::version>().c_str(),
// Go through children; if this object has no children obj->arity is 0,
// and we'll return an empty vector.
hwloc_obj_t tempNode = nullptr;
- while ((tempNode = hwloc_get_next_child(const_cast<hwloc_topology_t>(topo),
- const_cast<hwloc_obj_t>(obj), tempNode))
+ while ((tempNode = hwloc_get_next_child(
+ const_cast<hwloc_topology_t>(topo), const_cast<hwloc_obj_t>(obj), tempNode))
!= nullptr)
{
std::vector<const hwloc_obj*> v2 = getHwLocDescendantsByType(topo, tempNode, type);
// assign stuff
for (auto& v : machine->numa.relativeLatency)
{
- std::transform(v.begin(), v.end(), v.begin(),
+ std::transform(v.begin(),
+ v.end(),
+ v.begin(),
std::bind(std::multiplies<float>(), std::placeholders::_1, 1.0 / minLatency));
}
machine->numa.baseLatency = 1.0; // latencies still do not have any units in hwloc-2.x
GMX_RELEASE_ASSERT(p->attr, "Attributes should not be NULL for hwloc PCI object");
- machine->devices.push_back({ p->attr->pcidev.vendor_id, p->attr->pcidev.device_id,
- p->attr->pcidev.class_id, p->attr->pcidev.domain,
- p->attr->pcidev.bus, p->attr->pcidev.dev, p->attr->pcidev.func,
+ machine->devices.push_back({ p->attr->pcidev.vendor_id,
+ p->attr->pcidev.device_id,
+ p->attr->pcidev.class_id,
+ p->attr->pcidev.domain,
+ p->attr->pcidev.bus,
+ p->attr->pcidev.dev,
+ p->attr->pcidev.func,
numaId });
}
return !pcidevs.empty();
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
"\tmovq %%rdx, %0\n"
: "=r"(cycles)
: "r"(loopCount)
- : "rax", "rbx", "rcx", "rdx", "zmm0", "zmm1", "zmm2", "zmm3", "zmm4", "zmm5", "zmm6",
- "zmm7", "zmm8", "zmm9", "zmm10", "zmm11", "zmm12", "zmm13", "zmm14", "zmm15", "zmm16",
- "zmm17", "zmm18", "zmm19", "zmm20", "zmm21", "zmm22", "zmm23", "zmm30");
+ : "rax",
+ "rbx",
+ "rcx",
+ "rdx",
+ "zmm0",
+ "zmm1",
+ "zmm2",
+ "zmm3",
+ "zmm4",
+ "zmm5",
+ "zmm6",
+ "zmm7",
+ "zmm8",
+ "zmm9",
+ "zmm10",
+ "zmm11",
+ "zmm12",
+ "zmm13",
+ "zmm14",
+ "zmm15",
+ "zmm16",
+ "zmm17",
+ "zmm18",
+ "zmm19",
+ "zmm20",
+ "zmm21",
+ "zmm22",
+ "zmm23",
+ "zmm30");
return cycles;
}
"\tmovq %%rdx, %0\n"
: "=r"(cycles)
: "r"(loopCount)
- : "rax", "rbx", "rcx", "rdx", "zmm0", "zmm1", "zmm2", "zmm3", "zmm4", "zmm5", "zmm6",
- "zmm7", "zmm8", "zmm9", "zmm10", "zmm11");
+ : "rax",
+ "rbx",
+ "rcx",
+ "rdx",
+ "zmm0",
+ "zmm1",
+ "zmm2",
+ "zmm3",
+ "zmm4",
+ "zmm5",
+ "zmm6",
+ "zmm7",
+ "zmm8",
+ "zmm9",
+ "zmm10",
+ "zmm11");
return cycles;
}
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team.
- * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2020,2021, 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.
* (using sysconf), and the spins doing dummy compute operations for up to
* 2 seconds, or until all cores have come online. This can be used prior to
* hardware detection for platforms that take unused processors offline.
- *
- * This routine will not throw exceptions. In principle it should be
- * declared noexcept, but at least icc 19.1 and 21-beta08 with the
- * libstdc++-7.5 has difficulty implementing a std::vector of
- * std::thread started with this function when declared noexcept. It
- * is a known compiler bug that should be fixed after 19.1.
- * Fortunately, this function is not performance sensitive,
- * and only runs on platforms other than x86 and POWER (ie ARM),
- * so the possible overhead introduced by omitting noexcept is not
- * important.
*/
-static void spinUpCore()
+static void spinUpCore() noexcept
{
#if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_CONF) && defined(_SC_NPROCESSORS_ONLN)
float dummy = 0.1;
"speed as accurate timings are needed for load-balancing.\n"
"Please consider rebuilding %s with the GMX_USE_RDTSCP=ON CMake "
"option.",
- programName, programName);
+ programName,
+ programName);
}
}
}
const gmx::HardwareTopology& hwTop = *hwinfo->hardwareTopology;
s = gmx::formatString("\n");
- s += gmx::formatString("Running on %d node%s with total", hwinfo->nphysicalnode,
+ s += gmx::formatString("Running on %d node%s with total",
+ hwinfo->nphysicalnode,
hwinfo->nphysicalnode == 1 ? "" : "s");
if (hwinfo->ncore_tot > 0)
{
s += gmx::formatString(" %d logical cores", hwinfo->nhwthread_tot);
if (canPerformDeviceDetection(nullptr))
{
- s += gmx::formatString(", %d compatible GPU%s", hwinfo->ngpu_compatible_tot,
+ s += gmx::formatString(", %d compatible GPU%s",
+ hwinfo->ngpu_compatible_tot,
hwinfo->ngpu_compatible_tot == 1 ? "" : "s");
}
else if (bGPUBinary)
if (bFullCpuInfo)
{
- s += gmx::formatString(" Family: %d Model: %d Stepping: %d\n", cpuInfo.family(),
- cpuInfo.model(), cpuInfo.stepping());
+ s += gmx::formatString(" Family: %d Model: %d Stepping: %d\n",
+ cpuInfo.family(),
+ cpuInfo.model(),
+ cpuInfo.stepping());
s += gmx::formatString(" Features:");
for (auto& f : cpuInfo.featureSet())
{
s += gmx::formatString(
" L%d: %zu bytes, linesize %d bytes, assoc. %d, shared %d ways\n",
- c.level, c.size, c.linesize, c.associativity, c.shared);
+ c.level,
+ c.size,
+ c.linesize,
+ c.associativity,
+ c.shared);
}
}
if (hwTop.supportLevel() >= gmx::HardwareTopology::SupportLevel::FullWithDevices)
for (auto& d : hwTop.machine().devices)
{
s += gmx::formatString(
- " %04x:%02x:%02x.%1x Id: %04x:%04x Class: 0x%04x Numa: %d\n", d.domain,
- d.bus, d.dev, d.func, d.vendorId, d.deviceId, d.classId, d.numaNodeId);
+ " %04x:%02x:%02x.%1x Id: %04x:%04x Class: 0x%04x Numa: %d\n",
+ d.domain,
+ d.bus,
+ d.dev,
+ d.func,
+ d.vendorId,
+ d.deviceId,
+ d.classId,
+ d.numaNodeId);
}
}
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2016,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2015,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.
auto logicalProcessors = hwTop.machine().logicalProcessors;
for (auto logicalProcessorIt = logicalProcessors.begin();
- logicalProcessorIt != logicalProcessors.end(); ++logicalProcessorIt)
+ logicalProcessorIt != logicalProcessors.end();
+ ++logicalProcessorIt)
{
// Check that logical processor information contains
// reasonable values.
// for each logical processor.
for (auto remainingLogicalProcessorIt = logicalProcessorIt + 1;
- remainingLogicalProcessorIt != logicalProcessors.end(); ++remainingLogicalProcessorIt)
+ remainingLogicalProcessorIt != logicalProcessors.end();
+ ++remainingLogicalProcessorIt)
{
SCOPED_TRACE(gmx::formatString("Other socket rank in machine: %d",
remainingLogicalProcessorIt->socketRankInMachine));
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2014,2015, by the GROMACS development team, led by
+# Copyright (c) 2014,2015,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.
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+add_library(imd INTERFACE)
file(GLOB IMD_SOURCES *.cpp)
set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${IMD_SOURCES} PARENT_SCOPE)
+
+# Source files have the following private module dependencies.
+target_link_libraries(imd PRIVATE
+# gmxlib
+# math
+# mdtypes
+ )
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(imd PUBLIC
+target_include_directories(imd INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(imd PUBLIC
+target_link_libraries(imd INTERFACE
+ legacy_api
+ )
+
+# TODO: when imd is an OBJECT target
+#target_link_libraries(imd PUBLIC legacy_api)
+#target_link_libraries(imd PRIVATE common)
+
+# Module dependencies
+# imd interfaces convey transitive dependence on these modules.
+#target_link_libraries(imd PUBLIC
+target_link_libraries(imd INTERFACE
+ utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(imd PRIVATE tng_io)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(imd PRIVATE legacy_modules)
if (bIMD)
{
IMDatoms = gmx_mtop_global_atoms(sys);
- write_sto_conf_indexed(opt2fn("-imd", nfile, fnm), "IMDgroup", &IMDatoms,
- state->x.rvec_array(), state->v.rvec_array(), ir->pbcType,
- state->box, ir->imd->nat, ir->imd->ind);
+ write_sto_conf_indexed(opt2fn("-imd", nfile, fnm),
+ "IMDgroup",
+ &IMDatoms,
+ state->x.rvec_array(),
+ state->v.rvec_array(),
+ ir->pbcType,
+ state->box,
+ ir->imd->nat,
+ ir->imd->ind);
}
}
return;
}
- dd_make_local_group_indices(dd->ga2la, impl_->nat, impl_->ind, &impl_->nat_loc, &impl_->ind_loc,
- &impl_->nalloc_loc, impl_->xa_ind);
+ dd_make_local_group_indices(
+ dd->ga2la, impl_->nat, impl_->ind, &impl_->nat_loc, &impl_->ind_loc, &impl_->nalloc_loc, impl_->xa_ind);
}
/* Catch all rule for the remaining IMD types which we don't expect */
default:
GMX_LOG(mdlog.warning)
- .appendTextFormatted(" %s Received unexpected %s.", IMDstr,
+ .appendTextFormatted(" %s Received unexpected %s.",
+ IMDstr,
enum_name(static_cast<int>(itype), IMD_NR, eIMDType_names));
issueFatalError("Terminating connection");
break;
"%s For a log of the IMD pull forces explicitly specify '-if' on the command "
"line.\n"
"%s (Not possible with energy minimization.)\n",
- IMDstr, IMDstr);
+ IMDstr,
+ IMDstr);
return;
}
"the atoms suffices.\n");
}
- xvgr_header(outf, "IMD Pull Forces", "Time (ps)",
- "# of Forces / Atom IDs / Forces (kJ/mol)", exvggtNONE, oenv);
+ xvgr_header(outf, "IMD Pull Forces", "Time (ps)", "# of Forces / Atom IDs / Forces (kJ/mol)", exvggtNONE, oenv);
fprintf(outf, "# Can display and manipulate %d (of a total of %d) atoms via IMD.\n", nat, nat_total);
fprintf(outf, "# column 1 : time (ps)\n");
.appendTextFormatted(
"%s Integrator '%s' is not supported for Interactive Molecular Dynamics, "
"running normally instead",
- IMDstr, ei_names[ir->eI]);
+ IMDstr,
+ ei_names[ir->eI]);
return session;
}
if (isMultiSim(ms))
.appendTextFormatted(
"%s None of the -imd switches was used.\n"
"%s This run will not accept incoming IMD connections",
- IMDstr, IMDstr);
+ IMDstr,
+ IMDstr);
}
} /* end master only */
{
/* Transfer the IMD positions to the master node. Every node contributes
* its local positions x and stores them in the assembled xa array. */
- communicate_group_positions(cr, xa, xa_shifts, xa_eshifts, true, x, nat, nat_loc, ind_loc,
- xa_ind, xa_old, box);
+ communicate_group_positions(
+ cr, xa, xa_shifts, xa_eshifts, true, x, nat, nat_loc, ind_loc, xa_ind, xa_old, box);
/* If connected and master -> remove shifts */
if ((imdstep && bConnected) && MASTER(cr))
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2014,2015,2016,2017,2018 by the GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/math/vectypes.h"
#include "gromacs/utility/basedefinitions.h"
-#include "gromacs/utility/classhelpers.h"
struct gmx_domdec_t;
struct gmx_enerdata_t;
//! Implementation type.
class Impl;
//! Implementation object.
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
public:
// Befriend the factory function.
${LINEARALGEBRA_SOURCES} ${BLAS_SOURCES} ${LAPACK_SOURCES})
add_library(linearalgebra OBJECT ${LINEARALGEBRA_SOURCES})
+# TODO: Only expose the module's public headers.
+target_include_directories(linearalgebra INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+target_include_directories(linearalgebra PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
+
gmx_target_compile_options(linearalgebra)
target_compile_definitions(linearalgebra PRIVATE HAVE_CONFIG_H)
# The linearalgebra code is all considered external, and we will
# not expect null termination of C strings.
gmx_target_warning_suppression(linearalgebra -Wno-stringop-truncation HAS_NO_STRINGOP_TRUNCATION)
endif()
+target_link_libraries(linearalgebra PRIVATE legacy_api)
+target_link_libraries(linearalgebra PRIVATE common)
+# TODO: Link specific modules.
+target_link_libraries(linearalgebra PRIVATE legacy_modules)
list(APPEND libgromacs_object_library_dependencies linearalgebra)
set(libgromacs_object_library_dependencies ${libgromacs_object_library_dependencies} PARENT_SCOPE)
*/
#if GMX_DOUBLE
F77_FUNC(dsyevr, DSYEVR)
- (jobz, "I", "L", &n, a, &n, &vl, &vu, &index_lower, &index_upper, &abstol, &m, eigenvalues,
- eigenvectors, &n, isuppz, &w0, &lwork, &iw0, &liwork, &info);
+ (jobz,
+ "I",
+ "L",
+ &n,
+ a,
+ &n,
+ &vl,
+ &vu,
+ &index_lower,
+ &index_upper,
+ &abstol,
+ &m,
+ eigenvalues,
+ eigenvectors,
+ &n,
+ isuppz,
+ &w0,
+ &lwork,
+ &iw0,
+ &liwork,
+ &info);
#else
F77_FUNC(ssyevr, SSYEVR)
- (jobz, "I", "L", &n, a, &n, &vl, &vu, &index_lower, &index_upper, &abstol, &m, eigenvalues,
- eigenvectors, &n, isuppz, &w0, &lwork, &iw0, &liwork, &info);
+ (jobz,
+ "I",
+ "L",
+ &n,
+ a,
+ &n,
+ &vl,
+ &vu,
+ &index_lower,
+ &index_upper,
+ &abstol,
+ &m,
+ eigenvalues,
+ eigenvectors,
+ &n,
+ isuppz,
+ &w0,
+ &lwork,
+ &iw0,
+ &liwork,
+ &info);
#endif
if (info != 0)
#if GMX_DOUBLE
F77_FUNC(dsyevr, DSYEVR)
- (jobz, "I", "L", &n, a, &n, &vl, &vu, &index_lower, &index_upper, &abstol, &m, eigenvalues,
- eigenvectors, &n, isuppz, work, &lwork, iwork, &liwork, &info);
+ (jobz,
+ "I",
+ "L",
+ &n,
+ a,
+ &n,
+ &vl,
+ &vu,
+ &index_lower,
+ &index_upper,
+ &abstol,
+ &m,
+ eigenvalues,
+ eigenvectors,
+ &n,
+ isuppz,
+ work,
+ &lwork,
+ iwork,
+ &liwork,
+ &info);
#else
F77_FUNC(ssyevr, SSYEVR)
- (jobz, "I", "L", &n, a, &n, &vl, &vu, &index_lower, &index_upper, &abstol, &m, eigenvalues,
- eigenvectors, &n, isuppz, work, &lwork, iwork, &liwork, &info);
+ (jobz,
+ "I",
+ "L",
+ &n,
+ a,
+ &n,
+ &vl,
+ &vu,
+ &index_lower,
+ &index_upper,
+ &abstol,
+ &m,
+ eigenvalues,
+ eigenvectors,
+ &n,
+ isuppz,
+ work,
+ &lwork,
+ iwork,
+ &liwork,
+ &info);
#endif
sfree(isuppz);
{
# if GMX_DOUBLE
F77_FUNC(pdsaupd, PDSAUPD)
- (&ido, "I", &n, "SA", &neig, &abstol, resid, &ncv, v, &n, iparam, ipntr, workd, iwork,
- workl, &lworkl, &info);
+ (&ido, "I", &n, "SA", &neig, &abstol, resid, &ncv, v, &n, iparam, ipntr, workd, iwork, workl, &lworkl, &info);
# else
F77_FUNC(pssaupd, PSSAUPD)
- (&ido, "I", &n, "SA", &neig, &abstol, resid, &ncv, v, &n, iparam, ipntr, workd, iwork,
- workl, &lworkl, &info);
+ (&ido, "I", &n, "SA", &neig, &abstol, resid, &ncv, v, &n, iparam, ipntr, workd, iwork, workl, &lworkl, &info);
# endif
if (ido == -1 || ido == 1)
{
gmx_fatal(FARGS,
"Maximum number of iterations (%d) reached in Arnoldi\n"
"diagonalization, but only %d of %d eigenvectors converged.\n",
- maxiter, iparam[4], neig);
+ maxiter,
+ iparam[4],
+ neig);
}
else if (info != 0)
{
# if GMX_DOUBLE
F77_FUNC(pdseupd, PDSEUPD)
- (&dovec, "A", select, eigenvalues, eigenvectors, &n, NULL, "I", &n, "SA", &neig, &abstol, resid,
- &ncv, v, &n, iparam, ipntr, workd, workl, &lworkl, &info);
+ (&dovec,
+ "A",
+ select,
+ eigenvalues,
+ eigenvectors,
+ &n,
+ NULL,
+ "I",
+ &n,
+ "SA",
+ &neig,
+ &abstol,
+ resid,
+ &ncv,
+ v,
+ &n,
+ iparam,
+ ipntr,
+ workd,
+ workl,
+ &lworkl,
+ &info);
# else
F77_FUNC(psseupd, PSSEUPD)
- (&dovec, "A", select, eigenvalues, eigenvectors, &n, NULL, "I", &n, "SA", &neig, &abstol, resid,
- &ncv, v, &n, iparam, ipntr, workd, workl, &lworkl, &info);
+ (&dovec,
+ "A",
+ select,
+ eigenvalues,
+ eigenvectors,
+ &n,
+ NULL,
+ "I",
+ &n,
+ "SA",
+ &neig,
+ &abstol,
+ resid,
+ &ncv,
+ v,
+ &n,
+ iparam,
+ ipntr,
+ workd,
+ workl,
+ &lworkl,
+ &info);
# endif
sfree(v);
{
#if GMX_DOUBLE
F77_FUNC(dsaupd, DSAUPD)
- (&ido, "I", &n, "SA", &neig, &abstol, resid, &ncv, v, &n, iparam, ipntr, workd, iwork,
- workl, &lworkl, &info);
+ (&ido, "I", &n, "SA", &neig, &abstol, resid, &ncv, v, &n, iparam, ipntr, workd, iwork, workl, &lworkl, &info);
#else
F77_FUNC(ssaupd, SSAUPD)
- (&ido, "I", &n, "SA", &neig, &abstol, resid, &ncv, v, &n, iparam, ipntr, workd, iwork,
- workl, &lworkl, &info);
+ (&ido, "I", &n, "SA", &neig, &abstol, resid, &ncv, v, &n, iparam, ipntr, workd, iwork, workl, &lworkl, &info);
#endif
if (ido == -1 || ido == 1)
{
gmx_fatal(FARGS,
"Maximum number of iterations (%d) reached in Arnoldi\n"
"diagonalization, but only %d of %d eigenvectors converged.\n",
- maxiter, iparam[4], neig);
+ maxiter,
+ iparam[4],
+ neig);
}
else if (info != 0)
{
#if GMX_DOUBLE
F77_FUNC(dseupd, DSEUPD)
- (&dovec, "A", select, eigenvalues, eigenvectors, &n, nullptr, "I", &n, "SA", &neig, &abstol,
- resid, &ncv, v, &n, iparam, ipntr, workd, workl, &lworkl, &info);
+ (&dovec,
+ "A",
+ select,
+ eigenvalues,
+ eigenvectors,
+ &n,
+ nullptr,
+ "I",
+ &n,
+ "SA",
+ &neig,
+ &abstol,
+ resid,
+ &ncv,
+ v,
+ &n,
+ iparam,
+ ipntr,
+ workd,
+ workl,
+ &lworkl,
+ &info);
#else
F77_FUNC(sseupd, SSEUPD)
- (&dovec, "A", select, eigenvalues, eigenvectors, &n, nullptr, "I", &n, "SA", &neig, &abstol,
- resid, &ncv, v, &n, iparam, ipntr, workd, workl, &lworkl, &info);
+ (&dovec,
+ "A",
+ select,
+ eigenvalues,
+ eigenvectors,
+ &n,
+ nullptr,
+ "I",
+ &n,
+ "SA",
+ &neig,
+ &abstol,
+ resid,
+ &ncv,
+ v,
+ &n,
+ iparam,
+ ipntr,
+ workd,
+ workl,
+ &lworkl,
+ &info);
#endif
sfree(v);
if (h__[*kev + 1 + h_dim1] > 0.)
{
F77_FUNC(dgemv, DGEMV)
- ("N", n, &kplusp, &c_b5, &v[v_offset], ldv, &q[(*kev + 1) * q_dim1 + 1], &c__1, &c_b4,
- &workd[*n + 1], &c__1);
+ ("N", n, &kplusp, &c_b5, &v[v_offset], ldv, &q[(*kev + 1) * q_dim1 + 1], &c__1, &c_b4, &workd[*n + 1], &c__1);
}
i__1 = *kev;
{
i__2 = kplusp - i__ + 1;
F77_FUNC(dgemv, DGEMV)
- ("N", n, &i__2, &c_b5, &v[v_offset], ldv, &q[(*kev - i__ + 1) * q_dim1 + 1], &c__1, &c_b4,
- &workd[1], &c__1);
+ ("N", n, &i__2, &c_b5, &v[v_offset], ldv, &q[(*kev - i__ + 1) * q_dim1 + 1], &c__1, &c_b4, &workd[1], &c__1);
F77_FUNC(dcopy, DCOPY)(n, &workd[1], &c__1, &v[(kplusp - i__ + 1) * v_dim1 + 1], &c__1);
}
L30:
F77_FUNC(dgetv0, DGETV0)
- (ido, bmat, &iwork[11], &c__0, n, &iwork[12], &v[v_offset], ldv, &resid[1], rnorm, &ipntr[1],
- &workd[1], &iwork[21], &iwork[7]);
+ (ido,
+ bmat,
+ &iwork[11],
+ &c__0,
+ n,
+ &iwork[12],
+ &v[v_offset],
+ ldv,
+ &resid[1],
+ rnorm,
+ &ipntr[1],
+ &workd[1],
+ &iwork[21],
+ &iwork[7]);
if (*ido != 99)
{
goto L9000;
if (*mode != 2)
{
F77_FUNC(dgemv, DGEMV)
- ("T", n, &iwork[12], &c_b18, &v[v_offset], ldv, &workd[iwork[8]], &c__1, &c_b42,
- &workd[iwork[9]], &c__1);
+ ("T", n, &iwork[12], &c_b18, &v[v_offset], ldv, &workd[iwork[8]], &c__1, &c_b42, &workd[iwork[9]], &c__1);
}
else
{
F77_FUNC(dgemv, DGEMV)
- ("T", n, &iwork[12], &c_b18, &v[v_offset], ldv, &workd[iwork[10]], &c__1, &c_b42,
- &workd[iwork[9]], &c__1);
+ ("T", n, &iwork[12], &c_b18, &v[v_offset], ldv, &workd[iwork[10]], &c__1, &c_b42, &workd[iwork[9]], &c__1);
}
F77_FUNC(dgemv, DGEMV)
L80:
F77_FUNC(dgemv, DGEMV)
- ("T", n, &iwork[12], &c_b18, &v[v_offset], ldv, &workd[iwork[8]], &c__1, &c_b42,
- &workd[iwork[9]], &c__1);
+ ("T", n, &iwork[12], &c_b18, &v[v_offset], ldv, &workd[iwork[8]], &c__1, &c_b42, &workd[iwork[9]], &c__1);
F77_FUNC(dgemv, DGEMV)
("N", n, &iwork[12], &c_b50, &v[v_offset], ldv, &workd[iwork[9]], &c__1, &c_b18, &resid[1], &c__1);
if (iwork[2] == 1)
{
F77_FUNC(dgetv0, DGETV0)
- (ido, bmat, &c__1, &iwork[3], n, &c__1, &v[v_offset], ldv, &resid[1], &workd[*n * 3 + 1],
- &ipntr[1], &workd[1], &iwork[41], info);
+ (ido,
+ bmat,
+ &c__1,
+ &iwork[3],
+ n,
+ &c__1,
+ &v[v_offset],
+ ldv,
+ &resid[1],
+ &workd[*n * 3 + 1],
+ &ipntr[1],
+ &workd[1],
+ &iwork[41],
+ info);
if (*ido != 99)
{
}
F77_FUNC(dsaitr, DSAITR)
- (ido, bmat, n, &c__0, &iwork[9], mode, &resid[1], &workd[*n * 3 + 1], &v[v_offset], ldv,
- &h__[h_offset], ldh, &ipntr[1], &workd[1], &iwork[21], info);
+ (ido,
+ bmat,
+ n,
+ &c__0,
+ &iwork[9],
+ mode,
+ &resid[1],
+ &workd[*n * 3 + 1],
+ &v[v_offset],
+ ldv,
+ &h__[h_offset],
+ ldh,
+ &ipntr[1],
+ &workd[1],
+ &iwork[21],
+ info);
if (*ido != 99)
{
iwork[4] = 1;
F77_FUNC(dsaitr, DSAITR)
- (ido, bmat, n, nev, np, mode, &resid[1], &workd[*n * 3 + 1], &v[v_offset], ldv, &h__[h_offset],
- ldh, &ipntr[1], &workd[1], &iwork[21], info);
+ (ido,
+ bmat,
+ n,
+ nev,
+ np,
+ mode,
+ &resid[1],
+ &workd[*n * 3 + 1],
+ &v[v_offset],
+ ldv,
+ &h__[h_offset],
+ ldh,
+ &ipntr[1],
+ &workd[1],
+ &iwork[21],
+ info);
if (*ido != 99)
{
}
F77_FUNC(dsapps, DSAPPS)
- (n, nev, np, &ritz[1], &v[v_offset], ldv, &h__[h_offset], ldh, &resid[1], &q[q_offset], ldq,
- &workd[1]);
+ (n, nev, np, &ritz[1], &v[v_offset], ldv, &h__[h_offset], ldh, &resid[1], &q[q_offset], ldq, &workd[1]);
iwork[1] = 1;
if (*bmat == 'G')
}
F77_FUNC(dsaup2, DSAUP2)
- (ido, bmat, n, which, &iwork[13], &iwork[15], tol, &resid[1], &iwork[11], &iwork[6], &iwork[5],
- &iwork[10], &v[v_offset], ldv, &workl[iwork[3]], &iwork[8], &workl[iwork[16]], &workl[iwork[1]],
- &workl[iwork[4]], &iwork[9], &workl[iwork[7]], &ipntr[1], &workd[1], &iwork[21], info);
+ (ido,
+ bmat,
+ n,
+ which,
+ &iwork[13],
+ &iwork[15],
+ tol,
+ &resid[1],
+ &iwork[11],
+ &iwork[6],
+ &iwork[5],
+ &iwork[10],
+ &v[v_offset],
+ ldv,
+ &workl[iwork[3]],
+ &iwork[8],
+ &workl[iwork[16]],
+ &workl[iwork[1]],
+ &workl[iwork[4]],
+ &iwork[9],
+ &workl[iwork[7]],
+ &ipntr[1],
+ &workd[1],
+ &iwork[21],
+ info);
if (*ido == 3)
{
(ncv, &nconv, &workl[iq], &ldq, &workl[iw + *ncv], &workl[ihb], &ierr);
F77_FUNC(dorm2r, DORM2R)
- ("Right", "Notranspose", n, ncv, &nconv, &workl[iq], &ldq, &workl[iw + *ncv], &v[v_offset],
- ldv, &workd[*n + 1], &ierr);
+ ("Right",
+ "Notranspose",
+ n,
+ ncv,
+ &nconv,
+ &workl[iq],
+ &ldq,
+ &workl[iw + *ncv],
+ &v[v_offset],
+ ldv,
+ &workd[*n + 1],
+ &ierr);
F77_FUNC(dlacpy, DLACPY)("All", n, &nconv, &v[v_offset], ldv, &z__[z_offset], ldz);
i__1 = *ncv - 1;
}
workl[ihb + *ncv - 1] = 1.;
F77_FUNC(dorm2r, DORM2R)
- ("Left", "Transpose", ncv, &c__1, &nconv, &workl[iq], &ldq, &workl[iw + *ncv], &workl[ihb],
- ncv, &temp, &ierr);
+ ("Left", "Transpose", ncv, &c__1, &nconv, &workl[iq], &ldq, &workl[iw + *ncv], &workl[ihb], ncv, &temp, &ierr);
}
else if (*rvec && *howmny == 'S')
{
if (h__[*kev + 1 + h_dim1] > 0.)
{
F77_FUNC(sgemv, SGEMV)
- ("N", n, &kplusp, &c_b5, &v[v_offset], ldv, &q[(*kev + 1) * q_dim1 + 1], &c__1, &c_b4,
- &workd[*n + 1], &c__1);
+ ("N", n, &kplusp, &c_b5, &v[v_offset], ldv, &q[(*kev + 1) * q_dim1 + 1], &c__1, &c_b4, &workd[*n + 1], &c__1);
}
i__1 = *kev;
{
i__2 = kplusp - i__ + 1;
F77_FUNC(sgemv, SGEMV)
- ("N", n, &i__2, &c_b5, &v[v_offset], ldv, &q[(*kev - i__ + 1) * q_dim1 + 1], &c__1, &c_b4,
- &workd[1], &c__1);
+ ("N", n, &i__2, &c_b5, &v[v_offset], ldv, &q[(*kev - i__ + 1) * q_dim1 + 1], &c__1, &c_b4, &workd[1], &c__1);
F77_FUNC(scopy, SCOPY)(n, &workd[1], &c__1, &v[(kplusp - i__ + 1) * v_dim1 + 1], &c__1);
}
L30:
F77_FUNC(sgetv0, sgetv0)
- (ido, bmat, &iwork[11], &c__0, n, &iwork[12], &v[v_offset], ldv, &resid[1], rnorm, &ipntr[1],
- &workd[1], &iwork[21], &iwork[7]);
+ (ido,
+ bmat,
+ &iwork[11],
+ &c__0,
+ n,
+ &iwork[12],
+ &v[v_offset],
+ ldv,
+ &resid[1],
+ rnorm,
+ &ipntr[1],
+ &workd[1],
+ &iwork[21],
+ &iwork[7]);
if (*ido != 99)
{
goto L9000;
if (*mode != 2)
{
F77_FUNC(sgemv, SGEMV)
- ("T", n, &iwork[12], &c_b18, &v[v_offset], ldv, &workd[iwork[8]], &c__1, &c_b42,
- &workd[iwork[9]], &c__1);
+ ("T", n, &iwork[12], &c_b18, &v[v_offset], ldv, &workd[iwork[8]], &c__1, &c_b42, &workd[iwork[9]], &c__1);
}
else
{
F77_FUNC(sgemv, SGEMV)
- ("T", n, &iwork[12], &c_b18, &v[v_offset], ldv, &workd[iwork[10]], &c__1, &c_b42,
- &workd[iwork[9]], &c__1);
+ ("T", n, &iwork[12], &c_b18, &v[v_offset], ldv, &workd[iwork[10]], &c__1, &c_b42, &workd[iwork[9]], &c__1);
}
F77_FUNC(sgemv, SGEMV)
L80:
F77_FUNC(sgemv, SGEMV)
- ("T", n, &iwork[12], &c_b18, &v[v_offset], ldv, &workd[iwork[8]], &c__1, &c_b42,
- &workd[iwork[9]], &c__1);
+ ("T", n, &iwork[12], &c_b18, &v[v_offset], ldv, &workd[iwork[8]], &c__1, &c_b42, &workd[iwork[9]], &c__1);
F77_FUNC(sgemv, SGEMV)
("N", n, &iwork[12], &c_b50, &v[v_offset], ldv, &workd[iwork[9]], &c__1, &c_b18, &resid[1], &c__1);
if (iwork[2] == 1)
{
F77_FUNC(sgetv0, SGETV0)
- (ido, bmat, &c__1, &iwork[3], n, &c__1, &v[v_offset], ldv, &resid[1], &workd[*n * 3 + 1],
- &ipntr[1], &workd[1], &iwork[41], info);
+ (ido,
+ bmat,
+ &c__1,
+ &iwork[3],
+ n,
+ &c__1,
+ &v[v_offset],
+ ldv,
+ &resid[1],
+ &workd[*n * 3 + 1],
+ &ipntr[1],
+ &workd[1],
+ &iwork[41],
+ info);
if (*ido != 99)
{
}
F77_FUNC(ssaitr, SSAITR)
- (ido, bmat, n, &c__0, &iwork[9], mode, &resid[1], &workd[*n * 3 + 1], &v[v_offset], ldv,
- &h__[h_offset], ldh, &ipntr[1], &workd[1], &iwork[21], info);
+ (ido,
+ bmat,
+ n,
+ &c__0,
+ &iwork[9],
+ mode,
+ &resid[1],
+ &workd[*n * 3 + 1],
+ &v[v_offset],
+ ldv,
+ &h__[h_offset],
+ ldh,
+ &ipntr[1],
+ &workd[1],
+ &iwork[21],
+ info);
if (*ido != 99)
{
iwork[4] = 1;
F77_FUNC(ssaitr, SSAITR)
- (ido, bmat, n, nev, np, mode, &resid[1], &workd[*n * 3 + 1], &v[v_offset], ldv, &h__[h_offset],
- ldh, &ipntr[1], &workd[1], &iwork[21], info);
+ (ido,
+ bmat,
+ n,
+ nev,
+ np,
+ mode,
+ &resid[1],
+ &workd[*n * 3 + 1],
+ &v[v_offset],
+ ldv,
+ &h__[h_offset],
+ ldh,
+ &ipntr[1],
+ &workd[1],
+ &iwork[21],
+ info);
if (*ido != 99)
{
}
F77_FUNC(ssapps, SSAPPS)
- (n, nev, np, &ritz[1], &v[v_offset], ldv, &h__[h_offset], ldh, &resid[1], &q[q_offset], ldq,
- &workd[1]);
+ (n, nev, np, &ritz[1], &v[v_offset], ldv, &h__[h_offset], ldh, &resid[1], &q[q_offset], ldq, &workd[1]);
iwork[1] = 1;
if (*bmat == 'G')
}
F77_FUNC(ssaup2, SSAUP2)
- (ido, bmat, n, which, &iwork[13], &iwork[15], tol, &resid[1], &iwork[11], &iwork[6], &iwork[5],
- &iwork[10], &v[v_offset], ldv, &workl[iwork[3]], &iwork[8], &workl[iwork[16]], &workl[iwork[1]],
- &workl[iwork[4]], &iwork[9], &workl[iwork[7]], &ipntr[1], &workd[1], &iwork[21], info);
+ (ido,
+ bmat,
+ n,
+ which,
+ &iwork[13],
+ &iwork[15],
+ tol,
+ &resid[1],
+ &iwork[11],
+ &iwork[6],
+ &iwork[5],
+ &iwork[10],
+ &v[v_offset],
+ ldv,
+ &workl[iwork[3]],
+ &iwork[8],
+ &workl[iwork[16]],
+ &workl[iwork[1]],
+ &workl[iwork[4]],
+ &iwork[9],
+ &workl[iwork[7]],
+ &ipntr[1],
+ &workd[1],
+ &iwork[21],
+ info);
if (*ido == 3)
{
(ncv, &nconv, &workl[iq], &ldq, &workl[iw + *ncv], &workl[ihb], &ierr);
F77_FUNC(sorm2r, SORM2R)
- ("Right", "Notranspose", n, ncv, &nconv, &workl[iq], &ldq, &workl[iw + *ncv], &v[v_offset],
- ldv, &workd[*n + 1], &ierr);
+ ("Right",
+ "Notranspose",
+ n,
+ ncv,
+ &nconv,
+ &workl[iq],
+ &ldq,
+ &workl[iw + *ncv],
+ &v[v_offset],
+ ldv,
+ &workd[*n + 1],
+ &ierr);
F77_FUNC(slacpy, SLACPY)("All", n, &nconv, &v[v_offset], ldv, &z__[z_offset], ldz);
i__1 = *ncv - 1;
}
workl[ihb + *ncv - 1] = 1.;
F77_FUNC(sorm2r, SORM2R)
- ("Left", "Transpose", ncv, &c__1, &nconv, &workl[iq], &ldq, &workl[iw + *ncv], &workl[ihb],
- ncv, &temp, &ierr);
+ ("Left", "Transpose", ncv, &c__1, &nconv, &workl[iq], &ldq, &workl[iw + *ncv], &workl[ihb], ncv, &temp, &ierr);
}
else if (*rvec && *howmny == 'S')
{
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+add_library(listed_forces INTERFACE)
gmx_add_libgromacs_sources(
bonded.cpp
disre.cpp
)
endif()
+# Source files have the following private module dependencies.
+target_link_libraries(listed_forces PRIVATE
+# gmxlib
+# math
+# mdtypes
+ )
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(listed_forces PUBLIC
+target_include_directories(listed_forces INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(listed_forces PUBLIC
+target_link_libraries(listed_forces INTERFACE
+ legacy_api
+ )
+
+# TODO: when listed_forces is an OBJECT target
+#target_link_libraries(listed_forces PUBLIC legacy_api)
+#target_link_libraries(listed_forces PRIVATE common)
+
+# Module dependencies
+# listed_forces interfaces convey transitive dependence on these modules.
+#target_link_libraries(listed_forces PUBLIC
+target_link_libraries(listed_forces INTERFACE
+ utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(listed_forces PRIVATE tng_io)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(listed_forces PRIVATE legacy_modules)
+
if (BUILD_TESTING)
add_subdirectory(tests)
endif()
using namespace gmx; // TODO: Remove when this file is moved into gmx namespace
const EnumerationArray<BondedKernelFlavor, std::string> c_bondedKernelFlavorStrings = {
- "forces, using SIMD when available", "forces, not using SIMD",
- "forces, virial, and energy (ie. not using SIMD)", "forces and energy (ie. not using SIMD)"
+ "forces, using SIMD when available",
+ "forces, not using SIMD",
+ "forces, virial, and energy (ie. not using SIMD)",
+ "forces and energy (ie. not using SIMD)"
};
namespace
{
if (dr2 >= bm2)
{
- gmx_fatal(FARGS, "r^2 (%f) >= bm^2 (%f) in FENE bond between atoms %d and %d", dr2, bm2,
- glatnr(global_atom_index, ai), glatnr(global_atom_index, aj));
+ gmx_fatal(FARGS,
+ "r^2 (%f) >= bm^2 (%f) in FENE bond between atoms %d and %d",
+ dr2,
+ bm2,
+ glatnr(global_atom_index, ai),
+ glatnr(global_atom_index, aj));
}
omdr2obm2 = one - dr2 / bm2;
dr2 = iprod(dx, dx); /* 5 */
dr = std::sqrt(dr2); /* 10 */
- *dvdlambda += harmonic(forceparams[type].harmonic.krA, forceparams[type].harmonic.krB,
- forceparams[type].harmonic.rA, forceparams[type].harmonic.rB, dr,
- lambda, &vbond, &fbond); /* 19 */
+ *dvdlambda += harmonic(forceparams[type].harmonic.krA,
+ forceparams[type].harmonic.krB,
+ forceparams[type].harmonic.rA,
+ forceparams[type].harmonic.rB,
+ dr,
+ lambda,
+ &vbond,
+ &fbond); /* 19 */
if (dr2 == 0.0)
{
type = forceatoms[i];
if (type != type0)
{
- gmx_fatal(FARGS, "Sorry, type = %d, type0 = %d, file = %s, line = %d", type, type0,
- __FILE__, __LINE__);
+ gmx_fatal(FARGS, "Sorry, type = %d, type0 = %d, file = %s, line = %d", type, type0, __FILE__, __LINE__);
}
aO = forceatoms[i + 1];
aH1 = forceatoms[i + 2];
theta = bond_angle(x[ai], x[aj], x[ak], pbc, r_ij, r_kj, &cos_theta, &t1, &t2); /* 41 */
- *dvdlambda += harmonic(forceparams[type].harmonic.krA, forceparams[type].harmonic.krB,
+ *dvdlambda += harmonic(forceparams[type].harmonic.krA,
+ forceparams[type].harmonic.krB,
forceparams[type].harmonic.rA * DEG2RAD,
- forceparams[type].harmonic.rB * DEG2RAD, theta, lambda, &va, &dVdt); /* 21 */
+ forceparams[type].harmonic.rB * DEG2RAD,
+ theta,
+ lambda,
+ &va,
+ &dVdt); /* 21 */
vtot += va;
cos_theta2 = gmx::square(cos_theta);
f_kz_S = fnma(cik_S, rijz_S, f_kz_S);
transposeScatterIncrU<4>(reinterpret_cast<real*>(f), ai, f_ix_S, f_iy_S, f_iz_S);
- transposeScatterDecrU<4>(reinterpret_cast<real*>(f), aj, f_ix_S + f_kx_S, f_iy_S + f_ky_S,
- f_iz_S + f_kz_S);
+ transposeScatterDecrU<4>(
+ reinterpret_cast<real*>(f), aj, f_ix_S + f_kx_S, f_iy_S + f_ky_S, f_iz_S + f_kz_S);
transposeScatterIncrU<4>(reinterpret_cast<real*>(f), ak, f_kx_S, f_ky_S, f_kz_S);
}
const SimdReal f_kz_S = fnma(cik_S, rijz_S, ckk_S * rkjz_S) - f_ikz_S;
transposeScatterIncrU<4>(reinterpret_cast<real*>(f), ai, f_ix_S, f_iy_S, f_iz_S);
- transposeScatterDecrU<4>(reinterpret_cast<real*>(f), aj, f_ix_S + f_kx_S, f_iy_S + f_ky_S,
- f_iz_S + f_kz_S);
+ transposeScatterDecrU<4>(
+ reinterpret_cast<real*>(f), aj, f_ix_S + f_kx_S, f_iy_S + f_ky_S, f_iz_S + f_kz_S);
transposeScatterIncrU<4>(reinterpret_cast<real*>(f), ak, f_kx_S, f_ky_S, f_kz_S);
}
const int ak = forceatoms[i + 3];
const int al = forceatoms[i + 4];
- const real phi = dih_angle(x[ai], x[aj], x[ak], x[al], pbc, r_ij, r_kj, r_kl, m, n, &t1,
- &t2, &t3); /* 84 */
+ const real phi =
+ dih_angle(x[ai], x[aj], x[ak], x[al], pbc, r_ij, r_kj, r_kl, m, n, &t1, &t2, &t3); /* 84 */
/* Loop over dihedrals working on the same atoms,
* so we avoid recalculating angles and distributing forces.
do
{
const int type = forceatoms[i];
- ddphi_tot += dopdihs<flavor>(forceparams[type].pdihs.cpA, forceparams[type].pdihs.cpB,
- forceparams[type].pdihs.phiA, forceparams[type].pdihs.phiB,
- forceparams[type].pdihs.mult, phi, lambda, &vtot, dvdlambda);
+ ddphi_tot += dopdihs<flavor>(forceparams[type].pdihs.cpA,
+ forceparams[type].pdihs.cpB,
+ forceparams[type].pdihs.phiA,
+ forceparams[type].pdihs.phiB,
+ forceparams[type].pdihs.mult,
+ phi,
+ lambda,
+ &vtot,
+ dvdlambda);
i += 5;
} while (i < nbonds && forceatoms[i + 1] == ai && forceatoms[i + 2] == aj
&& forceatoms[i + 3] == ak && forceatoms[i + 4] == al);
- do_dih_fup<flavor>(ai, aj, ak, al, ddphi_tot, r_ij, r_kj, r_kl, m, n, f, fshift, pbc, x, t1,
- t2, t3); /* 112 */
- } /* 223 TOTAL */
+ do_dih_fup<flavor>(
+ ai, aj, ak, al, ddphi_tot, r_ij, r_kj, r_kl, m, n, f, fshift, pbc, x, t1, t2, t3); /* 112 */
+ } /* 223 TOTAL */
return vtot;
}
}
/* Calculate GMX_SIMD_REAL_WIDTH dihedral angles at once */
- dih_angle_simd(x, ai, aj, ak, al, pbc_simd, &phi_S, &mx_S, &my_S, &mz_S, &nx_S, &ny_S,
- &nz_S, &nrkj_m2_S, &nrkj_n2_S, &p_S, &q_S);
+ dih_angle_simd(
+ x, ai, aj, ak, al, pbc_simd, &phi_S, &mx_S, &my_S, &mz_S, &nx_S, &ny_S, &nz_S, &nrkj_m2_S, &nrkj_n2_S, &p_S, &q_S);
cp_S = load<SimdReal>(cp);
phi0_S = load<SimdReal>(phi0) * deg2rad_S;
}
/* Calculate GMX_SIMD_REAL_WIDTH dihedral angles at once */
- dih_angle_simd(x, ai, aj, ak, al, pbc_simd, &phi_S, &mx_S, &my_S, &mz_S, &nx_S, &ny_S,
- &nz_S, &nrkj_m2_S, &nrkj_n2_S, &p_S, &q_S);
+ dih_angle_simd(
+ x, ai, aj, ak, al, pbc_simd, &phi_S, &mx_S, &my_S, &mz_S, &nx_S, &ny_S, &nz_S, &nrkj_m2_S, &nrkj_n2_S, &p_S, &q_S);
/* Change to polymer convention */
phi_S = phi_S - pi_S;
dvdl_term += 0.5 * (kB - kA) * dp2 - kk * dphi0 * dp;
- do_dih_fup<flavor>(ai, aj, ak, al, -ddphi, r_ij, r_kj, r_kl, m, n, f, fshift, pbc, x, t1,
- t2, t3); /* 112 */
+ do_dih_fup<flavor>(ai, aj, ak, al, -ddphi, r_ij, r_kj, r_kl, m, n, f, fshift, pbc, x, t1, t2, t3); /* 112 */
/* 218 TOTAL */
}
cos_phi = cos_angle(r_ij, r_kl); /* 25 */
phi = std::acos(cos_phi); /* 10 */
- *dvdlambda += dopdihs_min(forceparams[type].pdihs.cpA, forceparams[type].pdihs.cpB,
- forceparams[type].pdihs.phiA, forceparams[type].pdihs.phiB,
- forceparams[type].pdihs.mult, phi, lambda, &vid, &dVdphi); /* 40 */
+ *dvdlambda += dopdihs_min(forceparams[type].pdihs.cpA,
+ forceparams[type].pdihs.cpB,
+ forceparams[type].pdihs.phiA,
+ forceparams[type].pdihs.phiB,
+ forceparams[type].pdihs.mult,
+ phi,
+ lambda,
+ &vid,
+ &dVdphi); /* 40 */
vtot += vid;
{
*dvdlambda += kfac * ddp * ((dphiB - dphiA) - (phi0B - phi0A));
}
- do_dih_fup<flavor>(ai, aj, ak, al, ddphi, r_ij, r_kj, r_kl, m, n, f, fshift, pbc, x, t1,
- t2, t3); /* 112 */
+ do_dih_fup<flavor>(
+ ai, aj, ak, al, ddphi, r_ij, r_kj, r_kl, m, n, f, fshift, pbc, x, t1, t2, t3); /* 112 */
}
}
return vtot;
* {\sin^2\theta_i}\f] ({eq:ReB} and ref \cite{MonicaGoga2013} from the manual).
* For more explanations see comments file "restcbt.h". */
- compute_factors_restangles(type, forceparams, delta_ante, delta_post, &prefactor,
- &ratio_ante, &ratio_post, &v);
+ compute_factors_restangles(
+ type, forceparams, delta_ante, delta_post, &prefactor, &ratio_ante, &ratio_post, &v);
/* Forces are computed per component */
for (d = 0; d < DIM; d++)
* ({eq:ReB} and ref \cite{MonicaGoga2013} from the manual).
* For more explanations see comments file "restcbt.h" */
- compute_factors_restrdihs(
- type, forceparams, delta_ante, delta_crnt, delta_post, &factor_phi_ai_ante,
- &factor_phi_ai_crnt, &factor_phi_ai_post, &factor_phi_aj_ante, &factor_phi_aj_crnt,
- &factor_phi_aj_post, &factor_phi_ak_ante, &factor_phi_ak_crnt, &factor_phi_ak_post,
- &factor_phi_al_ante, &factor_phi_al_crnt, &factor_phi_al_post, &prefactor_phi, &v);
+ compute_factors_restrdihs(type,
+ forceparams,
+ delta_ante,
+ delta_crnt,
+ delta_post,
+ &factor_phi_ai_ante,
+ &factor_phi_ai_crnt,
+ &factor_phi_ai_post,
+ &factor_phi_aj_ante,
+ &factor_phi_aj_crnt,
+ &factor_phi_aj_post,
+ &factor_phi_ak_ante,
+ &factor_phi_ak_crnt,
+ &factor_phi_ak_post,
+ &factor_phi_al_ante,
+ &factor_phi_al_crnt,
+ &factor_phi_al_post,
+ &prefactor_phi,
+ &v);
/* Computation of forces per component */
* --- the adjacent bending angles.
* For more explanations see comments file "restcbt.h". */
- compute_factors_cbtdihs(type, forceparams, delta_ante, delta_crnt, delta_post, f_phi_ai,
- f_phi_aj, f_phi_ak, f_phi_al, f_theta_ante_ai, f_theta_ante_aj,
- f_theta_ante_ak, f_theta_post_aj, f_theta_post_ak, f_theta_post_al, &v);
+ compute_factors_cbtdihs(type,
+ forceparams,
+ delta_ante,
+ delta_crnt,
+ delta_post,
+ f_phi_ai,
+ f_phi_aj,
+ f_phi_ak,
+ f_phi_al,
+ f_theta_ante_ai,
+ f_theta_ante_aj,
+ f_theta_ante_ak,
+ f_theta_post_aj,
+ f_theta_post_ak,
+ f_theta_post_al,
+ &v);
/* Acumulate the resuts per beads */
ddphi = -ddphi * sin_phi; /* 11 */
- do_dih_fup<flavor>(ai, aj, ak, al, ddphi, r_ij, r_kj, r_kl, m, n, f, fshift, pbc, x, t1, t2,
- t3); /* 112 */
+ do_dih_fup<flavor>(ai, aj, ak, al, ddphi, r_ij, r_kj, r_kl, m, n, f, fshift, pbc, x, t1, t2, t3); /* 112 */
vtot += v;
}
*dvdlambda += dvdl_term;
a1k = ak;
a1l = al;
- phi1 = dih_angle(x[a1i], x[a1j], x[a1k], x[a1l], pbc, r1_ij, r1_kj, r1_kl, m1, n1, &t11,
- &t21, &t31); /* 84 */
+ phi1 = dih_angle(
+ x[a1i], x[a1j], x[a1k], x[a1l], pbc, r1_ij, r1_kj, r1_kl, m1, n1, &t11, &t21, &t31); /* 84 */
cos_phi1 = std::cos(phi1);
a2k = al;
a2l = am;
- phi2 = dih_angle(x[a2i], x[a2j], x[a2k], x[a2l], pbc, r2_ij, r2_kj, r2_kl, m2, n2, &t12,
- &t22, &t32); /* 84 */
+ phi2 = dih_angle(
+ x[a2i], x[a2j], x[a2k], x[a2l], pbc, r2_ij, r2_kj, r2_kl, m2, n2, &t12, &t22, &t32); /* 84 */
cos_phi2 = std::cos(phi2);
ki = pbc_rvec_sub(pbc, x[ai], x[aj], dx); /* 3 */
dr2 = iprod(dx, dx); /* 5 */
- *dvdlambda += g96harmonic(forceparams[type].harmonic.krA, forceparams[type].harmonic.krB,
- forceparams[type].harmonic.rA, forceparams[type].harmonic.rB, dr2,
- lambda, &vbond, &fbond);
+ *dvdlambda += g96harmonic(forceparams[type].harmonic.krA,
+ forceparams[type].harmonic.krB,
+ forceparams[type].harmonic.rA,
+ forceparams[type].harmonic.rB,
+ dr2,
+ lambda,
+ &vbond,
+ &fbond);
vtot += 0.5 * vbond; /* 1*/
cos_theta = g96bond_angle(x[ai], x[aj], x[ak], pbc, r_ij, r_kj, &t1, &t2);
- *dvdlambda += g96harmonic(forceparams[type].harmonic.krA, forceparams[type].harmonic.krB,
- forceparams[type].harmonic.rA, forceparams[type].harmonic.rB,
- cos_theta, lambda, &va, &dVdt);
+ *dvdlambda += g96harmonic(forceparams[type].harmonic.krA,
+ forceparams[type].harmonic.krB,
+ forceparams[type].harmonic.rA,
+ forceparams[type].harmonic.rB,
+ cos_theta,
+ lambda,
+ &va,
+ &dVdt);
vtot += va;
rij_1 = gmx::invsqrt(iprod(r_ij, r_ij));
gmx_fatal(FARGS,
"A tabulated %s interaction table number %d is out of the table range: r %f, "
"between table indices %d and %d, table length %d",
- type, table_nr, r, n0, n0 + 1, table->n);
+ type,
+ table_nr,
+ r,
+ n0,
+ n0 + 1,
+ table->n);
}
eps = rt - n0;
eps2 = eps * eps;
table = forceparams[type].tab.table;
- *dvdlambda += bonded_tab("bond", table, &fcd->bondtab[table], forceparams[type].tab.kA,
- forceparams[type].tab.kB, dr, lambda, &vbond, &fbond); /* 22 */
+ *dvdlambda += bonded_tab("bond",
+ table,
+ &fcd->bondtab[table],
+ forceparams[type].tab.kA,
+ forceparams[type].tab.kB,
+ dr,
+ lambda,
+ &vbond,
+ &fbond); /* 22 */
if (dr2 == 0.0)
{
table = forceparams[type].tab.table;
- *dvdlambda += bonded_tab("angle", table, &fcd->angletab[table], forceparams[type].tab.kA,
- forceparams[type].tab.kB, theta, lambda, &va, &dVdt); /* 22 */
+ *dvdlambda += bonded_tab("angle",
+ table,
+ &fcd->angletab[table],
+ forceparams[type].tab.kA,
+ forceparams[type].tab.kB,
+ theta,
+ lambda,
+ &va,
+ &dVdt); /* 22 */
vtot += va;
cos_theta2 = gmx::square(cos_theta); /* 1 */
table = forceparams[type].tab.table;
/* Hopefully phi+M_PI never results in values < 0 */
- *dvdlambda += bonded_tab("dihedral", table, &fcd->dihtab[table], forceparams[type].tab.kA,
- forceparams[type].tab.kB, phi + M_PI, lambda, &vpd, &ddphi);
+ *dvdlambda += bonded_tab("dihedral",
+ table,
+ &fcd->dihtab[table],
+ forceparams[type].tab.kA,
+ forceparams[type].tab.kB,
+ phi + M_PI,
+ lambda,
+ &vpd,
+ &ddphi);
vtot += vpd;
- do_dih_fup<flavor>(ai, aj, ak, al, -ddphi, r_ij, r_kj, r_kl, m, n, f, fshift, pbc, x, t1,
- t2, t3); /* 112 */
+ do_dih_fup<flavor>(ai, aj, ak, al, -ddphi, r_ij, r_kj, r_kl, m, n, f, fshift, pbc, x, t1, t2, t3); /* 112 */
} /* 227 TOTAL */
{
const BondedInteractions& bonded = c_bondedInteractionFunctionsPerFlavor[bondedKernelFlavor][ftype];
- real v = bonded.function(numForceatoms, forceatoms, forceparams, x, f, fshift, pbc, lambda,
- dvdlambda, md, fcd, global_atom_index);
+ real v = bonded.function(
+ numForceatoms, forceatoms, forceparams, x, f, fshift, pbc, lambda, dvdlambda, md, fcd, global_atom_index);
return v;
}
gmx_fatal(FARGS,
"GMX_DISRE_ENSEMBLE_SIZE (%d) is not equal to 1 or the number of systems "
"(option -multidir) %d",
- dd->nsystems, ms->numSimulations_);
+ dd->nsystems,
+ ms->numSimulations_);
}
if (fplog)
{
{
if (fplog)
{
- fprintf(fplog, "There are %d distance restraints involving %d atom pairs\n", dd->nres,
- dd->npair);
+ fprintf(fplog, "There are %d distance restraints involving %d atom pairs\n", dd->nres, dd->npair);
}
/* Have to avoid g_disre de-referencing cr blindly, mdrun not
* doing consistency checks for ensemble-averaged distance
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2014,2015,2016,2017,2018 by the GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
#ifndef GMX_LISTED_FORCES_GPUBONDED_H
#define GMX_LISTED_FORCES_GPUBONDED_H
+#include <memory>
+
#include "gromacs/gpu_utils/devicebuffer_datatype.h"
#include "gromacs/math/vectypes.h"
#include "gromacs/pbcutil/pbc.h"
#include "gromacs/topology/idef.h"
-#include "gromacs/utility/classhelpers.h"
class DeviceContext;
class DeviceStream;
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
// This could be an async transfer (if the source is pinned), so
// long as it uses the same stream as the kernels and we are happy
// to consume additional pinned pages.
- copyToDeviceBuffer(&d_forceParams_, ffparams.iparams.data(), 0, ffparams.numTypes(),
- deviceStream_, GpuApiCallBehavior::Sync, nullptr);
+ copyToDeviceBuffer(&d_forceParams_,
+ ffparams.iparams.data(),
+ 0,
+ ffparams.numTypes(),
+ deviceStream_,
+ GpuApiCallBehavior::Sync,
+ nullptr);
vTot_.resize(F_NRE);
allocateDeviceBuffer(&d_vTot_, F_NRE, deviceContext_);
clearDeviceBufferAsync(&d_vTot_, 0, F_NRE, deviceStream_);
{
t_ilist& d_iList = d_iLists_[fType];
- reallocateDeviceBuffer(&d_iList.iatoms, iList.size(), &d_iList.nr, &d_iList.nalloc,
- deviceContext_);
+ reallocateDeviceBuffer(
+ &d_iList.iatoms, iList.size(), &d_iList.nr, &d_iList.nalloc, deviceContext_);
- copyToDeviceBuffer(&d_iList.iatoms, iList.iatoms.data(), 0, iList.size(), deviceStream_,
- GpuApiCallBehavior::Async, nullptr);
+ copyToDeviceBuffer(&d_iList.iatoms,
+ iList.iatoms.data(),
+ 0,
+ iList.size(),
+ deviceStream_,
+ GpuApiCallBehavior::Async,
+ nullptr);
}
kernelParams_.fTypesOnGpu[fTypesCounter] = fType;
kernelParams_.numFTypeIAtoms[fTypesCounter] = iList.size();
float cos_theta;
int t1;
int t2;
- float theta = bond_angle_gpu<calcVir>(gm_xq[ai], gm_xq[aj], gm_xq[ak], pbcAiuc, &r_ij,
- &r_kj, &cos_theta, &t1, &t2);
+ float theta = bond_angle_gpu<calcVir>(
+ gm_xq[ai], gm_xq[aj], gm_xq[ak], pbcAiuc, &r_ij, &r_kj, &cos_theta, &t1, &t2);
float va;
float dVdt;
harmonic_gpu(d_forceparams[type].harmonic.krA,
- d_forceparams[type].harmonic.rA * CUDA_DEG2RAD_F, theta, &va, &dVdt);
+ d_forceparams[type].harmonic.rA * CUDA_DEG2RAD_F,
+ theta,
+ &va,
+ &dVdt);
if (calcEner)
{
float cos_theta;
int t1;
int t2;
- float theta = bond_angle_gpu<calcVir>(gm_xq[ai], gm_xq[aj], gm_xq[ak], pbcAiuc, &r_ij,
- &r_kj, &cos_theta, &t1, &t2);
+ float theta = bond_angle_gpu<calcVir>(
+ gm_xq[ai], gm_xq[aj], gm_xq[ak], pbcAiuc, &r_ij, &r_kj, &cos_theta, &t1, &t2);
float va;
float dVdt;
int t1;
int t2;
int t3;
- float phi = dih_angle_gpu<calcVir>(gm_xq[ai], gm_xq[aj], gm_xq[ak], gm_xq[al], pbcAiuc,
- &r_ij, &r_kj, &r_kl, &m, &n, &t1, &t2, &t3);
+ float phi = dih_angle_gpu<calcVir>(
+ gm_xq[ai], gm_xq[aj], gm_xq[ak], gm_xq[al], pbcAiuc, &r_ij, &r_kj, &r_kl, &m, &n, &t1, &t2, &t3);
float vpd;
float ddphi;
- dopdihs_gpu(d_forceparams[type].pdihs.cpA, d_forceparams[type].pdihs.phiA,
- d_forceparams[type].pdihs.mult, phi, &vpd, &ddphi);
+ dopdihs_gpu(d_forceparams[type].pdihs.cpA,
+ d_forceparams[type].pdihs.phiA,
+ d_forceparams[type].pdihs.mult,
+ phi,
+ &vpd,
+ &ddphi);
if (calcEner)
{
*vtot_loc += vpd;
}
- do_dih_fup_gpu<calcVir>(ai, aj, ak, al, ddphi, r_ij, r_kj, r_kl, m, n, gm_f, sm_fShiftLoc,
- pbcAiuc, gm_xq, t1, t2, t3);
+ do_dih_fup_gpu<calcVir>(
+ ai, aj, ak, al, ddphi, r_ij, r_kj, r_kl, m, n, gm_f, sm_fShiftLoc, pbcAiuc, gm_xq, t1, t2, t3);
}
}
int t1;
int t2;
int t3;
- float phi = dih_angle_gpu<calcVir>(gm_xq[ai], gm_xq[aj], gm_xq[ak], gm_xq[al], pbcAiuc,
- &r_ij, &r_kj, &r_kl, &m, &n, &t1, &t2, &t3);
+ float phi = dih_angle_gpu<calcVir>(
+ gm_xq[ai], gm_xq[aj], gm_xq[ak], gm_xq[al], pbcAiuc, &r_ij, &r_kj, &r_kl, &m, &n, &t1, &t2, &t3);
/* Change to polymer convention */
if (phi < c0)
ddphi = -ddphi * sin_phi;
- do_dih_fup_gpu<calcVir>(ai, aj, ak, al, ddphi, r_ij, r_kj, r_kl, m, n, gm_f, sm_fShiftLoc,
- pbcAiuc, gm_xq, t1, t2, t3);
+ do_dih_fup_gpu<calcVir>(
+ ai, aj, ak, al, ddphi, r_ij, r_kj, r_kl, m, n, gm_f, sm_fShiftLoc, pbcAiuc, gm_xq, t1, t2, t3);
if (calcEner)
{
*vtot_loc += v;
int t1;
int t2;
int t3;
- float phi = dih_angle_gpu<calcVir>(gm_xq[ai], gm_xq[aj], gm_xq[ak], gm_xq[al], pbcAiuc,
- &r_ij, &r_kj, &r_kl, &m, &n, &t1, &t2, &t3);
+ float phi = dih_angle_gpu<calcVir>(
+ gm_xq[ai], gm_xq[aj], gm_xq[ak], gm_xq[al], pbcAiuc, &r_ij, &r_kj, &r_kl, &m, &n, &t1, &t2, &t3);
/* phi can jump if phi0 is close to Pi/-Pi, which will cause huge
* force changes if we just apply a normal harmonic.
float ddphi = -kA * dp;
- do_dih_fup_gpu<calcVir>(ai, aj, ak, al, -ddphi, r_ij, r_kj, r_kl, m, n, gm_f, sm_fShiftLoc,
- pbcAiuc, gm_xq, t1, t2, t3);
+ do_dih_fup_gpu<calcVir>(
+ ai, aj, ak, al, -ddphi, r_ij, r_kj, r_kl, m, n, gm_f, sm_fShiftLoc, pbcAiuc, gm_xq, t1, t2, t3);
if (calcEner)
{
switch (fType)
{
case F_BONDS:
- bonds_gpu<calcVir, calcEner>(fTypeTid, &vtot_loc, numBonds, iatoms,
- kernelParams.d_forceParams, kernelParams.d_xq,
- kernelParams.d_f, sm_fShiftLoc, kernelParams.pbcAiuc);
+ bonds_gpu<calcVir, calcEner>(fTypeTid,
+ &vtot_loc,
+ numBonds,
+ iatoms,
+ kernelParams.d_forceParams,
+ kernelParams.d_xq,
+ kernelParams.d_f,
+ sm_fShiftLoc,
+ kernelParams.pbcAiuc);
break;
case F_ANGLES:
- angles_gpu<calcVir, calcEner>(
- fTypeTid, &vtot_loc, numBonds, iatoms, kernelParams.d_forceParams,
- kernelParams.d_xq, kernelParams.d_f, sm_fShiftLoc, kernelParams.pbcAiuc);
+ angles_gpu<calcVir, calcEner>(fTypeTid,
+ &vtot_loc,
+ numBonds,
+ iatoms,
+ kernelParams.d_forceParams,
+ kernelParams.d_xq,
+ kernelParams.d_f,
+ sm_fShiftLoc,
+ kernelParams.pbcAiuc);
break;
case F_UREY_BRADLEY:
- urey_bradley_gpu<calcVir, calcEner>(
- fTypeTid, &vtot_loc, numBonds, iatoms, kernelParams.d_forceParams,
- kernelParams.d_xq, kernelParams.d_f, sm_fShiftLoc, kernelParams.pbcAiuc);
+ urey_bradley_gpu<calcVir, calcEner>(fTypeTid,
+ &vtot_loc,
+ numBonds,
+ iatoms,
+ kernelParams.d_forceParams,
+ kernelParams.d_xq,
+ kernelParams.d_f,
+ sm_fShiftLoc,
+ kernelParams.pbcAiuc);
break;
case F_PDIHS:
case F_PIDIHS:
- pdihs_gpu<calcVir, calcEner>(fTypeTid, &vtot_loc, numBonds, iatoms,
- kernelParams.d_forceParams, kernelParams.d_xq,
- kernelParams.d_f, sm_fShiftLoc, kernelParams.pbcAiuc);
+ pdihs_gpu<calcVir, calcEner>(fTypeTid,
+ &vtot_loc,
+ numBonds,
+ iatoms,
+ kernelParams.d_forceParams,
+ kernelParams.d_xq,
+ kernelParams.d_f,
+ sm_fShiftLoc,
+ kernelParams.pbcAiuc);
break;
case F_RBDIHS:
- rbdihs_gpu<calcVir, calcEner>(
- fTypeTid, &vtot_loc, numBonds, iatoms, kernelParams.d_forceParams,
- kernelParams.d_xq, kernelParams.d_f, sm_fShiftLoc, kernelParams.pbcAiuc);
+ rbdihs_gpu<calcVir, calcEner>(fTypeTid,
+ &vtot_loc,
+ numBonds,
+ iatoms,
+ kernelParams.d_forceParams,
+ kernelParams.d_xq,
+ kernelParams.d_f,
+ sm_fShiftLoc,
+ kernelParams.pbcAiuc);
break;
case F_IDIHS:
- idihs_gpu<calcVir, calcEner>(fTypeTid, &vtot_loc, numBonds, iatoms,
- kernelParams.d_forceParams, kernelParams.d_xq,
- kernelParams.d_f, sm_fShiftLoc, kernelParams.pbcAiuc);
+ idihs_gpu<calcVir, calcEner>(fTypeTid,
+ &vtot_loc,
+ numBonds,
+ iatoms,
+ kernelParams.d_forceParams,
+ kernelParams.d_xq,
+ kernelParams.d_f,
+ sm_fShiftLoc,
+ kernelParams.pbcAiuc);
break;
case F_LJ14:
- pairs_gpu<calcVir, calcEner>(
- fTypeTid, numBonds, iatoms, kernelParams.d_forceParams,
- kernelParams.d_xq, kernelParams.d_f, sm_fShiftLoc, kernelParams.pbcAiuc,
- kernelParams.electrostaticsScaleFactor, &vtotVdw_loc, &vtotElec_loc);
+ pairs_gpu<calcVir, calcEner>(fTypeTid,
+ numBonds,
+ iatoms,
+ kernelParams.d_forceParams,
+ kernelParams.d_xq,
+ kernelParams.d_f,
+ sm_fShiftLoc,
+ kernelParams.pbcAiuc,
+ kernelParams.electrostaticsScaleFactor,
+ &vtotVdw_loc,
+ &vtotElec_loc);
break;
}
break;
const auto kernelArgs = prepareGpuKernelArguments(kernelPtr, kernelLaunchConfig_, &kernelParams_);
- launchGpuKernel(kernelPtr, kernelLaunchConfig_, deviceStream_, nullptr,
- "exec_kernel_gpu<calcVir, calcEner>", kernelArgs);
+ launchGpuKernel(kernelPtr,
+ kernelLaunchConfig_,
+ deviceStream_,
+ nullptr,
+ "exec_kernel_gpu<calcVir, calcEner>",
+ kernelArgs);
wallcycle_sub_stop(wcycle_, ewcsLAUNCH_GPU_BONDED);
wallcycle_stop(wcycle_, ewcLAUNCH_GPU);
nice to account to its own subtimer, but first
wallcycle needs to be extended to support calling from
multiple threads. */
- v = cmap_dihs(nbn, iatoms.data() + nb0, iparams.data(), &idef.cmap_grid, x, f, fshift,
- pbc, lambda[efptFTYPE], &(dvdl[efptFTYPE]), md, fcd, global_atom_index);
+ v = cmap_dihs(nbn,
+ iatoms.data() + nb0,
+ iparams.data(),
+ &idef.cmap_grid,
+ x,
+ f,
+ fshift,
+ pbc,
+ lambda[efptFTYPE],
+ &(dvdl[efptFTYPE]),
+ md,
+ fcd,
+ global_atom_index);
}
else
{
- v = calculateSimpleBond(ftype, nbn, iatoms.data() + nb0, iparams.data(), x, f, fshift,
- pbc, lambda[efptFTYPE], &(dvdl[efptFTYPE]), md, fcd,
- global_atom_index, flavor);
+ v = calculateSimpleBond(ftype,
+ nbn,
+ iatoms.data() + nb0,
+ iparams.data(),
+ x,
+ f,
+ fshift,
+ pbc,
+ lambda[efptFTYPE],
+ &(dvdl[efptFTYPE]),
+ md,
+ fcd,
+ global_atom_index,
+ flavor);
}
}
else
/* TODO The execution time for pairs might be nice to account
to its own subtimer, but first wallcycle needs to be
extended to support calling from multiple threads. */
- do_pairs(ftype, nbn, iatoms.data() + nb0, iparams.data(), x, f, fshift, pbc, lambda, dvdl,
- md, fr, havePerturbedInteractions, stepWork, grpp, global_atom_index);
+ do_pairs(ftype,
+ nbn,
+ iatoms.data() + nb0,
+ iparams.data(),
+ x,
+ f,
+ fshift,
+ pbc,
+ lambda,
+ dvdl,
+ md,
+ fr,
+ havePerturbedInteractions,
+ stepWork,
+ grpp,
+ global_atom_index);
}
if (thread == 0)
if (!ilist.empty() && ftype_is_bonded_potential(ftype))
{
ArrayRef<const int> iatoms = gmx::makeConstArrayRef(ilist.iatoms);
- v = calc_one_bond(thread, ftype, idef, iatoms, idef.numNonperturbedInteractions[ftype],
- bt->workDivision, x, ft, fshift, fr, pbc_null, grpp, nrnb,
- lambda, dvdlt, md, fcd, stepWork, global_atom_index);
+ v = calc_one_bond(thread,
+ ftype,
+ idef,
+ iatoms,
+ idef.numNonperturbedInteractions[ftype],
+ bt->workDivision,
+ x,
+ ft,
+ fshift,
+ fr,
+ pbc_null,
+ grpp,
+ nrnb,
+ lambda,
+ dvdlt,
+ md,
+ fcd,
+ stepWork,
+ global_atom_index);
epot[ftype] += v;
}
}
/* The dummy array is to have a place to store the dhdl at other values
of lambda, which will be thrown away in the end */
real dvdl[efptNR] = { 0 };
- calcBondedForces(idef, bt, x, fr, fr->bMolPBC ? pbc : nullptr,
- as_rvec_array(forceWithShiftForces.shiftForces().data()), enerd, nrnb,
- lambda, dvdl, md, fcd, stepWork, global_atom_index);
+ calcBondedForces(idef,
+ bt,
+ x,
+ fr,
+ fr->bMolPBC ? pbc : nullptr,
+ as_rvec_array(forceWithShiftForces.shiftForces().data()),
+ enerd,
+ nrnb,
+ lambda,
+ dvdl,
+ md,
+ fcd,
+ stepWork,
+ global_atom_index);
wallcycle_sub_stop(wcycle, ewcsLISTED);
wallcycle_sub_start(wcycle, ewcsLISTED_BUF_OPS);
/* We already have the forces, so we use temp buffers here */
std::fill(forceBufferLambda.begin(), forceBufferLambda.end(), 0.0_real);
- std::fill(shiftForceBufferLambda.begin(), shiftForceBufferLambda.end(),
+ std::fill(shiftForceBufferLambda.begin(),
+ shiftForceBufferLambda.end(),
gmx::RVec{ 0.0_real, 0.0_real, 0.0_real });
rvec4* f = reinterpret_cast<rvec4*>(forceBufferLambda.data());
rvec* fshift = as_rvec_array(shiftForceBufferLambda.data());
gmx::StepWorkload tempFlags;
tempFlags.computeEnergy = true;
- real v = calc_one_bond(0, ftype, idef, iatomsPerturbed, iatomsPerturbed.ssize(),
- workDivision, x, f, fshift, fr, pbc_null, grpp, nrnb, lambda,
- dvdl.data(), md, fcd, tempFlags, global_atom_index);
+ real v = calc_one_bond(0,
+ ftype,
+ idef,
+ iatomsPerturbed,
+ iatomsPerturbed.ssize(),
+ workDivision,
+ x,
+ f,
+ fshift,
+ fr,
+ pbc_null,
+ grpp,
+ nrnb,
+ lambda,
+ dvdl.data(),
+ md,
+ fcd,
+ tempFlags,
+ global_atom_index);
epot[ftype] += v;
}
}
if (fcdata->orires->nr > 0)
{
GMX_ASSERT(!xWholeMolecules.empty(), "Need whole molecules for orienation restraints");
- enerd->term[F_ORIRESDEV] = calc_orires_dev(
- ms, idef.il[F_ORIRES].size(), idef.il[F_ORIRES].iatoms.data(), idef.iparams.data(),
- md, xWholeMolecules, x, fr->bMolPBC ? pbc : nullptr, fcdata->orires, hist);
+ enerd->term[F_ORIRESDEV] = calc_orires_dev(ms,
+ idef.il[F_ORIRES].size(),
+ idef.il[F_ORIRES].iatoms.data(),
+ idef.iparams.data(),
+ md,
+ xWholeMolecules,
+ x,
+ fr->bMolPBC ? pbc : nullptr,
+ fcdata->orires,
+ hist);
}
if (fcdata->disres->nres > 0)
{
- calc_disres_R_6(cr, ms, idef.il[F_DISRES].size(), idef.il[F_DISRES].iatoms.data(), x,
- fr->bMolPBC ? pbc : nullptr, fcdata->disres, hist);
+ calc_disres_R_6(cr,
+ ms,
+ idef.il[F_DISRES].size(),
+ idef.il[F_DISRES].iatoms.data(),
+ x,
+ fr->bMolPBC ? pbc : nullptr,
+ fcdata->disres,
+ hist);
}
wallcycle_sub_stop(wcycle, ewcsRESTRAINTS);
}
- calc_listed(wcycle, idef, threading_.get(), x, forceOutputs, fr, pbc, enerd, nrnb, lambda, md,
- fcdata, global_atom_index, stepWork);
+ calc_listed(wcycle, idef, threading_.get(), x, forceOutputs, fr, pbc, enerd, nrnb, lambda, md, fcdata, global_atom_index, stepWork);
/* Check if we have to determine energy differences
* at foreign lambda's.
{
lam_i[j] = (i == 0 ? lambda[j] : fepvals->all_lambda[j][i - 1]);
}
- calc_listed_lambda(idef, threading_.get(), x, fr, pbc, forceBufferLambda_,
- shiftForceBufferLambda_, &(enerd->foreign_grpp), enerd->foreign_term,
- dvdl, nrnb, lam_i, md, fcdata, global_atom_index);
+ calc_listed_lambda(idef,
+ threading_.get(),
+ x,
+ fr,
+ pbc,
+ forceBufferLambda_,
+ shiftForceBufferLambda_,
+ &(enerd->foreign_grpp),
+ enerd->foreign_term,
+ dvdl,
+ nrnb,
+ lam_i,
+ md,
+ fcdata,
+ global_atom_index);
sum_epot(enerd->foreign_grpp, enerd->foreign_term);
const double dvdlSum = std::accumulate(std::begin(dvdl), std::end(dvdl), 0.);
std::fill(std::begin(dvdl), std::end(dvdl), 0.0);
fprintf(debug, "%16s", interaction_function[f].name);
for (t = 0; t < numThreads; t++)
{
- fprintf(debug, " %4d",
+ fprintf(debug,
+ " %4d",
(bt->workDivision.bound(f, t + 1) - bt->workDivision.bound(f, t))
/ (1 + NRAL(f)));
}
"You are using %d OpenMP threads, which is larger than GMX_OPENMP_MAX_THREADS "
"(%d). Decrease the number of OpenMP threads or rebuild GROMACS with a larger "
"value for GMX_OPENMP_MAX_THREADS passed to CMake.",
- bondedThreading.nthreads, GMX_OPENMP_MAX_THREADS);
+ bondedThreading.nthreads,
+ GMX_OPENMP_MAX_THREADS);
}
GMX_ASSERT(bondedThreading.nthreads <= BITMASK_SIZE,
"We need at least nthreads bits in the mask");
if (debug)
{
fprintf(debug, "Number of %d atom blocks to reduce: %d\n", reduction_block_size, bt->nblock_used);
- fprintf(debug, "Reduction density %.2f for touched blocks only %.2f\n",
+ fprintf(debug,
+ "Reduction density %.2f for touched blocks only %.2f\n",
ctot * reduction_block_size / static_cast<double>(numAtomsForce),
ctot / static_cast<double>(bt->nblock_used));
}
sscanf(ptr, "%d", &max_nthread_uniform);
if (fplog != nullptr)
{
- fprintf(fplog, "\nMax threads for uniform bonded distribution set to %d by env.var.\n",
+ fprintf(fplog,
+ "\nMax threads for uniform bonded distribution set to %d by env.var.\n",
max_nthread_uniform);
}
}
gmx_fatal(FARGS,
"The system has %d orientation restraints, but at least %d are required, since "
"there are %d fitting parameters.",
- od->nr, numFitParams + 1, numFitParams);
+ od->nr,
+ numFitParams + 1,
+ numFitParams);
}
if (ir->bPeriodicMols)
if (ms)
{
- fprintf(fplog, " the orientation restraints are ensemble averaged over %d systems\n",
- ms->numSimulations_);
+ fprintf(fplog, " the orientation restraints are ensemble averaged over %d systems\n", ms->numSimulations_);
check_multi_int(fplog, ms, od->nr, "the number of orientation restraints", FALSE);
check_multi_int(fplog, ms, od->nref, "the number of fit atoms for orientation restraining", FALSE);
fprintf(log, " order parameter: %g\n", eig[0]);
for (int i = 0; i < DIM; i++)
{
- fprintf(log, " eig: %6.3f %6.3f %6.3f %6.3f\n", (eig[0] != 0) ? eig[i] / eig[0] : eig[i],
- eig[DIM + i * DIM + XX], eig[DIM + i * DIM + YY], eig[DIM + i * DIM + ZZ]);
+ fprintf(log,
+ " eig: %6.3f %6.3f %6.3f %6.3f\n",
+ (eig[0] != 0) ? eig[i] / eig[0] : eig[i],
+ eig[DIM + i * DIM + XX],
+ eig[DIM + i * DIM + YY],
+ eig[DIM + i * DIM + ZZ]);
}
fprintf(log, "\n");
}
"IMPORTANT: This should not happen in a stable simulation, so there is\n"
"probably something wrong with your system. Only change the table-extension\n"
"distance in the mdp file if you are really sure that is the reason.\n",
- glatnr(global_atom_index, ai), glatnr(global_atom_index, aj), r, rlimit);
+ glatnr(global_atom_index, ai),
+ glatnr(global_atom_index, aj),
+ r,
+ rlimit);
if (debug)
{
fprintf(debug,
"%8f %8f %8f\n%8f %8f %8f\n1-4 (%d,%d) interaction not within cut-off! r=%g. "
"Ignored\n",
- x[ai][XX], x[ai][YY], x[ai][ZZ], x[aj][XX], x[aj][YY], x[aj][ZZ],
- glatnr(global_atom_index, ai), glatnr(global_atom_index, aj), r);
+ x[ai][XX],
+ x[ai][YY],
+ x[ai][ZZ],
+ x[aj][XX],
+ x[aj][YY],
+ x[aj][ZZ],
+ glatnr(global_atom_index, ai),
+ glatnr(global_atom_index, aj),
+ r);
}
}
c6B = iparams[itype].lj14.c6B * 6.0;
c12B = iparams[itype].lj14.c12B * 12.0;
- fscal = free_energy_evaluate_single(
- r2, *fr->ic->softCoreParameters, fr->pairsTable->scale,
- fr->pairsTable->data.data(), fr->pairsTable->stride, qq, c6, c12, qqB, c6B, c12B,
- LFC, LFV, DLF, lfac_coul, lfac_vdw, dlfac_coul, dlfac_vdw, &velec, &vvdw, dvdl);
+ fscal = free_energy_evaluate_single(r2,
+ *fr->ic->softCoreParameters,
+ fr->pairsTable->scale,
+ fr->pairsTable->data.data(),
+ fr->pairsTable->stride,
+ qq,
+ c6,
+ c12,
+ qqB,
+ c6B,
+ c12B,
+ LFC,
+ LFV,
+ DLF,
+ lfac_coul,
+ lfac_vdw,
+ dlfac_coul,
+ dlfac_vdw,
+ &velec,
+ &vvdw,
+ dvdl);
}
else
{
/* Evaluate tabulated interaction without free energy */
- fscal = evaluate_single(r2, fr->pairsTable->scale, fr->pairsTable->data.data(),
- fr->pairsTable->stride, qq, c6, c12, &velec, &vvdw);
+ fscal = evaluate_single(r2,
+ fr->pairsTable->scale,
+ fr->pairsTable->data.data(),
+ fr->pairsTable->stride,
+ qq,
+ c6,
+ c12,
+ &velec,
+ &vvdw);
}
energygrp_elec[gid] += velec;
pbc_nonnull = &pbc_no;
}
- do_pairs_simple<real, 1, const t_pbc*>(nbonds, iatoms, iparams, x, f, pbc_nonnull, md,
- fr->ic->epsfac * fr->fudgeQQ);
+ do_pairs_simple<real, 1, const t_pbc*>(
+ nbonds, iatoms, iparams, x, f, pbc_nonnull, md, fr->ic->epsfac * fr->fudgeQQ);
}
}
else if (stepWork.computeVirial)
{
do_pairs_general<BondedKernelFlavor::ForcesAndVirialAndEnergy>(
- ftype, nbonds, iatoms, iparams, x, f, fshift, pbc, lambda, dvdl, md, fr, grppener,
- global_atom_index);
+ ftype, nbonds, iatoms, iparams, x, f, fshift, pbc, lambda, dvdl, md, fr, grppener, global_atom_index);
}
else
{
- do_pairs_general<BondedKernelFlavor::ForcesAndEnergy>(ftype, nbonds, iatoms, iparams, x, f,
- fshift, pbc, lambda, dvdl, md, fr,
- grppener, global_atom_index);
+ do_pairs_general<BondedKernelFlavor::ForcesAndEnergy>(
+ ftype, nbonds, iatoms, iparams, x, f, fshift, pbc, lambda, dvdl, md, fr, grppener, global_atom_index);
}
}
pr = &forceparams[type];
/* same calculation as for normal posres, but with identical A and B states, and lambda==0 */
- posres_dx(x[ai], forceparams[type].fbposres.pos0, forceparams[type].fbposres.pos0, com_sc,
- com_sc, 0.0, pbc, refcoord_scaling, npbcdim, dx, rdist, dpdl);
+ posres_dx(x[ai],
+ forceparams[type].fbposres.pos0,
+ forceparams[type].fbposres.pos0,
+ com_sc,
+ com_sc,
+ 0.0,
+ pbc,
+ refcoord_scaling,
+ npbcdim,
+ dx,
+ rdist,
+ dpdl);
clear_rvec(fm);
v = 0.0;
pr = &forceparams[type];
/* return dx, rdist, and dpdl */
- posres_dx(x[ai], forceparams[type].posres.pos0A, forceparams[type].posres.pos0B, comA_sc,
- comB_sc, lambda, pbc, refcoord_scaling, npbcdim, dx, rdist, dpdl);
+ posres_dx(x[ai],
+ forceparams[type].posres.pos0A,
+ forceparams[type].posres.pos0B,
+ comA_sc,
+ comB_sc,
+ lambda,
+ pbc,
+ refcoord_scaling,
+ npbcdim,
+ dx,
+ rdist,
+ dpdl);
for (m = 0; (m < DIM); m++)
{
real v, dvdl;
dvdl = 0;
- v = posres<true>(idef.il[F_POSRES].size(), idef.il[F_POSRES].iatoms.data(),
- idef.iparams_posres.data(), x, forceWithVirial,
- fr->pbcType == PbcType::No ? nullptr : pbc, lambda[efptRESTRAINT], &dvdl,
- fr->rc_scaling, fr->pbcType, fr->posres_com, fr->posres_comB);
+ v = posres<true>(idef.il[F_POSRES].size(),
+ idef.il[F_POSRES].iatoms.data(),
+ idef.iparams_posres.data(),
+ x,
+ forceWithVirial,
+ fr->pbcType == PbcType::No ? nullptr : pbc,
+ lambda[efptRESTRAINT],
+ &dvdl,
+ fr->rc_scaling,
+ fr->pbcType,
+ fr->posres_com,
+ fr->posres_comB);
enerd->term[F_POSRES] += v;
/* If just the force constant changes, the FEP term is linear,
* but if k changes, it is not.
const real lambda_dum =
(i == 0 ? lambda[efptRESTRAINT] : fepvals->all_lambda[efptRESTRAINT][i - 1]);
- const real v = posres<false>(idef.il[F_POSRES].size(), idef.il[F_POSRES].iatoms.data(),
- idef.iparams_posres.data(), x, nullptr,
- fr->pbcType == PbcType::No ? nullptr : pbc, lambda_dum, &dvdl,
- fr->rc_scaling, fr->pbcType, fr->posres_com, fr->posres_comB);
+ const real v = posres<false>(idef.il[F_POSRES].size(),
+ idef.il[F_POSRES].iatoms.data(),
+ idef.iparams_posres.data(),
+ x,
+ nullptr,
+ fr->pbcType == PbcType::No ? nullptr : pbc,
+ lambda_dum,
+ &dvdl,
+ fr->rc_scaling,
+ fr->pbcType,
+ fr->posres_com,
+ fr->posres_comB);
foreignTerms.accumulate(i, v, dvdl);
}
wallcycle_sub_stop(wcycle, ewcsRESTRAINTS);
{
real v;
- v = fbposres(idef.il[F_FBPOSRES].size(), idef.il[F_FBPOSRES].iatoms.data(),
- idef.iparams_fbposres.data(), x, forceWithVirial,
- fr->pbcType == PbcType::No ? nullptr : pbc, fr->rc_scaling, fr->pbcType, fr->posres_com);
+ v = fbposres(idef.il[F_FBPOSRES].size(),
+ idef.il[F_FBPOSRES].iatoms.data(),
+ idef.iparams_fbposres.data(),
+ x,
+ forceWithVirial,
+ fr->pbcType == PbcType::No ? nullptr : pbc,
+ fr->rc_scaling,
+ fr->pbcType,
+ fr->posres_com);
enerd->term[F_FBPOSRES] += v;
inc_nrnb(nrnb, eNR_FBPOSRES, gmx::exactDiv(idef.il[F_FBPOSRES].size(), 2));
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
// have an implementation for uint64_t(!) but this is likely to
// work because that type is likely to be a typedef for one of
// the other numerical types that happens to be 64-bits wide.
- shiftForcesTolerance_ = FloatingPointTolerance(singleShiftForcesAbsoluteTolerance, 1e-8, 1e-6,
- 1e-12, std::numeric_limits<uint64_t>::max(),
- std::numeric_limits<uint64_t>::max(), false);
+ shiftForcesTolerance_ = FloatingPointTolerance(singleShiftForcesAbsoluteTolerance,
+ 1e-8,
+ 1e-6,
+ 1e-12,
+ std::numeric_limits<uint64_t>::max(),
+ std::numeric_limits<uint64_t>::max(),
+ false);
}
void testOneIfunc(TestReferenceChecker* checker, const std::vector<t_iatom>& iatoms, const real lambda)
{
{
SCOPED_TRACE("Testing bonded kernel flavor: " + c_bondedKernelFlavorStrings[flavor]);
OutputQuantities output;
- output.energy =
- calculateSimpleBond(input_.ftype, iatoms.size(), iatoms.data(), &input_.iparams,
- as_rvec_array(x_.data()), output.f, output.fshift, &pbc_,
- lambda, &output.dvdlambda, &mdatoms,
- /* struct t_fcdata * */ nullptr, ddgatindex.data(), flavor);
+ output.energy = calculateSimpleBond(input_.ftype,
+ iatoms.size(),
+ iatoms.data(),
+ &input_.iparams,
+ as_rvec_array(x_.data()),
+ output.f,
+ output.fshift,
+ &pbc_,
+ lambda,
+ &output.dvdlambda,
+ &mdatoms,
+ /* struct t_fcdata * */ nullptr,
+ ddgatindex.data(),
+ flavor);
// Internal consistency test of both test input
// and bonded functions.
EXPECT_TRUE((input_.fep || (output.dvdlambda == 0.0))) << "dvdlambda was " << output.dvdlambda;
//! PBC values for testing
std::vector<PbcType> c_pbcForTests = { PbcType::No, PbcType::XY, PbcType::Xyz };
-// Those tests give errors with the intel compiler and nothing else, so we disable them only there.
-#ifndef __INTEL_COMPILER
INSTANTIATE_TEST_CASE_P(Bond,
ListedForcesTest,
::testing::Combine(::testing::ValuesIn(c_InputBonds),
::testing::Combine(::testing::ValuesIn(c_InputAnglesZeroAngle),
::testing::ValuesIn(c_coordinatesForTestsZeroAngle),
::testing::ValuesIn(c_pbcForTests)));
-#endif
} // namespace
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+# Set up the module library
+add_library(math INTERFACE)
+
file(GLOB MATH_SOURCES *.cpp)
set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${MATH_SOURCES} PARENT_SCOPE)
-# TODO: (https://gitlab.com/gromacs/gromacs/-/issues/988) Find a new convention for defining public API.
-install(FILES
- do_fit.h
- functions.h
- units.h
- utilities.h
- vec.h
- vectypes.h
- DESTINATION include/gromacs/math)
-
-if(GMX_INSTALL_LEGACY_API)
- install(FILES
- do_fit.h
- units.h
- utilities.h
- DESTINATION include/gromacs/math)
-endif()
+# Source files have the following private module dependencies.
+target_link_libraries(math PRIVATE
+ # gmxlib
+ # math
+ # mdtypes
+ # tng_io
+ )
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(math PUBLIC
+target_include_directories(math INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(math PUBLIC
+target_link_libraries(math INTERFACE
+ legacy_api
+ )
+
+# TODO: when fileio is an OBJECT target
+#target_link_libraries(math PUBLIC legacy_api)
+#target_link_libraries(math PRIVATE common)
+
+# Module dependencies
+# fileio interfaces convey transitive dependence on these modules.
+#target_link_libraries(math PUBLIC
+target_link_libraries(math INTERFACE
+ utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(math PRIVATE tng_io)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(math PRIVATE legacy_modules)
if (BUILD_TESTING)
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
#ifndef GMX_MATH_COORDINATETRANSFORMATION_H
#define GMX_MATH_COORDINATETRANSFORMATION_H
+#include <memory>
+
#include "gromacs/math/vectypes.h"
-#include "gromacs/utility/classhelpers.h"
#include "matrix.h"
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
/*! \libinternal \brief Transform coordinates in three dimensions by first
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
/*! \libinternal
const auto numVoxels = gradient_.asConstView().mapping().required_span_size();
/* the gradient for the inner product measure of fit is constant and does not
* depend on the compared density, so it is pre-computed here */
- std::transform(begin(referenceDensity_), end(referenceDensity_), begin(gradient_),
- [numVoxels](float x) { return x / numVoxels; });
+ std::transform(begin(referenceDensity_), end(referenceDensity_), begin(gradient_), [numVoxels](float x) {
+ return x / numVoxels;
+ });
}
real DensitySimilarityInnerProduct::similarity(density comparedDensity)
{
GMX_THROW(RangeError("Reference density and compared density need to have same extents."));
}
- return std::inner_product(begin(referenceDensity_), end(referenceDensity_),
- begin(comparedDensity), 0., std::plus<>(), relativeEntropyAtVoxel);
+ return std::inner_product(begin(referenceDensity_),
+ end(referenceDensity_),
+ begin(comparedDensity),
+ 0.,
+ std::plus<>(),
+ relativeEntropyAtVoxel);
}
DensitySimilarityMeasure::density DensitySimilarityRelativeEntropy::gradient(density comparedDensity)
{
GMX_THROW(RangeError("Reference density and compared density need to have same extents."));
}
- std::transform(begin(referenceDensity_), end(referenceDensity_), begin(comparedDensity),
- begin(gradient_), relativeEntropyGradientAtVoxel);
+ std::transform(begin(referenceDensity_),
+ end(referenceDensity_),
+ begin(comparedDensity),
+ begin(gradient_),
+ relativeEntropyGradientAtVoxel);
return gradient_.asConstView();
}
CrossCorrelationEvaluationHelperValues helperValues =
evaluateHelperValues(referenceDensity_, comparedDensity);
- std::transform(begin(referenceDensity_), end(referenceDensity_), begin(comparedDensity),
- begin(gradient_), CrossCorrelationGradientAtVoxel(helperValues));
+ std::transform(begin(referenceDensity_),
+ end(referenceDensity_),
+ begin(comparedDensity),
+ begin(gradient_),
+ CrossCorrelationGradientAtVoxel(helperValues));
return gradient_.asConstView();
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
#ifndef GMX_MATH_DENSITYFIT_H
#define GMX_MATH_DENSITYFIT_H
+#include <memory>
+
#include "gromacs/mdspan/extensions.h"
-#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/real.h"
namespace gmx
{
// multiply with amplitude so that Gauss3D = (amplitude * Gauss_x) * Gauss_y * Gauss_z
const float gauss1DAmplitude = dimension > XX ? 1.0 : localParameters.amplitude_;
- gauss1d_[dimension].spread(gauss1DAmplitude, localParameters.coordinate_[dimension]
- - closestLatticePoint[dimension]);
+ gauss1d_[dimension].spread(
+ gauss1DAmplitude, localParameters.coordinate_[dimension] - closestLatticePoint[dimension]);
}
const auto spreadZY = outerProductZY_(gauss1d_[ZZ].view(), gauss1d_[YY].view());
latticeSpreadRange_[YY] - closestLatticePoint[YY],
latticeSpreadRange_[ZZ] - closestLatticePoint[ZZ]);
- const DVec differenceVectorScale = { 1. / (square(sigma_[XX])), 1. / (square(sigma_[YY])),
+ const DVec differenceVectorScale = { 1. / (square(sigma_[XX])),
+ 1. / (square(sigma_[YY])),
1. / (square(sigma_[ZZ])) };
const DVec differenceVectorOffset = scaleByVector(
spreadRange.begin().toDVec() - localParameters.coordinate_.toDVec(), differenceVectorScale);
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 2019,2021, 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.
* \ingroup module_math
*/
+#include <memory>
+
#include "gromacs/math/gausstransform.h"
#include "gromacs/math/vectypes.h"
#include "gromacs/mdspan/extensions.h"
#include "gromacs/mdspan/mdspan.h"
-#include "gromacs/utility/classhelpers.h"
namespace gmx
{
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
*/
#include "gmxpre.h"
-#include "do_fit.h"
+#include "gromacs/math/do_fit.h"
#include <cmath>
#include <cstdio>
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2016,2019, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016,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.
#include "gmxpre.h"
-#include "functions.h"
+#include "gromacs/math/functions.h"
#include "config.h"
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
std::min(maxEvaluatedSpreadDistance_,
static_cast<int>(std::floor(sigma * sqrt(-2.0 * c_logMinFloat))) - 1);
- std::generate_n(std::back_inserter(e3_), maxEvaluatedSpreadDistance_ + 1,
- [sigma, latticeIndex = 0]() mutable {
- return std::exp(-0.5 * square(latticeIndex++ / sigma));
- });
+ std::generate_n(
+ std::back_inserter(e3_), maxEvaluatedSpreadDistance_ + 1, [sigma, latticeIndex = 0]() mutable {
+ return std::exp(-0.5 * square(latticeIndex++ / sigma));
+ });
std::fill(std::begin(spreadingResult_), std::end(spreadingResult_), 0.);
};
*/
IVec rangeEndWithinLattice(const IVec& index, const dynamicExtents3D& extents, const IVec& range)
{
- IVec extentAsIvec(static_cast<int>(extents.extent(ZZ)), static_cast<int>(extents.extent(YY)),
+ IVec extentAsIvec(static_cast<int>(extents.extent(ZZ)),
+ static_cast<int>(extents.extent(YY)),
static_cast<int>(extents.extent(XX)));
return elementWiseMin(extentAsIvec, index + range);
}
for (gmx::index xIndex = 0; xIndex < ssize(x); ++xIndex)
{
const auto xValue = x[xIndex];
- std::transform(std::begin(y), std::end(y), begin(data_.asView()[xIndex]),
- [xValue](float yValue) { return xValue * yValue; });
+ std::transform(std::begin(y), std::end(y), begin(data_.asView()[xIndex]), [xValue](float yValue) {
+ return xValue * yValue;
+ });
}
return data_.asConstView();
}
{
// multiply with amplitude so that Gauss3D = (amplitude * Gauss_x) * Gauss_y * Gauss_z
const float gauss1DAmplitude = dimension > XX ? 1.0 : localParameters.amplitude_;
- gauss1d_[dimension].spread(gauss1DAmplitude, localParameters.coordinate_[dimension]
- - closestLatticePoint[dimension]);
+ gauss1d_[dimension].spread(
+ gauss1DAmplitude, localParameters.coordinate_[dimension] - closestLatticePoint[dimension]);
}
const auto spreadZY = outerProductZY_(gauss1d_[ZZ].view(), gauss1d_[YY].view());
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
#ifndef GMX_MATH_GAUSSTRANSFORM_H
#define GMX_MATH_GAUSSTRANSFORM_H
+#include <memory>
#include <vector>
#include "gromacs/math/multidimarray.h"
#include "gromacs/math/vectypes.h"
#include "gromacs/mdspan/extensions.h"
#include "gromacs/mdspan/mdspan.h"
-#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/real.h"
namespace gmx
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
/*! \libinternal \brief Parameters for density spreading kernels.
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
/*! \internal \brief A 3-orthotope over integer intervals.
Matrix3x3 transpose(Matrix3x3ConstSpan matrixView)
{
- return Matrix3x3({ matrixView(0, 0), matrixView(1, 0), matrixView(2, 0), matrixView(0, 1),
- matrixView(1, 1), matrixView(2, 1), matrixView(0, 2), matrixView(1, 2),
+ return Matrix3x3({ matrixView(0, 0),
+ matrixView(1, 0),
+ matrixView(2, 0),
+ matrixView(0, 1),
+ matrixView(1, 1),
+ matrixView(2, 1),
+ matrixView(0, 2),
+ matrixView(1, 2),
matrixView(2, 2) });
}
GMX_ASSERT(a.size() == b.size(),
"Input vectors have to have the same size to evaluate their linear combination.");
std::vector<real> result(a.size());
- std::transform(std::begin(a), std::end(a), std::begin(b), std::begin(result),
- [alpha, beta](auto a, auto b) { return alpha * a + beta * b; });
+ std::transform(
+ std::begin(a), std::end(a), std::begin(b), std::begin(result), [alpha, beta](auto a, auto b) {
+ return alpha * a + beta * b;
+ });
return result;
};
NelderMeadSimplex::evaluateExpansionPoint(const std::function<real(ArrayRef<const real>)>& f) const
{
const std::vector<real> expansionPointCoordinate =
- linearCombination(1 - defaultNelderMeadParameters.gamma_, centroidWithoutWorstPoint_,
- defaultNelderMeadParameters.gamma_, reflectionPointCoordinates_);
+ linearCombination(1 - defaultNelderMeadParameters.gamma_,
+ centroidWithoutWorstPoint_,
+ defaultNelderMeadParameters.gamma_,
+ reflectionPointCoordinates_);
return { expansionPointCoordinate, f(expansionPointCoordinate) };
}
RealFunctionvalueAtCoordinate
NelderMeadSimplex::evaluateContractionPoint(const std::function<real(ArrayRef<const real>)>& f) const
{
- std::vector<real> contractionPoint =
- linearCombination(1 - defaultNelderMeadParameters.rho_, centroidWithoutWorstPoint_,
- defaultNelderMeadParameters.rho_, worstVertex().coordinate_);
+ std::vector<real> contractionPoint = linearCombination(1 - defaultNelderMeadParameters.rho_,
+ centroidWithoutWorstPoint_,
+ defaultNelderMeadParameters.rho_,
+ worstVertex().coordinate_);
return { contractionPoint, f(contractionPoint) };
}
// find the point to insert the new vertex, so that the simplex vertices
// keep being sorted according to function value
const auto insertionPoint = std::lower_bound(
- std::begin(simplex_), std::end(simplex_), newVertex.value_,
+ std::begin(simplex_),
+ std::end(simplex_),
+ newVertex.value_,
[](const RealFunctionvalueAtCoordinate& lhs, real value) { return lhs.value_ < value; });
simplex_.insert(insertionPoint, newVertex);
// now that the simplex has changed, it has a new centroid and reflection point
std::vector<real> bestPointCoordinate = simplex_.front().coordinate_;
// skipping over the first simplex vertex, pull points closer to the best
// vertex
- std::transform(std::next(std::begin(simplex_)), std::end(simplex_), std::next(std::begin(simplex_)),
+ std::transform(std::next(std::begin(simplex_)),
+ std::end(simplex_),
+ std::next(std::begin(simplex_)),
[bestPointCoordinate, f](const RealFunctionvalueAtCoordinate& d) -> RealFunctionvalueAtCoordinate {
- const std::vector<real> shrinkPoint = linearCombination(
- defaultNelderMeadParameters.sigma_, d.coordinate_,
- 1 - defaultNelderMeadParameters.sigma_, bestPointCoordinate);
+ const std::vector<real> shrinkPoint =
+ linearCombination(defaultNelderMeadParameters.sigma_,
+ d.coordinate_,
+ 1 - defaultNelderMeadParameters.sigma_,
+ bestPointCoordinate);
return { shrinkPoint, f(shrinkPoint) };
});
{
const std::vector<real> differenceVector =
linearCombination(1, firstSimplexVertexCoordinate, -1, simplexVertex.coordinate_);
- const real thisLength =
- std::accumulate(std::begin(differenceVector), std::end(differenceVector), 0.,
- [](real sum, real value) { return sum + value * value; });
+ const real thisLength = std::accumulate(
+ std::begin(differenceVector), std::end(differenceVector), 0., [](real sum, real value) {
+ return sum + value * value;
+ });
result = std::max(result, thisLength);
}
return sqrt(result);
{
// intialize with first vertex, then add up all other vertex coordinates
// expect last one
- centroidWithoutWorstPoint_ = std::accumulate(
- std::next(std::begin(simplex_)), std::prev(std::end(simplex_)), simplex_.front().coordinate_,
- [](std::vector<real> sum, const RealFunctionvalueAtCoordinate& x) {
- std::transform(std::begin(sum), std::end(sum), std::begin(x.coordinate_),
- std::begin(sum), std::plus<>());
- return sum;
- });
+ centroidWithoutWorstPoint_ =
+ std::accumulate(std::next(std::begin(simplex_)),
+ std::prev(std::end(simplex_)),
+ simplex_.front().coordinate_,
+ [](std::vector<real> sum, const RealFunctionvalueAtCoordinate& x) {
+ std::transform(std::begin(sum),
+ std::end(sum),
+ std::begin(x.coordinate_),
+ std::begin(sum),
+ std::plus<>());
+ return sum;
+ });
// divide the summed up coordinates by N (the simplex has N+1 vertices)
- std::transform(std::begin(centroidWithoutWorstPoint_), std::end(centroidWithoutWorstPoint_),
+ std::transform(std::begin(centroidWithoutWorstPoint_),
+ std::end(centroidWithoutWorstPoint_),
std::begin(centroidWithoutWorstPoint_),
[n = simplex_.size() - 1](const auto& x) { return x / n; });
// now, that we have evaluated the centroid, update the reflection points
- reflectionPointCoordinates_ =
- linearCombination(defaultNelderMeadParameters.alpha_ + 1, centroidWithoutWorstPoint_,
- -1, worstVertex().coordinate_);
+ reflectionPointCoordinates_ = linearCombination(
+ defaultNelderMeadParameters.alpha_ + 1, centroidWithoutWorstPoint_, -1, worstVertex().coordinate_);
}
} // namespace gmx
// the oriented simplex length is smaller or equal a given number.
const real minimumSimplexLength = minimumRelativeSimplexLength * nelderMeadSimplex.orientedLength();
for (int currentStep = 0;
- nelderMeadSimplex.orientedLength() > minimumSimplexLength && currentStep < maxSteps; ++currentStep)
+ nelderMeadSimplex.orientedLength() > minimumSimplexLength && currentStep < maxSteps;
+ ++currentStep)
{
// see if simplex can by improved by reflecing the worst vertex at the centroid
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
TYPED_TEST(ArrayRefWithPaddingTest, ConstructFromPointersWorks)
{
- typename TestFixture::ArrayRefType arrayRef(this->v.data(), this->v.data() + this->v.size(),
- this->v.data() + this->v.paddedSize());
+ typename TestFixture::ArrayRefType arrayRef(
+ this->v.data(), this->v.data() + this->v.size(), this->v.data() + this->v.paddedSize());
this->runTests(arrayRef);
}
RVec vectorTransformed = vector;
affineTransformation(&vectorTransformed);
// need relaxed tolerance here, due to the number of operations involved
- EXPECT_REAL_EQ_TOL((*expected)[XX], vectorTransformed[XX],
+ EXPECT_REAL_EQ_TOL((*expected)[XX],
+ vectorTransformed[XX],
relativeToleranceAsFloatingPoint((*expected)[XX], 1e-5));
- EXPECT_REAL_EQ_TOL((*expected)[YY], vectorTransformed[YY],
+ EXPECT_REAL_EQ_TOL((*expected)[YY],
+ vectorTransformed[YY],
relativeToleranceAsFloatingPoint((*expected)[YY], 1e-5));
- EXPECT_REAL_EQ_TOL((*expected)[ZZ], vectorTransformed[ZZ],
+ EXPECT_REAL_EQ_TOL((*expected)[ZZ],
+ vectorTransformed[ZZ],
relativeToleranceAsFloatingPoint((*expected)[ZZ], 1e-5));
++expected;
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
std::iota(begin(comparedDensity), end(comparedDensity), -18);
std::vector<float> expectedSimilarityGradient;
- std::copy(begin(referenceDensity), end(referenceDensity),
- std::back_inserter(expectedSimilarityGradient));
+ std::copy(begin(referenceDensity), end(referenceDensity), std::back_inserter(expectedSimilarityGradient));
for (auto& x : expectedSimilarityGradient)
{
x /= comparedDensity.asConstView().mapping().required_span_size();
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
TEST_F(StructureSimilarityTest, YieldsCorrectRMSDWithIndex)
{
- EXPECT_REAL_EQ_TOL(sqrt(2.0), rmsdev_ind(index_.size(), index_.data(), m_, x1_, x2_),
- defaultRealTolerance());
+ EXPECT_REAL_EQ_TOL(
+ sqrt(2.0), rmsdev_ind(index_.size(), index_.data(), m_, x1_, x2_), defaultRealTolerance());
}
TEST_F(StructureSimilarityTest, YieldsCorrectRhoWidthIndex)
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
FloatingPointTolerance tolerance(defaultFloatTolerance());
const real amplitude = 1.0;
gauss1d.spread(amplitude, shift);
- std::array<float, 2 * spreadWidth + 1> expected = {
- 0.0047816522419452667236328125, 0.2613909542560577392578125, 0.65811407566070556640625,
- 0.07631497085094451904296875, 0.000407583254855126142501831054688
- };
+ std::array<float, 2 * spreadWidth + 1> expected = { 0.0047816522419452667236328125,
+ 0.2613909542560577392578125,
+ 0.65811407566070556640625,
+ 0.07631497085094451904296875,
+ 0.000407583254855126142501831054688 };
EXPECT_THAT(expected, Pointwise(FloatEq(tolerance), viewOnResult));
}
gauss1d.spread(amplitude, shift);
std::vector<float> sumOfComplementaryGaussians;
// keep a copy of the first Gaussian
- std::copy(std::begin(viewOnResult), std::end(viewOnResult),
- std::back_inserter(sumOfComplementaryGaussians));
+ std::copy(std::begin(viewOnResult), std::end(viewOnResult), std::back_inserter(sumOfComplementaryGaussians));
gauss1d.spread(-amplitude, shift);
// add the two spread Gaussians
- std::transform(std::begin(viewOnResult), std::end(viewOnResult),
- std::begin(sumOfComplementaryGaussians), std::begin(sumOfComplementaryGaussians),
+ std::transform(std::begin(viewOnResult),
+ std::end(viewOnResult),
+ std::begin(sumOfComplementaryGaussians),
+ std::begin(sumOfComplementaryGaussians),
std::plus<>());
// Expect all zeros
std::array<float, 2 * spreadWidth + 1> expected = {};
*/
#include "gmxpre.h"
-#include "units.h"
+#include "gromacs/math/units.h"
#include <cstdio>
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2018 by the GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
*/
#include "gmxpre.h"
-#include "utilities.h"
+#include "gromacs/math/utilities.h"
#include "config.h"
return -1;
#endif
}
+
+bool gmxShouldEnableFPExceptions()
+{
+#if defined(NDEBUG)
+ return false; // Release build
+#elif ((defined __clang__ || (defined(__GNUC__) && __GNUC__ == 7)) && defined __OPTIMIZE__)
+ return false; // Buggy compiler
+#elif GMX_GPU_SYCL
+ return false; // avoid spurious FPE during SYCL JIT
+#else
+ return true;
+#endif
+}
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2016,2019, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016,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.
{
if (index != -1)
{
- fprintf(fp, "%s[%5d] (%12.5e %12.5e %12.5e) - (%12.5e %12.5e %12.5e)\n", s, index,
- i1[XX], i1[YY], i1[ZZ], i2[XX], i2[YY], i2[ZZ]);
+ fprintf(fp,
+ "%s[%5d] (%12.5e %12.5e %12.5e) - (%12.5e %12.5e %12.5e)\n",
+ s,
+ index,
+ i1[XX],
+ i1[YY],
+ i1[ZZ],
+ i2[XX],
+ i2[YY],
+ i2[ZZ]);
}
else
{
- fprintf(fp, "%s (%12.5e %12.5e %12.5e) - (%12.5e %12.5e %12.5e)\n", s, i1[XX], i1[YY],
- i1[ZZ], i2[XX], i2[YY], i2[ZZ]);
+ fprintf(fp,
+ "%s (%12.5e %12.5e %12.5e) - (%12.5e %12.5e %12.5e)\n",
+ s,
+ i1[XX],
+ i1[YY],
+ i1[ZZ],
+ i2[XX],
+ i2[YY],
+ i2[ZZ]);
}
}
}
{
if (index != -1)
{
- fprintf(fp, "%s[%5d] (%8d,%8d,%8d - %8d,%8d,%8d)\n", s, index, i1[XX], i1[YY], i1[ZZ],
- i2[XX], i2[YY], i2[ZZ]);
+ fprintf(fp,
+ "%s[%5d] (%8d,%8d,%8d - %8d,%8d,%8d)\n",
+ s,
+ index,
+ i1[XX],
+ i1[YY],
+ i1[ZZ],
+ i2[XX],
+ i2[YY],
+ i2[ZZ]);
}
else
{
- fprintf(fp, "%s (%8d,%8d,%8d - %8d,%8d,%8d)\n", s, i1[XX], i1[YY], i1[ZZ], i2[XX],
- i2[YY], i2[ZZ]);
+ fprintf(fp, "%s (%8d,%8d,%8d - %8d,%8d,%8d)\n", s, i1[XX], i1[YY], i1[ZZ], i2[XX], i2[YY], i2[ZZ]);
}
}
}
else
{
pr_indent(fp, indent);
- fprintf(fp, "%s[%d,...,%d] = {%d,...,%d}\n", title, bShowNumbers ? i : -1,
- bShowNumbers ? j - 1 : -1, vec[i], vec[j - 1]);
+ fprintf(fp,
+ "%s[%d,...,%d] = {%d,...,%d}\n",
+ title,
+ bShowNumbers ? i : -1,
+ bShowNumbers ? j - 1 : -1,
+ vec[i],
+ vec[j - 1]);
i = j;
}
}
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+add_library(mdlib INTERFACE)
+
file(GLOB MDLIB_SOURCES *.cpp)
# To avoid listing all the necessary files manually, we will remove SYCL-specfific one here:
list(REMOVE_ITEM MDLIB_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/leapfrog_gpu_sycl.cpp)
set(MDLIB_SOURCES ${MDLIB_SOURCES} PARENT_SCOPE)
-if (BUILD_TESTING)
- add_subdirectory(tests)
-endif()
if(GMX_GPU_CUDA)
gmx_add_libgromacs_sources(
leapfrog_gpu.cu
gpuforcereduction_impl.cu
)
endif()
+
if(GMX_GPU_SYCL)
gmx_add_libgromacs_sources(
leapfrog_gpu_sycl.cpp
leapfrog_gpu_sycl.cpp
)
endif()
+
+# Source files have the following private module dependencies.
+target_link_libraries(mdlib PRIVATE
+# gmxlib
+# math
+# mdtypes
+# tng_io
+ )
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(mdlib PUBLIC
+target_include_directories(mdlib INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(mdlib PUBLIC
+target_link_libraries(mdlib INTERFACE
+ legacy_api
+ )
+
+# TODO: when mdlib is an OBJECT target
+#target_link_libraries(mdlib PUBLIC legacy_api)
+#target_link_libraries(mdlib PRIVATE common)
+
+# Module dependencies
+# mdlib interfaces convey transitive dependence on these modules.
+#target_link_libraries(mdlib PUBLIC
+target_link_libraries(mdlib INTERFACE
+ utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(mdlib PRIVATE tng_io)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(mdlib PRIVATE legacy_modules)
+
+if (BUILD_TESTING)
+ add_subdirectory(tests)
+endif()
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012-2018, The GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
}
if (gmx_debug_at)
{
- fprintf(debug, "atom %4d %-20s mass %6.3f\n", a1,
- interaction_function[ilist.functionType].longname, vsite_m[a1]);
+ fprintf(debug,
+ "atom %4d %-20s mass %6.3f\n",
+ a1,
+ interaction_function[ilist.functionType].longname,
+ vsite_m[a1]);
}
}
}
{
for (size_t a = 0; a < att.size(); a++)
{
- fprintf(debug, "type %zu: m %5.2f t %d q %6.3f con %s con_m %5.3f con_l %5.3f n %d\n",
- a, att[a].prop.mass, att[a].prop.type, att[a].prop.q,
- gmx::boolToString(att[a].prop.bConstr), att[a].prop.con_mass,
- att[a].prop.con_len, att[a].n);
+ fprintf(debug,
+ "type %zu: m %5.2f t %d q %6.3f con %s con_m %5.3f con_l %5.3f n %d\n",
+ a,
+ att[a].prop.mass,
+ att[a].prop.type,
+ att[a].prop.q,
+ gmx::boolToString(att[a].prop.bConstr),
+ att[a].prop.con_mass,
+ att[a].prop.con_len,
+ att[a].n);
}
}
lj.d2 = c6 * ljDisp->d2 + c12 * ljRep->d2;
lj.md3 = c6 * ljDisp->md3 + c12 * ljRep->md3;
- real pot_lj = energyDriftAtomPair(prop_i->bConstr, prop_j->bConstr, s2, s2i_2d, s2j_2d,
- rlist - rlj, &lj);
+ real pot_lj = energyDriftAtomPair(
+ prop_i->bConstr, prop_j->bConstr, s2, s2i_2d, s2j_2d, rlist - rlj, &lj);
// Set -V' and V'' at the cut-off for Coulomb
pot_derivatives_t elec_qq;
elec_qq.d2 = elec->d2 * prop_i->q * prop_j->q;
elec_qq.md3 = 0;
- real pot_q = energyDriftAtomPair(prop_i->bConstr, prop_j->bConstr, s2, s2i_2d, s2j_2d,
- rlist - rcoulomb, &elec_qq);
+ real pot_q = energyDriftAtomPair(
+ prop_i->bConstr, prop_j->bConstr, s2, s2i_2d, s2j_2d, rlist - rcoulomb, &elec_qq);
// Note that attractive and repulsive potentials for individual
// pairs can partially cancel.
/* Calculate the average energy drift at the last step
* of the nstlist steps at which the pair-list is used.
*/
- drift = energyDrift(att, &mtop.ffparams, kT_fac, &ljDisp, &ljRep, &elec, ir.rvdw,
- ir.rcoulomb, rl, boxVolume);
+ drift = energyDrift(
+ att, &mtop.ffparams, kT_fac, &ljDisp, &ljRep, &elec, ir.rvdw, ir.rcoulomb, rl, boxVolume);
/* Correct for the fact that we are using a Ni x Nj particle pair list
* and not a 1 x 1 particle pair list. This reduces the drift.
if (debug)
{
- fprintf(debug, "ib %3d %3d %3d rb %.3f %dx%d fac %.3f drift %.1e\n", ib0, ib, ib1, rb,
- listSetup.cluster_size_i, listSetup.cluster_size_j,
- nb_clust_frac_pairs_not_in_list_at_cutoff, drift);
+ fprintf(debug,
+ "ib %3d %3d %3d rb %.3f %dx%d fac %.3f drift %.1e\n",
+ ib0,
+ ib,
+ ib1,
+ rb,
+ listSetup.cluster_size_i,
+ listSetup.cluster_size_j,
+ nb_clust_frac_pairs_not_in_list_at_cutoff,
+ drift);
}
if (std::abs(drift) > ir.verletbuf_tol)
real s2_3d;
get_atom_sigma2(kT_fac, &propAtom, &s2_2d, &s2_3d);
- real chancePerAtom = energyDriftAtomPair(propAtom.bConstr, false, s2_2d + s2_3d, s2_2d, 0,
- cellSize, &boundaryInteraction);
+ real chancePerAtom = energyDriftAtomPair(
+ propAtom.bConstr, false, s2_2d + s2_3d, s2_2d, 0, cellSize, &boundaryInteraction);
if (propAtom.bConstr)
{
}
}
real s2_3d = kT_fac / massSum;
- chance += energyDriftAtomPair(false, false, s2_3d, 0, 0, cellSize - 2 * maxComCogDistance,
- &boundaryInteraction);
+ chance += energyDriftAtomPair(
+ false, false, s2_3d, 0, 0, cellSize - 2 * maxComCogDistance, &boundaryInteraction);
}
return chance;
{
const gmx_moltype_t& moltype = mtop.moltype[molblock.type];
chance += molblock.nmol
- * chanceOfUpdateGroupCrossingCell(moltype, mtop.ffparams,
- updateGrouping[molblock.type], kT_fac, cellSize);
+ * chanceOfUpdateGroupCrossingCell(
+ moltype, mtop.ffparams, updateGrouping[molblock.type], kT_fac, cellSize);
}
return chance;
PartitioningPerMoltype updateGrouping,
real chanceRequested)
{
- if (!EI_DYNAMICS(ir.eI) || (EI_MD(ir.eI) && ir.etc == etcNO))
+ if (!EI_DYNAMICS(ir.eI) || (EI_MD(ir.eI) && ir.etc == TemperatureCoupling::No))
{
return minCellSizeFromPairlistBuffer(ir);
}
int start = (nxf * thread) / nthreads;
int end = std::min(nxf * (thread + 1) / nthreads, nxf);
- calc_x_times_f(end - start, x + start, f + start, bScrewPBC, box,
+ calc_x_times_f(end - start,
+ x + start,
+ f + start,
+ bScrewPBC,
+ box,
thread == 0 ? x_times_f : xf_buf[thread * 3]);
}
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
"If you know what you are doing you can %s"
"set the environment variable GMX_MAXCONSTRWARN to -1,\n"
"but normally it is better to fix the problem",
- (eConstrAlg == econtLINCS) ? "LINCS" : "SETTLE", warncount,
+ (eConstrAlg == econtLINCS) ? "LINCS" : "SETTLE",
+ warncount,
(eConstrAlg == econtLINCS) ? "adjust the lincs warning threshold in your mdp file\nor " : "\n");
}
ii = i;
}
mtopGetAtomAndResidueName(mtop, ii, &molb, &anm, &resnr, &resnm, nullptr);
- gmx_fprintf_pdb_atomline(out, epdbATOM, ii + 1, anm, ' ', resnm, ' ', resnr, ' ',
- 10 * x[i][XX], 10 * x[i][YY], 10 * x[i][ZZ], 1.0, 0.0, "");
+ gmx_fprintf_pdb_atomline(out,
+ epdbATOM,
+ ii + 1,
+ anm,
+ ' ',
+ resnm,
+ ' ',
+ resnr,
+ ' ',
+ 10 * x[i][XX],
+ 10 * x[i][YY],
+ 10 * x[i][ZZ],
+ 1.0,
+ 0.0,
+ "");
}
fprintf(out, "TER\n");
tensor constraintsVirial,
ConstraintVariable econq)
{
- return impl_->apply(bLog, bEner, step, delta_step, step_scaling, std::move(x),
- std::move(xprime), min_proj, box, lambda, dvdlambda, std::move(v),
- computeVirial, constraintsVirial, econq);
+ return impl_->apply(bLog,
+ bEner,
+ step,
+ delta_step,
+ step_scaling,
+ std::move(x),
+ std::move(xprime),
+ min_proj,
+ box,
+ lambda,
+ dvdlambda,
+ std::move(v),
+ computeVirial,
+ constraintsVirial,
+ econq);
}
bool Constraints::Impl::apply(bool bLog,
*/
if (cr->dd)
{
- dd_move_x_constraints(cr->dd, box, x.unpaddedArrayRef(), xprime.unpaddedArrayRef(),
+ dd_move_x_constraints(cr->dd,
+ box,
+ x.unpaddedArrayRef(),
+ xprime.unpaddedArrayRef(),
econq == ConstraintVariable::Positions);
if (!v.empty())
if (lincsd != nullptr)
{
- bOK = constrain_lincs(bLog || bEner, ir, step, lincsd, inverseMasses_, cr, ms, x, xprime,
- min_proj, box, pbc_null, hasMassPerturbedAtoms_, lambda, dvdlambda,
- invdt, v.unpaddedArrayRef(), computeVirial, constraintsVirial, econq,
- nrnb, maxwarn, &warncount_lincs);
+ bOK = constrain_lincs(bLog || bEner,
+ ir,
+ step,
+ lincsd,
+ inverseMasses_,
+ cr,
+ ms,
+ x,
+ xprime,
+ min_proj,
+ box,
+ pbc_null,
+ hasMassPerturbedAtoms_,
+ lambda,
+ dvdlambda,
+ invdt,
+ v.unpaddedArrayRef(),
+ computeVirial,
+ constraintsVirial,
+ econq,
+ nrnb,
+ maxwarn,
+ &warncount_lincs);
if (!bOK && maxwarn < INT_MAX)
{
if (log != nullptr)
{
- fprintf(log, "Constraint error in algorithm %s at step %s\n",
- econstr_names[econtLINCS], gmx_step_str(step, buf));
+ fprintf(log,
+ "Constraint error in algorithm %s at step %s\n",
+ econstr_names[econtLINCS],
+ gmx_step_str(step, buf));
}
bDump = TRUE;
}
if (shaked != nullptr)
{
- bOK = constrain_shake(log, shaked.get(), inverseMasses_, *idef, ir, x.unpaddedArrayRef(),
- xprime.unpaddedArrayRef(), min_proj, pbc_null, nrnb, lambda,
- dvdlambda, invdt, v.unpaddedArrayRef(), computeVirial,
- constraintsVirial, maxwarn < INT_MAX, econq);
+ bOK = constrain_shake(log,
+ shaked.get(),
+ inverseMasses_,
+ *idef,
+ ir,
+ x.unpaddedArrayRef(),
+ xprime.unpaddedArrayRef(),
+ min_proj,
+ pbc_null,
+ nrnb,
+ lambda,
+ dvdlambda,
+ invdt,
+ v.unpaddedArrayRef(),
+ computeVirial,
+ constraintsVirial,
+ maxwarn < INT_MAX,
+ econq);
if (!bOK && maxwarn < INT_MAX)
{
if (log != nullptr)
{
- fprintf(log, "Constraint error in algorithm %s at step %s\n",
- econstr_names[econtSHAKE], gmx_step_str(step, buf));
+ fprintf(log,
+ "Constraint error in algorithm %s at step %s\n",
+ econstr_names[econtSHAKE],
+ gmx_step_str(step, buf));
}
bDump = TRUE;
}
clear_mat(threadConstraintsVirial[th]);
}
- csettle(*settled, nth, th, pbc_null, x, xprime, invdt, v, computeVirial,
+ csettle(*settled,
+ nth,
+ th,
+ pbc_null,
+ x,
+ xprime,
+ invdt,
+ v,
+ computeVirial,
th == 0 ? constraintsVirial : threadConstraintsVirial[th],
th == 0 ? &bSettleErrorHasOccurred0 : &bSettleErrorHasOccurred[th]);
}
if (start_th >= 0 && end_th - start_th > 0)
{
- settle_proj(*settled, econq, end_th - start_th,
+ settle_proj(*settled,
+ econq,
+ end_th - start_th,
settle.iatoms.data() + start_th * (1 + NRAL(F_SETTLE)),
- pbc_null, x.unpaddedArrayRef(), xprime.unpaddedArrayRef(),
- min_proj, calcvir_atom_end,
+ pbc_null,
+ x.unpaddedArrayRef(),
+ xprime.unpaddedArrayRef(),
+ min_proj,
+ calcvir_atom_end,
th == 0 ? constraintsVirial : threadConstraintsVirial[th]);
}
}
if (bDump)
{
- dump_confs(log, step, mtop, start, numHomeAtoms_, cr, x.unpaddedArrayRef(),
- xprime.unpaddedArrayRef(), box);
+ dump_confs(log, step, mtop, start, numHomeAtoms_, cr, x.unpaddedArrayRef(), xprime.unpaddedArrayRef(), box);
}
if (econq == ConstraintVariable::Positions)
t = ir.init_t;
}
set_pbc(&pbc, ir.pbcType, box);
- pull_constraint(pull_work, masses_, &pbc, cr, ir.delta_t, t,
+ pull_constraint(pull_work,
+ masses_,
+ &pbc,
+ cr,
+ ir.delta_t,
+ t,
as_rvec_array(x.unpaddedArrayRef().data()),
as_rvec_array(xprime.unpaddedArrayRef().data()),
- as_rvec_array(v.unpaddedArrayRef().data()), constraintsVirial);
+ as_rvec_array(v.unpaddedArrayRef().data()),
+ constraintsVirial);
}
if (ed && delta_step > 0)
{
/* apply the essential dynamics constraints here */
- do_edsam(&ir, step, cr, as_rvec_array(xprime.unpaddedArrayRef().data()),
- as_rvec_array(v.unpaddedArrayRef().data()), box, ed);
+ do_edsam(&ir,
+ step,
+ cr,
+ as_rvec_array(xprime.unpaddedArrayRef().data()),
+ as_rvec_array(v.unpaddedArrayRef().data()),
+ box,
+ ed);
}
}
wallcycle_stop(wcycle, ewcCONSTR);
gmx::ArrayRef<const t_iparams> iparams,
FlexibleConstraintTreatment flexibleConstraintTreatment)
{
- return makeAtomsToConstraintsList(moltype.atoms.nr, makeConstArrayRef(moltype.ilist), iparams,
- flexibleConstraintTreatment);
+ return makeAtomsToConstraintsList(
+ moltype.atoms.nr, makeConstArrayRef(moltype.ilist), iparams, flexibleConstraintTreatment);
}
//! Return the number of flexible constraints in the \c ilist and \c iparams.
const real lambda,
unsigned short* cFREEZE)
{
- impl_->setConstraints(top, numAtoms, numHomeAtoms, masses, inverseMasses, hasMassPerturbedAtoms,
- lambda, cFREEZE);
+ impl_->setConstraints(
+ top, numAtoms, numHomeAtoms, masses, inverseMasses, hasMassPerturbedAtoms, lambda, cFREEZE);
}
/*! \brief Makes a per-moleculetype container of mappings from atom
nrnb(nrnb_p),
wcycle(wcycle_p)
{
- if (numConstraints + numSettles > 0 && ir.epc == epcMTTK)
+ if (numConstraints + numSettles > 0 && ir.epc == PressureCoupling::Mttk)
{
gmx_fatal(FARGS, "Constraints are not implemented with MTTK pressure control.");
}
if (ir.eConstrAlg == econtLINCS)
{
- lincsd = init_lincs(log, mtop, nflexcon, at2con_mt,
- DOMAINDECOMP(cr) && ddHaveSplitConstraints(*cr->dd), ir.nLincsIter,
+ lincsd = init_lincs(log,
+ mtop,
+ nflexcon,
+ at2con_mt,
+ DOMAINDECOMP(cr) && ddHaveSplitConstraints(*cr->dd),
+ ir.nLincsIter,
ir.nProjOrder);
}
bool computeEnergy = false;
bool computeVirial = false;
/* constrain the current position */
- constr->apply(needsLogging, computeEnergy, step, 0, 1.0, x, x, {}, box, lambda, &dvdl_dum, {},
- computeVirial, nullptr, gmx::ConstraintVariable::Positions);
+ constr->apply(needsLogging,
+ computeEnergy,
+ step,
+ 0,
+ 1.0,
+ x,
+ x,
+ {},
+ box,
+ lambda,
+ &dvdl_dum,
+ {},
+ computeVirial,
+ nullptr,
+ gmx::ConstraintVariable::Positions);
if (EI_VV(ir->eI))
{
/* constrain the inital velocity, and save it */
/* also may be useful if we need the ekin from the halfstep for velocity verlet */
- constr->apply(needsLogging, computeEnergy, step, 0, 1.0, x, v, v.unpaddedArrayRef(), box, lambda,
- &dvdl_dum, {}, computeVirial, nullptr, gmx::ConstraintVariable::Velocities);
+ constr->apply(needsLogging,
+ computeEnergy,
+ step,
+ 0,
+ 1.0,
+ x,
+ v,
+ v.unpaddedArrayRef(),
+ box,
+ lambda,
+ &dvdl_dum,
+ {},
+ computeVirial,
+ nullptr,
+ gmx::ConstraintVariable::Velocities);
}
/* constrain the inital velocities at t-dt/2 */
if (EI_STATE_VELOCITY(ir->eI) && ir->eI != eiVV)
fprintf(fplog, "\nConstraining the coordinates at t0-dt (step %s)\n", gmx_step_str(step, buf));
}
dvdl_dum = 0;
- constr->apply(needsLogging, computeEnergy, step, -1, 1.0, x, savex.arrayRefWithPadding(),
- {}, box, lambda, &dvdl_dum, v, computeVirial, nullptr,
+ constr->apply(needsLogging,
+ computeEnergy,
+ step,
+ -1,
+ 1.0,
+ x,
+ savex.arrayRefWithPadding(),
+ {},
+ box,
+ lambda,
+ &dvdl_dum,
+ v,
+ computeVirial,
+ nullptr,
gmx::ConstraintVariable::Positions);
for (i = start; i < end; i++)
{
if (constr != nullptr)
{
- constr->apply(do_log, do_ene, step, 1, 1.0, state->x.arrayRefWithPadding(),
- state->v.arrayRefWithPadding(), state->v.arrayRefWithPadding().unpaddedArrayRef(),
- state->box, state->lambda[efptBONDED], dvdlambda, ArrayRefWithPadding<RVec>(),
- computeVirial, constraintsVirial, ConstraintVariable::Velocities);
+ constr->apply(do_log,
+ do_ene,
+ step,
+ 1,
+ 1.0,
+ state->x.arrayRefWithPadding(),
+ state->v.arrayRefWithPadding(),
+ state->v.arrayRefWithPadding().unpaddedArrayRef(),
+ state->box,
+ state->lambda[efptBONDED],
+ dvdlambda,
+ ArrayRefWithPadding<RVec>(),
+ computeVirial,
+ constraintsVirial,
+ ConstraintVariable::Velocities);
}
}
{
if (constr != nullptr)
{
- constr->apply(do_log, do_ene, step, 1, 1.0, state->x.arrayRefWithPadding(), std::move(xp),
- ArrayRef<RVec>(), state->box, state->lambda[efptBONDED], dvdlambda,
- state->v.arrayRefWithPadding(), computeVirial, constraintsVirial,
+ constr->apply(do_log,
+ do_ene,
+ step,
+ 1,
+ 1.0,
+ state->x.arrayRefWithPadding(),
+ std::move(xp),
+ ArrayRef<RVec>(),
+ state->box,
+ state->lambda[efptBONDED],
+ dvdlambda,
+ state->v.arrayRefWithPadding(),
+ computeVirial,
+ constraintsVirial,
ConstraintVariable::Positions);
}
}
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <cstdio>
+#include <memory>
+
#include "gromacs/math/vectypes.h"
#include "gromacs/topology/idef.h"
#include "gromacs/utility/arrayref.h"
#include "gromacs/utility/basedefinitions.h"
-#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/real.h"
//! Implementation type.
class Impl;
//! Implementation object.
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
/*! \brief Generate a fatal error because of too many LINCS/SETTLE warnings. */
if (debug)
{
fprintf(debug,
- "Found longer constraint distance: r0 %5.3f r1 %5.3f rmax %5.3f\n", rn0,
- rn1, sqrt(*r2max));
+ "Found longer constraint distance: r0 %5.3f r1 %5.3f rmax %5.3f\n",
+ rn0,
+ rn1,
+ sqrt(*r2max));
for (int a1 = 0; a1 < depth; a1++)
{
- fprintf(debug, " %d %5.3f", path[a1],
+ fprintf(debug,
+ " %d %5.3f",
+ path[a1],
iparams[constr_iatomptr(ia1, ia2, con)[0]].constr.dA);
}
fprintf(debug, " %d %5.3f\n", con, len);
r1 = 0;
count = 0;
- constr_recur(at2con, molt->ilist, iparams, FALSE, at, 0, 1 + ir->nProjOrder, path, r0, r1,
- &r2maxA, &count);
+ constr_recur(
+ at2con, molt->ilist, iparams, FALSE, at, 0, 1 + ir->nProjOrder, path, r0, r1, &r2maxA, &count);
}
if (ir->efep == efepNO)
{
r0 = 0;
r1 = 0;
count = 0;
- constr_recur(at2con, molt->ilist, iparams, TRUE, at, 0, 1 + ir->nProjOrder, path, r0,
- r1, &r2maxB, &count);
+ constr_recur(
+ at2con, molt->ilist, iparams, TRUE, at, 0, 1 + ir->nProjOrder, path, r0, r1, &r2maxB, &count);
}
lam0 = ir->fepvals->init_lambda;
if (EI_DYNAMICS(ir->eI))
GMX_LOG(mdlog.info)
.appendTextFormatted(
"Maximum distance for %d constraints, at 120 deg. angles, all-trans: %.3f nm",
- 1 + ir->nProjOrder, rmax);
+ 1 + ir->nProjOrder,
+ rmax);
return rmax;
}
static const double sy_const_1[] = { 1. };
static const double sy_const_3[] = { 0.828981543588751, -0.657963087177502, 0.828981543588751 };
-static const double sy_const_5[] = { 0.2967324292201065, 0.2967324292201065, -0.186929716880426,
- 0.2967324292201065, 0.2967324292201065 };
+static const double sy_const_5[] = { 0.2967324292201065,
+ 0.2967324292201065,
+ -0.186929716880426,
+ 0.2967324292201065,
+ 0.2967324292201065 };
static const double* sy_const[] = { nullptr, sy_const_1, nullptr, sy_const_3, nullptr, sy_const_5 };
// For VV temperature coupling parameters are updated on the current
// step, for the others - one step before.
- if (inputrec->etc == etcNO)
+ if (inputrec->etc == TemperatureCoupling::No)
{
doTemperatureCoupling = false;
}
// subroutines
switch (inputrec->etc)
{
- case etcNO: break;
- case etcBERENDSEN:
+ case TemperatureCoupling::No:
+ case TemperatureCoupling::Andersen:
+ case TemperatureCoupling::AndersenMassive: break;
+ case TemperatureCoupling::Berendsen:
berendsen_tcoupl(inputrec, ekind, dttc, state->therm_integral);
break;
- case etcNOSEHOOVER:
- nosehoover_tcoupl(&(inputrec->opts), ekind, dttc, state->nosehoover_xi.data(),
- state->nosehoover_vxi.data(), MassQ);
+ case TemperatureCoupling::NoseHoover:
+ nosehoover_tcoupl(&(inputrec->opts),
+ ekind,
+ dttc,
+ state->nosehoover_xi.data(),
+ state->nosehoover_vxi.data(),
+ MassQ);
break;
- case etcVRESCALE:
+ case TemperatureCoupling::VRescale:
vrescale_tcoupl(inputrec, step, ekind, dttc, state->therm_integral.data());
break;
+ default: gmx_fatal(FARGS, "Unknown temperature coupling algorithm");
}
/* rescale in place here */
if (EI_VV(inputrec->eI))
/* Berendsen P-coupling is completely handled after the coordinate update.
* Trotter P-coupling is handled by separate calls to trotter_update().
*/
- if (inputrec->epc == epcPARRINELLORAHMAN
+ if (inputrec->epc == PressureCoupling::ParrinelloRahman
&& do_per_step(step + inputrec->nstpcouple - 1, inputrec->nstpcouple))
{
real dtpc = inputrec->nstpcouple * inputrec->delta_t;
- parrinellorahman_pcoupl(fplog, step, inputrec, dtpc, state->pres_prev, state->box,
- state->box_rel, state->boxv, M, parrinellorahmanMu, bInitStep);
+ parrinellorahman_pcoupl(
+ fplog, step, inputrec, dtpc, state->pres_prev, state->box, state->box_rel, state->boxv, M, parrinellorahmanMu, bInitStep);
}
}
/* now update boxes */
switch (inputrec->epc)
{
- case (epcNO): break;
- case (epcBERENDSEN):
+ case (PressureCoupling::No): break;
+ case (PressureCoupling::Berendsen):
if (do_per_step(step, inputrec->nstpcouple))
{
real dtpc = inputrec->nstpcouple * dt;
- berendsen_pcoupl(fplog, step, inputrec, dtpc, pressure, state->box, forceVirial,
- constraintVirial, pressureCouplingMu, &state->baros_integral);
- berendsen_pscale(inputrec, pressureCouplingMu, state->box, state->box_rel, start,
- homenr, state->x.rvec_array(), md->cFREEZE, nrnb, scaleCoordinates);
+ pressureCouplingCalculateScalingMatrix<PressureCoupling::Berendsen>(fplog,
+ step,
+ inputrec,
+ dtpc,
+ pressure,
+ state->box,
+ forceVirial,
+ constraintVirial,
+ pressureCouplingMu,
+ &state->baros_integral);
+ pressureCouplingScaleBoxAndCoordinates<PressureCoupling::Berendsen>(inputrec,
+ pressureCouplingMu,
+ state->box,
+ state->box_rel,
+ start,
+ homenr,
+ state->x.rvec_array(),
+ nullptr,
+ md->cFREEZE,
+ nrnb,
+ scaleCoordinates);
}
break;
- case (epcCRESCALE):
+ case (PressureCoupling::CRescale):
if (do_per_step(step, inputrec->nstpcouple))
{
real dtpc = inputrec->nstpcouple * dt;
- crescale_pcoupl(fplog, step, inputrec, dtpc, pressure, state->box, forceVirial,
- constraintVirial, pressureCouplingMu, &state->baros_integral);
- crescale_pscale(inputrec, pressureCouplingMu, state->box, state->box_rel, start,
- homenr, state->x.rvec_array(), state->v.rvec_array(), md->cFREEZE,
- nrnb, scaleCoordinates);
+ pressureCouplingCalculateScalingMatrix<PressureCoupling::CRescale>(fplog,
+ step,
+ inputrec,
+ dtpc,
+ pressure,
+ state->box,
+ forceVirial,
+ constraintVirial,
+ pressureCouplingMu,
+ &state->baros_integral);
+ pressureCouplingScaleBoxAndCoordinates<PressureCoupling::CRescale>(
+ inputrec,
+ pressureCouplingMu,
+ state->box,
+ state->box_rel,
+ start,
+ homenr,
+ state->x.rvec_array(),
+ state->v.rvec_array(),
+ md->cFREEZE,
+ nrnb,
+ scaleCoordinates);
}
break;
- case (epcPARRINELLORAHMAN):
+ case (PressureCoupling::ParrinelloRahman):
if (do_per_step(step + inputrec->nstpcouple - 1, inputrec->nstpcouple))
{
/* The box velocities were updated in do_pr_pcoupl,
}
}
break;
- case (epcMTTK):
+ case (PressureCoupling::Mttk):
switch (inputrec->epct)
{
case (epctISOTROPIC):
real rate = (ir->delta_t) / ir->opts.tau_t[0];
- if (ir->etc == etcANDERSEN && constr != nullptr)
+ if (ir->etc == TemperatureCoupling::Andersen && constr != nullptr)
{
/* Currently, Andersen thermostat does not support constrained
systems. Functionality exists in the andersen_tcoupl
/* proceed with andersen if 1) it's fixed probability per
particle andersen or 2) it's massive andersen and it's tau_t/dt */
- if ((ir->etc == etcANDERSEN) || do_per_step(step, gmx::roundToInt(1.0 / rate)))
+ if ((ir->etc == TemperatureCoupling::Andersen) || do_per_step(step, gmx::roundToInt(1.0 / rate)))
{
- andersen_tcoupl(ir, step, cr, md, v, rate, upd->getAndersenRandomizeGroup(),
- upd->getBoltzmanFactor());
+ andersen_tcoupl(
+ ir, step, cr, md, v, rate, upd->getAndersenRandomizeGroup(), upd->getBoltzmanFactor());
return TRUE;
}
return FALSE;
mmul_ur0(invbox, t1, mu);
}
-void berendsen_pcoupl(FILE* fplog,
- int64_t step,
- const t_inputrec* ir,
- real dt,
- const tensor pres,
- const matrix box,
- const matrix force_vir,
- const matrix constraint_vir,
- matrix mu,
- double* baros_integral)
+//! Return compressibility factor for entry (i,j) of Berendsen / C-rescale scaling matrix
+static inline real compressibilityFactor(int i, int j, const t_inputrec* ir, real dt)
{
- real scalar_pressure, xy_pressure, p_corr_z;
- char buf[STRLEN];
+ return ir->compress[i][j] * dt / ir->tau_p;
+}
- /*
- * Calculate the scaling matrix mu
- */
- scalar_pressure = 0;
- xy_pressure = 0;
+//! Details of Berendsen / C-rescale scaling matrix calculation
+template<PressureCoupling pressureCouplingType>
+static void calculateScalingMatrixImplDetail(const t_inputrec* ir,
+ matrix mu,
+ real dt,
+ const matrix pres,
+ const matrix box,
+ real scalar_pressure,
+ real xy_pressure,
+ int64_t step);
+
+//! Calculate Berendsen / C-rescale scaling matrix
+template<PressureCoupling pressureCouplingType>
+static void calculateScalingMatrixImpl(const t_inputrec* ir,
+ matrix mu,
+ real dt,
+ const matrix pres,
+ const matrix box,
+ int64_t step)
+{
+ real scalar_pressure = 0;
+ real xy_pressure = 0;
for (int d = 0; d < DIM; d++)
{
scalar_pressure += pres[d][d] / DIM;
xy_pressure += pres[d][d] / (DIM - 1);
}
}
- /* Pressure is now in bar, everywhere. */
-#define factor(d, m) (ir->compress[d][m] * dt / ir->tau_p)
-
- /* mu has been changed from pow(1+...,1/3) to 1+.../3, since this is
- * necessary for triclinic scaling
- */
clear_mat(mu);
+ calculateScalingMatrixImplDetail<pressureCouplingType>(
+ ir, mu, dt, pres, box, scalar_pressure, xy_pressure, step);
+}
+
+template<>
+void calculateScalingMatrixImplDetail<PressureCoupling::Berendsen>(const t_inputrec* ir,
+ matrix mu,
+ real dt,
+ const matrix pres,
+ const matrix box,
+ real scalar_pressure,
+ real xy_pressure,
+ int64_t gmx_unused step)
+{
+ real p_corr_z = 0;
switch (ir->epct)
{
case epctISOTROPIC:
for (int d = 0; d < DIM; d++)
{
- mu[d][d] = 1.0 - factor(d, d) * (ir->ref_p[d][d] - scalar_pressure) / DIM;
+ mu[d][d] = 1.0 - compressibilityFactor(d, d, ir, dt) * (ir->ref_p[d][d] - scalar_pressure) / DIM;
}
break;
case epctSEMIISOTROPIC:
for (int d = 0; d < ZZ; d++)
{
- mu[d][d] = 1.0 - factor(d, d) * (ir->ref_p[d][d] - xy_pressure) / DIM;
+ mu[d][d] = 1.0 - compressibilityFactor(d, d, ir, dt) * (ir->ref_p[d][d] - xy_pressure) / DIM;
}
- mu[ZZ][ZZ] = 1.0 - factor(ZZ, ZZ) * (ir->ref_p[ZZ][ZZ] - pres[ZZ][ZZ]) / DIM;
+ mu[ZZ][ZZ] =
+ 1.0 - compressibilityFactor(ZZ, ZZ, ir, dt) * (ir->ref_p[ZZ][ZZ] - pres[ZZ][ZZ]) / DIM;
break;
case epctANISOTROPIC:
for (int d = 0; d < DIM; d++)
{
for (int n = 0; n < DIM; n++)
{
- mu[d][n] = (d == n ? 1.0 : 0.0) - factor(d, n) * (ir->ref_p[d][n] - pres[d][n]) / DIM;
+ mu[d][n] = (d == n ? 1.0 : 0.0)
+ - compressibilityFactor(d, n, ir, dt) * (ir->ref_p[d][n] - pres[d][n]) / DIM;
}
}
break;
for (int d = 0; d < DIM - 1; d++)
{
mu[d][d] = 1.0
- + factor(d, d)
+ + compressibilityFactor(d, d, ir, dt)
* (ir->ref_p[d][d] / (mu[ZZ][ZZ] * box[ZZ][ZZ])
- (pres[ZZ][ZZ] + p_corr_z - xy_pressure))
/ (DIM - 1);
}
break;
default:
- gmx_fatal(FARGS, "Berendsen pressure coupling type %s not supported yet\n",
+ gmx_fatal(FARGS,
+ "Berendsen pressure coupling type %s not supported yet\n",
EPCOUPLTYPETYPE(ir->epct));
}
- /* To fullfill the orientation restrictions on triclinic boxes
- * we will set mu_yx, mu_zx and mu_zy to 0 and correct
- * the other elements of mu to first order.
- */
- mu[YY][XX] += mu[XX][YY];
- mu[ZZ][XX] += mu[XX][ZZ];
- mu[ZZ][YY] += mu[YY][ZZ];
- mu[XX][YY] = 0;
- mu[XX][ZZ] = 0;
- mu[YY][ZZ] = 0;
-
- /* Keep track of the work the barostat applies on the system.
- * Without constraints force_vir tells us how Epot changes when scaling.
- * With constraints constraint_vir gives us the constraint contribution
- * to both Epot and Ekin. Although we are not scaling velocities, scaling
- * the coordinates leads to scaling of distances involved in constraints.
- * This in turn changes the angular momentum (even if the constrained
- * distances are corrected at the next step). The kinetic component
- * of the constraint virial captures the angular momentum change.
- */
- for (int d = 0; d < DIM; d++)
- {
- for (int n = 0; n <= d; n++)
- {
- *baros_integral -=
- 2 * (mu[d][n] - (n == d ? 1 : 0)) * (force_vir[d][n] + constraint_vir[d][n]);
- }
- }
-
- if (debug)
- {
- pr_rvecs(debug, 0, "PC: pres ", pres, 3);
- pr_rvecs(debug, 0, "PC: mu ", mu, 3);
- }
-
- if (mu[XX][XX] < 0.99 || mu[XX][XX] > 1.01 || mu[YY][YY] < 0.99 || mu[YY][YY] > 1.01
- || mu[ZZ][ZZ] < 0.99 || mu[ZZ][ZZ] > 1.01)
- {
- char buf2[22];
- sprintf(buf,
- "\nStep %s Warning: pressure scaling more than 1%%, "
- "mu: %g %g %g\n",
- gmx_step_str(step, buf2), mu[XX][XX], mu[YY][YY], mu[ZZ][ZZ]);
- if (fplog)
- {
- fprintf(fplog, "%s", buf);
- }
- fprintf(stderr, "%s", buf);
- }
}
-void crescale_pcoupl(FILE* fplog,
- int64_t step,
- const t_inputrec* ir,
- real dt,
- const tensor pres,
- const matrix box,
- const matrix force_vir,
- const matrix constraint_vir,
- matrix mu,
- double* baros_integral)
+template<>
+void calculateScalingMatrixImplDetail<PressureCoupling::CRescale>(const t_inputrec* ir,
+ matrix mu,
+ real dt,
+ const matrix pres,
+ const matrix box,
+ real scalar_pressure,
+ real xy_pressure,
+ int64_t step)
{
- /*
- * Calculate the scaling matrix mu
- */
- real scalar_pressure = 0;
- real xy_pressure = 0;
- for (int d = 0; d < DIM; d++)
- {
- scalar_pressure += pres[d][d] / DIM;
- if (d != ZZ)
- {
- xy_pressure += pres[d][d] / (DIM - 1);
- }
- }
- clear_mat(mu);
-
gmx::ThreeFry2x64<64> rng(ir->ld_seed, gmx::RandomDomain::Barostat);
gmx::NormalDistribution<real> normalDist;
rng.restart(step, 0);
{
vol *= box[d][d];
}
- real gauss;
- real gauss2;
- real kt = ir->opts.ref_t[0] * BOLTZ;
+ real gauss = 0;
+ real gauss2 = 0;
+ real kt = ir->opts.ref_t[0] * BOLTZ;
if (kt < 0.0)
{
kt = 0.0;
gauss = normalDist(rng);
for (int d = 0; d < DIM; d++)
{
- const real compressibilityFactor = ir->compress[d][d] * dt / ir->tau_p;
- mu[d][d] = std::exp(-compressibilityFactor * (ir->ref_p[d][d] - scalar_pressure) / DIM
- + std::sqrt(2.0 * kt * compressibilityFactor * PRESFAC / vol)
- * gauss / DIM);
+ const real factor = compressibilityFactor(d, d, ir, dt);
+ mu[d][d] = std::exp(-factor * (ir->ref_p[d][d] - scalar_pressure) / DIM
+ + std::sqrt(2.0 * kt * factor * PRESFAC / vol) * gauss / DIM);
}
break;
case epctSEMIISOTROPIC:
gauss2 = normalDist(rng);
for (int d = 0; d < ZZ; d++)
{
- const real compressibilityFactor = ir->compress[d][d] * dt / ir->tau_p;
- mu[d][d] = std::exp(
- -compressibilityFactor * (ir->ref_p[d][d] - xy_pressure) / DIM
- + std::sqrt((DIM - 1) * 2.0 * kt * compressibilityFactor * PRESFAC / vol / DIM)
- / (DIM - 1) * gauss);
+ const real factor = compressibilityFactor(d, d, ir, dt);
+ mu[d][d] = std::exp(-factor * (ir->ref_p[d][d] - xy_pressure) / DIM
+ + std::sqrt((DIM - 1) * 2.0 * kt * factor * PRESFAC / vol / DIM)
+ / (DIM - 1) * gauss);
}
{
- const real compressibilityFactor = ir->compress[ZZ][ZZ] * dt / ir->tau_p;
- mu[ZZ][ZZ] = std::exp(
- -compressibilityFactor * (ir->ref_p[ZZ][ZZ] - pres[ZZ][ZZ]) / DIM
- + std::sqrt(2.0 * kt * compressibilityFactor * PRESFAC / vol / DIM) * gauss2);
+ const real factor = compressibilityFactor(ZZ, ZZ, ir, dt);
+ mu[ZZ][ZZ] = std::exp(-factor * (ir->ref_p[ZZ][ZZ] - pres[ZZ][ZZ]) / DIM
+ + std::sqrt(2.0 * kt * factor * PRESFAC / vol / DIM) * gauss2);
}
break;
case epctSURFACETENSION:
gauss2 = normalDist(rng);
for (int d = 0; d < ZZ; d++)
{
- const real compressibilityFactor = ir->compress[d][d] * dt / ir->tau_p;
+ const real factor = compressibilityFactor(d, d, ir, dt);
/* Notice: we here use ref_p[ZZ][ZZ] as isotropic pressure and ir->ref_p[d][d] as surface tension */
mu[d][d] = std::exp(
- -compressibilityFactor
- * (ir->ref_p[ZZ][ZZ] - ir->ref_p[d][d] / box[ZZ][ZZ] - xy_pressure) / DIM
- + std::sqrt(4.0 / 3.0 * kt * compressibilityFactor * PRESFAC / vol)
- / (DIM - 1) * gauss);
+ -factor * (ir->ref_p[ZZ][ZZ] - ir->ref_p[d][d] / box[ZZ][ZZ] - xy_pressure) / DIM
+ + std::sqrt(4.0 / 3.0 * kt * factor * PRESFAC / vol) / (DIM - 1) * gauss);
}
{
- const real compressibilityFactor = ir->compress[ZZ][ZZ] * dt / ir->tau_p;
- mu[ZZ][ZZ] = std::exp(
- -compressibilityFactor * (ir->ref_p[ZZ][ZZ] - pres[ZZ][ZZ]) / DIM
- + std::sqrt(2.0 / 3.0 * kt * compressibilityFactor * PRESFAC / vol) * gauss2);
+ const real factor = compressibilityFactor(ZZ, ZZ, ir, dt);
+ mu[ZZ][ZZ] = std::exp(-factor * (ir->ref_p[ZZ][ZZ] - pres[ZZ][ZZ]) / DIM
+ + std::sqrt(2.0 / 3.0 * kt * factor * PRESFAC / vol) * gauss2);
}
break;
default:
- gmx_fatal(FARGS, "C-rescale pressure coupling type %s not supported yet\n",
+ gmx_fatal(FARGS,
+ "C-rescale pressure coupling type %s not supported yet\n",
EPCOUPLTYPETYPE(ir->epct));
}
- /* To fullfill the orientation restrictions on triclinic boxes
+}
+
+template<PressureCoupling pressureCouplingType>
+void pressureCouplingCalculateScalingMatrix(FILE* fplog,
+ int64_t step,
+ const t_inputrec* ir,
+ real dt,
+ const tensor pres,
+ const matrix box,
+ const matrix force_vir,
+ const matrix constraint_vir,
+ matrix mu,
+ double* baros_integral)
+{
+ static_assert(pressureCouplingType == PressureCoupling::Berendsen
+ || pressureCouplingType == PressureCoupling::CRescale,
+ "pressureCouplingCalculateScalingMatrix is only implemented for Berendsen and "
+ "C-rescale pressure coupling");
+
+ calculateScalingMatrixImpl<pressureCouplingType>(ir, mu, dt, pres, box, step);
+
+ /* To fulfill the orientation restrictions on triclinic boxes
* we will set mu_yx, mu_zx and mu_zy to 0 and correct
* the other elements of mu to first order.
*/
sprintf(buf,
"\nStep %s Warning: pressure scaling more than 1%%, "
"mu: %g %g %g\n",
- gmx_step_str(step, buf2), mu[XX][XX], mu[YY][YY], mu[ZZ][ZZ]);
+ gmx_step_str(step, buf2),
+ mu[XX][XX],
+ mu[YY][YY],
+ mu[ZZ][ZZ]);
if (fplog)
{
fprintf(fplog, "%s", buf);
}
}
-void crescale_pscale(const t_inputrec* ir,
- const matrix mu,
- matrix box,
- matrix box_rel,
- int start,
- int nr_atoms,
- rvec x[],
- rvec v[],
- const unsigned short cFREEZE[],
- t_nrnb* nrnb,
- const bool scaleCoordinates)
+template<PressureCoupling pressureCouplingType>
+void pressureCouplingScaleBoxAndCoordinates(const t_inputrec* ir,
+ const matrix mu,
+ matrix box,
+ matrix box_rel,
+ int start,
+ int nr_atoms,
+ rvec x[],
+ rvec v[],
+ const unsigned short cFREEZE[],
+ t_nrnb* nrnb,
+ const bool scaleCoordinates)
{
- ivec* nFreeze = ir->opts.nFreeze;
- int nthreads gmx_unused;
- matrix inv_mu;
+ static_assert(pressureCouplingType == PressureCoupling::Berendsen
+ || pressureCouplingType == PressureCoupling::CRescale,
+ "pressureCouplingScaleBoxAndCoordinates is only implemented for Berendsen and "
+ "C-rescale pressure coupling");
-#ifndef __clang_analyzer__
- nthreads = gmx_omp_nthreads_get(emntUpdate);
-#endif
-
- gmx::invertBoxMatrix(mu, inv_mu);
-
- /* Scale the positions and the velocities */
- if (scaleCoordinates)
+ ivec* nFreeze = ir->opts.nFreeze;
+ matrix inv_mu;
+ if (pressureCouplingType == PressureCoupling::CRescale)
{
-#pragma omp parallel for num_threads(nthreads) schedule(static)
- for (int n = start; n < start + nr_atoms; n++)
- {
- // Trivial OpenMP region that does not throw
- int g;
-
- if (cFREEZE == nullptr)
- {
- g = 0;
- }
- else
- {
- g = cFREEZE[n];
- }
-
- if (!nFreeze[g][XX])
- {
- x[n][XX] = mu[XX][XX] * x[n][XX] + mu[YY][XX] * x[n][YY] + mu[ZZ][XX] * x[n][ZZ];
- v[n][XX] = inv_mu[XX][XX] * v[n][XX] + inv_mu[YY][XX] * v[n][YY]
- + inv_mu[ZZ][XX] * v[n][ZZ];
- }
- if (!nFreeze[g][YY])
- {
- x[n][YY] = mu[YY][YY] * x[n][YY] + mu[ZZ][YY] * x[n][ZZ];
- v[n][YY] = inv_mu[YY][YY] * v[n][YY] + inv_mu[ZZ][YY] * v[n][ZZ];
- }
- if (!nFreeze[g][ZZ])
- {
- x[n][ZZ] = mu[ZZ][ZZ] * x[n][ZZ];
- v[n][ZZ] = inv_mu[ZZ][ZZ] * v[n][ZZ];
- }
- }
+ gmx::invertBoxMatrix(mu, inv_mu);
}
- /* compute final boxlengths */
- for (int d = 0; d < DIM; d++)
- {
- box[d][XX] = mu[XX][XX] * box[d][XX] + mu[YY][XX] * box[d][YY] + mu[ZZ][XX] * box[d][ZZ];
- box[d][YY] = mu[YY][YY] * box[d][YY] + mu[ZZ][YY] * box[d][ZZ];
- box[d][ZZ] = mu[ZZ][ZZ] * box[d][ZZ];
- }
-
- preserve_box_shape(ir, box_rel, box);
-
- /* (un)shifting should NOT be done after this,
- * since the box vectors might have changed
- */
- inc_nrnb(nrnb, eNR_PCOUPL, nr_atoms);
-}
-
-void berendsen_pscale(const t_inputrec* ir,
- const matrix mu,
- matrix box,
- matrix box_rel,
- int start,
- int nr_atoms,
- rvec x[],
- const unsigned short cFREEZE[],
- t_nrnb* nrnb,
- const bool scaleCoordinates)
-{
- ivec* nFreeze = ir->opts.nFreeze;
- int d;
- int nthreads gmx_unused;
-
-#ifndef __clang_analyzer__
- nthreads = gmx_omp_nthreads_get(emntUpdate);
-#endif
- /* Scale the positions */
+ /* Scale the positions and the velocities */
if (scaleCoordinates)
{
-#pragma omp parallel for num_threads(nthreads) schedule(static)
+ const int gmx_unused numThreads = gmx_omp_nthreads_get(emntUpdate);
+#pragma omp parallel for num_threads(numThreads) schedule(static)
for (int n = start; n < start + nr_atoms; n++)
{
// Trivial OpenMP region that does not throw
- int g;
-
- if (cFREEZE == nullptr)
- {
- g = 0;
- }
- else
+ int g = 0;
+ if (cFREEZE != nullptr)
{
g = cFREEZE[n];
}
if (!nFreeze[g][XX])
{
x[n][XX] = mu[XX][XX] * x[n][XX] + mu[YY][XX] * x[n][YY] + mu[ZZ][XX] * x[n][ZZ];
+ if (pressureCouplingType == PressureCoupling::CRescale)
+ {
+ v[n][XX] = inv_mu[XX][XX] * v[n][XX] + inv_mu[YY][XX] * v[n][YY]
+ + inv_mu[ZZ][XX] * v[n][ZZ];
+ }
}
if (!nFreeze[g][YY])
{
x[n][YY] = mu[YY][YY] * x[n][YY] + mu[ZZ][YY] * x[n][ZZ];
+ if (pressureCouplingType == PressureCoupling::CRescale)
+ {
+ v[n][YY] = inv_mu[YY][YY] * v[n][YY] + inv_mu[ZZ][YY] * v[n][ZZ];
+ }
}
if (!nFreeze[g][ZZ])
{
x[n][ZZ] = mu[ZZ][ZZ] * x[n][ZZ];
+ if (pressureCouplingType == PressureCoupling::CRescale)
+ {
+ v[n][ZZ] = inv_mu[ZZ][ZZ] * v[n][ZZ];
+ }
}
}
}
/* compute final boxlengths */
- for (d = 0; d < DIM; d++)
+ for (int d = 0; d < DIM; d++)
{
box[d][XX] = mu[XX][XX] * box[d][XX] + mu[YY][XX] * box[d][YY] + mu[ZZ][XX] * box[d][ZZ];
box[d][YY] = mu[YY][YY] * box[d][YY] + mu[ZZ][YY] * box[d][ZZ];
}
if (randomize[gc])
{
- if (ir->etc == etcANDERSENMASSIVE)
+ if (ir->etc == TemperatureCoupling::AndersenMassive)
{
/* Randomize particle always */
bRandomize = TRUE;
{
case etrtBAROV:
case etrtBAROV2:
- boxv_trotter(ir, &(state->veta), dt, state->box, ekind, vir,
- enerd->term[F_PDISPCORR], MassQ);
+ boxv_trotter(ir, &(state->veta), dt, state->box, ekind, vir, enerd->term[F_PDISPCORR], MassQ);
break;
case etrtBARONHC:
case etrtBARONHC2:
- NHC_trotter(opts, state->nnhpres, ekind, dt, state->nhpres_xi.data(),
- state->nhpres_vxi.data(), nullptr, &(state->veta), MassQ, FALSE);
+ NHC_trotter(opts,
+ state->nnhpres,
+ ekind,
+ dt,
+ state->nhpres_xi.data(),
+ state->nhpres_vxi.data(),
+ nullptr,
+ &(state->veta),
+ MassQ,
+ FALSE);
break;
case etrtNHC:
case etrtNHC2:
- NHC_trotter(opts, opts->ngtc, ekind, dt, state->nosehoover_xi.data(),
- state->nosehoover_vxi.data(), scalefac, nullptr, MassQ, (ir->eI == eiVV));
+ NHC_trotter(opts,
+ opts->ngtc,
+ ekind,
+ dt,
+ state->nosehoover_xi.data(),
+ state->nosehoover_vxi.data(),
+ scalefac,
+ nullptr,
+ MassQ,
+ (ir->eI == eiVV));
/* need to rescale the kinetic energies and velocities here. Could
scale the velocities later, but we need them scaled in order to
produce the correct outputs, so we'll scale them here. */
nnhpres = state->nnhpres;
nh = state->nhchainlength;
- if (EI_VV(ir->eI) && (ir->epc == epcMTTK) && (ir->etc != etcNOSEHOOVER))
+ if (EI_VV(ir->eI) && (ir->epc == PressureCoupling::Mttk) && (ir->etc != TemperatureCoupling::NoseHoover))
{
- gmx_fatal(FARGS,
- "Cannot do MTTK pressure coupling without Nose-Hoover temperature control");
+ gmx_fatal(FARGS, "Cannot do MTTK pressure coupling without Nose-Hoover temperature control");
}
init_npt_masses(ir, state, MassQ, TRUE);
}
if (debug)
{
- fprintf(debug, "P-T-group: %10d Chain %4d ThermV: %15.8f ThermX: %15.8f", i, j,
- state->nhpres_vxi[i * nh + j], state->nhpres_xi[i * nh + j]);
+ fprintf(debug,
+ "P-T-group: %10d Chain %4d ThermV: %15.8f ThermX: %15.8f",
+ i,
+ j,
+ state->nhpres_vxi[i * nh + j],
+ state->nhpres_xi[i * nh + j]);
}
}
}
{
real energyNPT = 0;
- if (ir->epc != epcNO)
+ if (ir->epc != PressureCoupling::No)
{
/* Compute the contribution of the pressure to the conserved quantity*/
switch (ir->epc)
{
- case epcPARRINELLORAHMAN:
+ case PressureCoupling::ParrinelloRahman:
{
/* contribution from the pressure momenta */
tensor invMass;
energyNPT += vol * trace(ir->ref_p) / (DIM * PRESFAC);
break;
}
- case epcMTTK:
+ case PressureCoupling::Mttk:
/* contribution from the pressure momenta */
energyNPT += 0.5 * gmx::square(state->veta) / MassQ->Winv;
/* contribution from the PV term */
energyNPT += vol * trace(ir->ref_p) / (DIM * PRESFAC);
- if (ir->epc == epcMTTK)
+ if (ir->epc == PressureCoupling::Mttk)
{
/* contribution from the MTTK chain */
energyNPT += energyPressureMTTK(ir, state, MassQ);
}
break;
- case epcBERENDSEN:
- case epcCRESCALE: energyNPT += state->baros_integral; break;
+ case PressureCoupling::Berendsen:
+ case PressureCoupling::CRescale: energyNPT += state->baros_integral; break;
default:
GMX_RELEASE_ASSERT(
false,
switch (ir->etc)
{
- case etcNO: break;
- case etcVRESCALE:
- case etcBERENDSEN: energyNPT += energyVrescale(ir, state); break;
- case etcNOSEHOOVER: energyNPT += energyNoseHoover(ir, state, MassQ); break;
- case etcANDERSEN:
- case etcANDERSENMASSIVE:
+ case TemperatureCoupling::No: break;
+ case TemperatureCoupling::VRescale:
+ case TemperatureCoupling::Berendsen: energyNPT += energyVrescale(ir, state); break;
+ case TemperatureCoupling::NoseHoover:
+ energyNPT += energyNoseHoover(ir, state, MassQ);
+ break;
+ case TemperatureCoupling::Andersen:
+ case TemperatureCoupling::AndersenMassive:
// Not supported, excluded in integratorHasConservedEnergyQuantity()
break;
default:
if (debug)
{
- fprintf(debug, "TC: group %d: Ekr %g, Ek %g, Ek_new %g, Lambda: %g\n", i, Ek_ref,
- Ek, Ek_new, ekind->tcstat[i].lambda);
+ fprintf(debug,
+ "TC: group %d: Ekr %g, Ek %g, Ek_new %g, Lambda: %g\n",
+ i,
+ Ek_ref,
+ Ek,
+ Ek_new,
+ ekind->tcstat[i].lambda);
}
}
else
void rescale_velocities(const gmx_ekindata_t* ekind, const t_mdatoms* mdatoms, int start, int end, rvec v[])
{
- unsigned short *cACC, *cTC;
- int ga, gt, n, d;
- real lg;
- rvec vrel;
-
- cTC = mdatoms->cTC;
-
+ const unsigned short* cTC = mdatoms->cTC;
gmx::ArrayRef<const t_grp_tcstat> tcstat = ekind->tcstat;
- if (ekind->bNEMD)
+ for (int n = start; n < end; n++)
{
- gmx::ArrayRef<const t_grp_acc> gstat = ekind->grpstat;
- cACC = mdatoms->cACC;
-
- ga = 0;
- gt = 0;
- for (n = start; n < end; n++)
+ int gt = 0;
+ if (cTC)
{
- if (cACC)
- {
- ga = cACC[n];
- }
- if (cTC)
- {
- gt = cTC[n];
- }
- /* Only scale the velocity component relative to the COM velocity */
- rvec_sub(v[n], gstat[ga].u, vrel);
- lg = tcstat[gt].lambda;
- for (d = 0; d < DIM; d++)
- {
- v[n][d] = gstat[ga].u[d] + lg * vrel[d];
- }
+ gt = cTC[n];
}
- }
- else
- {
- gt = 0;
- for (n = start; n < end; n++)
+ const real lg = tcstat[gt].lambda;
+ for (int d = 0; d < DIM; d++)
{
- if (cTC)
- {
- gt = cTC[n];
- }
- lg = tcstat[gt].lambda;
- for (d = 0; d < DIM; d++)
- {
- v[n][d] *= lg;
- }
+ v[n][d] *= lg;
}
}
}
break;
case eannSINGLE: thist = t; break;
default:
- gmx_fatal(FARGS, "Death horror in update_annealing_target_temp (i=%d/%d npoints=%d)",
- i, ir->opts.ngtc, npoints);
+ gmx_fatal(FARGS,
+ "Death horror in update_annealing_target_temp (i=%d/%d npoints=%d)",
+ i,
+ ir->opts.ngtc,
+ npoints);
}
/* We are doing annealing for this group if we got here,
* and we have the (relative) time as thist.
{
if (EI_DYNAMICS(ir.eI))
{
- if (ir.etc == etcBERENDSEN)
+ if (ir.etc == TemperatureCoupling::Berendsen)
{
please_cite(fplog, "Berendsen84a");
}
- if (ir.etc == etcVRESCALE)
+ if (ir.etc == TemperatureCoupling::VRescale)
{
please_cite(fplog, "Bussi2007a");
}
- if (ir.epc == epcCRESCALE)
+ if (ir.epc == PressureCoupling::CRescale)
{
please_cite(fplog, "Bernetti2020");
}
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
matrix mu,
gmx_bool bFirstStep);
-void berendsen_pcoupl(FILE* fplog,
- int64_t step,
- const t_inputrec* ir,
- real dt,
- const tensor pres,
- const matrix box,
- const matrix force_vir,
- const matrix constraint_vir,
- matrix mu,
- double* baros_integral);
-
-void berendsen_pscale(const t_inputrec* ir,
- const matrix mu,
- matrix box,
- matrix box_rel,
- int start,
- int nr_atoms,
- rvec x[],
- const unsigned short cFREEZE[],
- t_nrnb* nrnb,
- bool scaleCoordinates);
-void crescale_pcoupl(FILE* fplog,
- int64_t step,
- const t_inputrec* ir,
- real dt,
- const tensor pres,
- const matrix box,
- const matrix force_vir,
- const matrix constraint_vir,
- matrix mu,
- double* baros_integral);
-
-void crescale_pscale(const t_inputrec* ir,
- const matrix mu,
- matrix box,
- matrix box_rel,
- int start,
- int nr_atoms,
- rvec x[],
- rvec v[],
- const unsigned short cFREEZE[],
- t_nrnb* nrnb,
- bool scaleCoordinates);
+/*! \brief Calculate the pressure coupling scaling matrix
+ *
+ * Used by Berendsen and C-Rescale pressure coupling, this function
+ * computes the current value of the scaling matrix. The template
+ * parameter determines the pressure coupling algorithm.
+ */
+template<PressureCoupling pressureCouplingType>
+void pressureCouplingCalculateScalingMatrix(FILE* fplog,
+ int64_t step,
+ const t_inputrec* ir,
+ real dt,
+ const tensor pres,
+ const matrix box,
+ const matrix force_vir,
+ const matrix constraint_vir,
+ matrix mu,
+ double* baros_integral);
+
+/*! \brief Scale the box and coordinates
+ *
+ * Used by Berendsen and C-Rescale pressure coupling, this function scales
+ * the box, the positions, and the velocities (C-Rescale only) according to
+ * the scaling matrix mu. The template parameter determines the pressure
+ * coupling algorithm.
+ */
+template<PressureCoupling pressureCouplingType>
+void pressureCouplingScaleBoxAndCoordinates(const t_inputrec* ir,
+ const matrix mu,
+ matrix box,
+ matrix box_rel,
+ int start,
+ int nr_atoms,
+ rvec x[],
+ rvec v[],
+ const unsigned short cFREEZE[],
+ t_nrnb* nrnb,
+ bool scaleCoordinates);
void pleaseCiteCouplingAlgorithms(FILE* fplog, const t_inputrec& ir);
}
else
{
- gmx_fatal(FARGS, "Dispersion correction is not implemented for vdw-type = %s",
- evdw_names[ic.vdwtype]);
+ gmx_fatal(FARGS, "Dispersion correction is not implemented for vdw-type = %s", evdw_names[ic.vdwtype]);
}
iParams->enerdiffsix_ = energy.dispersion;
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2012,2014,2015,2017,2018 by the GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
return index;
}
-// ICC 19 -O3 -msse2 generates wrong code. Lower optimization levels
-// and other SIMD levels seem fine, however.
-#if defined __ICC
-# pragma intel optimization_level 2
-#endif
void add_ebin(t_ebin* eb, int entryIndex, int nener, const real ener[], gmx_bool bSum)
{
int i, m;
if ((entryIndex + nener > eb->nener) || (entryIndex < 0))
{
- gmx_fatal(FARGS, "%s-%d: Energies out of range: entryIndex=%d nener=%d maxener=%d",
- __FILE__, __LINE__, entryIndex, nener, eb->nener);
+ gmx_fatal(FARGS,
+ "%s-%d: Energies out of range: entryIndex=%d nener=%d maxener=%d",
+ __FILE__,
+ __LINE__,
+ entryIndex,
+ nener,
+ eb->nener);
}
eg = &(eb->e[entryIndex]);
GMX_ASSERT(shouldUse.size() == ener.size(), "View sizes must match");
GMX_ASSERT(entryIndex + std::count(shouldUse.begin(), shouldUse.end(), true) <= eb->nener,
- gmx::formatString("Energies out of range: entryIndex=%d nener=%td maxener=%d", entryIndex,
- std::count(shouldUse.begin(), shouldUse.end(), true), eb->nener)
+ gmx::formatString("Energies out of range: entryIndex=%d nener=%td maxener=%d",
+ entryIndex,
+ std::count(shouldUse.begin(), shouldUse.end(), true),
+ eb->nener)
.c_str());
GMX_ASSERT(entryIndex >= 0, "Must have non-negative entry");
enerd->term[index] = enerd->dvdl_lin[i] + enerd->dvdl_nonlin[i];
if (debug)
{
- fprintf(debug, "dvdl-%s[%2d]: %f: non-linear %f + linear %f\n", efpt_names[i], i,
- enerd->term[index], enerd->dvdl_nonlin[i], enerd->dvdl_lin[i]);
+ fprintf(debug,
+ "dvdl-%s[%2d]: %f: non-linear %f + linear %f\n",
+ efpt_names[i],
+ i,
+ enerd->term[index],
+ enerd->dvdl_nonlin[i],
+ enerd->dvdl_lin[i]);
}
}
else
enerd->term[F_DVDL] += enerd->dvdl_lin[i] + enerd->dvdl_nonlin[i];
if (debug)
{
- fprintf(debug, "dvd-%sl[%2d]: %f: non-linear %f + linear %f\n", efpt_names[0], i,
- enerd->term[F_DVDL], enerd->dvdl_nonlin[i], enerd->dvdl_lin[i]);
+ fprintf(debug,
+ "dvd-%sl[%2d]: %f: non-linear %f + linear %f\n",
+ efpt_names[0],
+ i,
+ enerd->term[F_DVDL],
+ enerd->dvdl_nonlin[i],
+ enerd->dvdl_lin[i]);
}
}
}
enerd->term[F_DVDL] += enerd->term[F_DVDL_CONSTR];
}
- enerd->foreignLambdaTerms.finalizeKineticContributions(enerd->term, enerd->dvdl_lin[efptMASS],
- lambda, fepvals);
+ enerd->foreignLambdaTerms.finalizeKineticContributions(
+ enerd->term, enerd->dvdl_lin[efptMASS], lambda, fepvals);
/* The constrain contribution is now included in other terms, so clear it */
enerd->term[F_DVDL_CONSTR] = 0;
if (timeInterval() > 0)
{
mesg = formatString("Energy conservation over %s of length %g ns, time %g to %g ns\n",
- partName.c_str(), timeInterval(), firstTime_, lastTime_);
+ partName.c_str(),
+ timeInterval(),
+ firstTime_,
+ lastTime_);
mesg += formatString(" Conserved energy drift: %.2e kJ/mol/ps per atom\n", energyDrift());
}
else
{
mesg = formatString(
"Time interval for measuring conserved energy has length 0, time %g to %g\n",
- firstTime_, lastTime_);
+ firstTime_,
+ lastTime_);
}
return mesg;
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
}
}
- epc_ = isRerun ? epcNO : ir->epc;
+ epc_ = isRerun ? PressureCoupling::No : ir->epc;
bDiagPres_ = !TRICLINIC(ir->ref_p) && !isRerun;
ref_p_ = (ir->ref_p[XX][XX] + ir->ref_p[YY][YY] + ir->ref_p[ZZ][ZZ]) / DIM;
bTricl_ = TRICLINIC(ir->compress) || TRICLINIC(ir->deform);
bDynBox_ = inputrecDynamicBox(ir);
- etc_ = isRerun ? etcNO : ir->etc;
+ etc_ = isRerun ? TemperatureCoupling::No : ir->etc;
bNHC_trotter_ = inputrecNvtTrotter(ir) && !isRerun;
bPrintNHChains_ = ir->bPrintNHChains && !isRerun;
bMTTK_ = (inputrecNptTrotter(ir) || inputrecNphTrotter(ir)) && !isRerun;
}
if (bDynBox_)
{
- ib_ = get_ebin_space(ebin_, bTricl_ ? tricl_boxs_nm.size() : boxs_nm.size(),
- bTricl_ ? tricl_boxs_nm.data() : boxs_nm.data(), unit_length);
+ ib_ = get_ebin_space(ebin_,
+ bTricl_ ? tricl_boxs_nm.size() : boxs_nm.size(),
+ bTricl_ ? tricl_boxs_nm.data() : boxs_nm.data(),
+ unit_length);
ivol_ = get_ebin_space(ebin_, 1, vol_nm, unit_volume);
idens_ = get_ebin_space(ebin_, 1, dens_nm, unit_density_SI);
if (bDiagPres_)
ipres_ = get_ebin_space(ebin_, asize(pres_nm), pres_nm, unit_pres_bar);
isurft_ = get_ebin_space(ebin_, asize(surft_nm), surft_nm, unit_surft_bar);
}
- if (epc_ == epcPARRINELLORAHMAN || epc_ == epcMTTK)
+ if (epc_ == PressureCoupling::ParrinelloRahman || epc_ == PressureCoupling::Mttk)
{
ipc_ = get_ebin_space(ebin_, bTricl_ ? boxvel_nm.size() : DIM, boxvel_nm.data(), unit_vel);
}
{
if (bEInd_[k])
{
- sprintf(gnm[kk], "%s:%s-%s", egrp_nm[k], *(groups->groupNames[ni]),
+ sprintf(gnm[kk],
+ "%s:%s-%s",
+ egrp_nm[k],
+ *(groups->groupNames[ni]),
*(groups->groupNames[nj]));
kk++;
}
{
nTCP_ = 0;
}
- if (etc_ == etcNOSEHOOVER)
+ if (etc_ == TemperatureCoupling::NoseHoover)
{
if (bNHC_trotter_)
{
{
mde_n_ = 2 * nTC_;
}
- if (epc_ == epcMTTK)
+ if (epc_ == PressureCoupling::Mttk)
{
mdeb_n_ = 2 * nNHC_ * nTCP_;
}
}
int allocated = 0;
- if (etc_ == etcNOSEHOOVER)
+ if (etc_ == TemperatureCoupling::NoseHoover)
{
if (bPrintNHChains_)
{
}
}
}
- else if (etc_ == etcBERENDSEN || etc_ == etcYES || etc_ == etcVRESCALE)
+ else if (etc_ == TemperatureCoupling::Berendsen || etc_ == TemperatureCoupling::Yes
+ || etc_ == TemperatureCoupling::VRescale)
{
for (i = 0; (i < nTC_); i++)
{
}
sfree(grpnms);
- nU_ = groups->groups[SimulationAtomGroupType::Acceleration].size();
- snew(tmp_v_, nU_);
- if (nU_ > 1)
- {
- snew(grpnms, 3 * nU_);
- for (i = 0; (i < nU_); i++)
- {
- ni = groups->groups[SimulationAtomGroupType::Acceleration][i];
- sprintf(buf, "Ux-%s", *(groups->groupNames[ni]));
- grpnms[3 * i + XX] = gmx_strdup(buf);
- sprintf(buf, "Uy-%s", *(groups->groupNames[ni]));
- grpnms[3 * i + YY] = gmx_strdup(buf);
- sprintf(buf, "Uz-%s", *(groups->groupNames[ni]));
- grpnms[3 * i + ZZ] = gmx_strdup(buf);
- }
- iu_ = get_ebin_space(ebin_, 3 * nU_, grpnms, unit_vel);
- for (i = 0; i < 3 * nU_; i++)
- {
- sfree(grpnms[i]);
- }
- sfree(grpnms);
- }
-
/* Note that fp_ene should be valid on the master rank and null otherwise */
if (fp_ene != nullptr && startingBehavior != StartingBehavior::RestartWithAppending)
{
{
title = gmx::formatString("%s and %s", dhdl, deltag);
label_x = gmx::formatString("Time (ps)");
- label_y = gmx::formatString("%s and %s (%s %s)", dhdl, deltag, unit_energy,
- "[\\8l\\4]\\S-1\\N");
+ label_y = gmx::formatString(
+ "%s and %s (%s %s)", dhdl, deltag, unit_energy, "[\\8l\\4]\\S-1\\N");
}
fp = gmx_fio_fopen(filename, "w+");
xvgr_header(fp, title.c_str(), label_x, label_y, exvggtXNY, oenv);
{
print_lambda_vector(fep, fep->init_fep_state, true, false, lambda_vec_str);
print_lambda_vector(fep, fep->init_fep_state, true, true, lambda_name_str);
- buf += gmx::formatString("%s %d: %s = %s", lambdastate, fep->init_fep_state,
- lambda_name_str, lambda_vec_str);
+ buf += gmx::formatString(
+ "%s %d: %s = %s", lambdastate, fep->init_fep_state, lambda_name_str, lambda_vec_str);
}
}
xvgr_subtitle(fp, buf.c_str(), oenv);
}
nsetsextend = nsets;
- if ((ir->epc != epcNO) && (fep->n_lambda > 0) && (fep->init_lambda < 0))
+ if ((ir->epc != PressureCoupling::No) && (fep->n_lambda > 0) && (fep->init_lambda < 0))
{
nsetsextend += 1; /* for PV term, other terms possible if required for
the reduced potential (only needed with foreign
tmp = (pres[ZZ][ZZ] - (pres[XX][XX] + pres[YY][YY]) * 0.5) * box[ZZ][ZZ];
add_ebin(ebin_, isurft_, 1, &tmp, bSum);
}
- if (epc_ == epcPARRINELLORAHMAN || epc_ == epcMTTK)
+ if (epc_ == PressureCoupling::ParrinelloRahman || epc_ == PressureCoupling::Mttk)
{
tmp6[0] = ptCouplingArrays.boxv[XX][XX];
tmp6[1] = ptCouplingArrays.boxv[YY][YY];
}
add_ebin(ebin_, itemp_, nTC_, tmp_r_, bSum);
- if (etc_ == etcNOSEHOOVER)
+ if (etc_ == TemperatureCoupling::NoseHoover)
{
/* whether to print Nose-Hoover chains: */
if (bPrintNHChains_)
}
}
}
- else if (etc_ == etcBERENDSEN || etc_ == etcYES || etc_ == etcVRESCALE)
+ else if (etc_ == TemperatureCoupling::Berendsen || etc_ == TemperatureCoupling::Yes
+ || etc_ == TemperatureCoupling::VRescale)
{
for (int i = 0; (i < nTC_); i++)
{
}
}
- if (ekind && nU_ > 1)
- {
- for (int i = 0; (i < nU_); i++)
- {
- copy_rvec(ekind->grpstat[i].u, tmp_v_[i]);
- }
- add_ebin(ebin_, iu_, 3 * nU_, tmp_v_[0], bSum);
- }
-
ebin_increase_count(1, ebin_, bSum);
// BAR + thermodynamic integration values
{
fprintf(fp_dhdl_, " %#.8g", dE_[i]);
}
- if (bDynBox_ && bDiagPres_ && (epc_ != epcNO) && foreignTerms.numLambdas() > 0
- && (fep->init_lambda < 0))
+ if (bDynBox_ && bDiagPres_ && (epc_ != PressureCoupling::No)
+ && foreignTerms.numLambdas() > 0 && (fep->init_lambda < 0))
{
fprintf(fp_dhdl_, " %#.8g", pv); /* PV term only needed when
there are alternate state
}
store_energy = enerd->term[F_ETOT];
/* store_dh is dE */
- mde_delta_h_coll_add_dh(dhc_, static_cast<double>(fep_state), store_energy, pv,
- store_dhdl, dE_ + fep->lambda_start_n, time);
+ mde_delta_h_coll_add_dh(
+ dhc_, static_cast<double>(fep_state), store_energy, pv, store_dhdl, dE_ + fep->lambda_start_n, time);
}
}
fprintf(log,
" %12s %12s\n"
" %12s %12.5f\n\n",
- "Step", "Time", gmx_step_str(steps, buf), time);
+ "Step",
+ "Time",
+ gmx_step_str(steps, buf),
+ time);
}
void EnergyOutput::printStepToEnergyFile(ener_file* fp_ene,
}
}
-void EnergyOutput::printAnnealingTemperatures(FILE* log, const SimulationGroups* groups, t_grpopts* opts)
+void EnergyOutput::printAnnealingTemperatures(FILE* log, const SimulationGroups* groups, const t_grpopts* opts)
{
if (log)
{
{
if (opts->annealing[i] != eannNO)
{
- fprintf(log, "Current ref_t for group %s: %8.1f\n",
+ fprintf(log,
+ "Current ref_t for group %s: %8.1f\n",
*(groups->groupNames[groups->groups[SimulationAtomGroupType::TemperatureCoupling][i]]),
opts->ref_t[i]);
}
fprintf(log, "\t<==== A V E R A G E S ====>\n");
fprintf(log, "\t<== ############### ======>\n\n");
- fprintf(log, "\tStatistics over %s steps using %s frames\n",
- gmx_step_str(ebin_->nsteps_sim, buf1), gmx_step_str(ebin_->nsum_sim, buf2));
+ fprintf(log,
+ "\tStatistics over %s steps using %s frames\n",
+ gmx_step_str(ebin_->nsteps_sim, buf1),
+ gmx_step_str(ebin_->nsum_sim, buf2));
fprintf(log, "\n");
fprintf(log, " Energies (%s)\n", unit_energy);
int nj = groups->groups[SimulationAtomGroupType::EnergyOutput][j];
int padding =
14 - (strlen(*(groups->groupNames[ni])) + strlen(*(groups->groupNames[nj])));
- fprintf(log, "%*s%s-%s", padding, "", *(groups->groupNames[ni]),
- *(groups->groupNames[nj]));
+ fprintf(log, "%*s%s-%s", padding, "", *(groups->groupNames[ni]), *(groups->groupNames[nj]));
pr_ebin(log, ebin_, igrp_[n], nEc_, nEc_, eprAVER, false);
n++;
}
pr_ebin(log, ebin_, itemp_, nTC_, 4, eprAVER, true);
fprintf(log, "\n");
}
- if (nU_ > 1)
- {
- fprintf(log, "%15s %12s %12s %12s\n", "Group", "Ux", "Uy", "Uz");
- for (int i = 0; (i < nU_); i++)
- {
- int ni = groups->groups[SimulationAtomGroupType::Acceleration][i];
- fprintf(log, "%15s", *groups->groupNames[ni]);
- pr_ebin(log, ebin_, iu_ + 3 * i, 3, 3, eprAVER, false);
- }
- fprintf(log, "\n");
- }
}
}
gmx_fatal(FARGS,
"Mismatch between number of energies in run input (%u) and checkpoint file (%zu "
"or %zu).",
- nener, enerhist.ener_sum.size(), enerhist.ener_sum_sim.size());
+ nener,
+ enerhist.ener_sum.size(),
+ enerhist.ener_sum_sim.size());
}
ebin_->nsteps = enerhist.nsteps;
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
* \param[in] opts Atom temperature coupling groups options
* (annealing is done by groups).
*/
- static void printAnnealingTemperatures(FILE* log, const SimulationGroups* groups, t_grpopts* opts);
+ static void printAnnealingTemperatures(FILE* log, const SimulationGroups* groups, const t_grpopts* opts);
/*! \brief Prints average values to log file.
*
bool bMTTK_ = false;
//! Temperature control scheme
- int etc_ = 0;
+ TemperatureCoupling etc_ = TemperatureCoupling::No;
//! Which of the main energy terms should be printed
bool bEner_[F_NRE] = { false };
int isurft_ = 0;
//! Pressure control scheme
- int epc_ = 0;
+ PressureCoupling epc_ = PressureCoupling::No;
//! Index for velocity of the box borders
int ipc_ = 0;
//! Index for scalling factor of MTTK
int itcb_ = 0;
- //! Number of acceleration groups
- int nU_ = 0;
- //! Index for group velocities
- int iu_ = 0;
-
//! Array to accumulate values during update
real* tmp_r_ = nullptr;
//! Array to accumulate values during update
/* then increment weights (uses count) */
pks = 0.0;
- GenerateWeightedGibbsProbabilities(weighted_lamee, p_k, &pks, nlim, dfhist->wl_histo,
- dfhist->wl_delta);
+ GenerateWeightedGibbsProbabilities(
+ weighted_lamee, p_k, &pks, nlim, dfhist->wl_histo, dfhist->wl_delta);
for (i = 0; i < nlim; i++)
{
"Something wrong in choosing new lambda state with a Gibbs move -- "
"probably underflow in weight determination.\nDenominator is: "
"%3d%17.10e\n i dE numerator weights\n",
- 0, pks);
+ 0,
+ pks);
for (ifep = minfep; ifep <= maxfep; ifep++)
{
- loc += sprintf(&errorstr[loc], "%3d %17.10e%17.10e%17.10e\n", ifep,
- weighted_lamee[ifep], p_k[ifep], dfhist->sum_weights[ifep]);
+ loc += sprintf(&errorstr[loc],
+ "%3d %17.10e%17.10e%17.10e\n",
+ ifep,
+ weighted_lamee[ifep],
+ p_k[ifep],
+ dfhist->sum_weights[ifep]);
}
gmx_fatal(FARGS, "%s", errorstr);
}
}
if (expand->elamstats == elamstatsMINVAR)
{
- fprintf(outfile, " %10.5f %10.5f %10.5f %10.5f", dfhist->sum_weights[ifep],
- dfhist->sum_dg[ifep], dg, dv);
+ fprintf(outfile,
+ " %10.5f %10.5f %10.5f %10.5f",
+ dfhist->sum_weights[ifep],
+ dfhist->sum_dg[ifep],
+ dg,
+ dv);
}
else
{
}
int ExpandedEnsembleDynamics(FILE* log,
- const t_inputrec* ir,
+ t_inputrec* ir,
const gmx_enerdata_t* enerd,
t_state* state,
t_extmass* MassQ,
{
if (log)
{
- fprintf(log, "\nStep %" PRId64 ": Weights have equilibrated, using criteria: %s\n",
- step, elmceq_names[expand->elmceq]);
+ fprintf(log,
+ "\nStep %" PRId64 ": Weights have equilibrated, using criteria: %s\n",
+ step,
+ elmceq_names[expand->elmceq]);
}
}
- lamnew = ChooseNewLambda(nlim, expand, dfhist, fep_state, weighted_lamee, p_k,
- ir->expandedvals->lmc_seed, step);
+ lamnew = ChooseNewLambda(
+ nlim, expand, dfhist, fep_state, weighted_lamee, p_k, ir->expandedvals->lmc_seed, step);
/* if using simulated tempering, we need to adjust the temperatures */
if (ir->bSimTemp && (lamnew != fep_state)) /* only need to change the temperatures if we change the state */
{
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2021, 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.
void init_expanded_ensemble(gmx_bool bStateFromCP, const t_inputrec* ir, df_history_t* dfhist);
int ExpandedEnsembleDynamics(FILE* log,
- const t_inputrec* ir,
+ t_inputrec* ir,
const gmx_enerdata_t* enerd,
t_state* state,
t_extmass* MassQ,
* the forces in the normal, single forceWithVirial->force_ array.
*/
const rvec* x = as_rvec_array(coordinates.data());
- ewald_LRcorrection(md->homenr, cr, nthreads, t, *fr, *ir, md->chargeA,
- md->chargeB, (md->nChargePerturbed != 0), x, box, mu_tot,
+ ewald_LRcorrection(md->homenr,
+ cr,
+ nthreads,
+ t,
+ *fr,
+ *ir,
+ md->chargeA,
+ md->chargeB,
+ (md->nChargePerturbed != 0),
+ x,
+ box,
+ mu_tot,
as_rvec_array(forceWithVirial->force_.data()),
- &ewc_t.Vcorr_q, lambda[efptCOUL], &ewc_t.dvdl[efptCOUL]);
+ &ewc_t.Vcorr_q,
+ lambda[efptCOUL],
+ &ewc_t.dvdl[efptCOUL]);
}
GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
}
status = gmx_pme_do(
fr->pmedata,
gmx::constArrayRefFromArray(coordinates.data(), md->homenr - fr->n_tpi),
- forceWithVirial->force_, md->chargeA, md->chargeB, md->sqrt_c6A,
- md->sqrt_c6B, md->sigmaA, md->sigmaB, box, cr,
+ forceWithVirial->force_,
+ md->chargeA,
+ md->chargeB,
+ md->sqrt_c6A,
+ md->sqrt_c6B,
+ md->sigmaA,
+ md->sigmaB,
+ box,
+ cr,
DOMAINDECOMP(cr) ? dd_pme_maxshift_x(cr->dd) : 0,
- DOMAINDECOMP(cr) ? dd_pme_maxshift_y(cr->dd) : 0, nrnb, wcycle,
- ewaldOutput.vir_q, ewaldOutput.vir_lj, &Vlr_q, &Vlr_lj,
- lambda[efptCOUL], lambda[efptVDW], &ewaldOutput.dvdl[efptCOUL],
- &ewaldOutput.dvdl[efptVDW], stepWork);
+ DOMAINDECOMP(cr) ? dd_pme_maxshift_y(cr->dd) : 0,
+ nrnb,
+ wcycle,
+ ewaldOutput.vir_q,
+ ewaldOutput.vir_lj,
+ &Vlr_q,
+ &Vlr_lj,
+ lambda[efptCOUL],
+ lambda[efptVDW],
+ &ewaldOutput.dvdl[efptCOUL],
+ &ewaldOutput.dvdl[efptVDW],
+ stepWork);
wallcycle_stop(wcycle, ewcPMEMESH);
if (status != 0)
{
* with the PME grid potential of the other charges.
*/
gmx_pme_calc_energy(
- fr->pmedata, coordinates.subArray(md->homenr - fr->n_tpi, fr->n_tpi),
+ fr->pmedata,
+ coordinates.subArray(md->homenr - fr->n_tpi, fr->n_tpi),
gmx::arrayRefFromArray(md->chargeA + md->homenr - fr->n_tpi, fr->n_tpi),
&Vlr_q);
}
if (fr->ic->eeltype == eelEWALD)
{
const rvec* x = as_rvec_array(coordinates.data());
- Vlr_q = do_ewald(ir, x, as_rvec_array(forceWithVirial->force_.data()), md->chargeA,
- md->chargeB, box, cr, md->homenr, ewaldOutput.vir_q, fr->ic->ewaldcoeff_q,
- lambda[efptCOUL], &ewaldOutput.dvdl[efptCOUL], fr->ewald_table);
+ Vlr_q = do_ewald(ir,
+ x,
+ as_rvec_array(forceWithVirial->force_.data()),
+ md->chargeA,
+ md->chargeB,
+ box,
+ cr,
+ md->homenr,
+ ewaldOutput.vir_q,
+ fr->ic->ewaldcoeff_q,
+ lambda[efptCOUL],
+ &ewaldOutput.dvdl[efptCOUL],
+ fr->ewald_table);
}
/* Note that with separate PME nodes we get the real energies later */
if (debug)
{
- fprintf(debug, "Vlr_q = %g, Vcorr_q = %g, Vlr_corr_q = %g\n", Vlr_q,
- ewaldOutput.Vcorr_q, enerd->term[F_COUL_RECIP]);
+ fprintf(debug,
+ "Vlr_q = %g, Vcorr_q = %g, Vlr_corr_q = %g\n",
+ Vlr_q,
+ ewaldOutput.Vcorr_q,
+ enerd->term[F_COUL_RECIP]);
pr_rvecs(debug, 0, "vir_el_recip after corr", ewaldOutput.vir_q, DIM);
- fprintf(debug, "Vlr_lj: %g, Vcorr_lj = %g, Vlr_corr_lj = %g\n", Vlr_lj,
- ewaldOutput.Vcorr_lj, enerd->term[F_LJ_RECIP]);
+ fprintf(debug,
+ "Vlr_lj: %g, Vcorr_lj = %g, Vlr_corr_lj = %g\n",
+ Vlr_lj,
+ ewaldOutput.Vcorr_lj,
+ enerd->term[F_LJ_RECIP]);
pr_rvecs(debug, 0, "vir_lj_recip after corr", ewaldOutput.vir_lj, DIM);
}
}
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013-2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2013-2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/mdtypes/interaction_const.h"
#include "gromacs/mdtypes/md_enums.h"
#include "gromacs/mdtypes/multipletimestepping.h"
+#include "gromacs/mdtypes/nblist.h"
#include "gromacs/nbnxm/nbnxm.h"
#include "gromacs/pbcutil/ishift.h"
#include "gromacs/pbcutil/pbc.h"
int& atomInfo = cginfo[molculeOffsetInBlock + a];
/* Store the energy group in cginfo */
- int gid = getGroupType(mtop->groups, SimulationAtomGroupType::EnergyOutput,
+ int gid = getGroupType(mtop->groups,
+ SimulationAtomGroupType::EnergyOutput,
a_offset + molculeOffsetInBlock + a);
SET_CGINFO_GID(atomInfo, gid);
"Tabulated interaction of type '%s%s%s' with index %d cannot be used "
"because no table file whose name matched '%s' was passed via the "
"gmx mdrun -tableb command-line option.",
- interaction_function[ftype1].longname, isPlural ? "' or '" : "",
- isPlural ? interaction_function[ftype2].longname : "", i,
+ interaction_function[ftype1].longname,
+ isPlural ? "' or '" : "",
+ isPlural ? interaction_function[ftype2].longname : "",
+ i,
patternToFind.c_str());
}
}
{
if (fp)
{
- fprintf(fp, "Using the Ewald3DC correction for systems with a slab geometry%s.\n",
+ fprintf(fp,
+ "Using the Ewald3DC correction for systems with a slab geometry%s.\n",
systemHasNetCharge ? " and net charge" : "");
}
please_cite(fp, "In-Chul99a");
{
if (EEL_PME_EWALD(ic->eeltype) || EVDW_PME(ic->vdwtype))
{
- init_ewald_f_table(*ic, rlist, tableExtensionLength, ic->coulombEwaldTables.get(),
- ic->vdwEwaldTables.get());
+ init_ewald_f_table(
+ *ic, rlist, tableExtensionLength, ic->coulombEwaldTables.get(), ic->vdwEwaldTables.get());
if (fp != nullptr)
{
- fprintf(fp, "Initialized non-bonded Ewald tables, spacing: %.2e size: %zu\n\n",
- 1 / ic->coulombEwaldTables->scale, ic->coulombEwaldTables->tableF.size());
+ fprintf(fp,
+ "Initialized non-bonded Ewald tables, spacing: %.2e size: %zu\n\n",
+ 1 / ic->coulombEwaldTables->scale,
+ ic->coulombEwaldTables->tableF.size());
}
}
}
if (fr->useMts)
{
- gmx::assertMtsRequirements(*ir);
+ GMX_ASSERT(gmx::checkMtsRequirements(*ir).empty(),
+ "All MTS requirements should be met here");
}
const bool haveDirectVirialContributionsFast =
}
if (fp)
{
- fprintf(fp, "Using %s Lennard-Jones, switch between %g and %g nm\n",
- (ic->eeltype == eelSWITCH) ? "switched" : "shifted", ic->rvdw_switch, ic->rvdw);
+ fprintf(fp,
+ "Using %s Lennard-Jones, switch between %g and %g nm\n",
+ (ic->eeltype == eelSWITCH) ? "switched" : "shifted",
+ ic->rvdw_switch,
+ ic->rvdw);
}
}
interactionSelection.set(static_cast<int>(ListedForces::InteractionGroup::Rest));
isFirstLevel = false;
}
- fr->listedForces.emplace_back(
- mtop->ffparams, mtop->groups.groups[SimulationAtomGroupType::EnergyOutput].size(),
- gmx_omp_nthreads_get(emntBonded), interactionSelection, fp);
+ fr->listedForces.emplace_back(mtop->ffparams,
+ mtop->groups.groups[SimulationAtomGroupType::EnergyOutput].size(),
+ gmx_omp_nthreads_get(emntBonded),
+ interactionSelection,
+ fp);
}
}
else
{
// Add one ListedForces object with all listed interactions
- fr->listedForces.emplace_back(
- mtop->ffparams, mtop->groups.groups[SimulationAtomGroupType::EnergyOutput].size(),
- gmx_omp_nthreads_get(emntBonded), ListedForces::interactionSelectionAll(), fp);
+ fr->listedForces.emplace_back(mtop->ffparams,
+ mtop->groups.groups[SimulationAtomGroupType::EnergyOutput].size(),
+ gmx_omp_nthreads_get(emntBonded),
+ ListedForces::interactionSelectionAll(),
+ fp);
}
// QM/MM initialization if requested
std::fill(std::begin(lambdas), std::end(lambdas), fepvals.init_lambda);
return lambdas;
}
- const double globalLambda = currentGlobalLambda(step, fepvals.delta_lambda, fepvals.init_fep_state,
- fepvals.init_lambda, fepvals.n_lambda);
+ const double globalLambda = currentGlobalLambda(
+ step, fepvals.delta_lambda, fepvals.init_fep_state, fepvals.init_lambda, fepvals.n_lambda);
return interpolatedLambdas(globalLambda, fepvals.all_lambda, fepvals.n_lambda);
}
if (!bOMP)
{
- gmx_warning("%s=%d is set, but %s is compiled without OpenMP!", modth_env_var[m], nth,
+ gmx_warning("%s=%d is set, but %s is compiled without OpenMP!",
+ modth_env_var[m],
+ nth,
gmx::getProgramContext().displayName());
}
gmx_warning(
"%s=%d is set, the default number of threads also "
"needs to be set with OMP_NUM_THREADS!",
- modth_env_var[m], nth);
+ modth_env_var[m],
+ nth);
}
/* only babble if we are really overriding with a different value */
GMX_LOG(mdlog.warning)
.asParagraph()
.appendTextFormatted("%s=%d set, overriding the default number of %s threads",
- modth_env_var[m], nth, mod_name[m]);
+ modth_env_var[m],
+ nth,
+ mod_name[m]);
}
}
else
"Environment variable OMP_NUM_THREADS (%d) and the number of threads "
"requested on the command line (%d) have different values. Either omit one, "
"or set them both to the same value.",
- nt_omp, *nthreads_omp);
+ nt_omp,
+ *nthreads_omp);
}
/* Setting the number of OpenMP threads. */
if (nth_max == nth_min)
{
GMX_LOG(mdlog.warning)
- .appendTextFormatted("Using %d OpenMP thread%s %s", nth_min, nth_min > 1 ? "s" : "",
+ .appendTextFormatted("Using %d OpenMP thread%s %s",
+ nth_min,
+ nth_min > 1 ? "s" : "",
cr->nnodes > 1 ? mpi_str : "");
}
else
if (nth_pme_max == nth_pme_min)
{
GMX_LOG(mdlog.warning)
- .appendTextFormatted("Using %d OpenMP thread%s %s for PME", nth_pme_min,
- nth_pme_min > 1 ? "s" : "", cr->nnodes > 1 ? mpi_str : "");
+ .appendTextFormatted("Using %d OpenMP thread%s %s for PME",
+ nth_pme_min,
+ nth_pme_min > 1 ? "s" : "",
+ cr->nnodes > 1 ? mpi_str : "");
}
else
{
GMX_LOG(mdlog.warning)
- .appendTextFormatted("Using %d - %d OpenMP threads %s for PME", nth_pme_min,
- nth_pme_max, mpi_str);
+ .appendTextFormatted(
+ "Using %d - %d OpenMP threads %s for PME", nth_pme_min, nth_pme_max, mpi_str);
}
}
GMX_LOG(mdlog.warning);
bSepPME = (thisRankHasDuty(cr, DUTY_PP) != thisRankHasDuty(cr, DUTY_PME));
- manage_number_of_openmp_threads(mdlog, cr, bOMP, nthreads_hw_avail, omp_nthreads_req,
- omp_nthreads_pme_req, bThisNodePMEOnly, numRanksOnThisNode, bSepPME);
+ manage_number_of_openmp_threads(mdlog,
+ cr,
+ bOMP,
+ nthreads_hw_avail,
+ omp_nthreads_req,
+ omp_nthreads_pme_req,
+ bThisNodePMEOnly,
+ numRanksOnThisNode,
+ bSepPME);
#if GMX_THREAD_MPI
/* Non-master threads have to wait for the OpenMP management to be
* done, so that code elsewhere that uses OpenMP can be certain
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2020, by the GROMACS development team, led by
+ * Copyright (c) 2020,2021, 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.
#ifndef GMX_MDLIB_GPUFORCEREDUCTION_H
#define GMX_MDLIB_GPUFORCEREDUCTION_H
+#include <memory>
+
#include "gromacs/gpu_utils/devicebuffer_datatype.h"
#include "gromacs/math/vectypes.h"
#include "gromacs/timing/wallcycle.h"
#include "gromacs/utility/arrayref.h"
-#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/fixedcapacityvector.h"
class GpuEventSynchronizer;
private:
class Impl;
- gmx::PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
cellInfo_.cell = cell.data();
wallcycle_start_nocount(wcycle_, ewcLAUNCH_GPU);
- reallocateDeviceBuffer(&cellInfo_.d_cell, numAtoms_, &cellInfo_.cellSize,
- &cellInfo_.cellSizeAlloc, deviceContext_);
- copyToDeviceBuffer(&cellInfo_.d_cell, &(cellInfo_.cell[atomStart]), 0, numAtoms_, deviceStream_,
- GpuApiCallBehavior::Async, nullptr);
+ reallocateDeviceBuffer(
+ &cellInfo_.d_cell, numAtoms_, &cellInfo_.cellSize, &cellInfo_.cellSizeAlloc, deviceContext_);
+ copyToDeviceBuffer(&cellInfo_.d_cell,
+ &(cellInfo_.cell[atomStart]),
+ 0,
+ numAtoms_,
+ deviceStream_,
+ GpuApiCallBehavior::Async,
+ nullptr);
wallcycle_stop(wcycle_, ewcLAUNCH_GPU);
dependencyList_.clear();
? (accumulate_ ? reduceKernel<true, true> : reduceKernel<true, false>)
: (accumulate_ ? reduceKernel<false, true> : reduceKernel<false, false>);
- const auto kernelArgs = prepareGpuKernelArguments(kernelFn, config, &d_nbnxmForce, &d_rvecForceToAdd,
- &baseForce_, &cellInfo_.d_cell, &numAtoms_);
+ const auto kernelArgs = prepareGpuKernelArguments(
+ kernelFn, config, &d_nbnxmForce, &d_rvecForceToAdd, &baseForce_, &cellInfo_.d_cell, &numAtoms_);
launchGpuKernel(kernelFn, config, deviceStream_, nullptr, "Force Reduction", kernelArgs);
{
h_lambdas_[i] = tcstat[i].lambda;
}
- copyToDeviceBuffer(&d_lambdas_, h_lambdas_.data(), 0, numTempScaleValues_,
- deviceStream_, GpuApiCallBehavior::Async, nullptr);
+ copyToDeviceBuffer(&d_lambdas_,
+ h_lambdas_.data(),
+ 0,
+ numTempScaleValues_,
+ deviceStream_,
+ GpuApiCallBehavior::Async,
+ nullptr);
}
VelocityScalingType prVelocityScalingType = VelocityScalingType::None;
if (doParrinelloRahman)
kernelPtr = selectLeapFrogKernelPtr(doTemperatureScaling, numTempScaleValues_, prVelocityScalingType);
}
- const auto kernelArgs = prepareGpuKernelArguments(
- kernelPtr, kernelLaunchConfig_, &numAtoms_, &d_x, &d_xp, &d_v, &d_f, &d_inverseMasses_,
- &dt, &d_lambdas_, &d_tempScaleGroups_, &prVelocityScalingMatrixDiagonal_);
+ const auto kernelArgs = prepareGpuKernelArguments(kernelPtr,
+ kernelLaunchConfig_,
+ &numAtoms_,
+ &d_x,
+ &d_xp,
+ &d_v,
+ &d_f,
+ &d_inverseMasses_,
+ &dt,
+ &d_lambdas_,
+ &d_tempScaleGroups_,
+ &prVelocityScalingMatrixDiagonal_);
launchGpuKernel(kernelPtr, kernelLaunchConfig_, deviceStream_, nullptr, "leapfrog_kernel", kernelArgs);
return;
numTempScaleValues_ = numTempScaleValues;
- reallocateDeviceBuffer(&d_inverseMasses_, numAtoms_, &numInverseMasses_,
- &numInverseMassesAlloc_, deviceContext_);
- copyToDeviceBuffer(&d_inverseMasses_, (float*)inverseMasses, 0, numAtoms_, deviceStream_,
- GpuApiCallBehavior::Sync, nullptr);
+ reallocateDeviceBuffer(
+ &d_inverseMasses_, numAtoms_, &numInverseMasses_, &numInverseMassesAlloc_, deviceContext_);
+ copyToDeviceBuffer(
+ &d_inverseMasses_, (float*)inverseMasses, 0, numAtoms_, deviceStream_, GpuApiCallBehavior::Sync, nullptr);
// Temperature scale group map only used if there are more then one group
if (numTempScaleValues > 1)
{
- reallocateDeviceBuffer(&d_tempScaleGroups_, numAtoms_, &numTempScaleGroups_,
- &numTempScaleGroupsAlloc_, deviceContext_);
- copyToDeviceBuffer(&d_tempScaleGroups_, tempScaleGroups, 0, numAtoms_, deviceStream_,
- GpuApiCallBehavior::Sync, nullptr);
+ reallocateDeviceBuffer(
+ &d_tempScaleGroups_, numAtoms_, &numTempScaleGroups_, &numTempScaleGroupsAlloc_, deviceContext_);
+ copyToDeviceBuffer(
+ &d_tempScaleGroups_, tempScaleGroups, 0, numAtoms_, deviceStream_, GpuApiCallBehavior::Sync, nullptr);
}
// If the temperature coupling is enabled, we need to make space for scaling factors
if (numTempScaleValues_ > 0)
{
h_lambdas_.resize(numTempScaleValues);
- reallocateDeviceBuffer(&d_lambdas_, numTempScaleValues_, &numLambdas_, &numLambdasAlloc_,
- deviceContext_);
+ reallocateDeviceBuffer(
+ &d_lambdas_, numTempScaleValues_, &numLambdas_, &numLambdasAlloc_, deviceContext_);
}
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
# include "gromacs/gpu_utils/gputraits_sycl.h"
#endif
+#include <memory>
+
#include "gromacs/gpu_utils/hostallocator.h"
#include "gromacs/pbcutil/pbc.h"
#include "gromacs/pbcutil/pbc_aiuc.h"
#include "gromacs/utility/arrayref.h"
-#include "gromacs/utility/classhelpers.h"
class DeviceContext;
class DeviceStream;
[&](auto tempScalingType_, auto prScalingType_) {
return launchLeapFrogKernel<tempScalingType_, prScalingType_>(std::forward<Args>(args)...);
},
- tempScalingType, prVelocityScalingType);
+ tempScalingType,
+ prVelocityScalingType);
}
void LeapFrogGpu::integrate(DeviceBuffer<float3> d_x,
&& prVelocityScalingMatrix[XX][ZZ] == 0 && prVelocityScalingMatrix[YY][ZZ] == 0,
"Fully anisotropic Parrinello-Rahman pressure coupling is not yet supported "
"in GPU version of Leap-Frog integrator.");
- prVelocityScalingMatrixDiagonal_ =
- dtPressureCouple
- * float3{ prVelocityScalingMatrix[XX][XX], prVelocityScalingMatrix[YY][YY],
- prVelocityScalingMatrix[ZZ][ZZ] };
+ prVelocityScalingMatrixDiagonal_ = dtPressureCouple
+ * float3{ prVelocityScalingMatrix[XX][XX],
+ prVelocityScalingMatrix[YY][YY],
+ prVelocityScalingMatrix[ZZ][ZZ] };
}
- launchLeapFrogKernel(tempVelocityScalingType, prVelocityScalingType, deviceStream_, numAtoms_,
- d_x, d_xp, d_v, d_f, d_inverseMasses_, dt, d_lambdas_, d_tempScaleGroups_,
+ launchLeapFrogKernel(tempVelocityScalingType,
+ prVelocityScalingType,
+ deviceStream_,
+ numAtoms_,
+ d_x,
+ d_xp,
+ d_v,
+ d_f,
+ d_inverseMasses_,
+ dt,
+ d_lambdas_,
+ d_tempScaleGroups_,
prVelocityScalingMatrixDiagonal_);
}
numAtoms_ = numAtoms;
numTempScaleValues_ = numTempScaleValues;
- reallocateDeviceBuffer(&d_inverseMasses_, numAtoms_, &numInverseMasses_,
- &numInverseMassesAlloc_, deviceContext_);
- copyToDeviceBuffer(&d_inverseMasses_, inverseMasses, 0, numAtoms_, deviceStream_,
- GpuApiCallBehavior::Sync, nullptr);
+ reallocateDeviceBuffer(
+ &d_inverseMasses_, numAtoms_, &numInverseMasses_, &numInverseMassesAlloc_, deviceContext_);
+ copyToDeviceBuffer(
+ &d_inverseMasses_, inverseMasses, 0, numAtoms_, deviceStream_, GpuApiCallBehavior::Sync, nullptr);
// Temperature scale group map only used if there are more then one group
if (numTempScaleValues_ > 1)
{
- reallocateDeviceBuffer(&d_tempScaleGroups_, numAtoms_, &numTempScaleGroups_,
- &numTempScaleGroupsAlloc_, deviceContext_);
- copyToDeviceBuffer(&d_tempScaleGroups_, tempScaleGroups, 0, numAtoms_, deviceStream_,
- GpuApiCallBehavior::Sync, nullptr);
+ reallocateDeviceBuffer(
+ &d_tempScaleGroups_, numAtoms_, &numTempScaleGroups_, &numTempScaleGroupsAlloc_, deviceContext_);
+ copyToDeviceBuffer(
+ &d_tempScaleGroups_, tempScaleGroups, 0, numAtoms_, deviceStream_, GpuApiCallBehavior::Sync, nullptr);
}
// If the temperature coupling is enabled, we need to make space for scaling factors
if (numTempScaleValues_ > 0)
{
- reallocateDeviceBuffer(&d_lambdas_, numTempScaleValues_, &numLambdas_, &numLambdasAlloc_,
- deviceContext_);
+ reallocateDeviceBuffer(
+ &d_lambdas_, numTempScaleValues_, &numLambdas_, &numLambdasAlloc_, deviceContext_);
}
}
/* Compute normalized x i-j vectors, store in r.
* Compute the inner product of r and xp i-j and store in rhs1.
*/
- calc_dr_x_f_simd(b0, b1, atoms, x, f, blc.data(), pbc_simd, as_rvec_array(r.data()),
- rhs1.data(), sol.data());
+ calc_dr_x_f_simd(
+ b0, b1, atoms, x, f, blc.data(), pbc_simd, as_rvec_array(r.data()), rhs1.data(), sol.data());
#else // GMX_SIMD_HAVE_REAL
/* When constraining forces, we should not use mass weighting,
* so we pass invmass=NULL, which results in the use of 1 for all atoms.
*/
- lincs_update_atoms(lincsd, th, 1.0, sol, r, (econq != ConstraintVariable::Force) ? invmass : nullptr,
+ lincs_update_atoms(lincsd,
+ th,
+ 1.0,
+ sol,
+ r,
+ (econq != ConstraintVariable::Force) ? invmass : nullptr,
as_rvec_array(fp.data()));
if (bCalcDHDL)
/* Compute normalized x i-j vectors, store in r.
* Compute the inner product of r and xp i-j and store in rhs1.
*/
- calc_dr_x_xp_simd(b0, b1, atoms, x, xp, bllen.data(), blc.data(), pbc_simd,
- as_rvec_array(r.data()), rhs1.data(), sol.data());
+ calc_dr_x_xp_simd(
+ b0, b1, atoms, x, xp, bllen.data(), blc.data(), pbc_simd, as_rvec_array(r.data()), rhs1.data(), sol.data());
#else // GMX_SIMD_HAVE_REAL
}
#if GMX_SIMD_HAVE_REAL
- calc_dist_iter_simd(b0, b1, atoms, xp, bllen.data(), blc.data(), pbc_simd, wfac,
- rhs1.data(), sol.data(), bWarn);
+ calc_dist_iter_simd(
+ b0, b1, atoms, xp, bllen.data(), blc.data(), pbc_simd, wfac, rhs1.data(), sol.data(), bWarn);
#else
- calc_dist_iter(b0, b1, atoms, xp, bllen.data(), blc.data(), pbc, wfac, rhs1.data(),
- sol.data(), bWarn);
+ calc_dist_iter(b0, b1, atoms, xp, bllen.data(), blc.data(), pbc, wfac, rhs1.data(), sol.data(), bWarn);
/* 20*ncons flops */
#endif // GMX_SIMD_HAVE_REAL
if (debug)
{
fprintf(debug, "The %d constraints participate in %d triangles\n", li->nc, li->ntriangle);
- fprintf(debug, "There are %d constraint couplings, of which %d in triangles\n", li->ncc,
- li->ncc_triangle);
+ fprintf(debug, "There are %d constraint couplings, of which %d in triangles\n", li->ncc, li->ncc_triangle);
if (li->ntriangle > 0 && li->ntask > 1)
{
fprintf(debug,
li->bTaskDep = (li->ntask > 1 && bMoreThanTwoSeq);
if (debug)
{
- fprintf(debug, "LINCS: using %d threads, tasks are %sdependent\n", li->ntask,
- li->bTaskDep ? "" : "in");
+ fprintf(debug, "LINCS: using %d threads, tasks are %sdependent\n", li->ntask, li->bTaskDep ? "" : "in");
}
if (li->ntask == 1)
{
"%d constraints are involved in constraint triangles,\n"
"will apply an additional matrix expansion of order %d for couplings\n"
"between constraints inside triangles\n",
- li->ncg_triangle, li->nOrder);
+ li->ncg_triangle,
+ li->nOrder);
}
}
if (debug)
{
- fprintf(debug, "Number of constraints is %d, padded %d, couplings %d\n", li->nc_real,
- li->nc, li->ncc);
+ fprintf(debug, "Number of constraints is %d, padded %d, couplings %d\n", li->nc_real, li->nc, li->ncc);
}
if (li->ntask > 1)
real cosine = ::iprod(v0, v1) / (d0 * d1);
if (cosine < wfac)
{
- fprintf(stderr, " %6d %6d %5.1f %8.4f %8.4f %8.4f\n", ddglatnr(dd, i),
- ddglatnr(dd, j), RAD2DEG * std::acos(cosine), d0, d1, bllen[b]);
+ fprintf(stderr,
+ " %6d %6d %5.1f %8.4f %8.4f %8.4f\n",
+ ddglatnr(dd, i),
+ ddglatnr(dd, j),
+ RAD2DEG * std::acos(cosine),
+ d0,
+ d1,
+ bllen[b]);
if (!std::isfinite(d1))
{
gmx_fatal(FARGS, "Bond length not finite.");
{
LincsDeviations deviations = makeLincsDeviations(*lincsd, xprime, pbc);
fprintf(debug, " Rel. Constraint Deviation: RMS MAX between atoms\n");
- fprintf(debug, " Before LINCS %.6f %.6f %6d %6d\n",
+ fprintf(debug,
+ " Before LINCS %.6f %.6f %6d %6d\n",
std::sqrt(deviations.sumSquaredDeviation / deviations.numConstraints),
deviations.maxDeviation,
ddglatnr(cr->dd, lincsd->atoms[deviations.indexOfMaxDeviation].index1),
clear_mat(lincsd->task[th].vir_r_m_dr);
- do_lincs(xPadded, xprimePadded, box, pbc, lincsd, th, invmass, cr, bCalcDHDL,
- ir.LincsWarnAngle, &bWarn, invdt, v, bCalcVir,
+ do_lincs(xPadded,
+ xprimePadded,
+ box,
+ pbc,
+ lincsd,
+ th,
+ invmass,
+ cr,
+ bCalcDHDL,
+ ir.LincsWarnAngle,
+ &bWarn,
+ invdt,
+ v,
+ bCalcVir,
th == 0 ? vir_r_m_dr : lincsd->task[th].vir_r_m_dr);
}
GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
}
if (printDebugOutput)
{
- fprintf(debug, " After LINCS %.6f %.6f %6d %6d\n\n",
+ fprintf(debug,
+ " After LINCS %.6f %.6f %6d %6d\n\n",
std::sqrt(deviations.sumSquaredDeviation / deviations.numConstraints),
deviations.maxDeviation,
ddglatnr(cr->dd, lincsd->atoms[deviations.indexOfMaxDeviation].index1),
", time %g (ps) LINCS WARNING%s\n"
"relative constraint deviation after LINCS:\n"
"rms %.6f, max %.6f (between atoms %d and %d)\n",
- step, ir.init_t + step * ir.delta_t, simMesg.c_str(),
+ step,
+ ir.init_t + step * ir.delta_t,
+ simMesg.c_str(),
std::sqrt(deviations.sumSquaredDeviation / deviations.numConstraints),
deviations.maxDeviation,
ddglatnr(cr->dd, lincsd->atoms[deviations.indexOfMaxDeviation].index1),
ddglatnr(cr->dd, lincsd->atoms[deviations.indexOfMaxDeviation].index2));
- lincs_warning(cr->dd, x, xprime, pbc, lincsd->nc, lincsd->atoms, lincsd->bllen,
- ir.LincsWarnAngle, maxwarn, warncount);
+ lincs_warning(
+ cr->dd, x, xprime, pbc, lincsd->nc, lincsd->atoms, lincsd->bllen, ir.LincsWarnAngle, maxwarn, warncount);
}
bOK = (deviations.maxDeviation < 0.5);
}
{
int th = gmx_omp_get_thread_num();
- do_lincsp(xPadded, xprimePadded, min_proj, pbc, lincsd, th, invmass, econq,
- bCalcDHDL, bCalcVir, th == 0 ? vir_r_m_dr : lincsd->task[th].vir_r_m_dr);
+ do_lincsp(xPadded,
+ xprimePadded,
+ min_proj,
+ pbc,
+ lincsd,
+ th,
+ invmass,
+ econq,
+ bCalcDHDL,
+ bCalcVir,
+ th == 0 ? vir_r_m_dr : lincsd->task[th].vir_r_m_dr);
}
GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
}
const auto kernelArgs =
prepareGpuKernelArguments(kernelPtr, config, &kernelParams_, &d_x, &d_xp, &d_v, &invdt);
- launchGpuKernel(kernelPtr, config, deviceStream_, nullptr,
- "lincs_kernel<updateVelocities, computeVirial>", kernelArgs);
+ launchGpuKernel(kernelPtr,
+ config,
+ deviceStream_,
+ nullptr,
+ "lincs_kernel<updateVelocities, computeVirial>",
+ kernelArgs);
if (computeVirial)
{
// Copy LINCS virial data and add it to the common virial
- copyFromDeviceBuffer(h_virialScaled_.data(), &kernelParams_.d_virialScaled, 0, 6,
- deviceStream_, GpuApiCallBehavior::Sync, nullptr);
+ copyFromDeviceBuffer(h_virialScaled_.data(),
+ &kernelParams_.d_virialScaled,
+ 0,
+ 6,
+ deviceStream_,
+ GpuApiCallBehavior::Sync,
+ nullptr);
// Mapping [XX, XY, XZ, YY, YZ, ZZ] internal format to a tensor object
virialScaled[XX][XX] += h_virialScaled_[0];
numCoupledConstraints[c2] = 0; // To indicate we've been here
counted += 1
+ countCoupled(adjacentAtom.indexOfSecondConstrainedAtom_,
- numCoupledConstraints, atomsAdjacencyList);
+ numCoupledConstraints,
+ atomsAdjacencyList);
}
}
return counted;
"LINCS with constraints on all-bonds, which is not supported for large "
"molecules. When compatible with the force field and integration settings, "
"using constraints on H-bonds only.",
- numCoupledConstraints.at(c), c_threadsPerBlock);
+ numCoupledConstraints.at(c),
+ c_threadsPerBlock);
}
if (currentMapIndex / c_threadsPerBlock
!= (currentMapIndex + numCoupledConstraints.at(c)) / c_threadsPerBlock)
numConstraintsThreadsAlloc_ = kernelParams_.numConstraintsThreads;
- allocateDeviceBuffer(&kernelParams_.d_constraints, kernelParams_.numConstraintsThreads,
- deviceContext_);
+ allocateDeviceBuffer(
+ &kernelParams_.d_constraints, kernelParams_.numConstraintsThreads, deviceContext_);
allocateDeviceBuffer(&kernelParams_.d_constraintsTargetLengths,
- kernelParams_.numConstraintsThreads, deviceContext_);
+ kernelParams_.numConstraintsThreads,
+ deviceContext_);
allocateDeviceBuffer(&kernelParams_.d_coupledConstraintsCounts,
- kernelParams_.numConstraintsThreads, deviceContext_);
+ kernelParams_.numConstraintsThreads,
+ deviceContext_);
allocateDeviceBuffer(&kernelParams_.d_coupledConstraintsIndices,
- maxCoupledConstraints * kernelParams_.numConstraintsThreads, deviceContext_);
+ maxCoupledConstraints * kernelParams_.numConstraintsThreads,
+ deviceContext_);
allocateDeviceBuffer(&kernelParams_.d_massFactors,
- maxCoupledConstraints * kernelParams_.numConstraintsThreads, deviceContext_);
+ maxCoupledConstraints * kernelParams_.numConstraintsThreads,
+ deviceContext_);
allocateDeviceBuffer(&kernelParams_.d_matrixA,
- maxCoupledConstraints * kernelParams_.numConstraintsThreads, deviceContext_);
+ maxCoupledConstraints * kernelParams_.numConstraintsThreads,
+ deviceContext_);
}
// (Re)allocate the memory, if the number of atoms has increased.
}
// Copy data to GPU.
- copyToDeviceBuffer(&kernelParams_.d_constraints, constraintsHost.data(), 0,
- kernelParams_.numConstraintsThreads, deviceStream_, GpuApiCallBehavior::Sync,
+ copyToDeviceBuffer(&kernelParams_.d_constraints,
+ constraintsHost.data(),
+ 0,
+ kernelParams_.numConstraintsThreads,
+ deviceStream_,
+ GpuApiCallBehavior::Sync,
nullptr);
copyToDeviceBuffer(&kernelParams_.d_constraintsTargetLengths,
- constraintsTargetLengthsHost.data(), 0, kernelParams_.numConstraintsThreads,
- deviceStream_, GpuApiCallBehavior::Sync, nullptr);
+ constraintsTargetLengthsHost.data(),
+ 0,
+ kernelParams_.numConstraintsThreads,
+ deviceStream_,
+ GpuApiCallBehavior::Sync,
+ nullptr);
copyToDeviceBuffer(&kernelParams_.d_coupledConstraintsCounts,
- coupledConstraintsCountsHost.data(), 0, kernelParams_.numConstraintsThreads,
- deviceStream_, GpuApiCallBehavior::Sync, nullptr);
- copyToDeviceBuffer(&kernelParams_.d_coupledConstraintsIndices, coupledConstraintsIndicesHost.data(),
- 0, maxCoupledConstraints * kernelParams_.numConstraintsThreads,
- deviceStream_, GpuApiCallBehavior::Sync, nullptr);
- copyToDeviceBuffer(&kernelParams_.d_massFactors, massFactorsHost.data(), 0,
- maxCoupledConstraints * kernelParams_.numConstraintsThreads, deviceStream_,
- GpuApiCallBehavior::Sync, nullptr);
+ coupledConstraintsCountsHost.data(),
+ 0,
+ kernelParams_.numConstraintsThreads,
+ deviceStream_,
+ GpuApiCallBehavior::Sync,
+ nullptr);
+ copyToDeviceBuffer(&kernelParams_.d_coupledConstraintsIndices,
+ coupledConstraintsIndicesHost.data(),
+ 0,
+ maxCoupledConstraints * kernelParams_.numConstraintsThreads,
+ deviceStream_,
+ GpuApiCallBehavior::Sync,
+ nullptr);
+ copyToDeviceBuffer(&kernelParams_.d_massFactors,
+ massFactorsHost.data(),
+ 0,
+ maxCoupledConstraints * kernelParams_.numConstraintsThreads,
+ deviceStream_,
+ GpuApiCallBehavior::Sync,
+ nullptr);
GMX_RELEASE_ASSERT(invmass != nullptr, "Masses of atoms should be specified.\n");
- copyToDeviceBuffer(&kernelParams_.d_inverseMasses, invmass, 0, numAtoms, deviceStream_,
- GpuApiCallBehavior::Sync, nullptr);
+ copyToDeviceBuffer(
+ &kernelParams_.d_inverseMasses, invmass, 0, numAtoms, deviceStream_, GpuApiCallBehavior::Sync, nullptr);
}
} // namespace gmx
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
#ifndef GMX_MDLIB_LINCS_GPU_CUH
#define GMX_MDLIB_LINCS_GPU_CUH
+#include <memory>
+
#include "gromacs/gpu_utils/device_context.h"
#include "gromacs/gpu_utils/device_stream.h"
#include "gromacs/gpu_utils/gputraits.cuh"
#include "gromacs/mdlib/constr.h"
#include "gromacs/pbcutil/pbc_aiuc.h"
-#include "gromacs/utility/classhelpers.h"
class InteractionDefinitions;
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 The GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
gmx_bool bEkinAveVel)
{
int g;
- gmx::ArrayRef<t_grp_tcstat> tcstat = ekind->tcstat;
- gmx::ArrayRef<t_grp_acc> grpstat = ekind->grpstat;
+ gmx::ArrayRef<t_grp_tcstat> tcstat = ekind->tcstat;
/* three main: VV with AveVel, vv with AveEkin, leap with AveEkin. Leap with AveVel is also
an option, but not supported now.
bEkinAveVel: If TRUE, we sum into ekin, if FALSE, into ekinh.
*/
- /* group velocities are calculated in update_ekindata and
- * accumulated in acumulate_groups.
- * Now the partial global and groups ekin.
- */
+ // Now accumulate the partial global and groups ekin.
for (g = 0; (g < opts->ngtc); g++)
{
copy_mat(tcstat[g].ekinh, tcstat[g].ekinh_old);
// or memory allocation. It should not be able to throw, so for now
// we do not need a try/catch wrapper.
int start_t, end_t, n;
- int ga, gt;
- rvec v_corrt;
+ int gt;
real hm;
int d, m;
matrix* ekin_sum;
}
*dekindl_sum = 0.0;
- ga = 0;
gt = 0;
for (n = start_t; n < end_t; n++)
{
- if (md->cACC)
- {
- ga = md->cACC[n];
- }
if (md->cTC)
{
gt = md->cTC[n];
}
hm = 0.5 * md->massT[n];
- for (d = 0; (d < DIM); d++)
- {
- v_corrt[d] = v[n][d] - grpstat[ga].u[d];
- }
for (d = 0; (d < DIM); d++)
{
for (m = 0; (m < DIM); m++)
{
- /* if we're computing a full step velocity, v_corrt[d] has v(t). Otherwise, v(t+dt/2) */
- ekin_sum[gt][m][d] += hm * v_corrt[m] * v_corrt[d];
+ /* if we're computing a full step velocity, v[d] has v(t). Otherwise, v(t+dt/2) */
+ ekin_sum[gt][m][d] += hm * v[n][m] * v[n][d];
}
}
if (md->nMassPerturbed && md->bPerturbed[n])
{
- *dekindl_sum += 0.5 * (md->massB[n] - md->massA[n]) * iprod(v_corrt, v_corrt);
+ *dekindl_sum += 0.5 * (md->massB[n] - md->massA[n]) * iprod(v[n], v[n]);
}
}
}
tensor shake_vir,
tensor total_vir,
tensor pres,
- gmx::Constraints* constr,
+ gmx::ArrayRef<real> constraintsRmsdData,
gmx::SimulationSignaller* signalCoordinator,
const matrix lastbox,
int* totalNumberOfBondedInteractions,
if (bTemp)
{
- /* Non-equilibrium MD: this is parallellized, but only does communication
- * when there really is NEMD.
- */
-
- if (PAR(cr) && (ekind->bNEMD))
- {
- accumulate_u(cr, &(ir->opts), ekind);
- }
if (!bReadEkin)
{
calc_ke_part(x, v, box, &(ir->opts), mdatoms, ekind, nrnb, bEkinAveVel);
if (PAR(cr))
{
wallcycle_start(wcycle, ewcMoveE);
- global_stat(gstat, cr, enerd, force_vir, shake_vir, ir, ekind, constr,
- bStopCM ? vcm : nullptr, signalBuffer.size(), signalBuffer.data(),
- totalNumberOfBondedInteractions, *bSumEkinhOld, flags);
+ global_stat(gstat,
+ cr,
+ enerd,
+ force_vir,
+ shake_vir,
+ ir,
+ ekind,
+ constraintsRmsdData,
+ bStopCM ? vcm : nullptr,
+ signalBuffer.size(),
+ signalBuffer.data(),
+ totalNumberOfBondedInteractions,
+ *bSumEkinhOld,
+ flags);
wallcycle_stop(wcycle, ewcMoveE);
}
signalCoordinator->finalizeSignals();
return nst;
}
-int computeGlobalCommunicationPeriod(const gmx::MDLogger& mdlog, t_inputrec* ir, const t_commrec* cr)
+int computeGlobalCommunicationPeriod(const t_inputrec* ir)
{
- int nstglobalcomm;
+ int nstglobalcomm = 10;
{
// Set up the default behaviour
- if (!(ir->nstcalcenergy > 0 || ir->nstlist > 0 || ir->etc != etcNO || ir->epc != epcNO))
+ if (!(ir->nstcalcenergy > 0 || ir->nstlist > 0 || ir->etc != TemperatureCoupling::No
+ || ir->epc != PressureCoupling::No))
{
/* The user didn't choose the period for anything
important, so we just make sure we can send signals and
write output suitably. */
- nstglobalcomm = 10;
if (ir->nstenergy > 0 && ir->nstenergy < nstglobalcomm)
{
nstglobalcomm = ir->nstenergy;
* here a leftover of the twin-range scheme? Can we remove
* nstlist when we remove the group scheme?
*/
- nstglobalcomm = lcd4(ir->nstcalcenergy, ir->nstlist, ir->etc != etcNO ? ir->nsttcouple : 0,
- ir->epc != epcNO ? ir->nstpcouple : 0);
+ nstglobalcomm = lcd4(ir->nstcalcenergy,
+ ir->nstlist,
+ ir->etc != TemperatureCoupling::No ? ir->nsttcouple : 0,
+ ir->epc != PressureCoupling::No ? ir->nstpcouple : 0);
}
}
+ return nstglobalcomm;
+}
- // TODO change this behaviour. Instead grompp should print
- // a (performance) note and mdrun should not change ir.
- if (ir->comm_mode != ecmNO && ir->nstcomm < nstglobalcomm)
- {
- GMX_LOG(mdlog.warning)
- .asParagraph()
- .appendTextFormatted("WARNING: Changing nstcomm from %d to %d", ir->nstcomm, nstglobalcomm);
- ir->nstcomm = nstglobalcomm;
- }
+int computeGlobalCommunicationPeriod(const gmx::MDLogger& mdlog, const t_inputrec* ir, const t_commrec* cr)
+{
+ const int nstglobalcomm = computeGlobalCommunicationPeriod(ir);
if (cr->nnodes > 1)
{
{
state->flags |= (1 << estBOX_REL);
}
- if ((ir->epc == epcPARRINELLORAHMAN) || (ir->epc == epcMTTK))
+ if ((ir->epc == PressureCoupling::ParrinelloRahman) || (ir->epc == PressureCoupling::Mttk))
{
state->flags |= (1 << estBOXV);
if (!useModularSimulator)
state->flags |= (1 << estVETA);
state->flags |= (1 << estVOL0);
}
- if (ir->epc == epcBERENDSEN || ir->epc == epcCRESCALE)
+ if (ir->epc == PressureCoupling::Berendsen || ir->epc == PressureCoupling::CRescale)
{
state->flags |= (1 << estBAROS_INT);
}
}
- if (ir->etc == etcNOSEHOOVER)
+ if (ir->etc == TemperatureCoupling::NoseHoover)
{
state->flags |= (1 << estNH_XI);
state->flags |= (1 << estNH_VXI);
}
- if (ir->etc == etcVRESCALE || ir->etc == etcBERENDSEN)
+ if (ir->etc == TemperatureCoupling::VRescale || ir->etc == TemperatureCoupling::Berendsen)
{
state->flags |= (1 << estTHERM_INT);
}
- init_gtc_state(state, state->ngtc, state->nnhpres,
- ir->opts.nhchainlength); /* allocate the space for nose-hoover chains */
+ init_gtc_state(state, state->ngtc, state->nnhpres, ir->opts.nhchainlength); /* allocate the space for nose-hoover chains */
init_ekinstate(&state->ekinstate, ir);
if (ir->bExpanded)
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 The GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
* will be computed, to check none are missing. */
#define CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS (1u << 12u)
-
/*! \brief Return the number of steps that will take place between
* intra-simulation communications, given the constraints of the
* inputrec. */
-int computeGlobalCommunicationPeriod(const gmx::MDLogger& mdlog, t_inputrec* ir, const t_commrec* cr);
+int computeGlobalCommunicationPeriod(const t_inputrec* ir);
+
+/*! \brief Return the number of steps that will take place between
+ * intra-simulation communications, given the constraints of the
+ * inputrec, and write information to log.
+ * Calls computeGlobalCommunicationPeriod(ir) internally. */
+int computeGlobalCommunicationPeriod(const gmx::MDLogger& mdlog, const t_inputrec* ir, const t_commrec* cr);
void rerun_parallel_comm(t_commrec* cr, t_trxframe* fr, gmx_bool* bLastStep);
tensor shake_vir,
tensor total_vir,
tensor pres,
- gmx::Constraints* constr,
+ gmx::ArrayRef<real> constraintsRmsdData,
gmx::SimulationSignaller* signalCoordinator,
const matrix lastbox,
int* totalNumberOfBondedInteractions,
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team.
- * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2020,2021, 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.
sfree(mdatoms_->ptype);
sfree(mdatoms_->cTC);
sfree(mdatoms_->cENER);
- sfree(mdatoms_->cACC);
sfree(mdatoms_->cFREEZE);
sfree(mdatoms_->cVCM);
sfree(mdatoms_->cORF);
if (ir.efep != efepNO && fp)
{
- fprintf(fp, "There are %d atoms and %d charges for free energy perturbation\n",
- md->nPerturbed, md->nChargePerturbed);
+ fprintf(fp,
+ "There are %d atoms and %d charges for free energy perturbation\n",
+ md->nPerturbed,
+ md->nChargePerturbed);
}
md->havePartiallyFrozenAtoms = FALSE;
/* We always copy cTC with domain decomposition */
}
srenew(md->cENER, md->nalloc);
- if (opts->ngacc > 1)
- {
- srenew(md->cACC, md->nalloc);
- }
if (opts->nFreeze
&& (opts->ngfrz > 1 || opts->nFreeze[0][XX] || opts->nFreeze[0][YY] || opts->nFreeze[0][ZZ]))
{
else if (md->cFREEZE)
{
g = md->cFREEZE[i];
- GMX_ASSERT(opts->nFreeze != nullptr,
- "Must have freeze groups to initialize masses");
+ GMX_ASSERT(opts->nFreeze != nullptr, "Must have freeze groups to initialize masses");
if (opts->nFreeze[g][XX] && opts->nFreeze[g][YY] && opts->nFreeze[g][ZZ])
{
/* Set the mass of completely frozen particles to ALMOST_ZERO
md->cTC[i] = groups.groupNumbers[SimulationAtomGroupType::TemperatureCoupling][ag];
}
md->cENER[i] = getGroupType(groups, SimulationAtomGroupType::EnergyOutput, ag);
- if (md->cACC)
- {
- md->cACC[i] = groups.groupNumbers[SimulationAtomGroupType::Acceleration][ag];
- }
if (md->cVCM)
{
md->cVCM[i] = groups.groupNumbers[SimulationAtomGroupType::MassCenterVelocityRemoval][ag];
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
dhc->ndh += 1;
bEnergy = TRUE;
}
- if (ir->epc > epcNO)
+ if (ir->epc > PressureCoupling::No)
{
dhc->ndh += 1; /* include pressure-volume work */
bPV = TRUE;
if (bExpanded)
{
dhc->dh_expanded = dhc->dh + n;
- mde_delta_h_init(dhc->dh + n, ir->fepvals->dh_hist_size, ir->fepvals->dh_hist_spacing,
- ndhmax, dhbtEXPANDED, 0, 0, nullptr);
+ mde_delta_h_init(dhc->dh + n,
+ ir->fepvals->dh_hist_size,
+ ir->fepvals->dh_hist_spacing,
+ ndhmax,
+ dhbtEXPANDED,
+ 0,
+ 0,
+ nullptr);
n++;
}
if (bEnergy)
{
dhc->dh_energy = dhc->dh + n;
- mde_delta_h_init(dhc->dh + n, ir->fepvals->dh_hist_size, ir->fepvals->dh_hist_spacing,
- ndhmax, dhbtEN, 0, 0, nullptr);
+ mde_delta_h_init(
+ dhc->dh + n, ir->fepvals->dh_hist_size, ir->fepvals->dh_hist_spacing, ndhmax, dhbtEN, 0, 0, nullptr);
n++;
}
/* add the dhdl's */
if (ir->fepvals->separate_dvdl[i])
{
/* we give it init_lambda for compatibility */
- mde_delta_h_init(dhc->dh + n, ir->fepvals->dh_hist_size, ir->fepvals->dh_hist_spacing,
- ndhmax, dhbtDHDL, n_lambda_components, 1, &(fep->init_lambda));
+ mde_delta_h_init(dhc->dh + n,
+ ir->fepvals->dh_hist_size,
+ ir->fepvals->dh_hist_spacing,
+ ndhmax,
+ dhbtDHDL,
+ n_lambda_components,
+ 1,
+ &(fep->init_lambda));
n++;
n_lambda_components++;
}
}
}
- mde_delta_h_init(dhc->dh + n, ir->fepvals->dh_hist_size, ir->fepvals->dh_hist_spacing,
- ndhmax, dhbtDH, 0, n_lambda_components, lambda_vec);
+ mde_delta_h_init(dhc->dh + n,
+ ir->fepvals->dh_hist_size,
+ ir->fepvals->dh_hist_spacing,
+ ndhmax,
+ dhbtDH,
+ 0,
+ n_lambda_components,
+ lambda_vec);
n++;
}
sfree(lambda_vec);
if (bPV)
{
dhc->dh_pv = dhc->dh + n;
- mde_delta_h_init(dhc->dh + n, ir->fepvals->dh_hist_size, ir->fepvals->dh_hist_spacing,
- ndhmax, dhbtPV, 0, 0, nullptr);
+ mde_delta_h_init(
+ dhc->dh + n, ir->fepvals->dh_hist_size, ir->fepvals->dh_hist_spacing, ndhmax, dhbtPV, 0, 0, nullptr);
n++;
}
}
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2013,2014,2015,2016,2017 The GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
copy_ivec(domdecCells, headerContents.dd_nc);
}
- write_checkpoint_data(fp, headerContents, bExpanded, elamstats, state, observablesHistory,
- mdModulesNotifier, &outputfiles, modularSimulatorCheckpointData);
+ write_checkpoint_data(fp,
+ headerContents,
+ bExpanded,
+ elamstats,
+ state,
+ observablesHistory,
+ mdModulesNotifier,
+ &outputfiles,
+ modularSimulatorCheckpointData);
/* we really, REALLY, want to make sure to physically write the checkpoint,
and all the files it depends on, out to disk. Because we've
* checkpoint files getting out of sync.
*/
ivec one_ivec = { 1, 1, 1 };
- write_checkpoint(of->fn_cpt, of->bKeepAndNumCPT, fplog, cr,
+ write_checkpoint(of->fn_cpt,
+ of->bKeepAndNumCPT,
+ fplog,
+ cr,
DOMAINDECOMP(cr) ? cr->dd->numCells : one_ivec,
- DOMAINDECOMP(cr) ? cr->dd->nnodes : cr->nnodes, of->eIntegrator,
- of->simulation_part, of->bExpanded, of->elamstats, step, t, state_global,
- observablesHistory, *(of->mdModulesNotifier), modularSimulatorCheckpointData,
- of->simulationsShareState, of->mastersComm);
+ DOMAINDECOMP(cr) ? cr->dd->nnodes : cr->nnodes,
+ of->eIntegrator,
+ of->simulation_part,
+ of->bExpanded,
+ of->elamstats,
+ step,
+ t,
+ state_global,
+ observablesHistory,
+ *(of->mdModulesNotifier),
+ modularSimulatorCheckpointData,
+ of->simulationsShareState,
+ of->mastersComm);
}
void mdoutf_write_to_trajectory_files(FILE* fplog,
if (mdof_flags & (MDOF_X | MDOF_X_COMPRESSED))
{
auto globalXRef = MASTER(cr) ? state_global->x : gmx::ArrayRef<gmx::RVec>();
- dd_collect_vec(cr->dd, state_local->ddp_count, state_local->ddp_count_cg_gl,
- state_local->cg_gl, state_local->x, globalXRef);
+ dd_collect_vec(cr->dd,
+ state_local->ddp_count,
+ state_local->ddp_count_cg_gl,
+ state_local->cg_gl,
+ state_local->x,
+ globalXRef);
}
if (mdof_flags & MDOF_V)
{
auto globalVRef = MASTER(cr) ? state_global->v : gmx::ArrayRef<gmx::RVec>();
- dd_collect_vec(cr->dd, state_local->ddp_count, state_local->ddp_count_cg_gl,
- state_local->cg_gl, state_local->v, globalVRef);
+ dd_collect_vec(cr->dd,
+ state_local->ddp_count,
+ state_local->ddp_count_cg_gl,
+ state_local->cg_gl,
+ state_local->v,
+ globalVRef);
}
}
f_global = of->f_global;
if (mdof_flags & MDOF_F)
{
- dd_collect_vec(
- cr->dd, state_local->ddp_count, state_local->ddp_count_cg_gl, state_local->cg_gl, f_local,
- gmx::arrayRefFromArray(reinterpret_cast<gmx::RVec*>(of->f_global), f_local.size()));
+ auto globalFRef =
+ MASTER(cr) ? gmx::arrayRefFromArray(reinterpret_cast<gmx::RVec*>(of->f_global),
+ f_local.size())
+ : gmx::ArrayRef<gmx::RVec>();
+ dd_collect_vec(cr->dd,
+ state_local->ddp_count,
+ state_local->ddp_count_cg_gl,
+ state_local->cg_gl,
+ f_local,
+ globalFRef);
}
}
else
{
if (mdof_flags & MDOF_CPT)
{
- mdoutf_write_checkpoint(of, fplog, cr, step, t, state_global, observablesHistory,
- modularSimulatorCheckpointData);
+ mdoutf_write_checkpoint(
+ of, fplog, cr, step, t, state_global, observablesHistory, modularSimulatorCheckpointData);
}
if (mdof_flags & (MDOF_X | MDOF_V | MDOF_F))
if (of->fp_trn)
{
- gmx_trr_write_frame(of->fp_trn, step, t, state_local->lambda[efptFEP],
- state_local->box, natoms, x, v, f);
+ gmx_trr_write_frame(
+ of->fp_trn, step, t, state_local->lambda[efptFEP], state_local->box, natoms, x, v, f);
if (gmx_fio_flush(of->fp_trn) != 0)
{
gmx_file("Cannot write trajectory; maybe you are out of disk space?");
velocities and forces to it. */
else if (of->tng)
{
- gmx_fwrite_tng(of->tng, FALSE, step, t, state_local->lambda[efptFEP],
- state_local->box, natoms, x, v, f);
+ gmx_fwrite_tng(
+ of->tng, FALSE, step, t, state_local->lambda[efptFEP], state_local->box, natoms, x, v, f);
}
/* If only a TNG file is open for compressed coordinate output (no uncompressed
coordinate output) also write forces and velocities to it. */
else if (of->tng_low_prec)
{
- gmx_fwrite_tng(of->tng_low_prec, FALSE, step, t, state_local->lambda[efptFEP],
- state_local->box, natoms, x, v, f);
+ gmx_fwrite_tng(of->tng_low_prec,
+ FALSE,
+ step,
+ t,
+ state_local->lambda[efptFEP],
+ state_local->box,
+ natoms,
+ x,
+ v,
+ f);
}
}
if (mdof_flags & MDOF_X_COMPRESSED)
}
}
}
- if (write_xtc(of->fp_xtc, of->natoms_x_compressed, step, t, state_local->box, xxtc,
- of->x_compression_precision)
+ if (write_xtc(of->fp_xtc, of->natoms_x_compressed, step, t, state_local->box, xxtc, of->x_compression_precision)
== 0)
{
gmx_fatal(FARGS,
"simulation with major instabilities resulting in coordinates "
"that are NaN or too large to be represented in the XTC format.\n");
}
- gmx_fwrite_tng(of->tng_low_prec, TRUE, step, t, state_local->lambda[efptFEP],
- state_local->box, of->natoms_x_compressed, xxtc, nullptr, nullptr);
+ gmx_fwrite_tng(of->tng_low_prec,
+ TRUE,
+ step,
+ t,
+ state_local->lambda[efptFEP],
+ state_local->box,
+ of->natoms_x_compressed,
+ xxtc,
+ nullptr,
+ nullptr);
if (of->natoms_x_compressed != of->natoms_global)
{
sfree(xxtc);
{
lambda = state_local->lambda[efptFEP];
}
- gmx_fwrite_tng(of->tng_low_prec, FALSE, step, t, lambda, box, natoms, nullptr,
- nullptr, nullptr);
+ gmx_fwrite_tng(of->tng_low_prec, FALSE, step, t, lambda, box, natoms, nullptr, nullptr, nullptr);
}
}
"so that one membrane is distributed over two periodic box images. Another "
"possibility is that\n"
"your water layer is not thick enough.\n",
- zmax, zmin);
+ zmax,
+ zmin);
}
mem_p->zmin = zmin;
mem_p->zmax = zmax;
pos_ins->geom_cent[i][ZZ] = mem_p->zmed;
}
- fprintf(stderr, "Embedding piece %d with center of geometry: %f %f %f\n", i,
- pos_ins->geom_cent[i][XX], pos_ins->geom_cent[i][YY], pos_ins->geom_cent[i][ZZ]);
+ fprintf(stderr,
+ "Embedding piece %d with center of geometry: %f %f %f\n",
+ i,
+ pos_ins->geom_cent[i][XX],
+ pos_ins->geom_cent[i][YY],
+ pos_ins->geom_cent[i][ZZ]);
}
fprintf(stderr, "\n");
}
/* get input data out membed file */
try
{
- get_input(opt2fn("-membed", nfile, fnm), &xy_fac, &xy_max, &z_fac, &z_max, &it_xy,
- &it_z, &probe_rad, &low_up_rm, &maxwarn, &pieces, &bALLOW_ASYMMETRY);
+ get_input(opt2fn("-membed", nfile, fnm),
+ &xy_fac,
+ &xy_max,
+ &z_fac,
+ &z_max,
+ &it_xy,
+ &it_z,
+ &probe_rad,
+ &low_up_rm,
+ &maxwarn,
+ &pieces,
+ &bALLOW_ASYMMETRY);
}
GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
ins_grp_id = std::distance(gnames.begin(), found);
}
fprintf(stderr, "\nSelect a group to embed %s into (e.g. the membrane):\n", ins);
- get_index(&atoms, opt2fn_null("-mn", nfile, fnm), 1, &(mem_p->mem_at.nr),
- &(mem_p->mem_at.index), &(mem_p->name));
+ get_index(&atoms,
+ opt2fn_null("-mn", nfile, fnm),
+ 1,
+ &(mem_p->mem_at.nr),
+ &(mem_p->mem_at.index),
+ &(mem_p->name));
pos_ins->pieces = pieces;
snew(pos_ins->nidx, pieces);
if (pieces > 1)
{
fprintf(stderr, "\nSelect pieces to embed:\n");
- get_index(&atoms, opt2fn_null("-mn", nfile, fnm), pieces, pos_ins->nidx,
- pos_ins->subindex, piecename);
+ get_index(&atoms, opt2fn_null("-mn", nfile, fnm), pieces, pos_ins->nidx, pos_ins->subindex, piecename);
}
else
{
fprintf(stderr,
"\nWarning %d;\nThe number of steps used to grow the xy-coordinates of %s (%d)"
" is probably too small.\nIncrease -nxy or.\n\n",
- warn, ins, it_xy);
+ warn,
+ ins,
+ it_xy);
}
if ((it_z < min_it_z) && (z_fac < 0.99999999 || z_fac > 1.0000001))
"\nWarning %d;\nThe number of steps used to grow the z-coordinate of %s (%d)"
" is probably too small.\nIncrease -nz or the maxwarn setting in the membed "
"input file.\n\n",
- warn, ins, it_z);
+ warn,
+ ins,
+ it_z);
}
if (it_xy + it_z > inputrec->nsteps)
printf("The estimated area of the protein in the membrane is %.3f nm^2\n", prot_area);
printf("\nThere are %d lipids in the membrane part that overlaps the protein.\n"
"The area per lipid is %.4f nm^2.\n",
- mem_p->nmol, mem_p->lip_area);
+ mem_p->nmol,
+ mem_p->lip_area);
/* Maximum number of lipids to be removed*/
max_lip_rm = static_cast<int>(2 * prot_area / mem_p->lip_area);
"This resizing will be done with respect to the geometrical center of all protein "
"atoms\n"
"that span the membrane region, i.e. z between %.3f and %.3f\n\n",
- xy_fac, z_fac, mem_p->zmin, mem_p->zmax);
+ xy_fac,
+ z_fac,
+ mem_p->zmin,
+ mem_p->zmax);
/* resize the protein by xy and by z if necessary*/
snew(r_ins, ins_at->nr);
set_pbc(pbc, inputrec->pbcType, state->box);
snew(rm_p, 1);
- lip_rm = gen_rm_list(rm_p, ins_at, rest_at, pbc, mtop, state->x.rvec_array(), mem_p,
- pos_ins, probe_rad, low_up_rm, bALLOW_ASYMMETRY);
+ lip_rm = gen_rm_list(
+ rm_p, ins_at, rest_at, pbc, mtop, state->x.rvec_array(), mem_p, pos_ins, probe_rad, low_up_rm, bALLOW_ASYMMETRY);
lip_rm -= low_up_rm;
if (fplog)
"while %d atoms are embedded. Make sure that the atoms to be embedded are not "
"in the same"
"molecule type as atoms that are not to be embedded.\n",
- rm_bonded_at, ins_at->nr);
+ rm_bonded_at,
+ ins_at->nr);
}
if (warn > maxwarn)
{
if (debug)
{
- fprintf(debug, "set_grid_sizes, i-zone bounds for dim %d: %6.3f %6.3f\n", i,
- izones_x0[i], izones_x1[i]);
+ fprintf(debug,
+ "set_grid_sizes, i-zone bounds for dim %d: %6.3f %6.3f\n",
+ i,
+ izones_x0[i],
+ izones_x1[i]);
}
izones_size[i] = izones_x1[i] - izones_x0[i];
}
}
if (debug)
{
- fprintf(debug, "grid dim %d size %d x %f: %f - %f\n", i, grid->n[i], grid->cell_size[i],
- grid->cell_offset[i], grid->cell_offset[i] + grid->n[i] * grid->cell_size[i]);
+ fprintf(debug,
+ "grid dim %d size %d x %f: %f - %f\n",
+ i,
+ grid->n[i],
+ grid->cell_size[i],
+ grid->cell_offset[i],
+ grid->cell_offset[i] + grid->n[i] * grid->cell_size[i]);
}
}
if (debug)
{
- fprintf(debug, "CG ncg ideal %d, actual density %.1f\n", grid->ncg_ideal,
+ fprintf(debug,
+ "CG ncg ideal %d, actual density %.1f\n",
+ grid->ncg_ideal,
grid_density * grid->cell_size[XX] * grid->cell_size[YY] * grid->cell_size[ZZ]);
}
}
}
if (cg > grid->nr_alloc)
{
- fprintf(stderr, "WARNING: nra_alloc %d cg0 %d cg1 %d cg %d\n", grid->nr_alloc,
- cg0, cg1, cg);
+ fprintf(stderr, "WARNING: nra_alloc %d cg0 %d cg1 %d cg %d\n", grid->nr_alloc, cg0, cg1, cg);
}
if (bUse)
{
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2008, The GROMACS development team.
* Copyright (c) 2012,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
{
nonsimd_step_frac = 0;
}
- if (ir.epc != epcNO && 1.0 / ir.nstpcouple > nonsimd_step_frac)
+ if (ir.epc != PressureCoupling::No && 1.0 / ir.nstpcouple > nonsimd_step_frac)
{
nonsimd_step_frac = 1.0 / ir.nstpcouple;
}
if (debug)
{
- fprintf(debug, "nqlj %d nq %d nlj %d rlist %.3f r_eff %.3f pairs per atom %.1f\n", nqlj, nq,
- nlj, ir.rlist, r_eff, nppa);
+ fprintf(debug,
+ "nqlj %d nq %d nlj %d rlist %.3f r_eff %.3f pairs per atom %.1f\n",
+ nqlj,
+ nq,
+ nlj,
+ ir.rlist,
+ r_eff,
+ nppa);
}
/* Determine the cost per pair interaction */
"cost_spread %f\n"
"cost_fft %f\n"
"cost_solve %f\n",
- cost_bond, cost_pp, cost_redist, cost_spread, cost_fft, cost_solve);
+ cost_bond,
+ cost_pp,
+ cost_redist,
+ cost_spread,
+ cost_fft,
+ cost_solve);
fprintf(debug, "Estimate for relative PME load: %.3f\n", ratio);
}
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2010,2014,2015,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2010,2014,2015,2018,2019,2021, 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.
/* Copy pointer */
rbuf = b->rbuf + b->nreal;
-#if (defined __ICC && __ICC >= 1500 || defined __ICL && __ICL >= 1500) && defined __MIC__
-# pragma novector /* Work-around for incorrect vectorization */
-#endif
for (i = 0; (i < nr); i++)
{
rbuf[i] = r[i];
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
{
if (simulationNeedsReset_)
{
- if (resetCountersImpl(step, step_rel, mdlog, fplog, cr, nbv, nrnb, pme, pme_loadbal,
- wcycle, walltime_accounting))
+ if (resetCountersImpl(step, step_rel, mdlog, fplog, cr, nbv, nrnb, pme, pme_loadbal, wcycle, walltime_accounting))
{
// need to reset the counters only once
simulationNeedsReset_ = false;
fprintf(fplog,
"%s:\n"
"epsRF = %g, rc = %g, krf = %g, crf = %g, epsfac = %g\n",
- eel_names[eelRF], eps_rf, Rc, *krf, *crf, ONE_4PI_EPS0 / eps_r);
+ eel_names[eelRF],
+ eps_rf,
+ Rc,
+ *krf,
+ *crf,
+ ONE_4PI_EPS0 / eps_r);
// Make sure we don't lose resolution in pow() by casting real arg to double
real rmin = gmx::invcbrt(static_cast<double>(*krf * 2.0));
fprintf(fplog, "The electrostatics potential has its minimum at r = %g\n", rmin);
if (debug)
{
fprintf(debug, "wh =%g, rc = %g, ra = %g\n", params.wh, params.rc, params.ra);
- fprintf(debug, "rb = %g, irc2 = %g, dHH = %g, dOH = %g\n", params.rb, params.irc2,
- params.dHH, params.dOH);
+ fprintf(debug, "rb = %g, irc2 = %g, dHH = %g, dOH = %g\n", params.rb, params.irc2, params.dHH, params.dOH);
}
return params;
{
int firstO = iatoms[1];
int firstH = iatoms[2];
- parametersMassWeighted_ = settleParameters(
- masses[firstO], masses[firstH], inverseMasses[firstO], inverseMasses[firstH],
- parametersAllMasses1_.dOH, parametersAllMasses1_.dHH);
+ parametersMassWeighted_ = settleParameters(masses[firstO],
+ masses[firstH],
+ inverseMasses[firstO],
+ inverseMasses[firstH],
+ parametersAllMasses1_.dOH,
+ parametersAllMasses1_.dHH);
}
const int paddedSize = ((nsettle + pack_size - 1) / pack_size) * pack_size;
set_pbc_simd(pbc, pbcSimd);
settleTemplateWrapper<SimdReal, SimdBool, GMX_SIMD_REAL_WIDTH, const real*>(
- settled, nthread, thread, pbcSimd, xPtr, xprimePtr, invdt, vPtr, bCalcVirial,
- vir_r_m_dr, bErrorHasOccurred);
+ settled, nthread, thread, pbcSimd, xPtr, xprimePtr, invdt, vPtr, bCalcVirial, vir_r_m_dr, bErrorHasOccurred);
}
else
#endif
pbcNonNull = &pbcNo;
}
- settleTemplateWrapper<real, bool, 1, const t_pbc*>(settled, nthread, thread, pbcNonNull,
- &xPtr[0], &xprimePtr[0], invdt, &vPtr[0],
- bCalcVirial, vir_r_m_dr, bErrorHasOccurred);
+ settleTemplateWrapper<real, bool, 1, const t_pbc*>(
+ settled, nthread, thread, pbcNonNull, &xPtr[0], &xprimePtr[0], invdt, &vPtr[0], bCalcVirial, vir_r_m_dr, bErrorHasOccurred);
}
}
config.sharedMemorySize = 0;
}
- const auto kernelArgs = prepareGpuKernelArguments(kernelPtr, config, &numSettles_, &d_atomIds_,
- &settleParameters_, &d_x, &d_xp, &invdt, &d_v,
- &d_virialScaled_, &pbcAiuc);
+ const auto kernelArgs = prepareGpuKernelArguments(
+ kernelPtr, config, &numSettles_, &d_atomIds_, &settleParameters_, &d_x, &d_xp, &invdt, &d_v, &d_virialScaled_, &pbcAiuc);
- launchGpuKernel(kernelPtr, config, deviceStream_, nullptr,
- "settle_kernel<updateVelocities, computeVirial>", kernelArgs);
+ launchGpuKernel(kernelPtr,
+ config,
+ deviceStream_,
+ nullptr,
+ "settle_kernel<updateVelocities, computeVirial>",
+ kernelArgs);
if (computeVirial)
{
- copyFromDeviceBuffer(h_virialScaled_.data(), &d_virialScaled_, 0, 6, deviceStream_,
- GpuApiCallBehavior::Sync, nullptr);
+ copyFromDeviceBuffer(
+ h_virialScaled_.data(), &d_virialScaled_, 0, 6, deviceStream_, GpuApiCallBehavior::Sync, nullptr);
// Mapping [XX, XY, XZ, YY, YZ, ZZ] internal format to a tensor object
virialScaled[XX][XX] += h_virialScaled_[0];
settler.z = iatoms[i * nral1 + 3]; // Second hydrogen index
h_atomIds_.at(i) = settler;
}
- copyToDeviceBuffer(&d_atomIds_, h_atomIds_.data(), 0, numSettles_, deviceStream_,
- GpuApiCallBehavior::Sync, nullptr);
+ copyToDeviceBuffer(
+ &d_atomIds_, h_atomIds_.data(), 0, numSettles_, deviceStream_, GpuApiCallBehavior::Sync, nullptr);
}
} // namespace gmx
fprintf(fp, "%s\n", title);
for (i = 0; (i < nsb); i++)
{
- fprintf(fp, "i: %5d, iatom: (%5d %5d %5d), blocknr: %5d\n", i, sb[i].iatom[0],
- sb[i].iatom[1], sb[i].iatom[2], sb[i].blocknr);
+ fprintf(fp,
+ "i: %5d, iatom: (%5d %5d %5d), blocknr: %5d\n",
+ i,
+ sb[i].iatom[0],
+ sb[i].iatom[1],
+ sb[i].iatom[2],
+ sb[i].blocknr);
}
}
switch (econq)
{
case ConstraintVariable::Positions:
- cshake(iatom, ncon, &nit, maxnit, constraint_distance_squared, prime, pbc, rij,
- half_of_reduced_mass, omega, invmass, distance_squared_tolerance,
- scaled_lagrange_multiplier, &error);
+ cshake(iatom,
+ ncon,
+ &nit,
+ maxnit,
+ constraint_distance_squared,
+ prime,
+ pbc,
+ rij,
+ half_of_reduced_mass,
+ omega,
+ invmass,
+ distance_squared_tolerance,
+ scaled_lagrange_multiplier,
+ &error);
break;
case ConstraintVariable::Velocities:
- crattle(iatom, ncon, &nit, maxnit, constraint_distance_squared, prime, rij,
- half_of_reduced_mass, omega, invmass, distance_squared_tolerance,
- scaled_lagrange_multiplier, &error, invdt);
+ crattle(iatom,
+ ncon,
+ &nit,
+ maxnit,
+ constraint_distance_squared,
+ prime,
+ rij,
+ half_of_reduced_mass,
+ omega,
+ invmass,
+ distance_squared_tolerance,
+ scaled_lagrange_multiplier,
+ &error,
+ invdt);
break;
default: gmx_incons("Unknown constraint quantity for SHAKE");
}
fprintf(fplog,
"Inner product between old and new vector <= 0.0!\n"
"constraint #%d atoms %d and %d\n",
- error - 1, iatom[3 * (error - 1) + 1] + 1, iatom[3 * (error - 1) + 2] + 1);
+ error - 1,
+ iatom[3 * (error - 1) + 1] + 1,
+ iatom[3 * (error - 1) + 2] + 1);
}
fprintf(stderr,
"Inner product between old and new vector <= 0.0!\n"
"constraint #%d atoms %d and %d\n",
- error - 1, iatom[3 * (error - 1) + 1] + 1, iatom[3 * (error - 1) + 2] + 1);
+ error - 1,
+ iatom[3 * (error - 1) + 1] + 1,
+ iatom[3 * (error - 1) + 2] + 1);
nit = 0;
}
rvec_sub(prime[ai], prime[aj], dx);
}
dp = norm(dx);
- fprintf(log, "%5d %5.2f %5d %5.2f %10.5f %10.5f %10.5f\n", ai + 1,
- 1.0 / invmass[ai], aj + 1, 1.0 / invmass[aj], d, dp, ip[ia[0]].constr.dA);
+ fprintf(log,
+ "%5d %5.2f %5d %5.2f %10.5f %10.5f %10.5f\n",
+ ai + 1,
+ 1.0 / invmass[ai],
+ aj + 1,
+ 1.0 / invmass[aj],
+ d,
+ dp,
+ ip[ia[0]].constr.dA);
break;
case ConstraintVariable::Velocities:
rvec_sub(v[ai], v[aj], dv);
d = iprod(dx, dv);
rvec_sub(prime[ai], prime[aj], dv);
dp = iprod(dx, dv);
- fprintf(log, "%5d %5.2f %5d %5.2f %10.5f %10.5f %10.5f\n", ai + 1,
- 1.0 / invmass[ai], aj + 1, 1.0 / invmass[aj], d, dp, 0.);
+ fprintf(log,
+ "%5d %5.2f %5d %5.2f %10.5f %10.5f %10.5f\n",
+ ai + 1,
+ 1.0 / invmass[ai],
+ aj + 1,
+ 1.0 / invmass[aj],
+ d,
+ dp,
+ 0.);
break;
default: gmx_incons("Unknown constraint quantity for SHAKE");
}
{
blen = (shaked->sblock[i + 1] - shaked->sblock[i]);
blen /= 3;
- n0 = vec_shakef(log, shaked, invmass, blen, idef.iparams, iatoms, ir.shake_tol, x_s, prime,
- pbc, shaked->omega, ir.efep != efepNO, lambda, lam, invdt, v, bCalcVir,
- vir_r_m_dr, econq);
+ n0 = vec_shakef(log,
+ shaked,
+ invmass,
+ blen,
+ idef.iparams,
+ iatoms,
+ ir.shake_tol,
+ x_s,
+ prime,
+ pbc,
+ shaked->omega,
+ ir.efep != efepNO,
+ lambda,
+ lam,
+ invdt,
+ v,
+ bCalcVir,
+ vir_r_m_dr,
+ econq);
if (n0 == 0)
{
switch (econq)
{
case (ConstraintVariable::Positions):
- bOK = bshakef(log, shaked, invmass, idef, ir, x_s, xprime, pbc, nrnb, lambda, dvdlambda,
- invdt, v, bCalcVir, vir_r_m_dr, bDumpOnError, econq);
+ bOK = bshakef(
+ log, shaked, invmass, idef, ir, x_s, xprime, pbc, nrnb, lambda, dvdlambda, invdt, v, bCalcVir, vir_r_m_dr, bDumpOnError, econq);
break;
case (ConstraintVariable::Velocities):
- bOK = bshakef(log, shaked, invmass, idef, ir, x_s, vprime, pbc, nrnb, lambda, dvdlambda,
- invdt, {}, bCalcVir, vir_r_m_dr, bDumpOnError, econq);
+ bOK = bshakef(log,
+ shaked,
+ invmass,
+ idef,
+ ir,
+ x_s,
+ vprime,
+ pbc,
+ nrnb,
+ lambda,
+ dvdlambda,
+ invdt,
+ {},
+ bCalcVir,
+ vir_r_m_dr,
+ bDumpOnError,
+ econq);
break;
default:
gmx_fatal(FARGS,
#include "gromacs/utility/fatalerror.h"
-const char* gmx_stop_cond_name[] = { "None", "Stop at the next neighbor search step",
- "Stop at the next step", "Abort" };
+const char* gmx_stop_cond_name[] = { "None",
+ "Stop at the next neighbor search step",
+ "Stop at the next step",
+ "Abort" };
/* these do not neccesarily match the stop condition, but are
referred to in the signal handler. */
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013-2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2013-2019,2020,2021, 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.
wallcycle_start(wcycle, ewcPULLPOT);
set_pbc(&pbc, ir->pbcType, box);
dvdl = 0;
- enerd->term[F_COM_PULL] +=
- pull_potential(pull_work, mdatoms->massT, &pbc, cr, t, lambda[efptRESTRAINT],
- as_rvec_array(x.data()), force, &dvdl);
+ enerd->term[F_COM_PULL] += pull_potential(
+ pull_work, mdatoms->massT, &pbc, cr, t, lambda[efptRESTRAINT], as_rvec_array(x.data()), force, &dvdl);
enerd->dvdl_lin[efptRESTRAINT] += dvdl;
wallcycle_stop(wcycle, ewcPULLPOT);
}
wallcycle_start(wcycle, ewcPP_PMEWAITRECVF);
dvdl_q = 0;
dvdl_lj = 0;
- gmx_pme_receive_f(fr->pmePpCommGpu.get(), cr, forceWithVirial, &e_q, &e_lj, &dvdl_q, &dvdl_lj,
- useGpuPmePpComms, receivePmeForceToGpu, &cycles_seppme);
+ gmx_pme_receive_f(fr->pmePpCommGpu.get(),
+ cr,
+ forceWithVirial,
+ &e_q,
+ &e_lj,
+ &dvdl_q,
+ &dvdl_lj,
+ useGpuPmePpComms,
+ receivePmeForceToGpu,
+ &cycles_seppme);
enerd->term[F_COUL_RECIP] += e_q;
enerd->term[F_LJ_RECIP] += e_lj;
enerd->dvdl_lin[efptCOUL] += dvdl_q;
bool nonFinite = !std::isfinite(force2);
if (force2 >= force2Tolerance || nonFinite)
{
- fprintf(fp, "step %" PRId64 " atom %6d x %8.3f %8.3f %8.3f force %12.5e\n", step,
- ddglatnr(cr->dd, i), x[i][XX], x[i][YY], x[i][ZZ], std::sqrt(force2));
+ fprintf(fp,
+ "step %" PRId64 " atom %6d x %8.3f %8.3f %8.3f force %12.5e\n",
+ step,
+ ddglatnr(cr->dd, i),
+ x[i][XX],
+ x[i][YY],
+ x[i][ZZ],
+ std::sqrt(force2));
}
if (nonFinite)
{
if (stepWork.computeVirial)
{
/* Calculation of the virial must be done after vsites! */
- calc_virial(0, mdatoms.homenr, as_rvec_array(x.data()), forceWithShiftForces, vir_force,
- box, nrnb, &fr, fr.pbcType);
+ calc_virial(
+ 0, mdatoms.homenr, as_rvec_array(x.data()), forceWithShiftForces, vir_force, box, nrnb, &fr, fr.pbcType);
}
}
"can be caused by overlapping interactions in bonded interactions or very large%s "
"coordinate values. Usually this is caused by a badly- or non-equilibrated initial "
"configuration, incorrect interactions or parameters in the topology.",
- step, enerd.term[F_EPOT], energyIsNotFinite ? "not finite" : "extremely high",
- enerd.term[F_LJ], enerd.term[F_COUL_SR],
- energyIsNotFinite ? "non-finite" : "very high", energyIsNotFinite ? " or Nan" : "");
+ step,
+ enerd.term[F_EPOT],
+ energyIsNotFinite ? "not finite" : "extremely high",
+ enerd.term[F_LJ],
+ enerd.term[F_COUL_SR],
+ energyIsNotFinite ? "non-finite" : "very high",
+ energyIsNotFinite ? " or Nan" : "");
}
}
if (mtsLevel == 0 || stepWork.computeSlowForces)
{
auto& forceWithVirial = (mtsLevel == 0) ? forceWithVirialMtsLevel0 : forceWithVirialMtsLevel1;
- pull_potential_wrapper(cr, inputrec, box, x, forceWithVirial, mdatoms, enerd, pull_work,
- lambda.data(), t, wcycle);
+ pull_potential_wrapper(
+ cr, inputrec, box, x, forceWithVirial, mdatoms, enerd, pull_work, lambda.data(), t, wcycle);
}
}
if (awh)
std::vector<double> foreignLambdaDeltaH, foreignLambdaDhDl;
if (needForeignEnergyDifferences)
{
- enerd->foreignLambdaTerms.finalizePotentialContributions(enerd->dvdl_lin, lambda,
- *inputrec->fepvals);
+ enerd->foreignLambdaTerms.finalizePotentialContributions(
+ enerd->dvdl_lin, lambda, *inputrec->fepvals);
std::tie(foreignLambdaDeltaH, foreignLambdaDhDl) = enerd->foreignLambdaTerms.getTerms(cr);
}
auto& forceWithVirial = (mtsLevel == 0) ? forceWithVirialMtsLevel0 : forceWithVirialMtsLevel1;
- enerd->term[F_COM_PULL] += awh->applyBiasForcesAndUpdateBias(
- inputrec->pbcType, mdatoms->massT, foreignLambdaDeltaH, foreignLambdaDhDl, box,
- forceWithVirial, t, step, wcycle, fplog);
+ enerd->term[F_COM_PULL] += awh->applyBiasForcesAndUpdateBias(inputrec->pbcType,
+ mdatoms->massT,
+ foreignLambdaDeltaH,
+ foreignLambdaDhDl,
+ box,
+ forceWithVirial,
+ t,
+ step,
+ wcycle,
+ fplog);
}
}
{
GpuTaskCompletion completionType =
(isNbGpuDone) ? GpuTaskCompletion::Wait : GpuTaskCompletion::Check;
- isPmeGpuDone = pme_gpu_try_finish_task(pmedata, stepWork, wcycle,
- &forceOutputsPme->forceWithVirial(), enerd,
- lambdaQ, completionType);
+ isPmeGpuDone = pme_gpu_try_finish_task(
+ pmedata, stepWork, wcycle, &forceOutputsPme->forceWithVirial(), enerd, lambdaQ, completionType);
}
if (!isNbGpuDone)
auto& forceBuffersNonbonded = forceOutputsNonbonded->forceWithShiftForces();
GpuTaskCompletion completionType =
(isPmeGpuDone) ? GpuTaskCompletion::Wait : GpuTaskCompletion::Check;
- isNbGpuDone = Nbnxm::gpu_try_finish_task(
- nbv->gpu_nbv, stepWork, AtomLocality::Local, enerd->grpp.ener[egLJSR].data(),
- enerd->grpp.ener[egCOULSR].data(), forceBuffersNonbonded.shiftForces(),
- completionType, wcycle);
+ isNbGpuDone = Nbnxm::gpu_try_finish_task(nbv->gpu_nbv,
+ stepWork,
+ AtomLocality::Local,
+ enerd->grpp.ener[egLJSR].data(),
+ enerd->grpp.ener[egCOULSR].data(),
+ forceBuffersNonbonded.shiftForces(),
+ completionType,
+ wcycle);
if (isNbGpuDone)
{
wallcycle_sub_start(wcycle, ewcsCLEAR_FORCE_BUFFER);
/* NOTE: We assume fr->shiftForces is all zeros here */
- gmx::ForceWithShiftForces forceWithShiftForces(force, stepWork.computeVirial,
- forceHelperBuffers->shiftForces());
+ gmx::ForceWithShiftForces forceWithShiftForces(
+ force, stepWork.computeVirial, forceHelperBuffers->shiftForces());
if (stepWork.computeForces)
{
wallcycle_sub_stop(wcycle, ewcsCLEAR_FORCE_BUFFER);
- return ForceOutputs(forceWithShiftForces, forceHelperBuffers->haveDirectVirialContributions(),
- forceWithVirial);
+ return ForceOutputs(
+ forceWithShiftForces, forceHelperBuffers->haveDirectVirialContributions(), forceWithVirial);
}
const bool accumulate =
runScheduleWork->domainWork.haveCpuLocalForceWork || havePPDomainDecomposition(cr);
const int atomStart = 0;
- fr->gpuForceReduction[gmx::AtomLocality::Local]->reinit(
- stateGpu->getForces(), nbv->getNumAtoms(AtomLocality::Local), nbv->getGridIndices(),
- atomStart, accumulate, stateGpu->fReducedOnDevice());
+ fr->gpuForceReduction[gmx::AtomLocality::Local]->reinit(stateGpu->getForces(),
+ nbv->getNumAtoms(AtomLocality::Local),
+ nbv->getGridIndices(),
+ atomStart,
+ accumulate,
+ stateGpu->fReducedOnDevice());
// register forces and add dependencies
fr->gpuForceReduction[gmx::AtomLocality::Local]->registerNbnxmForce(nbv->getGpuForces());
const bool accumulate = runScheduleWork->domainWork.haveCpuBondedWork
|| runScheduleWork->domainWork.haveFreeEnergyWork;
const int atomStart = dd_numHomeAtoms(*cr->dd);
- fr->gpuForceReduction[gmx::AtomLocality::NonLocal]->reinit(
- stateGpu->getForces(), nbv->getNumAtoms(AtomLocality::NonLocal),
- nbv->getGridIndices(), atomStart, accumulate);
+ fr->gpuForceReduction[gmx::AtomLocality::NonLocal]->reinit(stateGpu->getForces(),
+ nbv->getNumAtoms(AtomLocality::NonLocal),
+ nbv->getGridIndices(),
+ atomStart,
+ accumulate);
// register forces and add dependencies
fr->gpuForceReduction[gmx::AtomLocality::NonLocal]->registerNbnxmForce(nbv->getGpuForces());
const SimulationWorkload& simulationWork = runScheduleWork->simulationWork;
- runScheduleWork->stepWork = setupStepWorkload(legacyFlags, inputrec->mtsLevels, step,
- simulationWork, thisRankHasDuty(cr, DUTY_PME));
+ runScheduleWork->stepWork = setupStepWorkload(
+ legacyFlags, inputrec->mtsLevels, step, simulationWork, thisRankHasDuty(cr, DUTY_PME));
const StepWorkload& stepWork = runScheduleWork->stepWork;
const bool useGpuPmeOnThisRank =
const bool calcCGCM = (fillGrid && !DOMAINDECOMP(cr));
if (calcCGCM)
{
- put_atoms_in_box_omp(fr->pbcType, box, x.unpaddedArrayRef().subArray(0, mdatoms->homenr),
+ put_atoms_in_box_omp(fr->pbcType,
+ box,
+ x.unpaddedArrayRef().subArray(0, mdatoms->homenr),
gmx_omp_nthreads_get(emntDefault));
inc_nrnb(nrnb, eNR_SHIFTX, mdatoms->homenr);
}
stateGpu->waitCoordinatesReadyOnHost(AtomLocality::Local);
}
- gmx_pme_send_coordinates(fr, cr, box, as_rvec_array(x.unpaddedArrayRef().data()), lambda[efptCOUL],
- lambda[efptVDW], (stepWork.computeVirial || stepWork.computeEnergy),
- step, simulationWork.useGpuPmePpCommunication, reinitGpuPmePpComms,
- pmeSendCoordinatesFromGpu, localXReadyOnDevice, wcycle);
+ gmx_pme_send_coordinates(fr,
+ cr,
+ box,
+ as_rvec_array(x.unpaddedArrayRef().data()),
+ lambda[efptCOUL],
+ lambda[efptVDW],
+ (stepWork.computeVirial || stepWork.computeEnergy),
+ step,
+ simulationWork.useGpuPmePpCommunication,
+ reinitGpuPmePpComms,
+ pmeSendCoordinatesFromGpu,
+ localXReadyOnDevice,
+ wcycle);
}
// Coordinates on the device are needed if PME or BufferOps are offloaded.
if (!thisRankHasDuty(cr, DUTY_PME) && pmeSendCoordinatesFromGpu)
{
/* Send particle coordinates to the pme nodes */
- gmx_pme_send_coordinates(fr, cr, box, as_rvec_array(x.unpaddedArrayRef().data()), lambda[efptCOUL],
- lambda[efptVDW], (stepWork.computeVirial || stepWork.computeEnergy),
- step, simulationWork.useGpuPmePpCommunication, reinitGpuPmePpComms,
- pmeSendCoordinatesFromGpu, localXReadyOnDevice, wcycle);
+ gmx_pme_send_coordinates(fr,
+ cr,
+ box,
+ as_rvec_array(x.unpaddedArrayRef().data()),
+ lambda[efptCOUL],
+ lambda[efptVDW],
+ (stepWork.computeVirial || stepWork.computeEnergy),
+ step,
+ simulationWork.useGpuPmePpCommunication,
+ reinitGpuPmePpComms,
+ pmeSendCoordinatesFromGpu,
+ localXReadyOnDevice,
+ wcycle);
}
if (useGpuPmeOnThisRank)
if (!DOMAINDECOMP(cr))
{
wallcycle_sub_start(wcycle, ewcsNBS_GRID_LOCAL);
- nbnxn_put_on_grid(nbv, box, 0, vzero, box_diag, nullptr, { 0, mdatoms->homenr }, -1,
- fr->cginfo, x.unpaddedArrayRef(), 0, nullptr);
+ nbnxn_put_on_grid(nbv,
+ box,
+ 0,
+ vzero,
+ box_diag,
+ nullptr,
+ { 0, mdatoms->homenr },
+ -1,
+ fr->cginfo,
+ x.unpaddedArrayRef(),
+ 0,
+ nullptr);
wallcycle_sub_stop(wcycle, ewcsNBS_GRID_LOCAL);
}
else
}
nbv->setAtomProperties(gmx::constArrayRefFromArray(mdatoms->typeA, mdatoms->nr),
- gmx::constArrayRefFromArray(mdatoms->chargeA, mdatoms->nr), fr->cginfo);
+ gmx::constArrayRefFromArray(mdatoms->chargeA, mdatoms->nr),
+ fr->cginfo);
wallcycle_stop(wcycle, ewcNS);
// TODO the xq, f, and fshift buffers are now shared
// resources, so they should be maintained by a
// higher-level object than the nb module.
- fr->gpuBonded->updateInteractionListsAndDeviceBuffers(
- nbv->getGridIndices(), top->idef, Nbnxm::gpu_get_xq(nbv->gpu_nbv),
- Nbnxm::gpu_get_f(nbv->gpu_nbv), Nbnxm::gpu_get_fshift(nbv->gpu_nbv));
+ fr->gpuBonded->updateInteractionListsAndDeviceBuffers(nbv->getGridIndices(),
+ top->idef,
+ Nbnxm::gpu_get_xq(nbv->gpu_nbv),
+ Nbnxm::gpu_get_f(nbv->gpu_nbv),
+ Nbnxm::gpu_get_fshift(nbv->gpu_nbv));
}
}
if (stepWork.useGpuXBufferOps)
{
GMX_ASSERT(stateGpu, "stateGpu should be valid when buffer ops are offloaded");
- nbv->convertCoordinatesGpu(AtomLocality::Local, false, stateGpu->getCoordinates(),
- localXReadyOnDevice);
+ nbv->convertCoordinatesGpu(
+ AtomLocality::Local, false, stateGpu->getCoordinates(), localXReadyOnDevice);
}
else
{
{
stateGpu->copyCoordinatesToGpu(x.unpaddedArrayRef(), AtomLocality::NonLocal);
}
- nbv->convertCoordinatesGpu(AtomLocality::NonLocal, false, stateGpu->getCoordinates(),
+ nbv->convertCoordinatesGpu(AtomLocality::NonLocal,
+ false,
+ stateGpu->getCoordinates(),
stateGpu->getCoordinatesReadyOnDeviceEvent(
AtomLocality::NonLocal, simulationWork, stepWork));
}
/* launch non-local nonbonded tasks on GPU */
wallcycle_start_nocount(wcycle, ewcLAUNCH_GPU);
wallcycle_sub_start(wcycle, ewcsLAUNCH_GPU_NONBONDED);
- do_nb_verlet(fr, ic, enerd, stepWork, InteractionLocality::NonLocal, enbvClearFNo, step,
- nrnb, wcycle);
+ do_nb_verlet(fr, ic, enerd, stepWork, InteractionLocality::NonLocal, enbvClearFNo, step, nrnb, wcycle);
wallcycle_sub_stop(wcycle, ewcsLAUNCH_GPU_NONBONDED);
wallcycle_stop(wcycle, ewcLAUNCH_GPU);
}
*/
gmx::ArrayRef<const gmx::RVec> xRef =
(xWholeMolecules.empty() ? x.unpaddedArrayRef() : xWholeMolecules);
- calc_mu(start, mdatoms->homenr, xRef, mdatoms->chargeA, mdatoms->chargeB,
- mdatoms->nChargePerturbed, dipoleData.muStaging[0], dipoleData.muStaging[1]);
+ calc_mu(start,
+ mdatoms->homenr,
+ xRef,
+ mdatoms->chargeA,
+ mdatoms->chargeB,
+ mdatoms->nChargePerturbed,
+ dipoleData.muStaging[0],
+ dipoleData.muStaging[1]);
reduceAndUpdateMuTot(&dipoleData, cr, (fr->efep != efepNO), lambda, muTotal, ddBalanceRegionHandler);
}
if (inputrec->bRot)
{
wallcycle_start(wcycle, ewcROT);
- do_rotation(cr, enforcedRotation, box, as_rvec_array(x.unpaddedArrayRef().data()), t, step,
- stepWork.doNeighborSearch);
+ do_rotation(cr, enforcedRotation, box, as_rvec_array(x.unpaddedArrayRef().data()), t, step, stepWork.doNeighborSearch);
wallcycle_stop(wcycle, ewcROT);
}
(fr->useMts && stepWork.computeSlowForces)
? std::optional(setupForceOutputs(&fr->forceHelperBuffers[1],
forceView->forceMtsCombinedWithPadding(),
- stepWork, wcycle))
+ stepWork,
+ wcycle))
: std::nullopt;
ForceOutputs* forceOutMtsLevel1 =
/* Calculate the local and non-local free energy interactions here.
* Happens here on the CPU both with and without GPU.
*/
- nbv->dispatchFreeEnergyKernel(InteractionLocality::Local, fr,
+ nbv->dispatchFreeEnergyKernel(InteractionLocality::Local,
+ fr,
as_rvec_array(x.unpaddedArrayRef().data()),
- &forceOutNonbonded->forceWithShiftForces(), *mdatoms,
- inputrec->fepvals, lambda, enerd, stepWork, nrnb);
+ &forceOutNonbonded->forceWithShiftForces(),
+ *mdatoms,
+ inputrec->fepvals,
+ lambda,
+ enerd,
+ stepWork,
+ nrnb);
if (havePPDomainDecomposition(cr))
{
- nbv->dispatchFreeEnergyKernel(InteractionLocality::NonLocal, fr,
+ nbv->dispatchFreeEnergyKernel(InteractionLocality::NonLocal,
+ fr,
as_rvec_array(x.unpaddedArrayRef().data()),
- &forceOutNonbonded->forceWithShiftForces(), *mdatoms,
- inputrec->fepvals, lambda, enerd, stepWork, nrnb);
+ &forceOutNonbonded->forceWithShiftForces(),
+ *mdatoms,
+ inputrec->fepvals,
+ lambda,
+ enerd,
+ stepWork,
+ nrnb);
}
}
{
if (havePPDomainDecomposition(cr))
{
- do_nb_verlet(fr, ic, enerd, stepWork, InteractionLocality::NonLocal, enbvClearFNo, step,
- nrnb, wcycle);
+ do_nb_verlet(fr, ic, enerd, stepWork, InteractionLocality::NonLocal, enbvClearFNo, step, nrnb, wcycle);
}
if (stepWork.computeForces)
if (inputrec->nwall && stepWork.computeNonbondedForces)
{
/* foreign lambda component for walls */
- real dvdl_walls = do_walls(*inputrec, *fr, box, *mdatoms, x.unpaddedConstArrayRef(),
- &forceOutMtsLevel0.forceWithVirial(), lambda[efptVDW],
- enerd->grpp.ener[egLJSR].data(), nrnb);
+ real dvdl_walls = do_walls(*inputrec,
+ *fr,
+ box,
+ *mdatoms,
+ x.unpaddedConstArrayRef(),
+ &forceOutMtsLevel0.forceWithVirial(),
+ lambda[efptVDW],
+ enerd->grpp.ener[egLJSR].data(),
+ nrnb);
enerd->dvdl_lin[efptVDW] += dvdl_walls;
}
{
ListedForces& listedForces = fr->listedForces[mtsIndex];
ForceOutputs& forceOut = (mtsIndex == 0 ? forceOutMtsLevel0 : *forceOutMtsLevel1);
- listedForces.calculate(
- wcycle, box, inputrec->fepvals, cr, ms, x, xWholeMolecules, fr->fcdata.get(),
- hist, &forceOut, fr, &pbc, enerd, nrnb, lambda.data(), mdatoms,
- DOMAINDECOMP(cr) ? cr->dd->globalAtomIndices.data() : nullptr, stepWork);
+ listedForces.calculate(wcycle,
+ box,
+ inputrec->fepvals,
+ cr,
+ ms,
+ x,
+ xWholeMolecules,
+ fr->fcdata.get(),
+ hist,
+ &forceOut,
+ fr,
+ &pbc,
+ enerd,
+ nrnb,
+ lambda.data(),
+ mdatoms,
+ DOMAINDECOMP(cr) ? cr->dd->globalAtomIndices.data() : nullptr,
+ stepWork);
}
}
if (stepWork.computeSlowForces)
{
- calculateLongRangeNonbondeds(fr, inputrec, cr, nrnb, wcycle, mdatoms,
- x.unpaddedConstArrayRef(), &forceOutMtsLevel1->forceWithVirial(),
- enerd, box, lambda.data(), as_rvec_array(dipoleData.muStateAB),
- stepWork, ddBalanceRegionHandler);
+ calculateLongRangeNonbondeds(fr,
+ inputrec,
+ cr,
+ nrnb,
+ wcycle,
+ mdatoms,
+ x.unpaddedConstArrayRef(),
+ &forceOutMtsLevel1->forceWithVirial(),
+ enerd,
+ box,
+ lambda.data(),
+ as_rvec_array(dipoleData.muStateAB),
+ stepWork,
+ ddBalanceRegionHandler);
}
wallcycle_stop(wcycle, ewcFORCE);
}
}
- computeSpecialForces(fplog, cr, inputrec, awh, enforcedRotation, imdSession, pull_work, step, t,
- wcycle, fr->forceProviders, box, x.unpaddedArrayRef(), mdatoms, lambda,
- stepWork, &forceOutMtsLevel0.forceWithVirial(),
- forceOutMtsLevel1 ? &forceOutMtsLevel1->forceWithVirial() : nullptr, enerd,
- ed, stepWork.doNeighborSearch);
+ computeSpecialForces(fplog,
+ cr,
+ inputrec,
+ awh,
+ enforcedRotation,
+ imdSession,
+ pull_work,
+ step,
+ t,
+ wcycle,
+ fr->forceProviders,
+ box,
+ x.unpaddedArrayRef(),
+ mdatoms,
+ lambda,
+ stepWork,
+ &forceOutMtsLevel0.forceWithVirial(),
+ forceOutMtsLevel1 ? &forceOutMtsLevel1->forceWithVirial() : nullptr,
+ enerd,
+ ed,
+ stepWork.doNeighborSearch);
+
+ if (havePPDomainDecomposition(cr) && stepWork.computeForces && stepWork.useGpuFHalo
+ && domainWork.haveCpuLocalForceWork)
+ {
+ stateGpu->copyForcesToGpu(forceOutMtsLevel0.forceWithShiftForces().force(), AtomLocality::Local);
+ }
GMX_ASSERT(!(nonbondedAtMtsLevel1 && stepWork.useGpuFBufferOps),
"The schedule below does not allow for nonbonded MTS with GPU buffer ops");
{
if (simulationWork.useGpuNonbonded)
{
- cycles_wait_gpu += Nbnxm::gpu_wait_finish_task(
- nbv->gpu_nbv, stepWork, AtomLocality::NonLocal, enerd->grpp.ener[egLJSR].data(),
- enerd->grpp.ener[egCOULSR].data(), forceWithShiftForces.shiftForces(), wcycle);
+ cycles_wait_gpu += Nbnxm::gpu_wait_finish_task(nbv->gpu_nbv,
+ stepWork,
+ AtomLocality::NonLocal,
+ enerd->grpp.ener[egLJSR].data(),
+ enerd->grpp.ener[egCOULSR].data(),
+ forceWithShiftForces.shiftForces(),
+ wcycle);
}
else
{
wallcycle_start_nocount(wcycle, ewcFORCE);
- do_nb_verlet(fr, ic, enerd, stepWork, InteractionLocality::NonLocal, enbvClearFYes,
- step, nrnb, wcycle);
+ do_nb_verlet(
+ fr, ic, enerd, stepWork, InteractionLocality::NonLocal, enbvClearFYes, step, nrnb, wcycle);
wallcycle_stop(wcycle, ewcFORCE);
}
if (combineMtsForcesBeforeHaloExchange)
{
const int numAtoms = havePPDomainDecomposition(cr) ? dd_numAtomsZones(*cr->dd) : mdatoms->homenr;
- combineMtsForces(numAtoms, force.unpaddedArrayRef(), forceView->forceMtsCombined(),
+ combineMtsForces(numAtoms,
+ force.unpaddedArrayRef(),
+ forceView->forceMtsCombined(),
inputrec->mtsLevels[1].stepFactor);
}
if (stepWork.useGpuFHalo)
{
- if (domainWork.haveCpuLocalForceWork)
- {
- stateGpu->copyForcesToGpu(forceOutMtsLevel0.forceWithShiftForces().force(),
- AtomLocality::Local);
- }
communicateGpuHaloForces(*cr, domainWork.haveCpuLocalForceWork);
}
else
&& !DOMAINDECOMP(cr) && !stepWork.useGpuFBufferOps);
if (alternateGpuWait)
{
- alternatePmeNbGpuWaitReduce(fr->nbv.get(), fr->pmedata, forceOutNonbonded,
- forceOutMtsLevel1, enerd, lambda[efptCOUL], stepWork, wcycle);
+ alternatePmeNbGpuWaitReduce(
+ fr->nbv.get(), fr->pmedata, forceOutNonbonded, forceOutMtsLevel1, enerd, lambda[efptCOUL], stepWork, wcycle);
}
if (!alternateGpuWait && useGpuPmeOnThisRank)
{
- pme_gpu_wait_and_reduce(fr->pmedata, stepWork, wcycle,
- &forceOutMtsLevel1->forceWithVirial(), enerd, lambda[efptCOUL]);
+ pme_gpu_wait_and_reduce(
+ fr->pmedata, stepWork, wcycle, &forceOutMtsLevel1->forceWithVirial(), enerd, lambda[efptCOUL]);
}
/* Wait for local GPU NB outputs on the non-alternating wait path */
* of the step time.
*/
const float gpuWaitApiOverheadMargin = 2e6F; /* cycles */
- const float waitCycles = Nbnxm::gpu_wait_finish_task(
- nbv->gpu_nbv, stepWork, AtomLocality::Local, enerd->grpp.ener[egLJSR].data(),
- enerd->grpp.ener[egCOULSR].data(),
- forceOutNonbonded->forceWithShiftForces().shiftForces(), wcycle);
+ const float waitCycles =
+ Nbnxm::gpu_wait_finish_task(nbv->gpu_nbv,
+ stepWork,
+ AtomLocality::Local,
+ enerd->grpp.ener[egLJSR].data(),
+ enerd->grpp.ener[egCOULSR].data(),
+ forceOutNonbonded->forceWithShiftForces().shiftForces(),
+ wcycle);
if (ddBalanceRegionHandler.useBalancingRegion())
{
// NOTE: emulation kernel is not included in the balancing region,
// but emulation mode does not target performance anyway
wallcycle_start_nocount(wcycle, ewcFORCE);
- do_nb_verlet(fr, ic, enerd, stepWork, InteractionLocality::Local,
- DOMAINDECOMP(cr) ? enbvClearFNo : enbvClearFYes, step, nrnb, wcycle);
+ do_nb_verlet(fr,
+ ic,
+ enerd,
+ stepWork,
+ InteractionLocality::Local,
+ DOMAINDECOMP(cr) ? enbvClearFNo : enbvClearFYes,
+ step,
+ nrnb,
+ wcycle);
wallcycle_stop(wcycle, ewcFORCE);
}
/* In case of node-splitting, the PP nodes receive the long-range
* forces, virial and energy from the PME nodes here.
*/
- pme_receive_force_ener(fr, cr, &forceOutMtsLevel1->forceWithVirial(), enerd,
+ pme_receive_force_ener(fr,
+ cr,
+ &forceOutMtsLevel1->forceWithVirial(),
+ enerd,
simulationWork.useGpuPmePpCommunication,
- stepWork.useGpuPmeFReduction, wcycle);
+ stepWork.useGpuPmeFReduction,
+ wcycle);
}
}
}
- launchGpuEndOfStepTasks(nbv, fr->gpuBonded, fr->pmedata, enerd, *runScheduleWork,
- useGpuPmeOnThisRank, step, wcycle);
+ launchGpuEndOfStepTasks(
+ nbv, fr->gpuBonded, fr->pmedata, enerd, *runScheduleWork, useGpuPmeOnThisRank, step, wcycle);
if (DOMAINDECOMP(cr))
{
&& combineMtsForcesBeforeHaloExchange);
if (stepWork.computeForces)
{
- postProcessForceWithShiftForces(nrnb, wcycle, box, x.unpaddedArrayRef(), &forceOutMtsLevel0,
- vir_force, *mdatoms, *fr, vsite, stepWork);
+ postProcessForceWithShiftForces(
+ nrnb, wcycle, box, x.unpaddedArrayRef(), &forceOutMtsLevel0, vir_force, *mdatoms, *fr, vsite, stepWork);
if (fr->useMts && stepWork.computeSlowForces && !haveCombinedMtsForces)
{
- postProcessForceWithShiftForces(nrnb, wcycle, box, x.unpaddedArrayRef(), forceOutMtsLevel1,
- vir_force, *mdatoms, *fr, vsite, stepWork);
+ postProcessForceWithShiftForces(
+ nrnb, wcycle, box, x.unpaddedArrayRef(), forceOutMtsLevel1, vir_force, *mdatoms, *fr, vsite, stepWork);
}
}
/* In case of node-splitting, the PP nodes receive the long-range
* forces, virial and energy from the PME nodes here.
*/
- pme_receive_force_ener(fr, cr, &forceOutMtsLevel1->forceWithVirial(), enerd,
- simulationWork.useGpuPmePpCommunication, false, wcycle);
+ pme_receive_force_ener(fr,
+ cr,
+ &forceOutMtsLevel1->forceWithVirial(),
+ enerd,
+ simulationWork.useGpuPmePpCommunication,
+ false,
+ wcycle);
}
if (stepWork.computeForces)
* otherwise we have to post-process two outputs and then combine them.
*/
ForceOutputs& forceOutCombined = (haveCombinedMtsForces ? forceOutMts.value() : forceOutMtsLevel0);
- postProcessForces(cr, step, nrnb, wcycle, box, x.unpaddedArrayRef(), &forceOutCombined,
- vir_force, mdatoms, fr, vsite, stepWork);
+ postProcessForces(
+ cr, step, nrnb, wcycle, box, x.unpaddedArrayRef(), &forceOutCombined, vir_force, mdatoms, fr, vsite, stepWork);
if (fr->useMts && stepWork.computeSlowForces && !haveCombinedMtsForces)
{
- postProcessForces(cr, step, nrnb, wcycle, box, x.unpaddedArrayRef(), forceOutMtsLevel1,
- vir_force, mdatoms, fr, vsite, stepWork);
+ postProcessForces(
+ cr, step, nrnb, wcycle, box, x.unpaddedArrayRef(), forceOutMtsLevel1, vir_force, mdatoms, fr, vsite, stepWork);
- combineMtsForces(mdatoms->homenr, force.unpaddedArrayRef(),
- forceView->forceMtsCombined(), inputrec->mtsLevels[1].stepFactor);
+ combineMtsForces(mdatoms->homenr,
+ force.unpaddedArrayRef(),
+ forceView->forceMtsCombined(),
+ inputrec->mtsLevels[1].stepFactor);
}
}
{
if (doIntraSim_)
{
- std::transform(std::begin(*signals_), std::end(*signals_), std::begin(mpiBuffer_),
+ std::transform(std::begin(*signals_),
+ std::end(*signals_),
+ std::begin(mpiBuffer_),
[](const SimulationSignals::value_type& s) { return s.sig; });
return mpiBuffer_;
range_check(ai + g0, 0, maxsid);
if (sid[aj + g0].sid != -1)
{
- gmx_fatal(FARGS, "sid[%d]=%d, sid[%d]=%d, file %s, line %d", ai, sid[ai + g0].sid,
- aj, sid[aj + g0].sid, __FILE__, __LINE__);
+ gmx_fatal(FARGS,
+ "sid[%d]=%d, sid[%d]=%d, file %s, line %d",
+ ai,
+ sid[ai + g0].sid,
+ aj,
+ sid[aj + g0].sid,
+ __FILE__,
+ __LINE__);
}
else
{
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/gmxlib/network.h"
#include "gromacs/math/utilities.h"
#include "gromacs/math/vec.h"
-#include "gromacs/mdlib/constr.h"
#include "gromacs/mdlib/md_support.h"
#include "gromacs/mdlib/rbin.h"
#include "gromacs/mdlib/tgroup.h"
return to;
}
-void global_stat(const gmx_global_stat* gs,
- const t_commrec* cr,
- gmx_enerdata_t* enerd,
- tensor fvir,
- tensor svir,
- const t_inputrec* inputrec,
- gmx_ekindata_t* ekind,
- const gmx::Constraints* constr,
- t_vcm* vcm,
- int nsig,
- real* sig,
- int* totalNumberOfBondedInteractions,
- bool bSumEkinhOld,
- int flags)
+void global_stat(const gmx_global_stat* gs,
+ const t_commrec* cr,
+ gmx_enerdata_t* enerd,
+ tensor fvir,
+ tensor svir,
+ const t_inputrec* inputrec,
+ gmx_ekindata_t* ekind,
+ gmx::ArrayRef<real> constraintsRmsdData,
+ t_vcm* vcm,
+ int nsig,
+ real* sig,
+ int* totalNumberOfBondedInteractions,
+ bool bSumEkinhOld,
+ int flags)
/* instead of current system, gmx_booleans for summing virial, kinetic energy, and other terms */
{
t_bin* rb;
ifv = add_binr(rb, DIM * DIM, fvir[0]);
}
- gmx::ArrayRef<real> rmsdData;
if (bEner)
{
ie = add_binr(rb, nener, copyenerd);
- if (constr)
+ if (!constraintsRmsdData.empty())
{
- rmsdData = constr->rmsdData();
- if (!rmsdData.empty())
- {
- irmsd = add_binr(rb, 2, rmsdData.data());
- }
+ irmsd = add_binr(rb, 2, constraintsRmsdData.data());
}
for (j = 0; (j < egNR); j++)
idvdlnl = add_bind(rb, efptNR, enerd->dvdl_nonlin);
if (enerd->foreignLambdaTerms.numLambdas() > 0)
{
- iepl = add_bind(rb, enerd->foreignLambdaTerms.energies().size(),
+ iepl = add_bind(rb,
+ enerd->foreignLambdaTerms.energies().size(),
enerd->foreignLambdaTerms.energies().data());
}
}
if (bEner)
{
extract_binr(rb, ie, nener, copyenerd);
- if (!rmsdData.empty())
+ if (!constraintsRmsdData.empty())
{
- extract_binr(rb, irmsd, rmsdData);
+ extract_binr(rb, irmsd, constraintsRmsdData);
}
for (j = 0; (j < egNR); j++)
extract_bind(rb, idvdlnl, efptNR, enerd->dvdl_nonlin);
if (enerd->foreignLambdaTerms.numLambdas() > 0)
{
- extract_bind(rb, iepl, enerd->foreignLambdaTerms.energies().size(),
+ extract_bind(rb,
+ iepl,
+ enerd->foreignLambdaTerms.energies().size(),
enerd->foreignLambdaTerms.energies().data());
}
}
namespace gmx
{
+template<typename T>
+class ArrayRef;
class Constraints;
-}
+} // namespace gmx
typedef struct gmx_global_stat* gmx_global_stat_t;
void global_stat_destroy(gmx_global_stat_t gs);
/*! \brief All-reduce energy-like quantities over cr->mpi_comm_mysim */
-void global_stat(const gmx_global_stat* gs,
- const t_commrec* cr,
- gmx_enerdata_t* enerd,
- tensor fvir,
- tensor svir,
- const t_inputrec* inputrec,
- gmx_ekindata_t* ekind,
- const gmx::Constraints* constr,
- t_vcm* vcm,
- int nsig,
- real* sig,
- int* totalNumberOfBondedInteractions,
- bool bSumEkinhOld,
- int flags);
+void global_stat(const gmx_global_stat* gs,
+ const t_commrec* cr,
+ gmx_enerdata_t* enerd,
+ tensor fvir,
+ tensor svir,
+ const t_inputrec* inputrec,
+ gmx_ekindata_t* ekind,
+ gmx::ArrayRef<real> constraintsRmsdData,
+ t_vcm* vcm,
+ int nsig,
+ real* sig,
+ int* totalNumberOfBondedInteractions,
+ bool bSumEkinhOld,
+ int flags);
/*! \brief Returns TRUE if io should be done */
inline bool do_per_step(int64_t step, int64_t nstep)
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
}
if (fplog)
{
- fprintf(fplog, "\n\nReceived the %s signal, stopping within %d steps\n\n",
- gmx_get_signal_name(), nsteps_stop);
+ fprintf(fplog,
+ "\n\nReceived the %s signal, stopping within %d steps\n\n",
+ gmx_get_signal_name(),
+ nsteps_stop);
fflush(fplog);
}
- fprintf(stderr, "\n\nReceived the %s signal, stopping within %d steps\n\n",
- gmx_get_signal_name(), nsteps_stop);
+ fprintf(stderr,
+ "\n\nReceived the %s signal, stopping within %d steps\n\n",
+ gmx_get_signal_name(),
+ nsteps_stop);
fflush(stderr);
handledStopCondition_ = static_cast<int>(gmx_get_stop_condition());
}
fprintf(fplog,
"\nStep %s: Run time exceeded %.3f hours, "
"will terminate the run within %d steps\n",
- gmx_step_str(step, sbuf), maximumHoursToRun_ * 0.99, nsteps_stop);
+ gmx_step_str(step, sbuf),
+ maximumHoursToRun_ * 0.99,
+ nsteps_stop);
}
fprintf(stderr,
"\nStep %s: Run time exceeded %.3f hours, "
"will terminate the run within %d steps\n",
- gmx_step_str(step, sbuf), maximumHoursToRun_ * 0.99, nsteps_stop);
+ gmx_step_str(step, sbuf),
+ maximumHoursToRun_ * 0.99,
+ nsteps_stop);
signalSent_ = true;
return StopSignal::stopAtNextNSStep;
}
});
}
- return std::make_unique<StopHandler>(signal, simulationShareState, stopConditions_,
- neverUpdateNeighborList);
+ return std::make_unique<StopHandler>(
+ signal, simulationShareState, stopConditions_, neverUpdateNeighborList);
}
} // namespace gmx
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
namespace
{
+// Define the set of PBCs to run the test for
+const std::vector<t_pbc> c_pbcs = [] {
+ std::vector<t_pbc> pbcs;
+ t_pbc pbc;
+
+ // Infinitely small box
+ matrix boxNone = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } };
+ set_pbc(&pbc, PbcType::No, boxNone);
+ pbcs.emplace_back(pbc);
+
+ // Rectangular box
+ matrix boxXyz = { { 10.0, 0.0, 0.0 }, { 0.0, 20.0, 0.0 }, { 0.0, 0.0, 15.0 } };
+ set_pbc(&pbc, PbcType::Xyz, boxXyz);
+ pbcs.emplace_back(pbc);
+
+ return pbcs;
+}();
+
+
+struct ConstraintsTestSystem
+{
+ //! Human-friendly name of the system.
+ std::string title;
+ //! Number of atoms in the system.
+ int numAtoms;
+ //! Atom masses. Size of this vector should be equal to numAtoms.
+ std::vector<real> masses;
+ /*! \brief List of constraints, organized in triples of integers.
+ *
+ * First integer is the index of type for a constraint, second
+ * and third are the indices of constrained atoms. The types
+ * of constraints should be sequential but not necessarily
+ * start from zero (which is the way they normally are in
+ * GROMACS).
+ */
+ std::vector<int> constraints;
+ /*! \brief Target values for bond lengths for bonds of each type.
+ *
+ * The size of this vector should be equal to the total number of
+ * unique types in constraints vector.
+ */
+ std::vector<real> constraintsR0;
+ //! Coordinates before integration step.
+ std::vector<RVec> x;
+ //! Coordinates after integration step, but before constraining.
+ std::vector<RVec> xPrime;
+ //! Velocities before constraining.
+ std::vector<RVec> v;
+
+ //! Reference values for scaled virial tensor.
+ tensor virialScaledRef;
+
+ //! Target tolerance for SHAKE.
+ real shakeTolerance = 0.0001;
+ /*! \brief Use successive over-relaxation method for SHAKE iterations.
+ *
+ * The general formula is:
+ * x_n+1 = (1-omega)*x_n + omega*f(x_n),
+ * where omega = 1 if SOR is off and may be < 1 if SOR is on.
+ */
+ bool shakeUseSOR = false;
+
+ //! Number of iterations used to compute the inverse matrix.
+ int lincsNIter = 1;
+ //! The order for algorithm that adjusts the direction of the bond after constraints are applied.
+ int lincslincsExpansionOrder = 4;
+ //! The threshold value for the change in bond angle. When exceeded the program will issue a warning
+ real lincsWarnAngle = 30.0;
+
+ FloatingPointTolerance lengthTolerance = absoluteTolerance(0.0002);
+ FloatingPointTolerance comTolerance = absoluteTolerance(0.0001);
+ FloatingPointTolerance virialTolerance = absoluteTolerance(0.0001);
+};
+
+const std::vector<ConstraintsTestSystem> c_constraintsTestSystemList = [] {
+ std::vector<ConstraintsTestSystem> constraintsTestSystemList;
+ {
+ ConstraintsTestSystem constraintsTestSystem;
+
+ constraintsTestSystem.title = "one constraint (e.g. OH)";
+ constraintsTestSystem.numAtoms = 2;
+
+ constraintsTestSystem.masses = { 1.0, 12.0 };
+ constraintsTestSystem.constraints = { 0, 0, 1 };
+ constraintsTestSystem.constraintsR0 = { 0.1 };
+
+ real oneTenthOverSqrtTwo = 0.1_real / std::sqrt(2.0_real);
+
+ constraintsTestSystem.x = { { 0.0, oneTenthOverSqrtTwo, 0.0 }, { oneTenthOverSqrtTwo, 0.0, 0.0 } };
+ constraintsTestSystem.xPrime = { { 0.01, 0.08, 0.01 }, { 0.06, 0.01, -0.01 } };
+ constraintsTestSystem.v = { { 1.0, 2.0, 3.0 }, { 3.0, 2.0, 1.0 } };
+
+ tensor virialScaledRef = { { -5.58e-04, 5.58e-04, 0.00e+00 },
+ { 5.58e-04, -5.58e-04, 0.00e+00 },
+ { 0.00e+00, 0.00e+00, 0.00e+00 } };
+
+ memcpy(constraintsTestSystem.virialScaledRef, virialScaledRef, DIM * DIM * sizeof(real));
+
+ constraintsTestSystemList.emplace_back(constraintsTestSystem);
+ }
+ {
+ ConstraintsTestSystem constraintsTestSystem;
+
+ constraintsTestSystem.title = "two disjoint constraints";
+ constraintsTestSystem.numAtoms = 4;
+ constraintsTestSystem.masses = { 0.5, 1.0 / 3.0, 0.25, 1.0 };
+ constraintsTestSystem.constraints = { 0, 0, 1, 1, 2, 3 };
+ constraintsTestSystem.constraintsR0 = { 2.0, 1.0 };
+
+
+ constraintsTestSystem.x = { { 2.50, -3.10, 15.70 },
+ { 0.51, -3.02, 15.55 },
+ { -0.50, -3.00, 15.20 },
+ { -1.51, -2.95, 15.05 } };
+
+ constraintsTestSystem.xPrime = { { 2.50, -3.10, 15.70 },
+ { 0.51, -3.02, 15.55 },
+ { -0.50, -3.00, 15.20 },
+ { -1.51, -2.95, 15.05 } };
+
+ constraintsTestSystem.v = { { 0.0, 1.0, 0.0 }, { 1.0, 0.0, 0.0 }, { 0.0, 0.0, 1.0 }, { 0.0, 0.0, 0.0 } };
+
+ tensor virialScaledRef = { { 3.3e-03, -1.7e-04, 5.6e-04 },
+ { -1.7e-04, 8.9e-06, -2.8e-05 },
+ { 5.6e-04, -2.8e-05, 8.9e-05 } };
+
+ memcpy(constraintsTestSystem.virialScaledRef, virialScaledRef, DIM * DIM * sizeof(real));
+
+ constraintsTestSystemList.emplace_back(constraintsTestSystem);
+ }
+ {
+ ConstraintsTestSystem constraintsTestSystem;
+
+ constraintsTestSystem.title = "three atoms, connected longitudinally (e.g. CH2)";
+ constraintsTestSystem.numAtoms = 3;
+ constraintsTestSystem.masses = { 1.0, 12.0, 16.0 };
+ constraintsTestSystem.constraints = { 0, 0, 1, 1, 1, 2 };
+ constraintsTestSystem.constraintsR0 = { 0.1, 0.2 };
+
+ real oneTenthOverSqrtTwo = 0.1_real / std::sqrt(2.0_real);
+ real twoTenthsOverSqrtThree = 0.2_real / std::sqrt(3.0_real);
+
+ constraintsTestSystem.x = { { oneTenthOverSqrtTwo, oneTenthOverSqrtTwo, 0.0 },
+ { 0.0, 0.0, 0.0 },
+ { twoTenthsOverSqrtThree, twoTenthsOverSqrtThree, twoTenthsOverSqrtThree } };
+
+ constraintsTestSystem.xPrime = { { 0.08, 0.07, 0.01 }, { -0.02, 0.01, -0.02 }, { 0.10, 0.12, 0.11 } };
+
+ constraintsTestSystem.v = { { 1.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }, { 0.0, 0.0, 1.0 } };
+
+ tensor virialScaledRef = { { 4.14e-03, 4.14e-03, 3.31e-03 },
+ { 4.14e-03, 4.14e-03, 3.31e-03 },
+ { 3.31e-03, 3.31e-03, 3.31e-03 } };
+
+ memcpy(constraintsTestSystem.virialScaledRef, virialScaledRef, DIM * DIM * sizeof(real));
+
+ constraintsTestSystemList.emplace_back(constraintsTestSystem);
+ }
+ {
+ ConstraintsTestSystem constraintsTestSystem;
+
+ constraintsTestSystem.title = "four atoms, connected longitudinally";
+ constraintsTestSystem.numAtoms = 4;
+ constraintsTestSystem.masses = { 0.5, 1.0 / 3.0, 0.25, 1.0 };
+ constraintsTestSystem.constraints = { 0, 0, 1, 1, 1, 2, 2, 2, 3 };
+ constraintsTestSystem.constraintsR0 = { 2.0, 1.0, 1.0 };
+
+
+ constraintsTestSystem.x = { { 2.50, -3.10, 15.70 },
+ { 0.51, -3.02, 15.55 },
+ { -0.50, -3.00, 15.20 },
+ { -1.51, -2.95, 15.05 } };
+
+ constraintsTestSystem.xPrime = { { 2.50, -3.10, 15.70 },
+ { 0.51, -3.02, 15.55 },
+ { -0.50, -3.00, 15.20 },
+ { -1.51, -2.95, 15.05 } };
+
+ constraintsTestSystem.v = {
+ { 0.0, 0.0, 2.0 }, { 0.0, 0.0, 3.0 }, { 0.0, 0.0, -4.0 }, { 0.0, 0.0, -1.0 }
+ };
+
+ tensor virialScaledRef = { { 1.15e-01, -4.20e-03, 2.12e-02 },
+ { -4.20e-03, 1.70e-04, -6.41e-04 },
+ { 2.12e-02, -6.41e-04, 5.45e-03 } };
+
+ memcpy(constraintsTestSystem.virialScaledRef, virialScaledRef, DIM * DIM * sizeof(real));
+
+
+ // Overriding default values since LINCS converges slowly for this system.
+ constraintsTestSystem.lincsNIter = 4;
+ constraintsTestSystem.lincslincsExpansionOrder = 8;
+ constraintsTestSystem.virialTolerance = absoluteTolerance(0.01);
+
+ constraintsTestSystemList.emplace_back(constraintsTestSystem);
+ }
+ {
+ ConstraintsTestSystem constraintsTestSystem;
+
+ constraintsTestSystem.title = "three atoms, connected to the central atom (e.g. CH3)";
+ constraintsTestSystem.numAtoms = 4;
+ constraintsTestSystem.masses = { 12.0, 1.0, 1.0, 1.0 };
+ constraintsTestSystem.constraints = { 0, 0, 1, 0, 0, 2, 0, 0, 3 };
+ constraintsTestSystem.constraintsR0 = { 0.1 };
+
+
+ constraintsTestSystem.x = {
+ { 0.00, 0.00, 0.00 }, { 0.10, 0.00, 0.00 }, { 0.00, -0.10, 0.00 }, { 0.00, 0.00, 0.10 }
+ };
+
+ constraintsTestSystem.xPrime = { { 0.004, 0.009, -0.010 },
+ { 0.110, -0.006, 0.003 },
+ { -0.007, -0.102, -0.007 },
+ { -0.005, 0.011, 0.102 } };
+
+ constraintsTestSystem.v = { { 1.0, 0.0, 0.0 }, { 1.0, 0.0, 0.0 }, { 1.0, 0.0, 0.0 }, { 1.0, 0.0, 0.0 } };
+
+ tensor virialScaledRef = { { 7.14e-04, 0.00e+00, 0.00e+00 },
+ { 0.00e+00, 1.08e-03, 0.00e+00 },
+ { 0.00e+00, 0.00e+00, 1.15e-03 } };
+
+ memcpy(constraintsTestSystem.virialScaledRef, virialScaledRef, DIM * DIM * sizeof(real));
+
+ constraintsTestSystemList.emplace_back(constraintsTestSystem);
+ }
+ {
+ ConstraintsTestSystem constraintsTestSystem;
+
+ constraintsTestSystem.title = "basic triangle (three atoms, connected to each other)";
+ constraintsTestSystem.numAtoms = 3;
+ constraintsTestSystem.masses = { 1.0, 1.0, 1.0 };
+ constraintsTestSystem.constraints = { 0, 0, 1, 2, 0, 2, 1, 1, 2 };
+ constraintsTestSystem.constraintsR0 = { 0.1, 0.1, 0.1 };
+
+ real oneTenthOverSqrtTwo = 0.1_real / std::sqrt(2.0_real);
+
+ constraintsTestSystem.x = { { oneTenthOverSqrtTwo, 0.0, 0.0 },
+ { 0.0, oneTenthOverSqrtTwo, 0.0 },
+ { 0.0, 0.0, oneTenthOverSqrtTwo } };
+
+ constraintsTestSystem.xPrime = { { 0.09, -0.02, 0.01 }, { -0.02, 0.10, -0.02 }, { 0.03, -0.01, 0.07 } };
+
+ constraintsTestSystem.v = { { 1.0, 1.0, 1.0 }, { -2.0, -2.0, -2.0 }, { 1.0, 1.0, 1.0 } };
+
+ tensor virialScaledRef = { { 6.00e-04, -1.61e-03, 1.01e-03 },
+ { -1.61e-03, 2.53e-03, -9.25e-04 },
+ { 1.01e-03, -9.25e-04, -8.05e-05 } };
+
+ memcpy(constraintsTestSystem.virialScaledRef, virialScaledRef, DIM * DIM * sizeof(real));
+
+ constraintsTestSystemList.emplace_back(constraintsTestSystem);
+ }
+
+ return constraintsTestSystemList;
+}();
+
+
/*! \brief Test fixture for constraints.
*
* The fixture uses following test systems:
* For some systems, the value for scaled virial tensor is checked against
* pre-computed data.
*/
-class ConstraintsTest : public ::testing::TestWithParam<std::string>
+class ConstraintsTest : public ::testing::TestWithParam<std::tuple<ConstraintsTestSystem, t_pbc>>
{
public:
- //! PBC setups
- std::unordered_map<std::string, t_pbc> pbcs_;
-
- /*! \brief Test setup function.
- *
- * Setting up the pbcs and algorithms. Note, that corresponding string keywords
- * have to be explicitly added at the end of this file when the tests are called.
- *
- */
- void SetUp() override
- {
-
- //
- // PBC initialization
- //
- t_pbc pbc;
-
- // Infinitely small box
- matrix boxNone = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } };
- set_pbc(&pbc, PbcType::No, boxNone);
- pbcs_["PBCNone"] = pbc;
-
- // Rectangular box
- matrix boxXyz = { { 10.0, 0.0, 0.0 }, { 0.0, 20.0, 0.0 }, { 0.0, 0.0, 15.0 } };
- set_pbc(&pbc, PbcType::Xyz, boxXyz);
- pbcs_["PBCXYZ"] = pbc;
- }
-
/*! \brief
* The test on the final length of constrained bonds.
*
"rij = %f, which is not equal to r0 = %f for constraint #%zd, between atoms %d "
"and %d"
" (before constraining rij was %f).",
- d1, r0, c, i, j, d0);
+ d1,
+ r0,
+ c,
+ i,
+ j,
+ d0);
}
}
<< gmx::formatString(
"Values in virial tensor at [%d][%d] are not within the "
"tolerance from reference value.",
- i, j);
+ i,
+ j);
}
}
}
}
};
-TEST_P(ConstraintsTest, SingleConstraint)
+TEST_P(ConstraintsTest, ConstraintsTest)
{
- std::string title = "one constraint (e.g. OH)";
- int numAtoms = 2;
-
- std::vector<real> masses = { 1.0, 12.0 };
- std::vector<int> constraints = { 0, 0, 1 };
- std::vector<real> constraintsR0 = { 0.1 };
-
- real oneTenthOverSqrtTwo = 0.1_real / std::sqrt(2.0_real);
-
- std::vector<RVec> x = { { 0.0, oneTenthOverSqrtTwo, 0.0 }, { oneTenthOverSqrtTwo, 0.0, 0.0 } };
- std::vector<RVec> xPrime = { { 0.01, 0.08, 0.01 }, { 0.06, 0.01, -0.01 } };
- std::vector<RVec> v = { { 1.0, 2.0, 3.0 }, { 3.0, 2.0, 1.0 } };
-
- tensor virialScaledRef = { { -5.58e-04, 5.58e-04, 0.00e+00 },
- { 5.58e-04, -5.58e-04, 0.00e+00 },
- { 0.00e+00, 0.00e+00, 0.00e+00 } };
-
- real shakeTolerance = 0.0001;
- gmx_bool shakeUseSOR = false;
-
- int lincsNIter = 1;
- int lincslincsExpansionOrder = 4;
- real lincsWarnAngle = 30.0;
-
- std::unique_ptr<ConstraintsTestData> testData = std::make_unique<ConstraintsTestData>(
- title, numAtoms, masses, constraints, constraintsR0, true, virialScaledRef, false, 0,
- real(0.0), real(0.001), x, xPrime, v, shakeTolerance, shakeUseSOR, lincsNIter,
- lincslincsExpansionOrder, lincsWarnAngle);
-
- std::string pbcName = GetParam();
- t_pbc pbc = pbcs_.at(pbcName);
+ auto params = GetParam();
+ ConstraintsTestSystem constraintsTestSystem = std::get<0>(params);
+ t_pbc pbc = std::get<1>(params);
+
+ ConstraintsTestData testData(constraintsTestSystem.title,
+ constraintsTestSystem.numAtoms,
+ constraintsTestSystem.masses,
+ constraintsTestSystem.constraints,
+ constraintsTestSystem.constraintsR0,
+ true,
+ constraintsTestSystem.virialScaledRef,
+ false,
+ 0,
+ real(0.0),
+ real(0.001),
+ constraintsTestSystem.x,
+ constraintsTestSystem.xPrime,
+ constraintsTestSystem.v,
+ constraintsTestSystem.shakeTolerance,
+ constraintsTestSystem.shakeUseSOR,
+ constraintsTestSystem.lincsNIter,
+ constraintsTestSystem.lincslincsExpansionOrder,
+ constraintsTestSystem.lincsWarnAngle);
// Cycle through all available runners
for (const auto& runner : getRunners())
{
- SCOPED_TRACE(formatString("Testing %s with %s using %s.", testData->title_.c_str(),
- pbcName.c_str(), runner->name().c_str()));
+ SCOPED_TRACE(formatString("Testing %s with %s PBC using %s.",
+ testData.title_.c_str(),
+ c_pbcTypeNames[pbc.pbcType].c_str(),
+ runner->name().c_str()));
- testData->reset();
+ testData.reset();
// Apply constraints
- runner->applyConstraints(testData.get(), pbc);
+ runner->applyConstraints(&testData, pbc);
- checkConstrainsLength(absoluteTolerance(0.0002), *testData, pbc);
- checkConstrainsDirection(*testData, pbc);
- checkCOMCoordinates(absoluteTolerance(0.0001), *testData);
- checkCOMVelocity(absoluteTolerance(0.0001), *testData);
-
- checkVirialTensor(absoluteTolerance(0.0001), *testData);
+ checkConstrainsLength(constraintsTestSystem.lengthTolerance, testData, pbc);
+ checkConstrainsDirection(testData, pbc);
+ checkCOMCoordinates(constraintsTestSystem.comTolerance, testData);
+ checkCOMVelocity(constraintsTestSystem.comTolerance, testData);
+ checkVirialTensor(constraintsTestSystem.virialTolerance, testData);
}
}
-TEST_P(ConstraintsTest, TwoDisjointConstraints)
-{
-
- std::string title = "two disjoint constraints";
- int numAtoms = 4;
- std::vector<real> masses = { 0.5, 1.0 / 3.0, 0.25, 1.0 };
- std::vector<int> constraints = { 0, 0, 1, 1, 2, 3 };
- std::vector<real> constraintsR0 = { 2.0, 1.0 };
-
-
- std::vector<RVec> x = {
- { 2.50, -3.10, 15.70 }, { 0.51, -3.02, 15.55 }, { -0.50, -3.00, 15.20 }, { -1.51, -2.95, 15.05 }
- };
-
- std::vector<RVec> xPrime = {
- { 2.50, -3.10, 15.70 }, { 0.51, -3.02, 15.55 }, { -0.50, -3.00, 15.20 }, { -1.51, -2.95, 15.05 }
- };
-
- std::vector<RVec> v = { { 0.0, 1.0, 0.0 }, { 1.0, 0.0, 0.0 }, { 0.0, 0.0, 1.0 }, { 0.0, 0.0, 0.0 } };
-
- tensor virialScaledRef = { { 3.3e-03, -1.7e-04, 5.6e-04 },
- { -1.7e-04, 8.9e-06, -2.8e-05 },
- { 5.6e-04, -2.8e-05, 8.9e-05 } };
-
- real shakeTolerance = 0.0001;
- gmx_bool shakeUseSOR = false;
-
- int lincsNIter = 1;
- int lincslincsExpansionOrder = 4;
- real lincsWarnAngle = 30.0;
-
- std::unique_ptr<ConstraintsTestData> testData = std::make_unique<ConstraintsTestData>(
- title, numAtoms, masses, constraints, constraintsR0, true, virialScaledRef, false, 0,
- real(0.0), real(0.001), x, xPrime, v, shakeTolerance, shakeUseSOR, lincsNIter,
- lincslincsExpansionOrder, lincsWarnAngle);
-
- std::string pbcName = GetParam();
- t_pbc pbc = pbcs_.at(pbcName);
-
- // Cycle through all available runners
- for (const auto& runner : getRunners())
- {
- SCOPED_TRACE(formatString("Testing %s with %s using %s.", testData->title_.c_str(),
- pbcName.c_str(), runner->name().c_str()));
-
- testData->reset();
-
- // Apply constraints
- runner->applyConstraints(testData.get(), pbc);
-
- checkConstrainsLength(absoluteTolerance(0.0002), *testData, pbc);
- checkConstrainsDirection(*testData, pbc);
- checkCOMCoordinates(absoluteTolerance(0.0001), *testData);
- checkCOMVelocity(absoluteTolerance(0.0001), *testData);
-
- checkVirialTensor(absoluteTolerance(0.0001), *testData);
- }
-}
-
-TEST_P(ConstraintsTest, ThreeSequentialConstraints)
-{
-
- std::string title = "three atoms, connected longitudinally (e.g. CH2)";
- int numAtoms = 3;
- std::vector<real> masses = { 1.0, 12.0, 16.0 };
- std::vector<int> constraints = { 0, 0, 1, 1, 1, 2 };
- std::vector<real> constraintsR0 = { 0.1, 0.2 };
-
- real oneTenthOverSqrtTwo = 0.1_real / std::sqrt(2.0_real);
- real twoTenthsOverSqrtThree = 0.2_real / std::sqrt(3.0_real);
-
- std::vector<RVec> x = { { oneTenthOverSqrtTwo, oneTenthOverSqrtTwo, 0.0 },
- { 0.0, 0.0, 0.0 },
- { twoTenthsOverSqrtThree, twoTenthsOverSqrtThree, twoTenthsOverSqrtThree } };
-
- std::vector<RVec> xPrime = { { 0.08, 0.07, 0.01 }, { -0.02, 0.01, -0.02 }, { 0.10, 0.12, 0.11 } };
-
- std::vector<RVec> v = { { 1.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }, { 0.0, 0.0, 1.0 } };
-
- tensor virialScaledRef = { { 4.14e-03, 4.14e-03, 3.31e-03 },
- { 4.14e-03, 4.14e-03, 3.31e-03 },
- { 3.31e-03, 3.31e-03, 3.31e-03 } };
-
- real shakeTolerance = 0.0001;
- gmx_bool shakeUseSOR = false;
-
- int lincsNIter = 1;
- int lincslincsExpansionOrder = 4;
- real lincsWarnAngle = 30.0;
-
- std::unique_ptr<ConstraintsTestData> testData = std::make_unique<ConstraintsTestData>(
- title, numAtoms, masses, constraints, constraintsR0, true, virialScaledRef, false, 0,
- real(0.0), real(0.001), x, xPrime, v, shakeTolerance, shakeUseSOR, lincsNIter,
- lincslincsExpansionOrder, lincsWarnAngle);
-
- std::string pbcName = GetParam();
- t_pbc pbc = pbcs_.at(pbcName);
-
- // Cycle through all available runners
- for (const auto& runner : getRunners())
- {
- SCOPED_TRACE(formatString("Testing %s with %s using %s.", testData->title_.c_str(),
- pbcName.c_str(), runner->name().c_str()));
-
- testData->reset();
-
- // Apply constraints
- runner->applyConstraints(testData.get(), pbc);
-
- checkConstrainsLength(absoluteTolerance(0.0002), *testData, pbc);
- checkConstrainsDirection(*testData, pbc);
- checkCOMCoordinates(absoluteTolerance(0.0001), *testData);
- checkCOMVelocity(absoluteTolerance(0.0001), *testData);
-
- checkVirialTensor(absoluteTolerance(0.0001), *testData);
- }
-}
-
-TEST_P(ConstraintsTest, ThreeConstraintsWithCentralAtom)
-{
-
- std::string title = "three atoms, connected to the central atom (e.g. CH3)";
- int numAtoms = 4;
- std::vector<real> masses = { 12.0, 1.0, 1.0, 1.0 };
- std::vector<int> constraints = { 0, 0, 1, 0, 0, 2, 0, 0, 3 };
- std::vector<real> constraintsR0 = { 0.1 };
-
-
- std::vector<RVec> x = {
- { 0.00, 0.00, 0.00 }, { 0.10, 0.00, 0.00 }, { 0.00, -0.10, 0.00 }, { 0.00, 0.00, 0.10 }
- };
-
- std::vector<RVec> xPrime = { { 0.004, 0.009, -0.010 },
- { 0.110, -0.006, 0.003 },
- { -0.007, -0.102, -0.007 },
- { -0.005, 0.011, 0.102 } };
-
- std::vector<RVec> v = { { 1.0, 0.0, 0.0 }, { 1.0, 0.0, 0.0 }, { 1.0, 0.0, 0.0 }, { 1.0, 0.0, 0.0 } };
-
- tensor virialScaledRef = { { 7.14e-04, 0.00e+00, 0.00e+00 },
- { 0.00e+00, 1.08e-03, 0.00e+00 },
- { 0.00e+00, 0.00e+00, 1.15e-03 } };
-
- real shakeTolerance = 0.0001;
- gmx_bool shakeUseSOR = false;
-
- int lincsNIter = 1;
- int lincslincsExpansionOrder = 4;
- real lincsWarnAngle = 30.0;
-
- std::unique_ptr<ConstraintsTestData> testData = std::make_unique<ConstraintsTestData>(
- title, numAtoms, masses, constraints, constraintsR0, true, virialScaledRef, false, 0,
- real(0.0), real(0.001), x, xPrime, v, shakeTolerance, shakeUseSOR, lincsNIter,
- lincslincsExpansionOrder, lincsWarnAngle);
-
- std::string pbcName = GetParam();
- t_pbc pbc = pbcs_.at(pbcName);
-
- // Cycle through all available runners
- for (const auto& runner : getRunners())
- {
- SCOPED_TRACE(formatString("Testing %s with %s using %s.", testData->title_.c_str(),
- pbcName.c_str(), runner->name().c_str()));
-
- testData->reset();
-
- // Apply constraints
- runner->applyConstraints(testData.get(), pbc);
-
- checkConstrainsLength(absoluteTolerance(0.0002), *testData, pbc);
- checkConstrainsDirection(*testData, pbc);
- checkCOMCoordinates(absoluteTolerance(0.0001), *testData);
- checkCOMVelocity(absoluteTolerance(0.0001), *testData);
-
- checkVirialTensor(absoluteTolerance(0.0001), *testData);
- }
-}
-
-TEST_P(ConstraintsTest, FourSequentialConstraints)
-{
-
- std::string title = "four atoms, connected longitudinally";
- int numAtoms = 4;
- std::vector<real> masses = { 0.5, 1.0 / 3.0, 0.25, 1.0 };
- std::vector<int> constraints = { 0, 0, 1, 1, 1, 2, 2, 2, 3 };
- std::vector<real> constraintsR0 = { 2.0, 1.0, 1.0 };
-
-
- std::vector<RVec> x = {
- { 2.50, -3.10, 15.70 }, { 0.51, -3.02, 15.55 }, { -0.50, -3.00, 15.20 }, { -1.51, -2.95, 15.05 }
- };
-
- std::vector<RVec> xPrime = {
- { 2.50, -3.10, 15.70 }, { 0.51, -3.02, 15.55 }, { -0.50, -3.00, 15.20 }, { -1.51, -2.95, 15.05 }
- };
-
- std::vector<RVec> v = { { 0.0, 0.0, 2.0 }, { 0.0, 0.0, 3.0 }, { 0.0, 0.0, -4.0 }, { 0.0, 0.0, -1.0 } };
-
- tensor virialScaledRef = { { 1.15e-01, -4.20e-03, 2.12e-02 },
- { -4.20e-03, 1.70e-04, -6.41e-04 },
- { 2.12e-02, -6.41e-04, 5.45e-03 } };
-
- real shakeTolerance = 0.0001;
- gmx_bool shakeUseSOR = false;
-
- int lincsNIter = 4;
- int lincslincsExpansionOrder = 8;
- real lincsWarnAngle = 30.0;
-
- std::unique_ptr<ConstraintsTestData> testData = std::make_unique<ConstraintsTestData>(
- title, numAtoms, masses, constraints, constraintsR0, true, virialScaledRef, false, 0,
- real(0.0), real(0.001), x, xPrime, v, shakeTolerance, shakeUseSOR, lincsNIter,
- lincslincsExpansionOrder, lincsWarnAngle);
-
- std::string pbcName = GetParam();
- t_pbc pbc = pbcs_.at(pbcName);
-
- // Cycle through all available runners
- for (const auto& runner : getRunners())
- {
- SCOPED_TRACE(formatString("Testing %s with %s using %s.", testData->title_.c_str(),
- pbcName.c_str(), runner->name().c_str()));
-
- testData->reset();
-
- // Apply constraints
- runner->applyConstraints(testData.get(), pbc);
-
- checkConstrainsLength(absoluteTolerance(0.0002), *testData, pbc);
- checkConstrainsDirection(*testData, pbc);
- checkCOMCoordinates(absoluteTolerance(0.0001), *testData);
- checkCOMVelocity(absoluteTolerance(0.0001), *testData);
-
- checkVirialTensor(absoluteTolerance(0.01), *testData);
- }
-}
-
-TEST_P(ConstraintsTest, TriangleOfConstraints)
-{
-
- std::string title = "basic triangle (tree atoms, connected to each other)";
- int numAtoms = 3;
- std::vector<real> masses = { 1.0, 1.0, 1.0 };
- std::vector<int> constraints = { 0, 0, 1, 2, 0, 2, 1, 1, 2 };
- std::vector<real> constraintsR0 = { 0.1, 0.1, 0.1 };
-
- real oneTenthOverSqrtTwo = 0.1_real / std::sqrt(2.0_real);
-
- std::vector<RVec> x = { { oneTenthOverSqrtTwo, 0.0, 0.0 },
- { 0.0, oneTenthOverSqrtTwo, 0.0 },
- { 0.0, 0.0, oneTenthOverSqrtTwo } };
-
- std::vector<RVec> xPrime = { { 0.09, -0.02, 0.01 }, { -0.02, 0.10, -0.02 }, { 0.03, -0.01, 0.07 } };
-
- std::vector<RVec> v = { { 1.0, 1.0, 1.0 }, { -2.0, -2.0, -2.0 }, { 1.0, 1.0, 1.0 } };
-
- tensor virialScaledRef = { { 6.00e-04, -1.61e-03, 1.01e-03 },
- { -1.61e-03, 2.53e-03, -9.25e-04 },
- { 1.01e-03, -9.25e-04, -8.05e-05 } };
-
- real shakeTolerance = 0.0001;
- gmx_bool shakeUseSOR = false;
-
- int lincsNIter = 1;
- int lincslincsExpansionOrder = 4;
- real lincsWarnAngle = 30.0;
-
- std::unique_ptr<ConstraintsTestData> testData = std::make_unique<ConstraintsTestData>(
- title, numAtoms, masses, constraints, constraintsR0, true, virialScaledRef, false, 0,
- real(0.0), real(0.001), x, xPrime, v, shakeTolerance, shakeUseSOR, lincsNIter,
- lincslincsExpansionOrder, lincsWarnAngle);
-
- std::string pbcName = GetParam();
- t_pbc pbc = pbcs_.at(pbcName);
-
- // Cycle through all available runners
- for (const auto& runner : getRunners())
- {
- SCOPED_TRACE(formatString("Testing %s with %s using %s.", testData->title_.c_str(),
- pbcName.c_str(), runner->name().c_str()));
-
- testData->reset();
-
- // Apply constraints
- runner->applyConstraints(testData.get(), pbc);
-
- checkConstrainsLength(absoluteTolerance(0.0002), *testData, pbc);
- checkConstrainsDirection(*testData, pbc);
- checkCOMCoordinates(absoluteTolerance(0.0001), *testData);
- checkCOMVelocity(absoluteTolerance(0.0001), *testData);
-
- checkVirialTensor(absoluteTolerance(0.00001), *testData);
- }
-}
-
-
-INSTANTIATE_TEST_CASE_P(WithParameters, ConstraintsTest, ::testing::Values("PBCNone", "PBCXYZ"));
+INSTANTIATE_TEST_CASE_P(WithParameters,
+ ConstraintsTest,
+ ::testing::Combine(::testing::ValuesIn(c_constraintsTestSystemList),
+ ::testing::ValuesIn(c_pbcs)));
} // namespace
} // namespace test
{
shakedata shaked;
make_shake_sblock_serial(&shaked, testData->idef_.get(), testData->numAtoms_);
- bool success = constrain_shake(
- nullptr, &shaked, testData->invmass_.data(), *testData->idef_, testData->ir_, testData->x_,
- testData->xPrime_, testData->xPrime2_, nullptr, &testData->nrnb_, testData->lambda_,
- &testData->dHdLambda_, testData->invdt_, testData->v_, testData->computeVirial_,
- testData->virialScaled_, false, gmx::ConstraintVariable::Positions);
+ bool success = constrain_shake(nullptr,
+ &shaked,
+ testData->invmass_.data(),
+ *testData->idef_,
+ testData->ir_,
+ testData->x_,
+ testData->xPrime_,
+ testData->xPrime2_,
+ nullptr,
+ &testData->nrnb_,
+ testData->lambda_,
+ &testData->dHdLambda_,
+ testData->invdt_,
+ testData->v_,
+ testData->computeVirial_,
+ testData->virialScaled_,
+ false,
+ gmx::ConstraintVariable::Positions);
EXPECT_TRUE(success) << "Test failed with a false return value in SHAKE.";
}
for (const gmx_moltype_t& moltype : testData->mtop_.moltype)
{
// This function is in constr.cpp
- at2con_mt.push_back(make_at2con(moltype, testData->mtop_.ffparams.iparams,
+ at2con_mt.push_back(make_at2con(moltype,
+ testData->mtop_.ffparams.iparams,
flexibleConstraintTreatment(EI_DYNAMICS(testData->ir_.eI))));
}
// Initialize LINCS
- lincsd = init_lincs(nullptr, testData->mtop_, testData->nflexcon_, at2con_mt, false,
- testData->ir_.nLincsIter, testData->ir_.nProjOrder);
- set_lincs(*testData->idef_, testData->numAtoms_, testData->invmass_.data(), testData->lambda_,
- EI_DYNAMICS(testData->ir_.eI), &cr, lincsd);
+ lincsd = init_lincs(nullptr,
+ testData->mtop_,
+ testData->nflexcon_,
+ at2con_mt,
+ false,
+ testData->ir_.nLincsIter,
+ testData->ir_.nProjOrder);
+ set_lincs(*testData->idef_,
+ testData->numAtoms_,
+ testData->invmass_.data(),
+ testData->lambda_,
+ EI_DYNAMICS(testData->ir_.eI),
+ &cr,
+ lincsd);
// Evaluate constraints
- bool success = constrain_lincs(
- false, testData->ir_, 0, lincsd, testData->invmass_.data(), &cr, &ms,
- testData->x_.arrayRefWithPadding(), testData->xPrime_.arrayRefWithPadding(),
- testData->xPrime2_.arrayRefWithPadding().unpaddedArrayRef(), pbc.box, &pbc,
- testData->hasMassPerturbed_, testData->lambda_, &testData->dHdLambda_, testData->invdt_,
- testData->v_.arrayRefWithPadding().unpaddedArrayRef(), testData->computeVirial_,
- testData->virialScaled_, gmx::ConstraintVariable::Positions, &testData->nrnb_, maxwarn,
- &warncount_lincs);
+ bool success = constrain_lincs(false,
+ testData->ir_,
+ 0,
+ lincsd,
+ testData->invmass_.data(),
+ &cr,
+ &ms,
+ testData->x_.arrayRefWithPadding(),
+ testData->xPrime_.arrayRefWithPadding(),
+ testData->xPrime2_.arrayRefWithPadding().unpaddedArrayRef(),
+ pbc.box,
+ &pbc,
+ testData->hasMassPerturbed_,
+ testData->lambda_,
+ &testData->dHdLambda_,
+ testData->invdt_,
+ testData->v_.arrayRefWithPadding().unpaddedArrayRef(),
+ testData->computeVirial_,
+ testData->virialScaled_,
+ gmx::ConstraintVariable::Positions,
+ &testData->nrnb_,
+ maxwarn,
+ &warncount_lincs);
EXPECT_TRUE(success) << "Test failed with a false return value in LINCS.";
EXPECT_EQ(warncount_lincs, 0) << "There were warnings in LINCS.";
done_lincs(lincsd);
const DeviceStream& deviceStream = testDevice_.deviceStream();
setActiveDevice(testDevice_.deviceInfo());
- auto lincsGpu = std::make_unique<LincsGpu>(testData->ir_.nLincsIter, testData->ir_.nProjOrder,
- deviceContext, deviceStream);
+ auto lincsGpu = std::make_unique<LincsGpu>(
+ testData->ir_.nLincsIter, testData->ir_.nProjOrder, deviceContext, deviceStream);
bool updateVelocities = true;
int numAtoms = testData->numAtoms_;
allocateDeviceBuffer(&d_xp, numAtoms, deviceContext);
allocateDeviceBuffer(&d_v, numAtoms, deviceContext);
- copyToDeviceBuffer(&d_x, (float3*)(testData->x_.data()), 0, numAtoms, deviceStream,
- GpuApiCallBehavior::Sync, nullptr);
- copyToDeviceBuffer(&d_xp, (float3*)(testData->xPrime_.data()), 0, numAtoms, deviceStream,
- GpuApiCallBehavior::Sync, nullptr);
+ copyToDeviceBuffer(
+ &d_x, (float3*)(testData->x_.data()), 0, numAtoms, deviceStream, GpuApiCallBehavior::Sync, nullptr);
+ copyToDeviceBuffer(
+ &d_xp, (float3*)(testData->xPrime_.data()), 0, numAtoms, deviceStream, GpuApiCallBehavior::Sync, nullptr);
if (updateVelocities)
{
- copyToDeviceBuffer(&d_v, (float3*)(testData->v_.data()), 0, numAtoms, deviceStream,
- GpuApiCallBehavior::Sync, nullptr);
+ copyToDeviceBuffer(
+ &d_v, (float3*)(testData->v_.data()), 0, numAtoms, deviceStream, GpuApiCallBehavior::Sync, nullptr);
}
- lincsGpu->apply(d_x, d_xp, updateVelocities, d_v, testData->invdt_, testData->computeVirial_,
- testData->virialScaled_, pbcAiuc);
+ lincsGpu->apply(
+ d_x, d_xp, updateVelocities, d_v, testData->invdt_, testData->computeVirial_, testData->virialScaled_, pbcAiuc);
- copyFromDeviceBuffer((float3*)(testData->xPrime_.data()), &d_xp, 0, numAtoms, deviceStream,
- GpuApiCallBehavior::Sync, nullptr);
+ copyFromDeviceBuffer(
+ (float3*)(testData->xPrime_.data()), &d_xp, 0, numAtoms, deviceStream, GpuApiCallBehavior::Sync, nullptr);
if (updateVelocities)
{
- copyFromDeviceBuffer((float3*)(testData->v_.data()), &d_v, 0, numAtoms, deviceStream,
- GpuApiCallBehavior::Sync, nullptr);
+ copyFromDeviceBuffer(
+ (float3*)(testData->v_.data()), &d_v, 0, numAtoms, deviceStream, GpuApiCallBehavior::Sync, nullptr);
}
freeDeviceBuffer(&d_x);
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
struct EnergyOutputTestParameters
{
//! Thermostat (enum)
- int temperatureCouplingScheme;
+ TemperatureCoupling temperatureCouplingScheme;
//! Barostat (enum)
- int pressureCouplingScheme;
+ PressureCoupling pressureCouplingScheme;
//! Integrator
int integrator;
//! Number of saved energy frames (to test averages output).
* Only several combinations of the parameters are used. Using all possible combinations will
* require ~10 MB of test data and ~2 sec to run the tests.
*/
-const EnergyOutputTestParameters parametersSets[] = { { etcNO, epcNO, eiMD, 1, false, false },
- { etcNO, epcNO, eiMD, 1, true, false },
- { etcNO, epcNO, eiMD, 1, false, true },
- { etcNO, epcNO, eiMD, 0, false, false },
- { etcNO, epcNO, eiMD, 10, false, false },
- { etcVRESCALE, epcNO, eiMD, 1, false, false },
- { etcNOSEHOOVER, epcNO, eiMD, 1, false, false },
- { etcNO, epcPARRINELLORAHMAN, eiMD, 1, false, false },
- { etcNO, epcMTTK, eiMD, 1, false, false },
- { etcNO, epcNO, eiVV, 1, false, false },
- { etcNO, epcMTTK, eiVV, 1, false, false } };
+const EnergyOutputTestParameters parametersSets[] = {
+ { TemperatureCoupling::No, PressureCoupling::No, eiMD, 1, false, false },
+ { TemperatureCoupling::No, PressureCoupling::No, eiMD, 1, true, false },
+ { TemperatureCoupling::No, PressureCoupling::No, eiMD, 1, false, true },
+ { TemperatureCoupling::No, PressureCoupling::No, eiMD, 0, false, false },
+ { TemperatureCoupling::No, PressureCoupling::No, eiMD, 10, false, false },
+ { TemperatureCoupling::VRescale, PressureCoupling::No, eiMD, 1, false, false },
+ { TemperatureCoupling::NoseHoover, PressureCoupling::No, eiMD, 1, false, false },
+ { TemperatureCoupling::No, PressureCoupling::ParrinelloRahman, eiMD, 1, false, false },
+ { TemperatureCoupling::No, PressureCoupling::Mttk, eiMD, 1, false, false },
+ { TemperatureCoupling::No, PressureCoupling::No, eiVV, 1, false, false },
+ { TemperatureCoupling::No, PressureCoupling::Mttk, eiVV, 1, false, false }
+};
/*! \brief Test fixture to test energy output.
*
mtop_.groups.groups[SimulationAtomGroupType::TemperatureCoupling][1] = 1;
mtop_.groups.groups[SimulationAtomGroupType::TemperatureCoupling][2] = 2;
- mtop_.groups.groups[SimulationAtomGroupType::Acceleration].resize(2);
- mtop_.groups.groups[SimulationAtomGroupType::Acceleration][0] = 0;
- mtop_.groups.groups[SimulationAtomGroupType::Acceleration][1] = 2;
-
// Nose-Hoover chains
inputrec_.bPrintNHChains = true;
inputrec_.opts.nhchainlength = 2;
// Kinetic energy and related data
ekindata_.tcstat.resize(mtop_.groups.groups[SimulationAtomGroupType::TemperatureCoupling].size());
- ekindata_.grpstat.resize(mtop_.groups.groups[SimulationAtomGroupType::Acceleration].size());
// This is needed so that the ebin space will be allocated
inputrec_.cos_accel = 1.0;
// TODO EnergyOutput should not take Constraints object
// TODO This object will always return zero as RMSD value.
// It is more relevant to have non-zero value for testing.
- constraints_ = makeConstraints(mtop_, inputrec_, nullptr, false, nullptr, &cr_, nullptr,
- nullptr, nullptr, false);
+ constraints_ = makeConstraints(
+ mtop_, inputrec_, nullptr, false, nullptr, &cr_, nullptr, nullptr, nullptr, false);
}
/*! \brief Helper function to generate synthetic data to output
tcstat.T = (*testValue += 0.1);
tcstat.lambda = (*testValue += 0.1);
}
- for (auto& grpstat : ekindata_.grpstat)
- {
- grpstat.u[XX] = (*testValue += 0.1);
- grpstat.u[YY] = (*testValue += 0.1);
- grpstat.u[ZZ] = (*testValue += 0.1);
- }
+ // Removing constant acceleration removed a total increment of 0.6
+ // To avoid unnecessary changes in reference data, we keep the increment
+ (*testValue += 0.6);
// This conditional is to check whether the ebin was allocated.
// Otherwise it will print cosacc data into the first bin.
}
MdModulesNotifier mdModulesNotifier;
- std::unique_ptr<EnergyOutput> energyOutput = std::make_unique<EnergyOutput>(
- energyFile_, &mtop_, &inputrec_, nullptr, nullptr, parameters.isRerun,
- StartingBehavior::NewSimulation, false, mdModulesNotifier);
+ std::unique_ptr<EnergyOutput> energyOutput =
+ std::make_unique<EnergyOutput>(energyFile_,
+ &mtop_,
+ &inputrec_,
+ nullptr,
+ nullptr,
+ parameters.isRerun,
+ StartingBehavior::NewSimulation,
+ false,
+ mdModulesNotifier);
// Add synthetic data for a single step
double testValue = 10.0;
for (int frame = 0; frame < parameters.numFrames; frame++)
{
setStepData(&testValue);
- energyOutput->addDataAtEnergyStep(
- false, true, time_, tmass_, enerdata_.get(), nullptr, nullptr, box_,
- PTCouplingArrays({ state_.boxv, state_.nosehoover_xi, state_.nosehoover_vxi,
- state_.nhpres_xi, state_.nhpres_vxi }),
- state_.fep_state, constraintsVirial_, forceVirial_, totalVirial_, pressure_,
- &ekindata_, muTotal_, constraints_.get());
+ energyOutput->addDataAtEnergyStep(false,
+ true,
+ time_,
+ tmass_,
+ enerdata_.get(),
+ nullptr,
+ nullptr,
+ box_,
+ PTCouplingArrays({ state_.boxv,
+ state_.nosehoover_xi,
+ state_.nosehoover_vxi,
+ state_.nhpres_xi,
+ state_.nhpres_vxi }),
+ state_.fep_state,
+ constraintsVirial_,
+ forceVirial_,
+ totalVirial_,
+ pressure_,
+ &ekindata_,
+ muTotal_,
+ constraints_.get());
energyOutput->printAnnealingTemperatures(log_, &mtop_.groups, &inputrec_.opts);
- energyOutput->printStepToEnergyFile(energyFile_, true, false, false, log_, 100 * frame,
- time_, nullptr, nullptr);
+ energyOutput->printStepToEnergyFile(
+ energyFile_, true, false, false, log_, 100 * frame, time_, nullptr, nullptr);
time_ += 1.0;
}
"groups and "
"%s pressure coupling (dt = %f, v0=(%f, %f, %f), f0=(%f, %f, %f), nstpcouple = "
"%d)",
- runner->hardwareDescription().c_str(), parameters.numAtoms, parameters.numSteps,
- parameters.numTCoupleGroups, parameters.nstpcouple == 0 ? "without" : "with",
- parameters.timestep, parameters.v[XX], parameters.v[YY], parameters.v[ZZ],
- parameters.f[XX], parameters.f[YY], parameters.f[ZZ], parameters.nstpcouple);
+ runner->hardwareDescription().c_str(),
+ parameters.numAtoms,
+ parameters.numSteps,
+ parameters.numTCoupleGroups,
+ parameters.nstpcouple == 0 ? "without" : "with",
+ parameters.timestep,
+ parameters.v[XX],
+ parameters.v[YY],
+ parameters.v[ZZ],
+ parameters.f[XX],
+ parameters.f[YY],
+ parameters.f[ZZ],
+ parameters.nstpcouple);
SCOPED_TRACE(testDescription);
- std::unique_ptr<LeapFrogTestData> testData = std::make_unique<LeapFrogTestData>(
- parameters.numAtoms, parameters.timestep, parameters.v, parameters.f,
- parameters.numTCoupleGroups, parameters.nstpcouple);
+ std::unique_ptr<LeapFrogTestData> testData =
+ std::make_unique<LeapFrogTestData>(parameters.numAtoms,
+ parameters.timestep,
+ parameters.v,
+ parameters.f,
+ parameters.numTCoupleGroups,
+ parameters.nstpcouple);
runner->integrate(testData.get(), parameters.numSteps);
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
if (numTCoupleGroups_ == 0)
{
- inputRecord_.etc = etcNO;
+ inputRecord_.etc = TemperatureCoupling::No;
for (int i = 0; i < numAtoms_; i++)
{
mdAtoms_.cTC[i] = 0;
}
else
{
- inputRecord_.etc = etcYES;
+ inputRecord_.etc = TemperatureCoupling::Yes;
for (int i = 0; i < numAtoms_; i++)
{
mdAtoms_.cTC[i] = i % numTCoupleGroups_;
state_.box[ZZ][YY] = 0.0;
state_.box[ZZ][ZZ] = 10.0;
- kineticEnergyData_.bNEMD = false;
kineticEnergyData_.cosacc.cos_accel = 0.0;
kineticEnergyData_.nthreads = 1;
if (doPressureCouple_)
{
- inputRecord_.epc = epcPARRINELLORAHMAN;
+ inputRecord_.epc = PressureCoupling::ParrinelloRahman;
inputRecord_.nstpcouple = nstpcouple;
dtPressureCouple_ = inputRecord_.nstpcouple * inputRecord_.delta_t;
}
else
{
- inputRecord_.epc = epcNO;
+ inputRecord_.epc = PressureCoupling::No;
velocityScalingMatrix_[XX][XX] = 1.0;
velocityScalingMatrix_[XX][YY] = 0.0;
velocityScalingMatrix_[XX][ZZ] = 0.0;
for (int step = 0; step < numSteps; step++)
{
- testData->update_->update_coords(
- testData->inputRecord_, step, &testData->mdAtoms_, &testData->state_, testData->f_,
- testData->forceCalculationData_, &testData->kineticEnergyData_,
- testData->velocityScalingMatrix_, etrtNONE, nullptr, false);
- testData->update_->finish_update(testData->inputRecord_, &testData->mdAtoms_,
- &testData->state_, nullptr, false);
+ testData->update_->update_coords(testData->inputRecord_,
+ step,
+ &testData->mdAtoms_,
+ &testData->state_,
+ testData->f_,
+ testData->forceCalculationData_,
+ &testData->kineticEnergyData_,
+ testData->velocityScalingMatrix_,
+ etrtNONE,
+ nullptr,
+ false);
+ testData->update_->finish_update(
+ testData->inputRecord_, &testData->mdAtoms_, &testData->state_, nullptr, false);
}
const auto xp = makeArrayRef(*testData->update_->xp()).subArray(0, testData->numAtoms_);
for (int i = 0; i < testData->numAtoms_; i++)
auto integrator = std::make_unique<LeapFrogGpu>(deviceContext, deviceStream);
- integrator->set(testData->numAtoms_, testData->inverseMasses_.data(),
- testData->numTCoupleGroups_, testData->mdAtoms_.cTC);
+ integrator->set(testData->numAtoms_,
+ testData->inverseMasses_.data(),
+ testData->numTCoupleGroups_,
+ testData->mdAtoms_.cTC);
bool doTempCouple = testData->numTCoupleGroups_ > 0;
for (int step = 0; step < numSteps; step++)
bool doPressureCouple = testData->doPressureCouple_
&& do_per_step(step + testData->inputRecord_.nstpcouple - 1,
testData->inputRecord_.nstpcouple);
- integrator->integrate(d_x, d_xp, d_v, d_f, testData->timestep_, doTempCouple,
- testData->kineticEnergyData_.tcstat, doPressureCouple,
- testData->dtPressureCouple_, testData->velocityScalingMatrix_);
+ integrator->integrate(d_x,
+ d_xp,
+ d_v,
+ d_f,
+ testData->timestep_,
+ doTempCouple,
+ testData->kineticEnergyData_.tcstat,
+ doPressureCouple,
+ testData->dtPressureCouple_,
+ testData->velocityScalingMatrix_);
}
copyFromDeviceBuffer(h_xp, &d_x, 0, numAtoms, deviceStream, GpuApiCallBehavior::Sync, nullptr);
<ReferenceData>
<File Name="EnergyFile">
<Sequence Name="EnergyTerms">
- <Int Name="Length">97</Int>
+ <Int Name="Length">91</Int>
<EnergyTerm>
<String Name="Name">LJ-14</String>
<String Name="Units">kJ/mol</String>
<String Name="Name">T-Lipid</String>
<String Name="Units">K</String>
</EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Protein</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Protein</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Protein</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Lipid</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Lipid</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Lipid</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
</Sequence>
<Sequence Name="Frames">
<Int Name="Length">1</Int>
<String Name="Step">0</String>
<String Name="NumSteps">0</String>
<Sequence Name="EnergyTerms">
- <Int Name="Length">97</Int>
+ <Int Name="Length">91</Int>
<EnergyTerm>
<String Name="Name">LJ-14</String>
<Real Name="Value">11.499999999999995</Real>
<String Name="Name">T-Lipid</String>
<Real Name="Value">18.000000000000007</Real>
</EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Protein</String>
- <Real Name="Value">18.20000000000001</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Protein</String>
- <Real Name="Value">18.300000000000011</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Protein</String>
- <Real Name="Value">18.400000000000013</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Lipid</String>
- <Real Name="Value">18.500000000000014</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Lipid</String>
- <Real Name="Value">18.600000000000016</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Lipid</String>
- <Real Name="Value">18.700000000000017</Real>
- </EnergyTerm>
</Sequence>
</Frame>
</Sequence>
</File>
- <Int Name="Number of Energy Terms">97</Int>
+ <Int Name="Number of Energy Terms">91</Int>
<String Name="log">Current ref_t for group Water: 25.7
Current ref_t for group Lipid: 25.8
T-Protein T-Water T-Lipid
1.76000e+01 1.78000e+01 1.80000e+01
- Group Ux Uy Uz
- Protein 1.82000e+01 1.83000e+01 1.84000e+01
- Lipid 1.85000e+01 1.86000e+01 1.87000e+01
-
</String>
</ReferenceData>
<ReferenceData>
<File Name="EnergyFile">
<Sequence Name="EnergyTerms">
- <Int Name="Length">51</Int>
+ <Int Name="Length">45</Int>
<EnergyTerm>
<String Name="Name">LJ-14</String>
<String Name="Units">kJ/mol</String>
<String Name="Name">LJ-14:Lipid-Lipid</String>
<String Name="Units">kJ/mol</String>
</EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Protein</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Protein</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Protein</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Lipid</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Lipid</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Lipid</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
</Sequence>
<Sequence Name="Frames">
<Int Name="Length">1</Int>
<String Name="Step">0</String>
<String Name="NumSteps">0</String>
<Sequence Name="EnergyTerms">
- <Int Name="Length">51</Int>
+ <Int Name="Length">45</Int>
<EnergyTerm>
<String Name="Name">LJ-14</String>
<Real Name="Value">11.499999999999995</Real>
<String Name="Name">LJ-14:Lipid-Lipid</String>
<Real Name="Value">17.5</Real>
</EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Protein</String>
- <Real Name="Value">18.20000000000001</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Protein</String>
- <Real Name="Value">18.300000000000011</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Protein</String>
- <Real Name="Value">18.400000000000013</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Lipid</String>
- <Real Name="Value">18.500000000000014</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Lipid</String>
- <Real Name="Value">18.600000000000016</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Lipid</String>
- <Real Name="Value">18.700000000000017</Real>
- </EnergyTerm>
</Sequence>
</Frame>
</Sequence>
</File>
- <Int Name="Number of Energy Terms">51</Int>
+ <Int Name="Number of Energy Terms">45</Int>
<String Name="log">Current ref_t for group Water: 25.7
Current ref_t for group Lipid: 25.8
Water-Lipid 1.56000e+01 1.57000e+01 1.59000e+01 1.60000e+01
Lipid-Lipid 1.71000e+01 1.72000e+01 1.74000e+01 1.75000e+01
- Group Ux Uy Uz
- Protein 1.82000e+01 1.83000e+01 1.84000e+01
- Lipid 1.85000e+01 1.86000e+01 1.87000e+01
-
</String>
</ReferenceData>
<ReferenceData>
<File Name="EnergyFile">
<Sequence Name="EnergyTerms">
- <Int Name="Length">108</Int>
+ <Int Name="Length">102</Int>
<EnergyTerm>
<String Name="Name">LJ-14</String>
<String Name="Units">kJ/mol</String>
<String Name="Name">T-Lipid</String>
<String Name="Units">K</String>
</EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Protein</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Protein</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Protein</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Lipid</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Lipid</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Lipid</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
</Sequence>
<Sequence Name="Frames">
<Int Name="Length">1</Int>
<String Name="Step">0</String>
<String Name="NumSteps">0</String>
<Sequence Name="EnergyTerms">
- <Int Name="Length">108</Int>
+ <Int Name="Length">102</Int>
<EnergyTerm>
<String Name="Name">LJ-14</String>
<Real Name="Value">11.499999999999995</Real>
<String Name="Name">T-Lipid</String>
<Real Name="Value">18.000000000000007</Real>
</EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Protein</String>
- <Real Name="Value">18.20000000000001</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Protein</String>
- <Real Name="Value">18.300000000000011</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Protein</String>
- <Real Name="Value">18.400000000000013</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Lipid</String>
- <Real Name="Value">18.500000000000014</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Lipid</String>
- <Real Name="Value">18.600000000000016</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Lipid</String>
- <Real Name="Value">18.700000000000017</Real>
- </EnergyTerm>
</Sequence>
</Frame>
</Sequence>
</File>
- <Int Name="Number of Energy Terms">108</Int>
+ <Int Name="Number of Energy Terms">102</Int>
<String Name="log">Current ref_t for group Water: 25.7
Current ref_t for group Lipid: 25.8
T-Protein T-Water T-Lipid
1.76000e+01 1.78000e+01 1.80000e+01
- Group Ux Uy Uz
- Protein 1.82000e+01 1.83000e+01 1.84000e+01
- Lipid 1.85000e+01 1.86000e+01 1.87000e+01
-
</String>
</ReferenceData>
<ReferenceData>
<File Name="EnergyFile">
<Sequence Name="EnergyTerms">
- <Int Name="Length">97</Int>
+ <Int Name="Length">91</Int>
<EnergyTerm>
<String Name="Name">LJ-14</String>
<String Name="Units">kJ/mol</String>
<String Name="Name">T-Lipid</String>
<String Name="Units">K</String>
</EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Protein</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Protein</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Protein</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Lipid</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Lipid</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Lipid</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
</Sequence>
<Sequence Name="Frames">
<Int Name="Length">1</Int>
<String Name="Step">0</String>
<String Name="NumSteps">0</String>
<Sequence Name="EnergyTerms">
- <Int Name="Length">97</Int>
+ <Int Name="Length">91</Int>
<EnergyTerm>
<String Name="Name">LJ-14</String>
<Real Name="Value">11.499999999999995</Real>
<String Name="Name">T-Lipid</String>
<Real Name="Value">18.000000000000007</Real>
</EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Protein</String>
- <Real Name="Value">18.20000000000001</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Protein</String>
- <Real Name="Value">18.300000000000011</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Protein</String>
- <Real Name="Value">18.400000000000013</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Lipid</String>
- <Real Name="Value">18.500000000000014</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Lipid</String>
- <Real Name="Value">18.600000000000016</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Lipid</String>
- <Real Name="Value">18.700000000000017</Real>
- </EnergyTerm>
</Sequence>
</Frame>
</Sequence>
</File>
- <Int Name="Number of Energy Terms">97</Int>
+ <Int Name="Number of Energy Terms">91</Int>
<String Name="log">Current ref_t for group Water: 25.7
Current ref_t for group Lipid: 25.8
T-Protein T-Water T-Lipid
1.76000e+01 1.78000e+01 1.80000e+01
- Group Ux Uy Uz
- Protein 1.82000e+01 1.83000e+01 1.84000e+01
- Lipid 1.85000e+01 1.86000e+01 1.87000e+01
-
</String>
</ReferenceData>
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
<ReferenceData>
- <Int Name="Number of Energy Terms">97</Int>
+ <Int Name="Number of Energy Terms">91</Int>
<String Name="log">Current ref_t for group Water: 0.0
Current ref_t for group Lipid: 0.0
<ReferenceData>
<File Name="EnergyFile">
<Sequence Name="EnergyTerms">
- <Int Name="Length">97</Int>
+ <Int Name="Length">91</Int>
<EnergyTerm>
<String Name="Name">LJ-14</String>
<String Name="Units">kJ/mol</String>
<String Name="Name">T-Lipid</String>
<String Name="Units">K</String>
</EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Protein</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Protein</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Protein</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Lipid</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Lipid</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Lipid</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
</Sequence>
<Sequence Name="Frames">
<Int Name="Length">10</Int>
<String Name="Step">0</String>
<String Name="NumSteps">0</String>
<Sequence Name="EnergyTerms">
- <Int Name="Length">97</Int>
+ <Int Name="Length">91</Int>
<EnergyTerm>
<String Name="Name">LJ-14</String>
<Real Name="Value">11.499999999999995</Real>
<String Name="Name">T-Lipid</String>
<Real Name="Value">18.000000000000007</Real>
</EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Protein</String>
- <Real Name="Value">18.20000000000001</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Protein</String>
- <Real Name="Value">18.300000000000011</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Protein</String>
- <Real Name="Value">18.400000000000013</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Lipid</String>
- <Real Name="Value">18.500000000000014</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Lipid</String>
- <Real Name="Value">18.600000000000016</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Lipid</String>
- <Real Name="Value">18.700000000000017</Real>
- </EnergyTerm>
</Sequence>
</Frame>
<Frame>
<String Name="Step">100</String>
<String Name="NumSteps">0</String>
<Sequence Name="EnergyTerms">
- <Int Name="Length">97</Int>
+ <Int Name="Length">91</Int>
<EnergyTerm>
<String Name="Name">LJ-14</String>
<Real Name="Value">28.900000000000162</Real>
<String Name="Name">T-Lipid</String>
<Real Name="Value">35.400000000000254</Real>
</EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Protein</String>
- <Real Name="Value">35.600000000000257</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Protein</String>
- <Real Name="Value">35.700000000000259</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Protein</String>
- <Real Name="Value">35.80000000000026</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Lipid</String>
- <Real Name="Value">35.900000000000261</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Lipid</String>
- <Real Name="Value">36.000000000000263</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Lipid</String>
- <Real Name="Value">36.100000000000264</Real>
- </EnergyTerm>
</Sequence>
</Frame>
<Frame>
<String Name="Step">200</String>
<String Name="NumSteps">0</String>
<Sequence Name="EnergyTerms">
- <Int Name="Length">97</Int>
+ <Int Name="Length">91</Int>
<EnergyTerm>
<String Name="Name">LJ-14</String>
<Real Name="Value">46.300000000000409</Real>
<String Name="Name">T-Lipid</String>
<Real Name="Value">52.800000000000502</Real>
</EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Protein</String>
- <Real Name="Value">53.000000000000504</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Protein</String>
- <Real Name="Value">53.100000000000506</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Protein</String>
- <Real Name="Value">53.200000000000507</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Lipid</String>
- <Real Name="Value">53.300000000000509</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Lipid</String>
- <Real Name="Value">53.40000000000051</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Lipid</String>
- <Real Name="Value">53.500000000000512</Real>
- </EnergyTerm>
</Sequence>
</Frame>
<Frame>
<String Name="Step">300</String>
<String Name="NumSteps">0</String>
<Sequence Name="EnergyTerms">
- <Int Name="Length">97</Int>
+ <Int Name="Length">91</Int>
<EnergyTerm>
<String Name="Name">LJ-14</String>
<Real Name="Value">63.700000000000657</Real>
<String Name="Name">T-Lipid</String>
<Real Name="Value">70.200000000000301</Real>
</EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Protein</String>
- <Real Name="Value">70.40000000000029</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Protein</String>
- <Real Name="Value">70.500000000000284</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Protein</String>
- <Real Name="Value">70.600000000000279</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Lipid</String>
- <Real Name="Value">70.700000000000273</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Lipid</String>
- <Real Name="Value">70.800000000000267</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Lipid</String>
- <Real Name="Value">70.900000000000261</Real>
- </EnergyTerm>
</Sequence>
</Frame>
<Frame>
<String Name="Step">400</String>
<String Name="NumSteps">0</String>
<Sequence Name="EnergyTerms">
- <Int Name="Length">97</Int>
+ <Int Name="Length">91</Int>
<EnergyTerm>
<String Name="Name">LJ-14</String>
<Real Name="Value">81.099999999999682</Real>
<String Name="Name">T-Lipid</String>
<Real Name="Value">87.599999999999312</Real>
</EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Protein</String>
- <Real Name="Value">87.799999999999301</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Protein</String>
- <Real Name="Value">87.899999999999295</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Protein</String>
- <Real Name="Value">87.999999999999289</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Lipid</String>
- <Real Name="Value">88.099999999999284</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Lipid</String>
- <Real Name="Value">88.199999999999278</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Lipid</String>
- <Real Name="Value">88.299999999999272</Real>
- </EnergyTerm>
</Sequence>
</Frame>
<Frame>
<String Name="Step">500</String>
<String Name="NumSteps">0</String>
<Sequence Name="EnergyTerms">
- <Int Name="Length">97</Int>
+ <Int Name="Length">91</Int>
<EnergyTerm>
<String Name="Name">LJ-14</String>
<Real Name="Value">98.499999999998693</Real>
<String Name="Name">T-Lipid</String>
<Real Name="Value">104.99999999999832</Real>
</EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Protein</String>
- <Real Name="Value">105.19999999999831</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Protein</String>
- <Real Name="Value">105.29999999999831</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Protein</String>
- <Real Name="Value">105.3999999999983</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Lipid</String>
- <Real Name="Value">105.49999999999829</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Lipid</String>
- <Real Name="Value">105.59999999999829</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Lipid</String>
- <Real Name="Value">105.69999999999828</Real>
- </EnergyTerm>
</Sequence>
</Frame>
<Frame>
<String Name="Step">600</String>
<String Name="NumSteps">0</String>
<Sequence Name="EnergyTerms">
- <Int Name="Length">97</Int>
+ <Int Name="Length">91</Int>
<EnergyTerm>
<String Name="Name">LJ-14</String>
<Real Name="Value">115.8999999999977</Real>
<String Name="Name">T-Lipid</String>
<Real Name="Value">122.39999999999733</Real>
</EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Protein</String>
- <Real Name="Value">122.59999999999732</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Protein</String>
- <Real Name="Value">122.69999999999732</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Protein</String>
- <Real Name="Value">122.79999999999731</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Lipid</String>
- <Real Name="Value">122.89999999999731</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Lipid</String>
- <Real Name="Value">122.9999999999973</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Lipid</String>
- <Real Name="Value">123.09999999999729</Real>
- </EnergyTerm>
</Sequence>
</Frame>
<Frame>
<String Name="Step">700</String>
<String Name="NumSteps">0</String>
<Sequence Name="EnergyTerms">
- <Int Name="Length">97</Int>
+ <Int Name="Length">91</Int>
<EnergyTerm>
<String Name="Name">LJ-14</String>
<Real Name="Value">133.29999999999671</Real>
<String Name="Name">T-Lipid</String>
<Real Name="Value">139.79999999999634</Real>
</EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Protein</String>
- <Real Name="Value">139.99999999999633</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Protein</String>
- <Real Name="Value">140.09999999999633</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Protein</String>
- <Real Name="Value">140.19999999999632</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Lipid</String>
- <Real Name="Value">140.29999999999632</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Lipid</String>
- <Real Name="Value">140.39999999999631</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Lipid</String>
- <Real Name="Value">140.49999999999631</Real>
- </EnergyTerm>
</Sequence>
</Frame>
<Frame>
<String Name="Step">800</String>
<String Name="NumSteps">0</String>
<Sequence Name="EnergyTerms">
- <Int Name="Length">97</Int>
+ <Int Name="Length">91</Int>
<EnergyTerm>
<String Name="Name">LJ-14</String>
<Real Name="Value">150.69999999999573</Real>
<String Name="Name">T-Lipid</String>
<Real Name="Value">157.19999999999536</Real>
</EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Protein</String>
- <Real Name="Value">157.39999999999534</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Protein</String>
- <Real Name="Value">157.49999999999534</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Protein</String>
- <Real Name="Value">157.59999999999533</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Lipid</String>
- <Real Name="Value">157.69999999999533</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Lipid</String>
- <Real Name="Value">157.79999999999532</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Lipid</String>
- <Real Name="Value">157.89999999999532</Real>
- </EnergyTerm>
</Sequence>
</Frame>
<Frame>
<String Name="Step">900</String>
<String Name="NumSteps">0</String>
<Sequence Name="EnergyTerms">
- <Int Name="Length">97</Int>
+ <Int Name="Length">91</Int>
<EnergyTerm>
<String Name="Name">LJ-14</String>
<Real Name="Value">168.09999999999474</Real>
<String Name="Name">T-Lipid</String>
<Real Name="Value">174.59999999999437</Real>
</EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Protein</String>
- <Real Name="Value">174.79999999999436</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Protein</String>
- <Real Name="Value">174.89999999999435</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Protein</String>
- <Real Name="Value">174.99999999999434</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Lipid</String>
- <Real Name="Value">175.09999999999434</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Lipid</String>
- <Real Name="Value">175.19999999999433</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Lipid</String>
- <Real Name="Value">175.29999999999433</Real>
- </EnergyTerm>
</Sequence>
</Frame>
</Sequence>
</File>
- <Int Name="Number of Energy Terms">97</Int>
+ <Int Name="Number of Energy Terms">91</Int>
<String Name="log">Current ref_t for group Water: 25.7
Current ref_t for group Lipid: 25.8
T-Protein T-Water T-Lipid
9.59000e+01 9.61000e+01 9.63000e+01
- Group Ux Uy Uz
- Protein 9.65000e+01 9.66000e+01 9.67000e+01
- Lipid 9.68000e+01 9.69000e+01 9.70000e+01
-
</String>
</ReferenceData>
<ReferenceData>
<File Name="EnergyFile">
<Sequence Name="EnergyTerms">
- <Int Name="Length">101</Int>
+ <Int Name="Length">95</Int>
<EnergyTerm>
<String Name="Name">LJ-14</String>
<String Name="Units">kJ/mol</String>
<String Name="Name">Lamb-Lipid</String>
<String Name="Units"></String>
</EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Protein</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Protein</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Protein</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Lipid</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Lipid</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Lipid</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
</Sequence>
<Sequence Name="Frames">
<Int Name="Length">1</Int>
<String Name="Step">0</String>
<String Name="NumSteps">0</String>
<Sequence Name="EnergyTerms">
- <Int Name="Length">101</Int>
+ <Int Name="Length">95</Int>
<EnergyTerm>
<String Name="Name">LJ-14</String>
<Real Name="Value">11.499999999999995</Real>
<String Name="Name">Lamb-Lipid</String>
<Real Name="Value">18.100000000000009</Real>
</EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Protein</String>
- <Real Name="Value">18.20000000000001</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Protein</String>
- <Real Name="Value">18.300000000000011</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Protein</String>
- <Real Name="Value">18.400000000000013</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Lipid</String>
- <Real Name="Value">18.500000000000014</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Lipid</String>
- <Real Name="Value">18.600000000000016</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Lipid</String>
- <Real Name="Value">18.700000000000017</Real>
- </EnergyTerm>
</Sequence>
</Frame>
</Sequence>
</File>
- <Int Name="Number of Energy Terms">101</Int>
+ <Int Name="Number of Energy Terms">95</Int>
<String Name="log">Current ref_t for group Water: 25.7
Current ref_t for group Lipid: 25.8
T-Protein T-Water T-Lipid
1.76000e+01 1.78000e+01 1.80000e+01
- Group Ux Uy Uz
- Protein 1.82000e+01 1.83000e+01 1.84000e+01
- Lipid 1.85000e+01 1.86000e+01 1.87000e+01
-
</String>
</ReferenceData>
<ReferenceData>
<File Name="EnergyFile">
<Sequence Name="EnergyTerms">
- <Int Name="Length">104</Int>
+ <Int Name="Length">98</Int>
<EnergyTerm>
<String Name="Name">LJ-14</String>
<String Name="Units">kJ/mol</String>
<String Name="Name">vXi-Lipid</String>
<String Name="Units">1/ps</String>
</EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Protein</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Protein</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Protein</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Lipid</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Lipid</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Lipid</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
</Sequence>
<Sequence Name="Frames">
<Int Name="Length">1</Int>
<String Name="Step">0</String>
<String Name="NumSteps">0</String>
<Sequence Name="EnergyTerms">
- <Int Name="Length">104</Int>
+ <Int Name="Length">98</Int>
<EnergyTerm>
<String Name="Name">LJ-14</String>
<Real Name="Value">11.499999999999995</Real>
<String Name="Name">vXi-Lipid</String>
<Real Name="Value">26.400000000000126</Real>
</EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Protein</String>
- <Real Name="Value">18.20000000000001</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Protein</String>
- <Real Name="Value">18.300000000000011</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Protein</String>
- <Real Name="Value">18.400000000000013</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Lipid</String>
- <Real Name="Value">18.500000000000014</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Lipid</String>
- <Real Name="Value">18.600000000000016</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Lipid</String>
- <Real Name="Value">18.700000000000017</Real>
- </EnergyTerm>
</Sequence>
</Frame>
</Sequence>
</File>
- <Int Name="Number of Energy Terms">104</Int>
+ <Int Name="Number of Energy Terms">98</Int>
<String Name="log">Current ref_t for group Water: 25.7
Current ref_t for group Lipid: 25.8
T-Protein T-Water T-Lipid
1.76000e+01 1.78000e+01 1.80000e+01
- Group Ux Uy Uz
- Protein 1.82000e+01 1.83000e+01 1.84000e+01
- Lipid 1.85000e+01 1.86000e+01 1.87000e+01
-
</String>
</ReferenceData>
<ReferenceData>
<File Name="EnergyFile">
<Sequence Name="EnergyTerms">
- <Int Name="Length">108</Int>
+ <Int Name="Length">102</Int>
<EnergyTerm>
<String Name="Name">LJ-14</String>
<String Name="Units">kJ/mol</String>
<String Name="Name">T-Lipid</String>
<String Name="Units">K</String>
</EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Protein</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Protein</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Protein</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Lipid</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Lipid</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Lipid</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
</Sequence>
<Sequence Name="Frames">
<Int Name="Length">1</Int>
<String Name="Step">0</String>
<String Name="NumSteps">0</String>
<Sequence Name="EnergyTerms">
- <Int Name="Length">108</Int>
+ <Int Name="Length">102</Int>
<EnergyTerm>
<String Name="Name">LJ-14</String>
<Real Name="Value">11.499999999999995</Real>
<String Name="Name">T-Lipid</String>
<Real Name="Value">18.000000000000007</Real>
</EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Protein</String>
- <Real Name="Value">18.20000000000001</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Protein</String>
- <Real Name="Value">18.300000000000011</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Protein</String>
- <Real Name="Value">18.400000000000013</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Lipid</String>
- <Real Name="Value">18.500000000000014</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Lipid</String>
- <Real Name="Value">18.600000000000016</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Lipid</String>
- <Real Name="Value">18.700000000000017</Real>
- </EnergyTerm>
</Sequence>
</Frame>
</Sequence>
</File>
- <Int Name="Number of Energy Terms">108</Int>
+ <Int Name="Number of Energy Terms">102</Int>
<String Name="log">Current ref_t for group Water: 25.7
Current ref_t for group Lipid: 25.8
T-Protein T-Water T-Lipid
1.76000e+01 1.78000e+01 1.80000e+01
- Group Ux Uy Uz
- Protein 1.82000e+01 1.83000e+01 1.84000e+01
- Lipid 1.85000e+01 1.86000e+01 1.87000e+01
-
</String>
</ReferenceData>
<ReferenceData>
<File Name="EnergyFile">
<Sequence Name="EnergyTerms">
- <Int Name="Length">108</Int>
+ <Int Name="Length">102</Int>
<EnergyTerm>
<String Name="Name">LJ-14</String>
<String Name="Units">kJ/mol</String>
<String Name="Name">T-Lipid</String>
<String Name="Units">K</String>
</EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Protein</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Protein</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Protein</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Lipid</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Lipid</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Lipid</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
</Sequence>
<Sequence Name="Frames">
<Int Name="Length">1</Int>
<String Name="Step">0</String>
<String Name="NumSteps">0</String>
<Sequence Name="EnergyTerms">
- <Int Name="Length">108</Int>
+ <Int Name="Length">102</Int>
<EnergyTerm>
<String Name="Name">LJ-14</String>
<Real Name="Value">11.499999999999995</Real>
<String Name="Name">T-Lipid</String>
<Real Name="Value">18.000000000000007</Real>
</EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Protein</String>
- <Real Name="Value">18.20000000000001</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Protein</String>
- <Real Name="Value">18.300000000000011</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Protein</String>
- <Real Name="Value">18.400000000000013</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Lipid</String>
- <Real Name="Value">18.500000000000014</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Lipid</String>
- <Real Name="Value">18.600000000000016</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Lipid</String>
- <Real Name="Value">18.700000000000017</Real>
- </EnergyTerm>
</Sequence>
</Frame>
</Sequence>
</File>
- <Int Name="Number of Energy Terms">108</Int>
+ <Int Name="Number of Energy Terms">102</Int>
<String Name="log">Current ref_t for group Water: 25.7
Current ref_t for group Lipid: 25.8
T-Protein T-Water T-Lipid
1.76000e+01 1.78000e+01 1.80000e+01
- Group Ux Uy Uz
- Protein 1.82000e+01 1.83000e+01 1.84000e+01
- Lipid 1.85000e+01 1.86000e+01 1.87000e+01
-
</String>
</ReferenceData>
<ReferenceData>
<File Name="EnergyFile">
<Sequence Name="EnergyTerms">
- <Int Name="Length">97</Int>
+ <Int Name="Length">91</Int>
<EnergyTerm>
<String Name="Name">LJ-14</String>
<String Name="Units">kJ/mol</String>
<String Name="Name">T-Lipid</String>
<String Name="Units">K</String>
</EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Protein</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Protein</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Protein</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Lipid</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Lipid</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Lipid</String>
- <String Name="Units">nm/ps</String>
- </EnergyTerm>
</Sequence>
<Sequence Name="Frames">
<Int Name="Length">1</Int>
<String Name="Step">0</String>
<String Name="NumSteps">0</String>
<Sequence Name="EnergyTerms">
- <Int Name="Length">97</Int>
+ <Int Name="Length">91</Int>
<EnergyTerm>
<String Name="Name">LJ-14</String>
<Real Name="Value">11.499999999999995</Real>
<String Name="Name">T-Lipid</String>
<Real Name="Value">18.000000000000007</Real>
</EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Protein</String>
- <Real Name="Value">18.20000000000001</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Protein</String>
- <Real Name="Value">18.300000000000011</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Protein</String>
- <Real Name="Value">18.400000000000013</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Ux-Lipid</String>
- <Real Name="Value">18.500000000000014</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uy-Lipid</String>
- <Real Name="Value">18.600000000000016</Real>
- </EnergyTerm>
- <EnergyTerm>
- <String Name="Name">Uz-Lipid</String>
- <Real Name="Value">18.700000000000017</Real>
- </EnergyTerm>
</Sequence>
</Frame>
</Sequence>
</File>
- <Int Name="Number of Energy Terms">97</Int>
+ <Int Name="Number of Energy Terms">91</Int>
<String Name="log">Current ref_t for group Water: 25.7
Current ref_t for group Lipid: 25.8
T-Protein T-Water T-Lipid
1.76000e+01 1.78000e+01 1.80000e+01
- Group Ux Uy Uz
- Protein 1.82000e+01 1.83000e+01 1.84000e+01
- Lipid 1.85000e+01 1.86000e+01 1.87000e+01
-
</String>
</ReferenceData>
// being tested, to help make failing tests comprehensible.
std::string testDescription = formatString(
"Testing %s with %d SETTLEs, %s, %svelocities and %scalculating the virial.",
- runner->hardwareDescription().c_str(), numSettles, pbcName.c_str(),
- updateVelocities ? "with " : "without ", calcVirial ? "" : "not ");
+ runner->hardwareDescription().c_str(),
+ numSettles,
+ pbcName.c_str(),
+ updateVelocities ? "with " : "without ",
+ calcVirial ? "" : "not ");
SCOPED_TRACE(testDescription);
{
SettleData settled(testData->mtop_);
- settled.setConstraints(testData->idef_->il[F_SETTLE], testData->numAtoms_,
- testData->masses_.data(), testData->inverseMasses_.data());
+ settled.setConstraints(testData->idef_->il[F_SETTLE],
+ testData->numAtoms_,
+ testData->masses_.data(),
+ testData->inverseMasses_.data());
bool errorOccured;
int numThreads = 1;
int threadIndex = 0;
- csettle(settled, numThreads, threadIndex, &pbc, testData->x_.arrayRefWithPadding(),
- testData->xPrime_.arrayRefWithPadding(), testData->reciprocalTimeStep_,
+ csettle(settled,
+ numThreads,
+ threadIndex,
+ &pbc,
+ testData->x_.arrayRefWithPadding(),
+ testData->xPrime_.arrayRefWithPadding(),
+ testData->reciprocalTimeStep_,
updateVelocities ? testData->v_.arrayRefWithPadding() : ArrayRefWithPadding<RVec>(),
- calcVirial, testData->virial_, &errorOccured);
+ calcVirial,
+ testData->virial_,
+ &errorOccured);
EXPECT_FALSE(errorOccured) << testDescription;
}
{
copyToDeviceBuffer(&d_v, (float3*)h_v, 0, numAtoms, deviceStream, GpuApiCallBehavior::Sync, nullptr);
}
- settleGpu->apply(d_x, d_xp, updateVelocities, d_v, testData->reciprocalTimeStep_, calcVirial,
- testData->virial_, pbcAiuc);
+ settleGpu->apply(
+ d_x, d_xp, updateVelocities, d_v, testData->reciprocalTimeStep_, calcVirial, testData->virial_, pbcAiuc);
copyFromDeviceBuffer((float3*)h_xp, &d_xp, 0, numAtoms, deviceStream, GpuApiCallBehavior::Sync, nullptr);
if (updateVelocities)
{
- copyFromDeviceBuffer((float3*)h_v, &d_v, 0, numAtoms, deviceStream,
- GpuApiCallBehavior::Sync, nullptr);
+ copyFromDeviceBuffer(
+ (float3*)h_v, &d_v, 0, numAtoms, deviceStream, GpuApiCallBehavior::Sync, nullptr);
}
freeDeviceBuffer(&d_x);
int numIterations = 0;
int numErrors = 0;
- cshake(iatom.data(), numConstraints, &numIterations, ShakeTest::maxNumIterations_,
- constrainedDistancesSquared, finalPositions, nullptr, initialDisplacements,
- halfOfReducedMasses, omega_, inverseMasses.data(), distanceSquaredTolerances,
- lagrangianValues, &numErrors);
+ cshake(iatom.data(),
+ numConstraints,
+ &numIterations,
+ ShakeTest::maxNumIterations_,
+ constrainedDistancesSquared,
+ finalPositions,
+ nullptr,
+ initialDisplacements,
+ halfOfReducedMasses,
+ omega_,
+ inverseMasses.data(),
+ distanceSquaredTolerances,
+ lagrangianValues,
+ &numErrors);
std::vector<RVec> finalDisplacements = computeDisplacements(iatom, finalPositions);
std::vector<real> finalDistancesSquared = computeDistancesSquared(finalDisplacements);
+ coordMax * GMX_REAL_EPS);
// Assert that the constrained distances are within the required tolerance
EXPECT_FLOAT_EQ_TOL(std::sqrt(constrainedDistancesSquared[i]),
- std::sqrt(finalDistancesSquared[i]), constraintTolerance);
+ std::sqrt(finalDistancesSquared[i]),
+ constraintTolerance);
}
}
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
-static void init_grpstat(const gmx_mtop_t* mtop, int ngacc, t_grp_acc gstat[])
-{
- if (ngacc > 0)
- {
- const SimulationGroups& groups = mtop->groups;
- for (const AtomProxy atomP : AtomRange(*mtop))
- {
- const t_atom& local = atomP.atom();
- int i = atomP.globalAtomNumber();
- int grp = getGroupType(groups, SimulationAtomGroupType::Acceleration, i);
- if ((grp < 0) && (grp >= ngacc))
- {
- gmx_incons("Input for acceleration groups wrong");
- }
- gstat[grp].nat++;
- /* This will not work for integrator BD */
- gstat[grp].mA += local.m;
- gstat[grp].mB += local.mB;
- }
- }
-}
-
-void init_ekindata(FILE gmx_unused* log,
- const gmx_mtop_t* mtop,
- const t_grpopts* opts,
- gmx_ekindata_t* ekind,
- real cos_accel)
+void init_ekindata(FILE gmx_unused* log, const t_grpopts* opts, gmx_ekindata_t* ekind, real cos_accel)
{
int i;
- /* bNEMD tells if we should remove remove the COM velocity
- * from the velocities during velocity scaling in T-coupling.
- * Turn this on when we have multiple acceleration groups
- * or one accelerated group.
- */
- ekind->bNEMD = (opts->ngacc > 1 || norm2(opts->acc[0]) > 0);
-
ekind->ngtc = opts->ngtc;
ekind->tcstat.resize(opts->ngtc);
/* Set Berendsen tcoupl lambda's to 1,
GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
}
- ekind->ngacc = opts->ngacc;
- ekind->grpstat.resize(opts->ngacc);
- init_grpstat(mtop, opts->ngacc, ekind->grpstat.data());
-
ekind->cosacc.cos_accel = cos_accel;
}
-void accumulate_u(const t_commrec* cr, const t_grpopts* opts, gmx_ekindata_t* ekind)
-{
- /* This routine will only be called when it's necessary */
- t_bin* rb;
- int g;
-
- rb = mk_bin();
-
- for (g = 0; (g < opts->ngacc); g++)
- {
- add_binr(rb, DIM, ekind->grpstat[g].u);
- }
- sum_bin(rb, cr);
-
- for (g = 0; (g < opts->ngacc); g++)
- {
- extract_binr(rb, DIM * g, DIM, ekind->grpstat[g].u);
- }
- destroy_bin(rb);
-}
-
-void update_ekindata(int start,
- int homenr,
- gmx_ekindata_t* ekind,
- const t_grpopts* opts,
- const rvec v[],
- const t_mdatoms* md,
- real lambda)
-{
- int d, g, n;
- real mv;
-
- /* calculate mean velocities at whole timestep */
- for (g = 0; (g < opts->ngtc); g++)
- {
- ekind->tcstat[g].T = 0;
- }
-
- if (ekind->bNEMD)
- {
- for (g = 0; (g < opts->ngacc); g++)
- {
- clear_rvec(ekind->grpstat[g].u);
- }
-
- g = 0;
- for (n = start; (n < start + homenr); n++)
- {
- if (md->cACC)
- {
- g = md->cACC[n];
- }
- for (d = 0; (d < DIM); d++)
- {
- mv = md->massT[n] * v[n][d];
- ekind->grpstat[g].u[d] += mv;
- }
- }
-
- for (g = 0; (g < opts->ngacc); g++)
- {
- for (d = 0; (d < DIM); d++)
- {
- ekind->grpstat[g].u[d] /=
- (1 - lambda) * ekind->grpstat[g].mA + lambda * ekind->grpstat[g].mB;
- }
- }
- }
-}
-
real sum_ekin(const t_grpopts* opts, gmx_ekindata_t* ekind, real* dekindlambda, gmx_bool bEkinAveVel, gmx_bool bScaleEkin)
{
int i, j, m, ngtc;
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2018,2019,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <cstdio>
-#include "gromacs/math/vectypes.h"
#include "gromacs/utility/basedefinitions.h"
#include "gromacs/utility/real.h"
struct gmx_ekindata_t;
-struct gmx_mtop_t;
struct t_commrec;
struct t_grpopts;
struct t_mdatoms;
-void init_ekindata(FILE* log, const gmx_mtop_t* mtop, const t_grpopts* opts, gmx_ekindata_t* ekind, real cos_accel);
+void init_ekindata(FILE* log, const t_grpopts* opts, gmx_ekindata_t* ekind, real cos_accel);
/* Allocate memory and set the grpnr array. */
void done_ekindata(gmx_ekindata_t* ekind);
/* Free the memory */
-void accumulate_u(const t_commrec* cr, const t_grpopts* opts, gmx_ekindata_t* ekind);
-
-/* Communicate subsystem - group velocities and subsystem ekin respectively
- * and sum them up. Return them in grps.
- */
-
real sum_ekin(const t_grpopts* opts, gmx_ekindata_t* ekind, real* dekindlambda, gmx_bool bEkinFullStep, gmx_bool bScaleEkin);
/* Sum the group ekins into total ekin and calc temp per group,
* return total temperature.
*/
-void update_ekindata(int start,
- int homenr,
- gmx_ekindata_t* ekind,
- const t_grpopts* opts,
- const rvec v[],
- const t_mdatoms* md,
- real lambda);
-/* Do the update of group velocities (if bNEMD) and
- * (partial) group ekin.
- */
-
#endif
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2013,2014,2015,2016,2017, The GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
int64_t step,
int64_t step_rel,
double t,
- t_inputrec* ir,
+ const t_inputrec* ir,
t_state* state,
t_state* state_global,
ObservablesHistory* observablesHistory,
// Note that part of the following code is duplicated in StatePropagatorData::trajectoryWriterTeardown.
// This duplication is needed while both legacy and modular code paths are in use.
// TODO: Remove duplication asap, make sure to keep in sync in the meantime.
- mdoutf_write_to_trajectory_files(fplog, cr, outf, mdof_flags, top_global->natoms, step, t, state,
- state_global, observablesHistory, f, &checkpointDataHolder);
+ mdoutf_write_to_trajectory_files(
+ fplog, cr, outf, mdof_flags, top_global->natoms, step, t, state, state_global, observablesHistory, f, &checkpointDataHolder);
if (bLastStep && step_rel == ir->nsteps && bDoConfOut && MASTER(cr) && !bRerunMD)
{
if (fr->bMolPBC && state == state_global)
/* Make molecules whole only for confout writing */
do_pbc_mtop(ir->pbcType, state->box, top_global, x_for_confout);
}
- write_sto_conf_mtop(ftp2fn(efSTO, nfile, fnm), *top_global->name, top_global,
- x_for_confout, state_global->v.rvec_array(), ir->pbcType, state->box);
+ write_sto_conf_mtop(ftp2fn(efSTO, nfile, fnm),
+ *top_global->name,
+ top_global,
+ x_for_confout,
+ state_global->v.rvec_array(),
+ ir->pbcType,
+ state->box);
if (fr->bMolPBC && state == state_global)
{
sfree(x_for_confout);
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
int64_t step,
int64_t step_rel,
double t,
- t_inputrec* ir,
+ const t_inputrec* ir,
t_state* state,
t_state* state_global,
ObservablesHistory* observablesHistory,
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
const t_commrec* cr,
const bool haveConstraints)
{
- return impl_->update_coords(inputRecord, step, md, state, f, fcdata, ekind, M, updatePart, cr,
- haveConstraints);
+ return impl_->update_coords(
+ inputRecord, step, md, state, f, fcdata, ekind, M, updatePart, cr, haveConstraints);
}
void Update::finish_update(const t_inputrec& inputRecord,
bool do_log,
bool do_ene)
{
- return impl_->update_sd_second_half(inputRecord, step, dvdlambda, md, state, cr, nrnb, wcycle,
- constr, do_log, do_ene);
+ return impl_->update_sd_second_half(
+ inputRecord, step, dvdlambda, md, state, cr, nrnb, wcycle, constr, do_log, do_ene);
}
void Update::update_for_constraint_virial(const t_inputrec& inputRecord,
enum class AccelerationType
{
none,
- group,
cosine
};
* \param[in] dt The time step.
* \param[in] dtPressureCouple Time step for pressure coupling, is 0 when no pressure
* coupling should be applied at this step.
- * \param[in] accel Acceleration per group.
* \param[in] md Atom properties.
* \param[in] ekind Kinetic energy data.
* \param[in] box The box dimensions.
bool doNoseHoover,
real dt,
real dtPressureCouple,
- const rvec* accel,
const t_mdatoms* md,
const gmx_ekindata_t* ekind,
const matrix box,
* Holian et al. Phys Rev E 52(3) : 2338, 1995
*/
- gmx::ArrayRef<const t_grp_tcstat> tcstat = ekind->tcstat;
- gmx::ArrayRef<const t_grp_acc> grpstat = ekind->grpstat;
- const unsigned short* cTC = md->cTC;
- const unsigned short* cACC = md->cACC;
+ gmx::ArrayRef<const t_grp_tcstat> tcstat = ekind->tcstat;
+ const unsigned short* cTC = md->cTC;
const rvec* gmx_restrict invMassPerDim = md->invMassPerDim;
/* Initialize group values, changed later when multiple groups are used */
- int ga = 0;
int gt = 0;
real omega_Z = 2 * static_cast<real>(M_PI) / box[ZZ][ZZ];
rvec vRel;
real cosineZ, vCosine;
-#ifdef __INTEL_COMPILER
-# pragma warning(disable : 280)
-#endif
switch (accelerationType)
{
case AccelerationType::none: copy_rvec(v[n], vRel); break;
- case AccelerationType::group:
- if (cACC)
- {
- ga = cACC[n];
- }
- /* Avoid scaling the group velocity */
- rvec_sub(v[n], grpstat[ga].u, vRel);
- break;
case AccelerationType::cosine:
cosineZ = std::cos(x[n][ZZ] * omega_Z);
vCosine = cosineZ * ekind->cosacc.vcos;
switch (accelerationType)
{
case AccelerationType::none: break;
- case AccelerationType::group:
- /* Add back the mean velocity and apply acceleration */
- vNew += grpstat[ga].u[d] + accel[ga][d] * dt;
- break;
case AccelerationType::cosine:
if (d == XX)
{
const rvec* gmx_restrict x,
rvec* gmx_restrict xprime,
rvec* gmx_restrict v,
- const rvec* gmx_restrict f,
- const rvec* gmx_restrict accel,
- const int etc,
- const int epc,
- const int nsttcouple,
- const int nstpcouple,
- const t_mdatoms* md,
- const gmx_ekindata_t* ekind,
- const matrix box,
+ const rvec* gmx_restrict f,
+ const TemperatureCoupling etc,
+ const PressureCoupling epc,
+ const int nsttcouple,
+ const int nstpcouple,
+ const t_mdatoms* md,
+ const gmx_ekindata_t* ekind,
+ const matrix box,
const double* gmx_restrict nh_vxi,
const matrix M)
{
"For SIMD optimization certain compilers need to have xprime != x");
/* Note: Berendsen pressure scaling is handled after do_update_md() */
- bool doTempCouple = (etc != etcNO && do_per_step(step + nsttcouple - 1, nsttcouple));
- bool doNoseHoover = (etc == etcNOSEHOOVER && doTempCouple);
- bool doParrinelloRahman =
- (epc == epcPARRINELLORAHMAN && do_per_step(step + nstpcouple - 1, nstpcouple));
+ bool doTempCouple =
+ (etc != TemperatureCoupling::No && do_per_step(step + nsttcouple - 1, nsttcouple));
+ bool doNoseHoover = (etc == TemperatureCoupling::NoseHoover && doTempCouple);
+ bool doParrinelloRahman = (epc == PressureCoupling::ParrinelloRahman
+ && do_per_step(step + nstpcouple - 1, nstpcouple));
bool doPROffDiagonal = (doParrinelloRahman && (M[YY][XX] != 0 || M[ZZ][XX] != 0 || M[ZZ][YY] != 0));
real dtPressureCouple = (doParrinelloRahman ? nstpcouple * dt : 0);
- /* NEMD (also cosine) acceleration is applied in updateMDLeapFrogGeneral */
- bool doAcceleration = (ekind->bNEMD || ekind->cosacc.cos_accel != 0);
+ /* NEMD cosine acceleration is applied in updateMDLeapFrogGeneral */
+ bool doAcceleration = (ekind->cosacc.cos_accel != 0);
if (doNoseHoover || doPROffDiagonal || doAcceleration)
{
if (!doAcceleration)
{
- updateMDLeapfrogGeneral<AccelerationType::none>(start, nrend, doNoseHoover, dt,
- dtPressureCouple, accel, md, ekind, box, x,
- xprime, v, f, nh_vxi, nsttcouple, stepM);
- }
- else if (ekind->bNEMD)
- {
- updateMDLeapfrogGeneral<AccelerationType::group>(
- start, nrend, doNoseHoover, dt, dtPressureCouple, accel, md, ekind, box, x,
- xprime, v, f, nh_vxi, nsttcouple, stepM);
+ updateMDLeapfrogGeneral<AccelerationType::none>(
+ start, nrend, doNoseHoover, dt, dtPressureCouple, md, ekind, box, x, xprime, v, f, nh_vxi, nsttcouple, stepM);
}
else
{
updateMDLeapfrogGeneral<AccelerationType::cosine>(
- start, nrend, doNoseHoover, dt, dtPressureCouple, accel, md, ekind, box, x,
- xprime, v, f, nh_vxi, nsttcouple, stepM);
+ start, nrend, doNoseHoover, dt, dtPressureCouple, md, ekind, box, x, xprime, v, f, nh_vxi, nsttcouple, stepM);
}
}
else
if (haveSingleTempScaleValue)
{
- updateMDLeapfrogSimple<StoreUpdatedVelocities::yes, NumTempScaleValues::single,
- ApplyParrinelloRahmanVScaling::diagonal>(
- start, nrend, dt, dtPressureCouple, invMassPerDim, tcstat, cTC, diagM, x,
- xprime, v, f);
+ updateMDLeapfrogSimple<StoreUpdatedVelocities::yes, NumTempScaleValues::single, ApplyParrinelloRahmanVScaling::diagonal>(
+ start, nrend, dt, dtPressureCouple, invMassPerDim, tcstat, cTC, diagM, x, xprime, v, f);
}
else
{
- updateMDLeapfrogSimple<StoreUpdatedVelocities::yes, NumTempScaleValues::multiple,
- ApplyParrinelloRahmanVScaling::diagonal>(
- start, nrend, dt, dtPressureCouple, invMassPerDim, tcstat, cTC, diagM, x,
- xprime, v, f);
+ updateMDLeapfrogSimple<StoreUpdatedVelocities::yes, NumTempScaleValues::multiple, ApplyParrinelloRahmanVScaling::diagonal>(
+ start, nrend, dt, dtPressureCouple, invMassPerDim, tcstat, cTC, diagM, x, xprime, v, f);
}
}
else
else
#endif
{
- updateMDLeapfrogSimple<StoreUpdatedVelocities::yes, NumTempScaleValues::single,
- ApplyParrinelloRahmanVScaling::no>(
- start, nrend, dt, dtPressureCouple, invMassPerDim, tcstat, cTC, nullptr,
- x, xprime, v, f);
+ updateMDLeapfrogSimple<StoreUpdatedVelocities::yes, NumTempScaleValues::single, ApplyParrinelloRahmanVScaling::no>(
+ start, nrend, dt, dtPressureCouple, invMassPerDim, tcstat, cTC, nullptr, x, xprime, v, f);
}
}
else
{
- updateMDLeapfrogSimple<StoreUpdatedVelocities::yes, NumTempScaleValues::multiple,
- ApplyParrinelloRahmanVScaling::no>(
- start, nrend, dt, dtPressureCouple, invMassPerDim, tcstat, cTC, nullptr, x,
- xprime, v, f);
+ updateMDLeapfrogSimple<StoreUpdatedVelocities::yes, NumTempScaleValues::multiple, ApplyParrinelloRahmanVScaling::no>(
+ start, nrend, dt, dtPressureCouple, invMassPerDim, tcstat, cTC, nullptr, x, xprime, v, f);
}
}
}
#if GMX_HAVE_SIMD_UPDATE
if (!md.havePartiallyFrozenAtoms)
{
- updateMDLeapfrogSimpleSimd<StoreUpdatedVelocities::no>(start, nrend, dt, md.invmass, tcstat,
- x, xprime, v, f);
+ updateMDLeapfrogSimpleSimd<StoreUpdatedVelocities::no>(
+ start, nrend, dt, md.invmass, tcstat, x, xprime, v, f);
}
else
#endif
static void do_update_vv_vel(int start,
int nrend,
real dt,
- const rvec accel[],
const ivec nFreeze[],
const real invmass[],
const unsigned short ptype[],
const unsigned short cFREEZE[],
- const unsigned short cACC[],
rvec v[],
const rvec f[],
gmx_bool bExtended,
real veta,
real alpha)
{
- int gf = 0, ga = 0;
+ int gf = 0;
int n, d;
real g, mv1, mv2;
{
gf = cFREEZE[n];
}
- if (cACC)
- {
- ga = cACC[n];
- }
for (d = 0; d < DIM; d++)
{
if ((ptype[n] != eptVSite) && (ptype[n] != eptShell) && !nFreeze[gf][d])
{
- v[n][d] = mv1 * (mv1 * v[n][d] + 0.5 * (w_dt * mv2 * f[n][d])) + 0.5 * accel[ga][d] * dt;
+ v[n][d] = mv1 * (mv1 * v[n][d] + 0.5 * (w_dt * mv2 * f[n][d]));
}
else
{
int start,
int nrend,
real dt,
- const rvec accel[],
const ivec nFreeze[],
const real invmass[],
const unsigned short ptype[],
const unsigned short cFREEZE[],
- const unsigned short cACC[],
const unsigned short cTC[],
const rvec x[],
rvec xprime[],
int seed,
const int* gatindex)
{
- // cTC, cACC and cFREEZE can be nullptr any time, but various
+ // cTC and cFREEZE can be nullptr any time, but various
// instantiations do not make sense with particular pointer
// values.
if (updateType == SDUpdate::ForcesOnly)
if (updateType == SDUpdate::FrictionAndNoiseOnly)
{
GMX_ASSERT(f == nullptr, "SD update with only noise cannot handle forces");
- GMX_ASSERT(cACC == nullptr, "SD update with only noise cannot handle acceleration groups");
}
if (updateType == SDUpdate::Combined)
{
real inverseMass = invmass[n];
real invsqrtMass = std::sqrt(inverseMass);
- int freezeGroup = cFREEZE ? cFREEZE[n] : 0;
- int accelerationGroup = cACC ? cACC[n] : 0;
- int temperatureGroup = cTC ? cTC[n] : 0;
+ int freezeGroup = cFREEZE ? cFREEZE[n] : 0;
+ int temperatureGroup = cTC ? cTC[n] : 0;
for (int d = 0; d < DIM; d++)
{
{
if (updateType == SDUpdate::ForcesOnly)
{
- real vn = v[n][d] + (inverseMass * f[n][d] + accel[accelerationGroup][d]) * dt;
+ real vn = v[n][d] + inverseMass * f[n][d] * dt;
v[n][d] = vn;
// Simple position update.
xprime[n][d] = x[n][d] + v[n][d] * dt;
}
else
{
- real vn = v[n][d] + (inverseMass * f[n][d] + accel[accelerationGroup][d]) * dt;
+ real vn = v[n][d] + inverseMass * f[n][d] * dt;
v[n][d] = (vn * sd.sdc[temperatureGroup].em
+ invsqrtMass * sd.sdsig[temperatureGroup].V * dist(rng));
// Here we include half of the friction+noise
rvec* gmx_restrict xprime,
rvec* gmx_restrict v,
const rvec* gmx_restrict f,
- const rvec accel[],
const ivec nFreeze[],
const real invmass[],
const unsigned short ptype[],
const unsigned short cFREEZE[],
- const unsigned short cACC[],
const unsigned short cTC[],
int seed,
const t_commrec* cr,
if (haveConstraints)
{
// With constraints, the SD update is done in 2 parts
- doSDUpdateGeneral<SDUpdate::ForcesOnly>(sd, start, nrend, dt, accel, nFreeze, invmass,
- ptype, cFREEZE, cACC, nullptr, x, xprime, v, f,
- step, seed, nullptr);
+ doSDUpdateGeneral<SDUpdate::ForcesOnly>(
+ sd, start, nrend, dt, nFreeze, invmass, ptype, cFREEZE, nullptr, x, xprime, v, f, step, seed, nullptr);
}
else
{
- doSDUpdateGeneral<SDUpdate::Combined>(
- sd, start, nrend, dt, accel, nFreeze, invmass, ptype, cFREEZE, cACC, cTC, x, xprime,
- v, f, step, seed, DOMAINDECOMP(cr) ? cr->dd->globalAtomIndices.data() : nullptr);
+ doSDUpdateGeneral<SDUpdate::Combined>(sd,
+ start,
+ nrend,
+ dt,
+ nFreeze,
+ invmass,
+ ptype,
+ cFREEZE,
+ cTC,
+ x,
+ xprime,
+ v,
+ f,
+ step,
+ seed,
+ DOMAINDECOMP(cr) ? cr->dd->globalAtomIndices.data() : nullptr);
}
}
gmx_bcast(sizeof(n), &n, cr->mpi_comm_mygroup);
for (i = 0; i < n; i++)
{
- gmx_bcast(DIM * DIM * sizeof(ekind->tcstat[i].ekinh[0][0]), ekind->tcstat[i].ekinh[0],
+ gmx_bcast(DIM * DIM * sizeof(ekind->tcstat[i].ekinh[0][0]),
+ ekind->tcstat[i].ekinh[0],
cr->mpi_comm_mygroup);
- gmx_bcast(DIM * DIM * sizeof(ekind->tcstat[i].ekinf[0][0]), ekind->tcstat[i].ekinf[0],
+ gmx_bcast(DIM * DIM * sizeof(ekind->tcstat[i].ekinf[0][0]),
+ ekind->tcstat[i].ekinf[0],
cr->mpi_comm_mygroup);
gmx_bcast(DIM * DIM * sizeof(ekind->tcstat[i].ekinh_old[0][0]),
- ekind->tcstat[i].ekinh_old[0], cr->mpi_comm_mygroup);
-
- gmx_bcast(sizeof(ekind->tcstat[i].ekinscalef_nhc), &(ekind->tcstat[i].ekinscalef_nhc),
+ ekind->tcstat[i].ekinh_old[0],
cr->mpi_comm_mygroup);
- gmx_bcast(sizeof(ekind->tcstat[i].ekinscaleh_nhc), &(ekind->tcstat[i].ekinscaleh_nhc),
+
+ gmx_bcast(sizeof(ekind->tcstat[i].ekinscalef_nhc),
+ &(ekind->tcstat[i].ekinscalef_nhc),
cr->mpi_comm_mygroup);
- gmx_bcast(sizeof(ekind->tcstat[i].vscale_nhc), &(ekind->tcstat[i].vscale_nhc),
+ gmx_bcast(sizeof(ekind->tcstat[i].ekinscaleh_nhc),
+ &(ekind->tcstat[i].ekinscaleh_nhc),
cr->mpi_comm_mygroup);
+ gmx_bcast(sizeof(ekind->tcstat[i].vscale_nhc), &(ekind->tcstat[i].vscale_nhc), cr->mpi_comm_mygroup);
}
gmx_bcast(DIM * DIM * sizeof(ekind->ekin[0][0]), ekind->ekin[0], cr->mpi_comm_mygroup);
getThreadAtomRange(nth, th, homenr, &start_th, &end_th);
doSDUpdateGeneral<SDUpdate::FrictionAndNoiseOnly>(
- sd_, start_th, end_th, dt, inputRecord.opts.acc, inputRecord.opts.nFreeze,
- md->invmass, md->ptype, md->cFREEZE, nullptr, md->cTC, state->x.rvec_array(),
- xp_.rvec_array(), state->v.rvec_array(), nullptr, step, inputRecord.ld_seed,
+ sd_,
+ start_th,
+ end_th,
+ dt,
+ inputRecord.opts.nFreeze,
+ md->invmass,
+ md->ptype,
+ md->cFREEZE,
+ md->cTC,
+ state->x.rvec_array(),
+ xp_.rvec_array(),
+ state->v.rvec_array(),
+ nullptr,
+ step,
+ inputRecord.ld_seed,
DOMAINDECOMP(cr) ? cr->dd->globalAtomIndices.data() : nullptr);
}
GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
/* Constrain the coordinates upd->xp for half a time step */
bool computeVirial = false;
- constr->apply(do_log, do_ene, step, 1, 0.5, state->x.arrayRefWithPadding(),
- xp_.arrayRefWithPadding(), ArrayRef<RVec>(), state->box,
- state->lambda[efptBONDED], dvdlambda, state->v.arrayRefWithPadding(),
- computeVirial, nullptr, ConstraintVariable::Positions);
+ constr->apply(do_log,
+ do_ene,
+ step,
+ 1,
+ 0.5,
+ state->x.arrayRefWithPadding(),
+ xp_.arrayRefWithPadding(),
+ ArrayRef<RVec>(),
+ state->box,
+ state->lambda[efptBONDED],
+ dvdlambda,
+ state->v.arrayRefWithPadding(),
+ computeVirial,
+ nullptr,
+ ConstraintVariable::Positions);
}
}
switch (inputRecord.eI)
{
case (eiMD):
- do_update_md(start_th, end_th, dt, step, x_rvec, xp_rvec, v_rvec, f_rvec,
- inputRecord.opts.acc, inputRecord.etc, inputRecord.epc,
- inputRecord.nsttcouple, inputRecord.nstpcouple, md, ekind,
- state->box, state->nosehoover_vxi.data(), M);
+ do_update_md(start_th,
+ end_th,
+ dt,
+ step,
+ x_rvec,
+ xp_rvec,
+ v_rvec,
+ f_rvec,
+ inputRecord.etc,
+ inputRecord.epc,
+ inputRecord.nsttcouple,
+ inputRecord.nstpcouple,
+ md,
+ ekind,
+ state->box,
+ state->nosehoover_vxi.data(),
+ M);
break;
case (eiSD1):
- do_update_sd(start_th, end_th, dt, step, x_rvec, xp_rvec, v_rvec, f_rvec,
- inputRecord.opts.acc, inputRecord.opts.nFreeze, md->invmass,
- md->ptype, md->cFREEZE, md->cACC, md->cTC, inputRecord.ld_seed, cr,
- sd_, haveConstraints);
+ do_update_sd(start_th,
+ end_th,
+ dt,
+ step,
+ x_rvec,
+ xp_rvec,
+ v_rvec,
+ f_rvec,
+ inputRecord.opts.nFreeze,
+ md->invmass,
+ md->ptype,
+ md->cFREEZE,
+ md->cTC,
+ inputRecord.ld_seed,
+ cr,
+ sd_,
+ haveConstraints);
break;
case (eiBD):
- do_update_bd(start_th, end_th, dt, step, x_rvec, xp_rvec, v_rvec, f_rvec,
- inputRecord.opts.nFreeze, md->invmass, md->ptype, md->cFREEZE,
- md->cTC, inputRecord.bd_fric, sd_.bd_rf.data(), inputRecord.ld_seed,
+ do_update_bd(start_th,
+ end_th,
+ dt,
+ step,
+ x_rvec,
+ xp_rvec,
+ v_rvec,
+ f_rvec,
+ inputRecord.opts.nFreeze,
+ md->invmass,
+ md->ptype,
+ md->cFREEZE,
+ md->cTC,
+ inputRecord.bd_fric,
+ sd_.bd_rf.data(),
+ inputRecord.ld_seed,
DOMAINDECOMP(cr) ? cr->dd->globalAtomIndices.data() : nullptr);
break;
case (eiVV):
case (eiVVAK):
{
- gmx_bool bExtended = (inputRecord.etc == etcNOSEHOOVER || inputRecord.epc == epcPARRINELLORAHMAN
- || inputRecord.epc == epcMTTK);
+ gmx_bool bExtended = (inputRecord.etc == TemperatureCoupling::NoseHoover
+ || inputRecord.epc == PressureCoupling::ParrinelloRahman
+ || inputRecord.epc == PressureCoupling::Mttk);
/* assuming barostat coupled to group 0 */
real alpha = 1.0 + DIM / static_cast<real>(inputRecord.opts.nrdf[0]);
{
case etrtVELOCITY1:
case etrtVELOCITY2:
- do_update_vv_vel(start_th, end_th, dt, inputRecord.opts.acc,
- inputRecord.opts.nFreeze, md->invmass, md->ptype, md->cFREEZE,
- md->cACC, v_rvec, f_rvec, bExtended, state->veta, alpha);
+ do_update_vv_vel(start_th,
+ end_th,
+ dt,
+ inputRecord.opts.nFreeze,
+ md->invmass,
+ md->ptype,
+ md->cFREEZE,
+ v_rvec,
+ f_rvec,
+ bExtended,
+ state->veta,
+ alpha);
break;
case etrtPOSITION:
- do_update_vv_pos(start_th, end_th, dt, inputRecord.opts.nFreeze,
- md->ptype, md->cFREEZE, x_rvec, xp_rvec, v_rvec,
- bExtended, state->veta);
+ do_update_vv_pos(start_th,
+ end_th,
+ dt,
+ inputRecord.opts.nFreeze,
+ md->ptype,
+ md->cFREEZE,
+ x_rvec,
+ xp_rvec,
+ v_rvec,
+ bExtended,
+ state->veta);
break;
}
break;
rvec* v_rvec = const_cast<rvec*>(state.v.rvec_array());
const rvec* f_rvec = as_rvec_array(f.unpaddedConstArrayRef().data());
- doUpdateMDDoNotUpdateVelocities(start_th, end_th, dt, x_rvec, xp_rvec, v_rvec, f_rvec,
- md, ekind);
+ doUpdateMDDoNotUpdateVelocities(
+ start_th, end_th, dt, x_rvec, xp_rvec, v_rvec, f_rvec, md, ekind);
}
GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
}
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
#ifndef GMX_MDLIB_UPDATE_H
#define GMX_MDLIB_UPDATE_H
+#include <memory>
+
#include "gromacs/math/paddedvector.h"
#include "gromacs/math/vectypes.h"
#include "gromacs/mdtypes/md_enums.h"
#include "gromacs/timing/wallcycle.h"
#include "gromacs/utility/arrayref.h"
#include "gromacs/utility/basedefinitions.h"
-#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/real.h"
class ekinstate_t;
//! Implementation type.
class Impl;
//! Implementation object.
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
}; // namespace gmx
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
#ifndef GMX_MDLIB_UPDATE_CONSTRAIN_GPU_H
#define GMX_MDLIB_UPDATE_CONSTRAIN_GPU_H
+#include <memory>
+
#include "gromacs/gpu_utils/devicebuffer_datatype.h"
#include "gromacs/mdtypes/group.h"
#include "gromacs/timing/wallcycle.h"
#include "gromacs/utility/arrayref.h"
-#include "gromacs/utility/classhelpers.h"
class DeviceContext;
class DeviceStream;
private:
class Impl;
- gmx::PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
// The integrate should save a copy of the current coordinates in d_xp_ and write updated
// once into d_x_. The d_xp_ is only needed by constraints.
- integrator_->integrate(d_x_, d_xp_, d_v_, d_f_, dt, doTemperatureScaling, tcstat,
- doParrinelloRahman, dtPressureCouple, prVelocityScalingMatrix);
+ integrator_->integrate(
+ d_x_, d_xp_, d_v_, d_f_, dt, doTemperatureScaling, tcstat, doParrinelloRahman, dtPressureCouple, prVelocityScalingMatrix);
// Constraints need both coordinates before (d_x_) and after (d_xp_) update. However, after constraints
// are applied, the d_x_ can be discarded. So we intentionally swap the d_x_ and d_xp_ here to avoid the
// d_xp_ -> d_x_ copy after constraints. Note that the integrate saves them in the wrong order as well.
const auto kernelArgs = prepareGpuKernelArguments(
scaleCoordinates_kernel, coordinateScalingKernelLaunchConfig_, &numAtoms_, &d_x_, &mu);
- launchGpuKernel(scaleCoordinates_kernel, coordinateScalingKernelLaunchConfig_, deviceStream_,
- nullptr, "scaleCoordinates_kernel", kernelArgs);
+ launchGpuKernel(scaleCoordinates_kernel,
+ coordinateScalingKernelLaunchConfig_,
+ deviceStream_,
+ nullptr,
+ "scaleCoordinates_kernel",
+ kernelArgs);
// TODO: Although this only happens on the pressure coupling steps, this synchronization
// can affect the performance if nstpcouple is small.
deviceStream_.synchronize();
const auto kernelArgs = prepareGpuKernelArguments(
scaleCoordinates_kernel, coordinateScalingKernelLaunchConfig_, &numAtoms_, &d_v_, &mu);
- launchGpuKernel(scaleCoordinates_kernel, coordinateScalingKernelLaunchConfig_, deviceStream_,
- nullptr, "scaleCoordinates_kernel", kernelArgs);
+ launchGpuKernel(scaleCoordinates_kernel,
+ coordinateScalingKernelLaunchConfig_,
+ deviceStream_,
+ nullptr,
+ "scaleCoordinates_kernel",
+ kernelArgs);
// TODO: Although this only happens on the pressure coupling steps, this synchronization
// can affect the performance if nstpcouple is small.
deviceStream_.synchronize();
reallocateDeviceBuffer(&d_xp_, numAtoms_, &numXp_, &numXpAlloc_, deviceContext_);
- reallocateDeviceBuffer(&d_inverseMasses_, numAtoms_, &numInverseMasses_,
- &numInverseMassesAlloc_, deviceContext_);
+ reallocateDeviceBuffer(
+ &d_inverseMasses_, numAtoms_, &numInverseMasses_, &numInverseMassesAlloc_, deviceContext_);
// Integrator should also update something, but it does not even have a method yet
integrator_->set(numAtoms_, md.invmass, numTempScaleValues, md.cTC);
const float dtPressureCouple,
const matrix prVelocityScalingMatrix)
{
- impl_->integrate(fReadyOnDevice, dt, updateVelocities, computeVirial, virialScaled, doTemperatureScaling,
- tcstat, doParrinelloRahman, dtPressureCouple, prVelocityScalingMatrix);
+ impl_->integrate(fReadyOnDevice,
+ dt,
+ updateVelocities,
+ computeVirial,
+ virialScaled,
+ doTemperatureScaling,
+ tcstat,
+ doParrinelloRahman,
+ dtPressureCouple,
+ prVelocityScalingMatrix);
}
void UpdateConstrainGpu::scaleCoordinates(const matrix scalingMatrix)
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2004, The GROMACS development team.
+ * Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
+ * Copyright (c) 2018,2019,2020,2021, 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.
+ */
+#include "gmxpre.h"
+
+#include "update_vv.h"
+
+#include <cmath>
+#include <cstdio>
+
+#include <algorithm>
+#include <memory>
+
+#include "gromacs/domdec/partition.h"
+#include "gromacs/gmxlib/nrnb.h"
+#include "gromacs/math/units.h"
+#include "gromacs/math/vec.h"
+#include "gromacs/mdlib/constr.h"
+#include "gromacs/mdlib/coupling.h"
+#include "gromacs/mdlib/enerdata_utils.h"
+#include "gromacs/mdlib/mdatoms.h"
+#include "gromacs/mdlib/md_support.h"
+#include "gromacs/mdlib/stat.h"
+#include "gromacs/mdlib/tgroup.h"
+#include "gromacs/mdlib/update.h"
+#include "gromacs/mdtypes/commrec.h"
+#include "gromacs/mdtypes/enerdata.h"
+#include "gromacs/mdtypes/fcdata.h"
+#include "gromacs/mdtypes/forcebuffers.h"
+#include "gromacs/mdtypes/forcerec.h"
+#include "gromacs/mdtypes/group.h"
+#include "gromacs/mdtypes/inputrec.h"
+#include "gromacs/mdtypes/mdatom.h"
+#include "gromacs/mdtypes/state.h"
+#include "gromacs/pulling/pull.h"
+#include "gromacs/timing/wallcycle.h"
+#include "gromacs/topology/topology.h"
+
+void integrateVVFirstStep(int64_t step,
+ bool bFirstStep,
+ bool bInitStep,
+ gmx::StartingBehavior startingBehavior,
+ int nstglobalcomm,
+ const t_inputrec* ir,
+ t_forcerec* fr,
+ t_commrec* cr,
+ t_state* state,
+ t_mdatoms* mdatoms,
+ const t_fcdata& fcdata,
+ t_extmass* MassQ,
+ t_vcm* vcm,
+ const gmx_mtop_t* top_global,
+ const gmx_localtop_t& top,
+ gmx_enerdata_t* enerd,
+ gmx_ekindata_t* ekind,
+ gmx_global_stat* gstat,
+ real* last_ekin,
+ bool bCalcVir,
+ tensor total_vir,
+ tensor shake_vir,
+ tensor force_vir,
+ tensor pres,
+ matrix M,
+ bool do_log,
+ bool do_ene,
+ bool bCalcEner,
+ bool bGStat,
+ bool bStopCM,
+ bool bTrotter,
+ bool bExchanged,
+ bool* bSumEkinhOld,
+ bool* shouldCheckNumberOfBondedInteractions,
+ real* saved_conserved_quantity,
+ gmx::ForceBuffers* f,
+ gmx::Update* upd,
+ gmx::Constraints* constr,
+ gmx::SimulationSignaller* nullSignaller,
+ std::array<std::vector<int>, ettTSEQMAX> trotter_seq,
+ t_nrnb* nrnb,
+ const gmx::MDLogger& mdlog,
+ FILE* fplog,
+ gmx_wallcycle* wcycle)
+{
+ if (!bFirstStep || startingBehavior == gmx::StartingBehavior::NewSimulation)
+ {
+ /* ############### START FIRST UPDATE HALF-STEP FOR VV METHODS############### */
+ rvec* vbuf = nullptr;
+
+ wallcycle_start(wcycle, ewcUPDATE);
+ if (ir->eI == eiVV && bInitStep)
+ {
+ /* if using velocity verlet with full time step Ekin,
+ * take the first half step only to compute the
+ * virial for the first step. From there,
+ * revert back to the initial coordinates
+ * so that the input is actually the initial step.
+ */
+ snew(vbuf, state->natoms);
+ copy_rvecn(state->v.rvec_array(), vbuf, 0, state->natoms); /* should make this better for parallelizing? */
+ }
+ else
+ {
+ /* this is for NHC in the Ekin(t+dt/2) version of vv */
+ trotter_update(ir, step, ekind, enerd, state, total_vir, mdatoms, MassQ, trotter_seq, ettTSEQ1);
+ }
+
+ upd->update_coords(
+ *ir, step, mdatoms, state, f->view().forceWithPadding(), fcdata, ekind, M, etrtVELOCITY1, cr, constr != nullptr);
+
+ wallcycle_stop(wcycle, ewcUPDATE);
+ constrain_velocities(constr, do_log, do_ene, step, state, nullptr, bCalcVir, shake_vir);
+ wallcycle_start(wcycle, ewcUPDATE);
+ /* if VV, compute the pressure and constraints */
+ /* For VV2, we strictly only need this if using pressure
+ * control, but we really would like to have accurate pressures
+ * printed out.
+ * Think about ways around this in the future?
+ * For now, keep this choice in comments.
+ */
+ /*bPres = (ir->eI==eiVV || inputrecNptTrotter(ir)); */
+ /*bTemp = ((ir->eI==eiVV &&(!bInitStep)) || (ir->eI==eiVVAK && inputrecNptTrotter(ir)));*/
+ bool bPres = TRUE;
+ bool bTemp = ((ir->eI == eiVV && (!bInitStep)) || (ir->eI == eiVVAK));
+ if (bCalcEner && ir->eI == eiVVAK)
+ {
+ *bSumEkinhOld = TRUE;
+ }
+ /* for vv, the first half of the integration actually corresponds to the previous step.
+ So we need information from the last step in the first half of the integration */
+ if (bGStat || do_per_step(step - 1, nstglobalcomm))
+ {
+ wallcycle_stop(wcycle, ewcUPDATE);
+ int totalNumberOfBondedInteractions = -1;
+ compute_globals(gstat,
+ cr,
+ ir,
+ fr,
+ ekind,
+ makeConstArrayRef(state->x),
+ makeConstArrayRef(state->v),
+ state->box,
+ mdatoms,
+ nrnb,
+ vcm,
+ wcycle,
+ enerd,
+ force_vir,
+ shake_vir,
+ total_vir,
+ pres,
+ (bCalcEner && constr != nullptr) ? constr->rmsdData() : gmx::ArrayRef<real>{},
+ nullSignaller,
+ state->box,
+ &totalNumberOfBondedInteractions,
+ bSumEkinhOld,
+ (bGStat ? CGLO_GSTAT : 0) | (bCalcEner ? CGLO_ENERGY : 0)
+ | (bTemp ? CGLO_TEMPERATURE : 0) | (bPres ? CGLO_PRESSURE : 0)
+ | (bPres ? CGLO_CONSTRAINT : 0) | (bStopCM ? CGLO_STOPCM : 0)
+ | (*shouldCheckNumberOfBondedInteractions ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS
+ : 0)
+ | CGLO_SCALEEKIN);
+ /* explanation of above:
+ a) We compute Ekin at the full time step
+ if 1) we are using the AveVel Ekin, and it's not the
+ initial step, or 2) if we are using AveEkin, but need the full
+ time step kinetic energy for the pressure (always true now, since we want accurate statistics).
+ b) If we are using EkinAveEkin for the kinetic energy for the temperature control, we still feed in
+ EkinAveVel because it's needed for the pressure */
+ checkNumberOfBondedInteractions(mdlog,
+ cr,
+ totalNumberOfBondedInteractions,
+ top_global,
+ &top,
+ makeConstArrayRef(state->x),
+ state->box,
+ shouldCheckNumberOfBondedInteractions);
+ if (bStopCM)
+ {
+ process_and_stopcm_grp(
+ fplog, vcm, *mdatoms, makeArrayRef(state->x), makeArrayRef(state->v));
+ inc_nrnb(nrnb, eNR_STOPCM, mdatoms->homenr);
+ }
+ wallcycle_start(wcycle, ewcUPDATE);
+ }
+ /* temperature scaling and pressure scaling to produce the extended variables at t+dt */
+ if (!bInitStep)
+ {
+ if (bTrotter)
+ {
+ m_add(force_vir, shake_vir, total_vir); /* we need the un-dispersion corrected total vir here */
+ trotter_update(ir, step, ekind, enerd, state, total_vir, mdatoms, MassQ, trotter_seq, ettTSEQ2);
+
+ /* TODO This is only needed when we're about to write
+ * a checkpoint, because we use it after the restart
+ * (in a kludge?). But what should we be doing if
+ * the startingBehavior is NewSimulation or bInitStep are true? */
+ if (inputrecNptTrotter(ir) || inputrecNphTrotter(ir))
+ {
+ copy_mat(shake_vir, state->svir_prev);
+ copy_mat(force_vir, state->fvir_prev);
+ }
+ if ((inputrecNptTrotter(ir) || inputrecNvtTrotter(ir)) && ir->eI == eiVV)
+ {
+ /* update temperature and kinetic energy now that step is over - this is the v(t+dt) point */
+ enerd->term[F_TEMP] = sum_ekin(&(ir->opts), ekind, nullptr, (ir->eI == eiVV), FALSE);
+ enerd->term[F_EKIN] = trace(ekind->ekin);
+ }
+ }
+ else if (bExchanged)
+ {
+ wallcycle_stop(wcycle, ewcUPDATE);
+ /* We need the kinetic energy at minus the half step for determining
+ * the full step kinetic energy and possibly for T-coupling.*/
+ /* This may not be quite working correctly yet . . . . */
+ compute_globals(gstat,
+ cr,
+ ir,
+ fr,
+ ekind,
+ makeConstArrayRef(state->x),
+ makeConstArrayRef(state->v),
+ state->box,
+ mdatoms,
+ nrnb,
+ vcm,
+ wcycle,
+ enerd,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ gmx::ArrayRef<real>{},
+ nullSignaller,
+ state->box,
+ nullptr,
+ bSumEkinhOld,
+ CGLO_GSTAT | CGLO_TEMPERATURE);
+ wallcycle_start(wcycle, ewcUPDATE);
+ }
+ }
+ /* if it's the initial step, we performed this first step just to get the constraint virial */
+ if (ir->eI == eiVV && bInitStep)
+ {
+ copy_rvecn(vbuf, state->v.rvec_array(), 0, state->natoms);
+ sfree(vbuf);
+ }
+ wallcycle_stop(wcycle, ewcUPDATE);
+ }
+
+ /* compute the conserved quantity */
+ *saved_conserved_quantity = NPT_energy(ir, state, MassQ);
+ if (ir->eI == eiVV)
+ {
+ *last_ekin = enerd->term[F_EKIN];
+ }
+ if ((ir->eDispCorr != edispcEnerPres) && (ir->eDispCorr != edispcAllEnerPres))
+ {
+ *saved_conserved_quantity -= enerd->term[F_DISPCORR];
+ }
+ /* sum up the foreign kinetic energy and dK/dl terms for vv. currently done every step so that dhdl is correct in the .edr */
+ if (ir->efep != efepNO)
+ {
+ accumulateKineticLambdaComponents(enerd, state->lambda, *ir->fepvals);
+ }
+}
+
+void integrateVVSecondStep(int64_t step,
+ const t_inputrec* ir,
+ t_forcerec* fr,
+ t_commrec* cr,
+ t_state* state,
+ t_mdatoms* mdatoms,
+ const t_fcdata& fcdata,
+ t_extmass* MassQ,
+ t_vcm* vcm,
+ pull_t* pull_work,
+ gmx_enerdata_t* enerd,
+ gmx_ekindata_t* ekind,
+ gmx_global_stat* gstat,
+ real* dvdl_constr,
+ bool bCalcVir,
+ tensor total_vir,
+ tensor shake_vir,
+ tensor force_vir,
+ tensor pres,
+ matrix M,
+ matrix lastbox,
+ bool do_log,
+ bool do_ene,
+ bool bGStat,
+ bool* bSumEkinhOld,
+ gmx::ForceBuffers* f,
+ std::vector<gmx::RVec>* cbuf,
+ gmx::Update* upd,
+ gmx::Constraints* constr,
+ gmx::SimulationSignaller* nullSignaller,
+ std::array<std::vector<int>, ettTSEQMAX> trotter_seq,
+ t_nrnb* nrnb,
+ gmx_wallcycle* wcycle)
+{
+ /* velocity half-step update */
+ upd->update_coords(
+ *ir, step, mdatoms, state, f->view().forceWithPadding(), fcdata, ekind, M, etrtVELOCITY2, cr, constr != nullptr);
+
+
+ /* Above, initialize just copies ekinh into ekin,
+ * it doesn't copy position (for VV),
+ * and entire integrator for MD.
+ */
+
+ if (ir->eI == eiVVAK)
+ {
+ cbuf->resize(state->x.size());
+ std::copy(state->x.begin(), state->x.end(), cbuf->begin());
+ }
+
+ if (ir->bPull && ir->pull->bSetPbcRefToPrevStepCOM)
+ {
+ updatePrevStepPullCom(pull_work, state);
+ }
+
+ upd->update_coords(
+ *ir, step, mdatoms, state, f->view().forceWithPadding(), fcdata, ekind, M, etrtPOSITION, cr, constr != nullptr);
+
+ wallcycle_stop(wcycle, ewcUPDATE);
+
+ constrain_coordinates(
+ constr, do_log, do_ene, step, state, upd->xp()->arrayRefWithPadding(), dvdl_constr, bCalcVir, shake_vir);
+
+ upd->update_sd_second_half(
+ *ir, step, dvdl_constr, mdatoms, state, cr, nrnb, wcycle, constr, do_log, do_ene);
+ upd->finish_update(*ir, mdatoms, state, wcycle, constr != nullptr);
+
+ if (ir->eI == eiVVAK)
+ {
+ /* erase F_EKIN and F_TEMP here? */
+ /* just compute the kinetic energy at the half step to perform a trotter step */
+ compute_globals(gstat,
+ cr,
+ ir,
+ fr,
+ ekind,
+ makeConstArrayRef(state->x),
+ makeConstArrayRef(state->v),
+ state->box,
+ mdatoms,
+ nrnb,
+ vcm,
+ wcycle,
+ enerd,
+ force_vir,
+ shake_vir,
+ total_vir,
+ pres,
+ gmx::ArrayRef<real>{},
+ nullSignaller,
+ lastbox,
+ nullptr,
+ bSumEkinhOld,
+ (bGStat ? CGLO_GSTAT : 0) | CGLO_TEMPERATURE);
+ wallcycle_start(wcycle, ewcUPDATE);
+ trotter_update(ir, step, ekind, enerd, state, total_vir, mdatoms, MassQ, trotter_seq, ettTSEQ4);
+ /* now we know the scaling, we can compute the positions again */
+ std::copy(cbuf->begin(), cbuf->end(), state->x.begin());
+
+ upd->update_coords(
+ *ir, step, mdatoms, state, f->view().forceWithPadding(), fcdata, ekind, M, etrtPOSITION, cr, constr != nullptr);
+ wallcycle_stop(wcycle, ewcUPDATE);
+
+ /* do we need an extra constraint here? just need to copy out of as_rvec_array(state->v.data()) to upd->xp? */
+ /* are the small terms in the shake_vir here due
+ * to numerical errors, or are they important
+ * physically? I'm thinking they are just errors, but not completely sure.
+ * For now, will call without actually constraining, constr=NULL*/
+ upd->finish_update(*ir, mdatoms, state, wcycle, false);
+ }
+ /* this factor or 2 correction is necessary
+ because half of the constraint force is removed
+ in the vv step, so we have to double it. See
+ the Issue #1255. It is not yet clear
+ if the factor of 2 is exact, or just a very
+ good approximation, and this will be
+ investigated. The next step is to see if this
+ can be done adding a dhdl contribution from the
+ rattle step, but this is somewhat more
+ complicated with the current code. Will be
+ investigated, hopefully for 4.6.3. However,
+ this current solution is much better than
+ having it completely wrong.
+ */
+ enerd->term[F_DVDL_CONSTR] += 2 * *dvdl_constr;
+}
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2004, The GROMACS development team.
+ * Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
+ * Copyright (c) 2018,2019,2020,2021, 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.
+ */
+#ifndef GMX_MDLIB_UPDATE_VV_H
+#define GMX_MDLIB_UPDATE_VV_H
+
+#include <vector>
+
+#include "gromacs/math/vectypes.h"
+#include "gromacs/mdrunutility/handlerestart.h"
+#include "gromacs/mdtypes/md_enums.h"
+
+struct gmx_ekindata_t;
+struct gmx_enerdata_t;
+struct gmx_global_stat;
+struct gmx_localtop_t;
+struct gmx_mtop_t;
+struct gmx_wallcycle;
+struct pull_t;
+struct t_commrec;
+struct t_extmass;
+struct t_fcdata;
+struct t_forcerec;
+struct t_inputrec;
+struct t_mdatoms;
+struct t_nrnb;
+class t_state;
+struct t_vcm;
+
+namespace gmx
+{
+class Constraints;
+class ForceBuffers;
+class MDLogger;
+class SimulationSignaller;
+class Update;
+} // namespace gmx
+
+/*! \brief Make the first step of Velocity Verlet integration
+ *
+ * \param[in] step Current timestep.
+ * \param[in] bFirstStep Is it a first step.
+ * \param[in] bInitStep Is it an initialization step.
+ * \param[in] startingBehavior Describes whether this is a restart appending to output files.
+ * \param[in] nstglobalcomm Will globals be computed on this step.
+ * \param[in] ir Input record.
+ * \param[in] fr Force record.
+ * \param[in] cr Comunication record.
+ * \param[in] state Simulation state.
+ * \param[in] mdatoms MD atoms data.
+ * \param[in] fcdata Force calculation data.
+ * \param[in] MassQ Mass/pressure data.
+ * \param[in] vcm Center of mass motion removal.
+ * \param[in] top_global Global topology.
+ * \param[in] top Local topology.
+ * \param[in] enerd Energy data.
+ * \param[in] ekind Kinetic energy data.
+ * \param[in] gstat Storage of thermodynamic parameters data.
+ * \param[out] last_ekin Kinetic energies of the last step.
+ * \param[in] bCalcVir If the virial is computed on this step.
+ * \param[in] total_vir Total virial tensor.
+ * \param[in] shake_vir Constraints virial.
+ * \param[in] force_vir Force virial.
+ * \param[in] pres Pressure tensor.
+ * \param[in] M Parrinello-Rahman velocity scaling matrix.
+ * \param[in] do_log Do logging on this step.
+ * \param[in] do_ene Print energies on this step.
+ * \param[in] bCalcEner Compute energies on this step.
+ * \param[in] bGStat Collect globals this step.
+ * \param[in] bStopCM Stop the center of mass motion on this step.
+ * \param[in] bTrotter Do trotter routines this step.
+ * \param[in] bExchanged If this is a replica exchange step.
+ * \param[out] bSumEkinhOld Old kinetic energies will need to be summed up.
+ * \param[out] shouldCheckNumberOfBondedInteractions If checks for missing bonded
+ * interactions will be needed.
+ * \param[out] saved_conserved_quantity Place to store the conserved energy.
+ * \param[in] f Force buffers.
+ * \param[in] upd Update object.
+ * \param[in] constr Constraints object.
+ * \param[in] nullSignaller Simulation signaller.
+ * \param[in] trotter_seq NPT variables.
+ * \param[in] nrnb Cycle counters.
+ * \param[in] mdlog Logger.
+ * \param[in] fplog Another logger.
+ * \param[in] wcycle Wall-clock cycle counter.
+ */
+void integrateVVFirstStep(int64_t step,
+ bool bFirstStep,
+ bool bInitStep,
+ gmx::StartingBehavior startingBehavior,
+ int nstglobalcomm,
+ const t_inputrec* ir,
+ t_forcerec* fr,
+ t_commrec* cr,
+ t_state* state,
+ t_mdatoms* mdatoms,
+ const t_fcdata& fcdata,
+ t_extmass* MassQ,
+ t_vcm* vcm,
+ const gmx_mtop_t* top_global,
+ const gmx_localtop_t& top,
+ gmx_enerdata_t* enerd,
+ gmx_ekindata_t* ekind,
+ gmx_global_stat* gstat,
+ real* last_ekin,
+ bool bCalcVir,
+ tensor total_vir,
+ tensor shake_vir,
+ tensor force_vir,
+ tensor pres,
+ matrix M,
+ bool do_log,
+ bool do_ene,
+ bool bCalcEner,
+ bool bGStat,
+ bool bStopCM,
+ bool bTrotter,
+ bool bExchanged,
+ bool* bSumEkinhOld,
+ bool* shouldCheckNumberOfBondedInteractions,
+ real* saved_conserved_quantity,
+ gmx::ForceBuffers* f,
+ gmx::Update* upd,
+ gmx::Constraints* constr,
+ gmx::SimulationSignaller* nullSignaller,
+ std::array<std::vector<int>, ettTSEQMAX> trotter_seq,
+ t_nrnb* nrnb,
+ const gmx::MDLogger& mdlog,
+ FILE* fplog,
+ gmx_wallcycle* wcycle);
+
+
+/*! \brief Make the second step of Velocity Verlet integration
+ *
+ * \param[in] step Current timestep.
+ * \param[in] ir Input record.
+ * \param[in] fr Force record.
+ * \param[in] cr Comunication record.
+ * \param[in] state Simulation state.
+ * \param[in] mdatoms MD atoms data.
+ * \param[in] fcdata Force calculation data.
+ * \param[in] MassQ Mass/pressure data.
+ * \param[in] vcm Center of mass motion removal.
+ * \param[in] pull_work Pulling data.
+ * \param[in] enerd Energy data.
+ * \param[in] ekind Kinetic energy data.
+ * \param[in] gstat Storage of thermodynamic parameters data.
+ * \param[out] dvdl_constr FEP data for constraints.
+ * \param[in] bCalcVir If the virial is computed on this step.
+ * \param[in] total_vir Total virial tensor.
+ * \param[in] shake_vir Constraints virial.
+ * \param[in] force_vir Force virial.
+ * \param[in] pres Pressure tensor.
+ * \param[in] M Parrinello-Rahman velocity scaling matrix.
+ * \param[in] lastbox Last recorded PBC box.
+ * \param[in] do_log Do logging on this step.
+ * \param[in] do_ene Print energies on this step.
+ * \param[in] bGStat Collect globals this step.
+ * \param[out] bSumEkinhOld Old kinetic energies need to be summed up.
+ * \param[in] f Force buffers.
+ * \param[in] cbuf Buffer to store intermediate coordinates
+ * \param[in] upd Update object.
+ * \param[in] constr Constraints object.
+ * \param[in] nullSignaller Simulation signaller.
+ * \param[in] trotter_seq NPT variables.
+ * \param[in] nrnb Cycle counters.
+ * \param[in] wcycle Wall-clock cycle counter.
+ */
+void integrateVVSecondStep(int64_t step,
+ const t_inputrec* ir,
+ t_forcerec* fr,
+ t_commrec* cr,
+ t_state* state,
+ t_mdatoms* mdatoms,
+ const t_fcdata& fcdata,
+ t_extmass* MassQ,
+ t_vcm* vcm,
+ pull_t* pull_work,
+ gmx_enerdata_t* enerd,
+ gmx_ekindata_t* ekind,
+ gmx_global_stat* gstat,
+ real* dvdl_constr,
+ bool bCalcVir,
+ tensor total_vir,
+ tensor shake_vir,
+ tensor force_vir,
+ tensor pres,
+ matrix M,
+ matrix lastbox,
+ bool do_log,
+ bool do_ene,
+ bool bGStat,
+ bool* bSumEkinhOld,
+ gmx::ForceBuffers* f,
+ std::vector<gmx::RVec>* cbuf,
+ gmx::Update* upd,
+ gmx::Constraints* constr,
+ gmx::SimulationSignaller* nullSignaller,
+ std::array<std::vector<int>, ettTSEQMAX> trotter_seq,
+ t_nrnb* nrnb,
+ gmx_wallcycle* wcycle);
+
+
+#endif // GMX_MDLIB_UPDATE_VV_H
std::array<InteractionList, F_NRE> ilistsCombined;
ilistsCombined[F_CONSTR] = jointConstraintList(moltype);
/* We "include" flexible constraints, but none are present (checked above) */
- const ListOfLists<int> at2con = make_at2con(moltype.atoms.nr, ilistsCombined, iparams,
- FlexibleConstraintTreatment::Include);
+ const ListOfLists<int> at2con = make_at2con(
+ moltype.atoms.nr, ilistsCombined, iparams, FlexibleConstraintTreatment::Include);
bool satisfiesCriteria = true;
*/
if (numConstraints == 2 && allTypesAreEqual && temperature > 0)
{
- radius = constraintGroupRadius<2>(moltype, iparams, maxAtom, at2con, angleIndices,
- maxConstraintLength, temperature);
+ radius = constraintGroupRadius<2>(
+ moltype, iparams, maxAtom, at2con, angleIndices, maxConstraintLength, temperature);
}
/* With 3 constraints the maximum possible radius is 1.4 times
* the constraint length, so it is worth computing a smaller
*/
if (numConstraints == 3 && allTypesAreEqual && temperature >= 0)
{
- radius = constraintGroupRadius<3>(moltype, iparams, maxAtom, at2con, angleIndices,
- maxConstraintLength, temperature);
+ radius = constraintGroupRadius<3>(
+ moltype, iparams, maxAtom, at2con, angleIndices, maxConstraintLength, temperature);
if (temperature == 0 && radius >= 0)
{
/* Add a 10% margin for deviation at 0 K */
for (size_t moltype = 0; moltype < mtop.moltype.size(); moltype++)
{
maxRadius = std::max(
- maxRadius, computeMaxUpdateGroupRadius(mtop.moltype[moltype], mtop.ffparams.iparams,
- updateGroups[moltype], temperature));
+ maxRadius,
+ computeMaxUpdateGroupRadius(
+ mtop.moltype[moltype], mtop.ffparams.iparams, updateGroups[moltype], temperature));
}
return maxRadius;
if (mode == ecmANGULAR && ndim < 3)
{
- gmx_fatal(FARGS, "Can not have angular comm removal with pbc=%s",
- c_pbcTypeNames[ir.pbcType].c_str());
+ gmx_fatal(FARGS, "Can not have angular comm removal with pbc=%s", c_pbcTypeNames[ir.pbcType].c_str());
}
if (mode != ecmNO)
if ((Temp_cm > Temp_Max) && fp)
{
- fprintf(fp, "Large VCM(group %s): %12.5f, %12.5f, %12.5f, Temp-cm: %12.5e\n",
- vcm->group_name[g], vcm->group_v[g][XX], vcm->group_v[g][YY],
- vcm->group_v[g][ZZ], Temp_cm);
+ fprintf(fp,
+ "Large VCM(group %s): %12.5f, %12.5f, %12.5f, Temp-cm: %12.5e\n",
+ vcm->group_name[g],
+ vcm->group_v[g][XX],
+ vcm->group_v[g][YY],
+ vcm->group_v[g][ZZ],
+ Temp_cm);
}
if (vcm->mode == ecmANGULAR)
{
/* if we have an integrator that may not conserve momenta, skip */
tm = vcm->group_mass[g];
- fprintf(fp, "Group %s with mass %12.5e, Ekrot %12.5e Det(I) = %12.5e\n",
- vcm->group_name[g], tm, ekrot, det(vcm->group_i[g]));
- fprintf(fp, " COM: %12.5f %12.5f %12.5f\n", vcm->group_x[g][XX],
- vcm->group_x[g][YY], vcm->group_x[g][ZZ]);
- fprintf(fp, " P: %12.5f %12.5f %12.5f\n", vcm->group_p[g][XX],
- vcm->group_p[g][YY], vcm->group_p[g][ZZ]);
- fprintf(fp, " V: %12.5f %12.5f %12.5f\n", vcm->group_v[g][XX],
- vcm->group_v[g][YY], vcm->group_v[g][ZZ]);
- fprintf(fp, " J: %12.5f %12.5f %12.5f\n", vcm->group_j[g][XX],
- vcm->group_j[g][YY], vcm->group_j[g][ZZ]);
- fprintf(fp, " w: %12.5f %12.5f %12.5f\n", vcm->group_w[g][XX],
- vcm->group_w[g][YY], vcm->group_w[g][ZZ]);
+ fprintf(fp,
+ "Group %s with mass %12.5e, Ekrot %12.5e Det(I) = %12.5e\n",
+ vcm->group_name[g],
+ tm,
+ ekrot,
+ det(vcm->group_i[g]));
+ fprintf(fp,
+ " COM: %12.5f %12.5f %12.5f\n",
+ vcm->group_x[g][XX],
+ vcm->group_x[g][YY],
+ vcm->group_x[g][ZZ]);
+ fprintf(fp,
+ " P: %12.5f %12.5f %12.5f\n",
+ vcm->group_p[g][XX],
+ vcm->group_p[g][YY],
+ vcm->group_p[g][ZZ]);
+ fprintf(fp,
+ " V: %12.5f %12.5f %12.5f\n",
+ vcm->group_v[g][XX],
+ vcm->group_v[g][YY],
+ vcm->group_v[g][ZZ]);
+ fprintf(fp,
+ " J: %12.5f %12.5f %12.5f\n",
+ vcm->group_j[g][XX],
+ vcm->group_j[g][YY],
+ vcm->group_j[g][ZZ]);
+ fprintf(fp,
+ " w: %12.5f %12.5f %12.5f\n",
+ vcm->group_w[g][XX],
+ vcm->group_w[g][YY],
+ vcm->group_w[g][ZZ]);
pr_rvecs(fp, 0, "Inertia tensor", vcm->group_i[g], DIM);
}
}
*/
ivec null_ivec;
clear_ivec(null_ivec);
- pbc_null = set_pbc_dd(&pbc, domainInfo.pbcType_,
- useDomdec ? domainInfo.domdec_->numCells : null_ivec, FALSE, box);
+ pbc_null = set_pbc_dd(
+ &pbc, domainInfo.pbcType_, useDomdec ? domainInfo.domdec_->numCells : null_ivec, FALSE, box);
}
else
{
int atomOffset = mtop.moleculeBlockIndices[mb].globalAtomStart;
for (int mol = 0; mol < molb.nmol; mol++)
{
- constructVirtualSites(x.subArray(atomOffset, molt.atoms.nr), mtop.ffparams.iparams,
- molt.ilist);
+ constructVirtualSites(
+ x.subArray(atomOffset, molt.atoms.nr), mtop.ffparams.iparams, molt.ilist);
atomOffset += molt.atoms.nr;
}
}
/* This is wasting some CPU time as we now do this multiple times
* per MD step.
*/
- pbc_null = set_pbc_dd(&pbc, domainInfo_.pbcType_,
- useDomdec ? domainInfo_.domdec_->numCells : nullptr, FALSE, box);
+ pbc_null = set_pbc_dd(
+ &pbc, domainInfo_.pbcType_, useDomdec ? domainInfo_.domdec_->numCells : nullptr, FALSE, box);
}
else
{
{
/* First spread the vsites that might depend on non-local vsites */
auto& nlDependentVSites = threadingInfo_.threadDataNonLocalDependent();
- spreadForceWrapper(x, f, virialHandling, fshift, nlDependentVSites.dxdf, true, iparams_,
- nlDependentVSites.ilist, pbc_null);
+ spreadForceWrapper(x,
+ f,
+ virialHandling,
+ fshift,
+ nlDependentVSites.dxdf,
+ true,
+ iparams_,
+ nlDependentVSites.ilist,
+ pbc_null);
#pragma omp parallel num_threads(numThreads)
{
{
copy_rvec(f[idTask->vsite[i]], idTask->force[idTask->vsite[i]]);
}
- spreadForceWrapper(x, idTask->force, virialHandling, fshift_t, tData.dxdf, true,
- iparams_, tData.idTask.ilist, pbc_null);
+ spreadForceWrapper(x,
+ idTask->force,
+ virialHandling,
+ fshift_t,
+ tData.dxdf,
+ true,
+ iparams_,
+ tData.idTask.ilist,
+ pbc_null);
/* We need a barrier before reducing forces below
* that have been produced by a different thread above.
}
/* Spread the vsites that spread locally only */
- spreadForceWrapper(x, f, virialHandling, fshift_t, tData.dxdf, false, iparams_,
- tData.ilist, pbc_null);
+ spreadForceWrapper(
+ x, f, virialHandling, fshift_t, tData.dxdf, false, iparams_, tData.ilist, pbc_null);
}
GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
}
if (debug)
{
- fprintf(debug, "virtual site thread dist: natoms %d, range %d, natperthread %d\n",
- mdatoms.nr, vsite_atom_range, natperthread);
+ fprintf(debug,
+ "virtual site thread dist: natoms %d, range %d, natperthread %d\n",
+ mdatoms.nr,
+ vsite_atom_range,
+ natperthread);
}
/* To simplify the vsite assignment, we make an index which tells us
/* The last thread should cover up to the end of the range */
tData.rangeEnd = mdatoms.nr;
}
- assignVsitesToThread(&tData, thread, numThreads_, natperthread, taskIndex_, ilists,
- iparams, mdatoms.ptype);
+ assignVsitesToThread(
+ &tData, thread, numThreads_, natperthread, taskIndex_, ilists, iparams, mdatoms.ptype);
if (tData.useInterdependentTask)
{
if (debug && numThreads_ > 1)
{
- fprintf(debug, "virtual site useInterdependentTask %d, nuse:\n",
+ fprintf(debug,
+ "virtual site useInterdependentTask %d, nuse:\n",
static_cast<int>(tData_[0]->useInterdependentTask));
for (int th = 0; th < numThreads_ + 1; th++)
{
fprintf(debug, "%-20s thread dist:", interaction_function[ftype].longname);
for (int th = 0; th < numThreads_ + 1; th++)
{
- fprintf(debug, " %4d %4d ", tData_[th]->ilist[ftype].size(),
+ fprintf(debug,
+ " %4d %4d ",
+ tData_[th]->ilist[ftype].size(),
tData_[th]->idTask.ilist[ftype].size());
}
fprintf(debug, "\n");
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 The GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/topology/idef.h"
#include "gromacs/utility/arrayref.h"
#include "gromacs/utility/basedefinitions.h"
-#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/real.h"
struct gmx_domdec_t;
//! Implementation type.
class Impl;
//! Implementation object.
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
/*! \brief Create positions of vsite atoms based for the local system
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2008, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
fprintf(fplog, "Reading user tables for %d energy groups with %d walls\n", negp_pp, ir->nwall);
}
- snew(fr->wall_tab, ir->nwall);
+ fr->wall_tab.resize(ir->nwall);
for (int w = 0; w < ir->nwall; w++)
{
- snew(fr->wall_tab[w], negp_pp);
+ fr->wall_tab[w].resize(negp_pp);
for (int egp = 0; egp < negp_pp; egp++)
{
/* If the energy group pair is excluded, we don't need a table */
if (!(fr->egp_flags[egp * ir->opts.ngener + negp_pp + w] & EGP_EXCL))
{
sprintf(buf, "%s", tabfn);
- sprintf(buf + strlen(tabfn) - strlen(ftp2ext(efXVG)) - 1, "_%s_%s.%s",
- *groups->groupNames[nm_ind[egp]], *groups->groupNames[nm_ind[negp_pp + w]],
+ sprintf(buf + strlen(tabfn) - strlen(ftp2ext(efXVG)) - 1,
+ "_%s_%s.%s",
+ *groups->groupNames[nm_ind[egp]],
+ *groups->groupNames[nm_ind[negp_pp + w]],
ftp2ext(efXVG));
fr->wall_tab[w][egp] = make_tables(fplog, fr->ic, buf, 0, GMX_MAKETABLES_FORCEUSER);
gmx_fatal(FARGS,
"An atom is beyond the wall: coordinates %f %f %f, distance %f\n"
"You might want to use the mdp option wall_r_linpot",
- x[a][XX], x[a][YY], x[a][ZZ], r);
+ x[a][XX],
+ x[a][YY],
+ x[a][ZZ],
+ r);
}
static void tableForce(real r, const t_forcetable& tab, real Cd, real Cr, real* V, real* F)
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+add_library(mdrun INTERFACE)
gmx_add_libgromacs_sources(
legacymdrunoptions.cpp
legacysimulator.cpp
tpi.cpp
)
+# Source files have the following private module dependencies.
+target_link_libraries(mdrun PRIVATE
+# gmxlib
+# math
+# mdtypes
+# tng_io
+ )
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(mdrun PUBLIC
+target_include_directories(mdrun INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(mdrun PUBLIC
+target_link_libraries(mdrun INTERFACE
+ legacy_api
+ )
+
+# TODO: when mdrun is an OBJECT target
+#target_link_libraries(mdrun PUBLIC legacy_api)
+#target_link_libraries(mdrun PRIVATE common)
+
+# Module dependencies
+# mdrun interfaces convey transitive dependence on these modules.
+#target_link_libraries(mdrun PUBLIC
+target_link_libraries(mdrun INTERFACE
+ utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(mdrun PRIVATE tng_io)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(mdrun PRIVATE legacy_modules)
+
# TODO: Find a home for this header and a scheme for installation.
# This header straddles the installed libraries and is a transitive interface
# from libgromacs to libgmxapi to libgmxapi clients. Near term efforts are
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
IMDOutputProvider* outputProvider;
//! Handles notifications to MdModules for checkpoint writing
const MdModulesNotifier& mdModulesNotifier;
- //! Contains user input mdp options.
- t_inputrec* inputrec;
+ //! Contains user input mdp options. Note: The const-ness is casted away in a few instances, see #3854.
+ const t_inputrec* inputrec;
//! The Interactive Molecular Dynamics session.
ImdSession* imdSession;
//! The pull work object.
PCA_Flags |= PCA_DISABLE_INPUT_FILE_CHECKING;
}
- if (!parse_common_args(&argc, argv, PCA_Flags, ssize(filenames), filenames.data(), asize(pa),
- pa, ssize(desc), desc.data(), 0, nullptr, &oenv))
+ if (!parse_common_args(&argc,
+ argv,
+ PCA_Flags,
+ ssize(filenames),
+ filenames.data(),
+ asize(pa),
+ pa,
+ ssize(desc),
+ desc.data(),
+ 0,
+ nullptr,
+ &oenv))
{
return 0;
}
/*! \brief Command line options, defaults, docs and storage for them to fill. */
/*! \{ */
- rvec realddxyz = { 0, 0, 0 };
- const char* ddrank_opt_choices[static_cast<int>(DdRankOrder::Count) + 1] = {
- nullptr, "interleave", "pp_pme", "cartesian", nullptr
- };
- const char* dddlb_opt_choices[static_cast<int>(DlbOption::Count) + 1] = { nullptr, "auto", "no",
- "yes", nullptr };
- const char* thread_aff_opt_choices[static_cast<int>(ThreadAffinity::Count) + 1] = {
- nullptr, "auto", "on", "off", nullptr
- };
+ rvec realddxyz = { 0, 0, 0 };
+ const char* ddrank_opt_choices[static_cast<int>(DdRankOrder::Count) + 1] = { nullptr,
+ "interleave",
+ "pp_pme",
+ "cartesian",
+ nullptr };
+ const char* dddlb_opt_choices[static_cast<int>(DlbOption::Count) + 1] = { nullptr,
+ "auto",
+ "no",
+ "yes",
+ nullptr };
+ const char* thread_aff_opt_choices[static_cast<int>(ThreadAffinity::Count) + 1] = { nullptr,
+ "auto",
+ "on",
+ "off",
+ nullptr };
const char* nbpu_opt_choices[5] = { nullptr, "auto", "cpu", "gpu", nullptr };
const char* pme_opt_choices[5] = { nullptr, "auto", "cpu", "gpu", nullptr };
const char* pme_fft_opt_choices[5] = { nullptr, "auto", "cpu", "gpu", nullptr };
#include "gromacs/mdlib/trajectory_writing.h"
#include "gromacs/mdlib/update.h"
#include "gromacs/mdlib/update_constrain_gpu.h"
+#include "gromacs/mdlib/update_vv.h"
#include "gromacs/mdlib/vcm.h"
#include "gromacs/mdlib/vsite.h"
#include "gromacs/mdrunutility/handlerestart.h"
// alias to avoid a large ripple of nearly useless changes.
// t_inputrec is being replaced by IMdpOptionsProvider, so this
// will go away eventually.
- t_inputrec* ir = inputrec;
+ const t_inputrec* ir = inputrec;
+
int64_t step, step_rel;
double t, t0 = ir->init_t;
gmx_bool bGStatEveryStep, bGStat, bCalcVir, bCalcEnerStep, bCalcEner;
gmx_global_stat_t gstat;
gmx_shellfc_t* shellfc;
gmx_bool bSumEkinhOld, bDoReplEx, bExchanged, bNeedRepartition;
- gmx_bool bTemp, bPres, bTrotter;
+ gmx_bool bTrotter;
real dvdl_constr;
std::vector<RVec> cbuf;
matrix lastbox;
if (opt2bSet("-ei", nfile, fnm))
{
/* Initialize essential dynamics sampling */
- ed = init_edsam(mdlog, opt2fn_null("-ei", nfile, fnm), opt2fn("-eo", nfile, fnm), top_global,
- ir, cr, constr, state_global, observablesHistory, oenv, startingBehavior);
+ ed = init_edsam(mdlog,
+ opt2fn_null("-ei", nfile, fnm),
+ opt2fn("-eo", nfile, fnm),
+ top_global,
+ ir,
+ cr,
+ constr,
+ state_global,
+ observablesHistory,
+ oenv,
+ startingBehavior);
}
else if (observablesHistory->edsamHistory)
{
int* fep_state = MASTER(cr) ? &state_global->fep_state : nullptr;
gmx::ArrayRef<real> lambda = MASTER(cr) ? state_global->lambda : gmx::ArrayRef<real>();
initialize_lambdas(fplog, *ir, MASTER(cr), fep_state, lambda);
- Update upd(*ir, deform);
- const bool doSimulatedAnnealing = initSimulatedAnnealing(ir, &upd);
- const bool useReplicaExchange = (replExParams.exchangeInterval > 0);
+ Update upd(*ir, deform);
+ bool doSimulatedAnnealing = false;
+ {
+ // TODO: Avoid changing inputrec (#3854)
+ // Simulated annealing updates the reference temperature.
+ auto* nonConstInputrec = const_cast<t_inputrec*>(inputrec);
+ doSimulatedAnnealing = initSimulatedAnnealing(nonConstInputrec, &upd);
+ }
+ const bool useReplicaExchange = (replExParams.exchangeInterval > 0);
const t_fcdata& fcdata = *fr->fcdata;
{
pleaseCiteCouplingAlgorithms(fplog, *ir);
}
- gmx_mdoutf* outf =
- init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr, outputProvider, mdModulesNotifier, ir,
- top_global, oenv, wcycle, startingBehavior, simulationsShareState, ms);
- gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf), top_global, ir, pull_work,
- mdoutf_get_fp_dhdl(outf), false, startingBehavior,
- simulationsShareState, mdModulesNotifier);
+ gmx_mdoutf* outf = init_mdoutf(fplog,
+ nfile,
+ fnm,
+ mdrunOptions,
+ cr,
+ outputProvider,
+ mdModulesNotifier,
+ ir,
+ top_global,
+ oenv,
+ wcycle,
+ startingBehavior,
+ simulationsShareState,
+ ms);
+ gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf),
+ top_global,
+ ir,
+ pull_work,
+ mdoutf_get_fp_dhdl(outf),
+ false,
+ startingBehavior,
+ simulationsShareState,
+ mdModulesNotifier);
gstat = global_stat_init(ir);
const bool useGpuForUpdate = simulationWork.useGpuUpdate;
/* Check for polarizable models and flexible constraints */
- shellfc = init_shell_flexcon(fplog, top_global, constr ? constr->numFlexibleConstraints() : 0,
- ir->nstcalcenergy, DOMAINDECOMP(cr), useGpuForPme);
+ shellfc = init_shell_flexcon(fplog,
+ top_global,
+ constr ? constr->numFlexibleConstraints() : 0,
+ ir->nstcalcenergy,
+ DOMAINDECOMP(cr),
+ useGpuForPme);
{
double io = compute_io(ir, top_global->natoms, *groups, energyOutput.numEnergyTerms(), 1);
auto mdatoms = mdAtoms->mdatoms();
- ForceBuffers f(fr->useMts, ((useGpuForNonbonded && useGpuForBufferOps) || useGpuForUpdate)
- ? PinningPolicy::PinnedIfSupported
- : PinningPolicy::CannotBePinned);
+ ForceBuffers f(fr->useMts,
+ ((useGpuForNonbonded && useGpuForBufferOps) || useGpuForUpdate)
+ ? PinningPolicy::PinnedIfSupported
+ : PinningPolicy::CannotBePinned);
if (DOMAINDECOMP(cr))
{
stateInstance = std::make_unique<t_state>();
dd_init_local_state(cr->dd, state_global, state);
/* Distribute the charge groups over the nodes from the master node */
- dd_partition_system(fplog, mdlog, ir->init_step, cr, TRUE, 1, state_global, *top_global, ir,
- imdSession, pull_work, state, &f, mdAtoms, &top, fr, vsite, constr,
- nrnb, nullptr, FALSE);
+ dd_partition_system(fplog,
+ mdlog,
+ ir->init_step,
+ cr,
+ TRUE,
+ 1,
+ state_global,
+ *top_global,
+ ir,
+ imdSession,
+ pull_work,
+ state,
+ &f,
+ mdAtoms,
+ &top,
+ fr,
+ vsite,
+ constr,
+ nrnb,
+ nullptr,
+ FALSE);
shouldCheckNumberOfBondedInteractions = true;
upd.setNumAtoms(state->natoms);
}
GMX_RELEASE_ASSERT(ir->eI == eiMD,
"Only the md integrator is supported with the GPU update.\n");
GMX_RELEASE_ASSERT(
- ir->etc != etcNOSEHOOVER,
+ ir->etc != TemperatureCoupling::NoseHoover,
"Nose-Hoover temperature coupling is not supported with the GPU update.\n");
GMX_RELEASE_ASSERT(
- ir->epc == epcNO || ir->epc == epcPARRINELLORAHMAN || ir->epc == epcBERENDSEN
- || ir->epc == epcCRESCALE,
+ ir->epc == PressureCoupling::No || ir->epc == PressureCoupling::ParrinelloRahman
+ || ir->epc == PressureCoupling::Berendsen || ir->epc == PressureCoupling::CRescale,
"Only Parrinello-Rahman, Berendsen, and C-rescale pressure coupling are supported "
"with the GPU update.\n");
GMX_RELEASE_ASSERT(!mdatoms->haveVsites,
"Update stream should be initialized in order to use GPU "
"update-constraints.");
integrator = std::make_unique<UpdateConstrainGpu>(
- *ir, *top_global, fr->deviceStreamManager->context(),
+ *ir,
+ *top_global,
+ fr->deviceStreamManager->context(),
fr->deviceStreamManager->stream(gmx::DeviceStreamType::UpdateAndConstraints),
- stateGpu->xUpdatedOnDevice(), wcycle);
+ stateGpu->xUpdatedOnDevice(),
+ wcycle);
integrator->setPbc(PbcType::Xyz, state->box);
}
EnergyData::initializeEnergyHistory(startingBehavior, observablesHistory, &energyOutput);
}
- preparePrevStepPullCom(ir, pull_work, mdatoms->massT, state, state_global, cr,
- startingBehavior != StartingBehavior::NewSimulation);
+ preparePrevStepPullCom(
+ ir, pull_work, mdatoms->massT, state, state_global, cr, startingBehavior != StartingBehavior::NewSimulation);
// TODO: Remove this by converting AWH into a ForceProvider
- auto awh = prepareAwhModule(fplog, *ir, state_global, cr, ms,
+ auto awh = prepareAwhModule(fplog,
+ *ir,
+ state_global,
+ cr,
+ ms,
startingBehavior != StartingBehavior::NewSimulation,
- shellfc != nullptr, opt2fn("-awh", nfile, fnm), pull_work);
+ shellfc != nullptr,
+ opt2fn("-awh", nfile, fnm),
+ pull_work);
if (useReplicaExchange && MASTER(cr))
{
pme_load_balancing_t* pme_loadbal = nullptr;
if (bPMETune)
{
- pme_loadbal_init(&pme_loadbal, cr, mdlog, *ir, state->box, *fr->ic, *fr->nbv, fr->pmedata,
- fr->nbv->useGpu());
+ pme_loadbal_init(
+ &pme_loadbal, cr, mdlog, *ir, state->box, *fr->ic, *fr->nbv, fr->pmedata, fr->nbv->useGpu());
}
if (!ir->bContinuation)
if (constr)
{
/* Constrain the initial coordinates and velocities */
- do_constrain_first(fplog, constr, ir, mdatoms->nr, mdatoms->homenr,
- state->x.arrayRefWithPadding(), state->v.arrayRefWithPadding(),
- state->box, state->lambda[efptBONDED]);
- }
- if (vsite)
- {
- /* Construct the virtual sites for the initial configuration */
- vsite->construct(state->x, ir->delta_t, {}, state->box);
+ do_constrain_first(fplog,
+ constr,
+ ir,
+ mdatoms->nr,
+ mdatoms->homenr,
+ state->x.arrayRefWithPadding(),
+ state->v.arrayRefWithPadding(),
+ state->box,
+ state->lambda[efptBONDED]);
}
}
cglo_flags_iteration |= CGLO_STOPCM;
cglo_flags_iteration &= ~CGLO_TEMPERATURE;
}
- compute_globals(gstat, cr, ir, fr, ekind, makeConstArrayRef(state->x),
- makeConstArrayRef(state->v), state->box, mdatoms, nrnb, &vcm, nullptr,
- enerd, force_vir, shake_vir, total_vir, pres, constr, &nullSignaller,
- state->box, &totalNumberOfBondedInteractions, &bSumEkinhOld,
+ compute_globals(gstat,
+ cr,
+ ir,
+ fr,
+ ekind,
+ makeConstArrayRef(state->x),
+ makeConstArrayRef(state->v),
+ state->box,
+ mdatoms,
+ nrnb,
+ &vcm,
+ nullptr,
+ enerd,
+ force_vir,
+ shake_vir,
+ total_vir,
+ pres,
+ gmx::ArrayRef<real>{},
+ &nullSignaller,
+ state->box,
+ &totalNumberOfBondedInteractions,
+ &bSumEkinhOld,
cglo_flags_iteration
| (shouldCheckNumberOfBondedInteractions ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS
: 0));
inc_nrnb(nrnb, eNR_STOPCM, mdatoms->homenr);
}
}
- checkNumberOfBondedInteractions(mdlog, cr, totalNumberOfBondedInteractions, top_global, &top,
- makeConstArrayRef(state->x), state->box,
+ checkNumberOfBondedInteractions(mdlog,
+ cr,
+ totalNumberOfBondedInteractions,
+ top_global,
+ &top,
+ makeConstArrayRef(state->x),
+ state->box,
&shouldCheckNumberOfBondedInteractions);
if (ir->eI == eiVVAK)
{
kinetic energy calculation. This minimized excess variables, but
perhaps loses some logic?*/
- compute_globals(gstat, cr, ir, fr, ekind, makeConstArrayRef(state->x),
- makeConstArrayRef(state->v), state->box, mdatoms, nrnb, &vcm, nullptr,
- enerd, force_vir, shake_vir, total_vir, pres, constr, &nullSignaller,
- state->box, nullptr, &bSumEkinhOld, cglo_flags & ~CGLO_PRESSURE);
+ compute_globals(gstat,
+ cr,
+ ir,
+ fr,
+ ekind,
+ makeConstArrayRef(state->x),
+ makeConstArrayRef(state->v),
+ state->box,
+ mdatoms,
+ nrnb,
+ &vcm,
+ nullptr,
+ enerd,
+ force_vir,
+ shake_vir,
+ total_vir,
+ pres,
+ gmx::ArrayRef<real>{},
+ &nullSignaller,
+ state->box,
+ nullptr,
+ &bSumEkinhOld,
+ cglo_flags & ~CGLO_PRESSURE);
}
/* Calculate the initial half step temperature, and save the ekinh_old */
{
if (constr && ir->eConstrAlg == econtLINCS)
{
- fprintf(fplog, "RMS relative constraint deviation after constraining: %.2e\n",
+ fprintf(fplog,
+ "RMS relative constraint deviation after constraining: %.2e\n",
constr->rmsd());
}
if (EI_STATE_VELOCITY(ir->eI))
}
if (ir->init_step > 0)
{
- fprintf(stderr, "%s steps, %s ps (continuing from step %s, %8.1f ps).\n",
- gmx_step_str(ir->init_step + ir->nsteps, sbuf), tbuf,
- gmx_step_str(ir->init_step, sbuf2), ir->init_step * ir->delta_t);
+ fprintf(stderr,
+ "%s steps, %s ps (continuing from step %s, %8.1f ps).\n",
+ gmx_step_str(ir->init_step + ir->nsteps, sbuf),
+ tbuf,
+ gmx_step_str(ir->init_step, sbuf2),
+ ir->init_step * ir->delta_t);
}
else
{
step_rel = 0;
auto stopHandler = stopHandlerBuilder->getStopHandlerMD(
- compat::not_null<SimulationSignal*>(&signals[eglsSTOPCOND]), simulationsShareState,
- MASTER(cr), ir->nstlist, mdrunOptions.reproducible, nstSignalComm,
- mdrunOptions.maximumHoursToRun, ir->nstlist == 0, fplog, step, bNS, walltime_accounting);
+ compat::not_null<SimulationSignal*>(&signals[eglsSTOPCOND]),
+ simulationsShareState,
+ MASTER(cr),
+ ir->nstlist,
+ mdrunOptions.reproducible,
+ nstSignalComm,
+ mdrunOptions.maximumHoursToRun,
+ ir->nstlist == 0,
+ fplog,
+ step,
+ bNS,
+ walltime_accounting);
auto checkpointHandler = std::make_unique<CheckpointHandler>(
- compat::make_not_null<SimulationSignal*>(&signals[eglsCHKPT]), simulationsShareState,
- ir->nstlist == 0, MASTER(cr), mdrunOptions.writeConfout,
+ compat::make_not_null<SimulationSignal*>(&signals[eglsCHKPT]),
+ simulationsShareState,
+ ir->nstlist == 0,
+ MASTER(cr),
+ mdrunOptions.writeConfout,
mdrunOptions.checkpointOptions.period);
const bool resetCountersIsLocal = true;
auto resetHandler = std::make_unique<ResetHandler>(
compat::make_not_null<SimulationSignal*>(&signals[eglsRESETCOUNTERS]),
- !resetCountersIsLocal, ir->nsteps, MASTER(cr), mdrunOptions.timingOptions.resetHalfway,
- mdrunOptions.maximumHoursToRun, mdlog, wcycle, walltime_accounting);
+ !resetCountersIsLocal,
+ ir->nsteps,
+ MASTER(cr),
+ mdrunOptions.timingOptions.resetHalfway,
+ mdrunOptions.maximumHoursToRun,
+ mdlog,
+ wcycle,
+ walltime_accounting);
const DDBalanceRegionHandler ddBalanceRegionHandler(cr);
stateGpu->waitCoordinatesReadyOnHost(AtomLocality::Local);
}
/* PME grid + cut-off optimization with GPUs or PME nodes */
- pme_loadbal_do(pme_loadbal, cr, (mdrunOptions.verbose && MASTER(cr)) ? stderr : nullptr,
- fplog, mdlog, *ir, fr, state->box, state->x, wcycle, step, step_rel,
- &bPMETunePrinting, simulationWork.useGpuPmePpCommunication);
+ pme_loadbal_do(pme_loadbal,
+ cr,
+ (mdrunOptions.verbose && MASTER(cr)) ? stderr : nullptr,
+ fplog,
+ mdlog,
+ *ir,
+ fr,
+ state->box,
+ state->x,
+ wcycle,
+ step,
+ step_rel,
+ &bPMETunePrinting,
+ simulationWork.useGpuPmePpCommunication);
}
wallcycle_start(wcycle, ewcSTEP);
if (doSimulatedAnnealing)
{
- update_annealing_target_temp(ir, t, &upd);
+ // TODO: Avoid changing inputrec (#3854)
+ // Simulated annealing updates the reference temperature.
+ auto* nonConstInputrec = const_cast<t_inputrec*>(inputrec);
+ update_annealing_target_temp(nonConstInputrec, t, &upd);
}
/* Stop Center of Mass motion */
stateGpu->waitCoordinatesReadyOnHost(AtomLocality::Local);
}
+ if (vsite != nullptr)
+ {
+ // Virtual sites need to be updated before domain decomposition and forces are calculated
+ wallcycle_start(wcycle, ewcVSITECONSTR);
+ vsite->construct(state->x, ir->delta_t, state->v, state->box);
+ wallcycle_stop(wcycle, ewcVSITECONSTR);
+ }
+
if (bNS && !(bFirstStep && ir->bContinuation))
{
bMasterState = FALSE;
if (DOMAINDECOMP(cr))
{
/* Repartition the domain decomposition */
- dd_partition_system(fplog, mdlog, step, cr, bMasterState, nstglobalcomm, state_global,
- *top_global, ir, imdSession, pull_work, state, &f, mdAtoms, &top,
- fr, vsite, constr, nrnb, wcycle, do_verbose && !bPMETunePrinting);
+ dd_partition_system(fplog,
+ mdlog,
+ step,
+ cr,
+ bMasterState,
+ nstglobalcomm,
+ state_global,
+ *top_global,
+ ir,
+ imdSession,
+ pull_work,
+ state,
+ &f,
+ mdAtoms,
+ &top,
+ fr,
+ vsite,
+ constr,
+ nrnb,
+ wcycle,
+ do_verbose && !bPMETunePrinting);
shouldCheckNumberOfBondedInteractions = true;
upd.setNumAtoms(state->natoms);
}
if (MASTER(cr) && do_log)
{
- gmx::EnergyOutput::printHeader(fplog, step,
- t); /* can we improve the information printed here? */
+ gmx::EnergyOutput::printHeader(
+ fplog, step, t); /* can we improve the information printed here? */
}
if (ir->efep != efepNO)
if (bExchanged)
{
-
/* We need the kinetic energy at minus the half step for determining
* the full step kinetic energy and possibly for T-coupling.*/
/* This may not be quite working correctly yet . . . . */
- compute_globals(gstat, cr, ir, fr, ekind, makeConstArrayRef(state->x),
- makeConstArrayRef(state->v), state->box, mdatoms, nrnb, &vcm, wcycle,
- enerd, nullptr, nullptr, nullptr, nullptr, constr, &nullSignaller,
- state->box, &totalNumberOfBondedInteractions, &bSumEkinhOld,
+ compute_globals(gstat,
+ cr,
+ ir,
+ fr,
+ ekind,
+ makeConstArrayRef(state->x),
+ makeConstArrayRef(state->v),
+ state->box,
+ mdatoms,
+ nrnb,
+ &vcm,
+ wcycle,
+ enerd,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ gmx::ArrayRef<real>{},
+ &nullSignaller,
+ state->box,
+ &totalNumberOfBondedInteractions,
+ &bSumEkinhOld,
CGLO_GSTAT | CGLO_TEMPERATURE | CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS);
- checkNumberOfBondedInteractions(mdlog, cr, totalNumberOfBondedInteractions, top_global,
- &top, makeConstArrayRef(state->x), state->box,
+ checkNumberOfBondedInteractions(mdlog,
+ cr,
+ totalNumberOfBondedInteractions,
+ top_global,
+ &top,
+ makeConstArrayRef(state->x),
+ state->box,
&shouldCheckNumberOfBondedInteractions);
}
clear_mat(force_vir);
{
bCalcEnerStep = do_per_step(step, ir->nstcalcenergy);
bCalcVir = bCalcEnerStep
- || (ir->epc != epcNO
+ || (ir->epc != PressureCoupling::No
&& (do_per_step(step, ir->nstpcouple) || do_per_step(step - 1, ir->nstpcouple)));
}
else
{
bCalcEnerStep = do_per_step(step, ir->nstcalcenergy);
- bCalcVir = bCalcEnerStep || (ir->epc != epcNO && do_per_step(step, ir->nstpcouple));
+ bCalcVir = bCalcEnerStep
+ || (ir->epc != PressureCoupling::No && do_per_step(step, ir->nstpcouple));
}
bCalcEner = bCalcEnerStep;
if (shellfc)
{
/* Now is the time to relax the shells */
- relax_shell_flexcon(fplog, cr, ms, mdrunOptions.verbose, enforcedRotation, step, ir,
- imdSession, pull_work, bNS, force_flags, &top, constr, enerd,
- state->natoms, state->x.arrayRefWithPadding(),
- state->v.arrayRefWithPadding(), state->box, state->lambda,
- &state->hist, &f.view(), force_vir, mdatoms, nrnb, wcycle, shellfc,
- fr, runScheduleWork, t, mu_tot, vsite, ddBalanceRegionHandler);
+ relax_shell_flexcon(fplog,
+ cr,
+ ms,
+ mdrunOptions.verbose,
+ enforcedRotation,
+ step,
+ ir,
+ imdSession,
+ pull_work,
+ bNS,
+ force_flags,
+ &top,
+ constr,
+ enerd,
+ state->natoms,
+ state->x.arrayRefWithPadding(),
+ state->v.arrayRefWithPadding(),
+ state->box,
+ state->lambda,
+ &state->hist,
+ &f.view(),
+ force_vir,
+ mdatoms,
+ nrnb,
+ wcycle,
+ shellfc,
+ fr,
+ runScheduleWork,
+ t,
+ mu_tot,
+ vsite,
+ ddBalanceRegionHandler);
}
else
{
* This is parallellized as well, and does communication too.
* Check comments in sim_util.c
*/
- do_force(fplog, cr, ms, ir, awh.get(), enforcedRotation, imdSession, pull_work, step,
- nrnb, wcycle, &top, state->box, state->x.arrayRefWithPadding(), &state->hist,
- &f.view(), force_vir, mdatoms, enerd, state->lambda, fr, runScheduleWork,
- vsite, mu_tot, t, ed ? ed->getLegacyED() : nullptr,
- (bNS ? GMX_FORCE_NS : 0) | force_flags, ddBalanceRegionHandler);
+ do_force(fplog,
+ cr,
+ ms,
+ ir,
+ awh.get(),
+ enforcedRotation,
+ imdSession,
+ pull_work,
+ step,
+ nrnb,
+ wcycle,
+ &top,
+ state->box,
+ state->x.arrayRefWithPadding(),
+ &state->hist,
+ &f.view(),
+ force_vir,
+ mdatoms,
+ enerd,
+ state->lambda,
+ fr,
+ runScheduleWork,
+ vsite,
+ mu_tot,
+ t,
+ ed ? ed->getLegacyED() : nullptr,
+ (bNS ? GMX_FORCE_NS : 0) | force_flags,
+ ddBalanceRegionHandler);
}
// VV integrators do not need the following velocity half step
// if it is the first step after starting from a checkpoint.
// That is, the half step is needed on all other steps, and
// also the first step when starting from a .tpr file.
- if (EI_VV(ir->eI) && (!bFirstStep || startingBehavior == StartingBehavior::NewSimulation))
- /* ############### START FIRST UPDATE HALF-STEP FOR VV METHODS############### */
- {
- rvec* vbuf = nullptr;
-
- wallcycle_start(wcycle, ewcUPDATE);
- if (ir->eI == eiVV && bInitStep)
- {
- /* if using velocity verlet with full time step Ekin,
- * take the first half step only to compute the
- * virial for the first step. From there,
- * revert back to the initial coordinates
- * so that the input is actually the initial step.
- */
- snew(vbuf, state->natoms);
- copy_rvecn(state->v.rvec_array(), vbuf, 0,
- state->natoms); /* should make this better for parallelizing? */
- }
- else
- {
- /* this is for NHC in the Ekin(t+dt/2) version of vv */
- trotter_update(ir, step, ekind, enerd, state, total_vir, mdatoms, &MassQ,
- trotter_seq, ettTSEQ1);
- }
-
- upd.update_coords(*ir, step, mdatoms, state, f.view().forceWithPadding(), fcdata, ekind,
- M, etrtVELOCITY1, cr, constr != nullptr);
-
- wallcycle_stop(wcycle, ewcUPDATE);
- constrain_velocities(constr, do_log, do_ene, step, state, nullptr, bCalcVir, shake_vir);
- wallcycle_start(wcycle, ewcUPDATE);
- /* if VV, compute the pressure and constraints */
- /* For VV2, we strictly only need this if using pressure
- * control, but we really would like to have accurate pressures
- * printed out.
- * Think about ways around this in the future?
- * For now, keep this choice in comments.
- */
- /*bPres = (ir->eI==eiVV || inputrecNptTrotter(ir)); */
- /*bTemp = ((ir->eI==eiVV &&(!bInitStep)) || (ir->eI==eiVVAK && inputrecNptTrotter(ir)));*/
- bPres = TRUE;
- bTemp = ((ir->eI == eiVV && (!bInitStep)) || (ir->eI == eiVVAK));
- if (bCalcEner && ir->eI == eiVVAK)
- {
- bSumEkinhOld = TRUE;
- }
- /* for vv, the first half of the integration actually corresponds to the previous step.
- So we need information from the last step in the first half of the integration */
- if (bGStat || do_per_step(step - 1, nstglobalcomm))
- {
- wallcycle_stop(wcycle, ewcUPDATE);
- compute_globals(gstat, cr, ir, fr, ekind, makeConstArrayRef(state->x),
- makeConstArrayRef(state->v), state->box, mdatoms, nrnb, &vcm, wcycle,
- enerd, force_vir, shake_vir, total_vir, pres, constr, &nullSignaller,
- state->box, &totalNumberOfBondedInteractions, &bSumEkinhOld,
- (bGStat ? CGLO_GSTAT : 0) | (bCalcEner ? CGLO_ENERGY : 0)
- | (bTemp ? CGLO_TEMPERATURE : 0) | (bPres ? CGLO_PRESSURE : 0)
- | (bPres ? CGLO_CONSTRAINT : 0) | (bStopCM ? CGLO_STOPCM : 0)
- | (shouldCheckNumberOfBondedInteractions ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS
- : 0)
- | CGLO_SCALEEKIN);
- /* explanation of above:
- a) We compute Ekin at the full time step
- if 1) we are using the AveVel Ekin, and it's not the
- initial step, or 2) if we are using AveEkin, but need the full
- time step kinetic energy for the pressure (always true now, since we want accurate statistics).
- b) If we are using EkinAveEkin for the kinetic energy for the temperature control, we still feed in
- EkinAveVel because it's needed for the pressure */
- checkNumberOfBondedInteractions(mdlog, cr, totalNumberOfBondedInteractions,
- top_global, &top, makeConstArrayRef(state->x),
- state->box, &shouldCheckNumberOfBondedInteractions);
- if (bStopCM)
- {
- process_and_stopcm_grp(fplog, &vcm, *mdatoms, makeArrayRef(state->x),
- makeArrayRef(state->v));
- inc_nrnb(nrnb, eNR_STOPCM, mdatoms->homenr);
- }
- wallcycle_start(wcycle, ewcUPDATE);
- }
- /* temperature scaling and pressure scaling to produce the extended variables at t+dt */
- if (!bInitStep)
- {
- if (bTrotter)
- {
- m_add(force_vir, shake_vir,
- total_vir); /* we need the un-dispersion corrected total vir here */
- trotter_update(ir, step, ekind, enerd, state, total_vir, mdatoms, &MassQ,
- trotter_seq, ettTSEQ2);
-
- /* TODO This is only needed when we're about to write
- * a checkpoint, because we use it after the restart
- * (in a kludge?). But what should we be doing if
- * the startingBehavior is NewSimulation or bInitStep are true? */
- if (inputrecNptTrotter(ir) || inputrecNphTrotter(ir))
- {
- copy_mat(shake_vir, state->svir_prev);
- copy_mat(force_vir, state->fvir_prev);
- }
- if ((inputrecNptTrotter(ir) || inputrecNvtTrotter(ir)) && ir->eI == eiVV)
- {
- /* update temperature and kinetic energy now that step is over - this is the v(t+dt) point */
- enerd->term[F_TEMP] =
- sum_ekin(&(ir->opts), ekind, nullptr, (ir->eI == eiVV), FALSE);
- enerd->term[F_EKIN] = trace(ekind->ekin);
- }
- }
- else if (bExchanged)
- {
- wallcycle_stop(wcycle, ewcUPDATE);
- /* We need the kinetic energy at minus the half step for determining
- * the full step kinetic energy and possibly for T-coupling.*/
- /* This may not be quite working correctly yet . . . . */
- compute_globals(gstat, cr, ir, fr, ekind, makeConstArrayRef(state->x),
- makeConstArrayRef(state->v), state->box, mdatoms, nrnb, &vcm, wcycle,
- enerd, nullptr, nullptr, nullptr, nullptr, constr, &nullSignaller,
- state->box, nullptr, &bSumEkinhOld, CGLO_GSTAT | CGLO_TEMPERATURE);
- wallcycle_start(wcycle, ewcUPDATE);
- }
- }
- /* if it's the initial step, we performed this first step just to get the constraint virial */
- if (ir->eI == eiVV && bInitStep)
- {
- copy_rvecn(vbuf, state->v.rvec_array(), 0, state->natoms);
- sfree(vbuf);
- }
- wallcycle_stop(wcycle, ewcUPDATE);
- }
-
- /* compute the conserved quantity */
if (EI_VV(ir->eI))
{
- saved_conserved_quantity = NPT_energy(ir, state, &MassQ);
- if (ir->eI == eiVV)
- {
- last_ekin = enerd->term[F_EKIN];
- }
- if ((ir->eDispCorr != edispcEnerPres) && (ir->eDispCorr != edispcAllEnerPres))
- {
- saved_conserved_quantity -= enerd->term[F_DISPCORR];
- }
- /* sum up the foreign kinetic energy and dK/dl terms for vv. currently done every step so that dhdl is correct in the .edr */
- if (ir->efep != efepNO)
- {
- accumulateKineticLambdaComponents(enerd, state->lambda, *ir->fepvals);
- }
+ integrateVVFirstStep(step,
+ bFirstStep,
+ bInitStep,
+ startingBehavior,
+ nstglobalcomm,
+ ir,
+ fr,
+ cr,
+ state,
+ mdatoms,
+ fcdata,
+ &MassQ,
+ &vcm,
+ top_global,
+ top,
+ enerd,
+ ekind,
+ gstat,
+ &last_ekin,
+ bCalcVir,
+ total_vir,
+ shake_vir,
+ force_vir,
+ pres,
+ M,
+ do_log,
+ do_ene,
+ bCalcEner,
+ bGStat,
+ bStopCM,
+ bTrotter,
+ bExchanged,
+ &bSumEkinhOld,
+ &shouldCheckNumberOfBondedInteractions,
+ &saved_conserved_quantity,
+ &f,
+ &upd,
+ constr,
+ &nullSignaller,
+ trotter_seq,
+ nrnb,
+ mdlog,
+ fplog,
+ wcycle);
}
/* ######## END FIRST UPDATE STEP ############## */
actually move to the new state before outputting
statistics, but if performing simulated tempering, we
do update the velocities and the tau_t. */
-
- lamnew = ExpandedEnsembleDynamics(fplog, ir, enerd, state, &MassQ, state->fep_state,
- state->dfhist, step, state->v.rvec_array(), mdatoms);
+ // TODO: Avoid changing inputrec (#3854)
+ // Simulated tempering updates the reference temperature.
+ // Expanded ensemble without simulated tempering does not change the inputrec.
+ auto* nonConstInputrec = const_cast<t_inputrec*>(inputrec);
+ lamnew = ExpandedEnsembleDynamics(fplog,
+ nonConstInputrec,
+ enerd,
+ state,
+ &MassQ,
+ state->fep_state,
+ state->dfhist,
+ step,
+ state->v.rvec_array(),
+ mdatoms);
/* history is maintained in state->dfhist, but state_global is what is sent to trajectory and log output */
if (MASTER(cr))
{
* coordinates at time t. We must output all of this before
* the update.
*/
- do_md_trajectory_writing(fplog, cr, nfile, fnm, step, step_rel, t, ir, state, state_global,
- observablesHistory, top_global, fr, outf, energyOutput, ekind,
- f.view().force(), checkpointHandler->isCheckpointingStep(),
- bRerunMD, bLastStep, mdrunOptions.writeConfout, bSumEkinhOld);
+ do_md_trajectory_writing(fplog,
+ cr,
+ nfile,
+ fnm,
+ step,
+ step_rel,
+ t,
+ ir,
+ state,
+ state_global,
+ observablesHistory,
+ top_global,
+ fr,
+ outf,
+ energyOutput,
+ ekind,
+ f.view().force(),
+ checkpointHandler->isCheckpointingStep(),
+ bRerunMD,
+ bLastStep,
+ mdrunOptions.writeConfout,
+ bSumEkinhOld);
/* Check if IMD step and do IMD communication, if bIMD is TRUE. */
bInteractiveMDstep = imdSession->run(step, bNS, state->box, state->x.rvec_array(), t);
update_pcouple_before_coordinates(fplog, step, ir, state, pressureCouplingMu, M, bInitStep);
}
- if (EI_VV(ir->eI))
- {
- /* velocity half-step update */
- upd.update_coords(*ir, step, mdatoms, state, f.view().forceWithPadding(), fcdata, ekind,
- M, etrtVELOCITY2, cr, constr != nullptr);
- }
-
- /* Above, initialize just copies ekinh into ekin,
- * it doesn't copy position (for VV),
- * and entire integrator for MD.
- */
-
- if (ir->eI == eiVVAK)
- {
- cbuf.resize(state->x.size());
- std::copy(state->x.begin(), state->x.end(), cbuf.begin());
- }
-
/* With leap-frog type integrators we compute the kinetic energy
* at a whole time step as the average of the half-time step kinetic
* energies of two subsequent steps. Therefore we need to compute the
// Parrinello-Rahman requires the pressure to be availible before the update to compute
// the velocity scaling matrix. Hence, it runs one step after the nstpcouple step.
- const bool doParrinelloRahman = (ir->epc == epcPARRINELLORAHMAN
+ const bool doParrinelloRahman = (ir->epc == PressureCoupling::ParrinelloRahman
&& do_per_step(step + ir->nstpcouple - 1, ir->nstpcouple));
- if (useGpuForUpdate)
+ if (EI_VV(ir->eI))
{
- if (bNS && (bFirstStep || DOMAINDECOMP(cr)))
- {
- integrator->set(stateGpu->getCoordinates(), stateGpu->getVelocities(),
- stateGpu->getForces(), top.idef, *mdatoms, ekind->ngtc);
-
- // Copy data to the GPU after buffers might have being reinitialized
- stateGpu->copyVelocitiesToGpu(state->v, AtomLocality::Local);
- stateGpu->copyCoordinatesToGpu(state->x, AtomLocality::Local);
- }
-
- if (simulationWork.useGpuPme && !runScheduleWork->simulationWork.useGpuPmePpCommunication
- && !thisRankHasDuty(cr, DUTY_PME))
- {
- // The PME forces were recieved to the host, so have to be copied
- stateGpu->copyForcesToGpu(f.view().force(), AtomLocality::All);
- }
- else if (!runScheduleWork->stepWork.useGpuFBufferOps)
- {
- // The buffer ops were not offloaded this step, so the forces are on the
- // host and have to be copied
- stateGpu->copyForcesToGpu(f.view().force(), AtomLocality::Local);
- }
-
- const bool doTemperatureScaling =
- (ir->etc != etcNO && do_per_step(step + ir->nsttcouple - 1, ir->nsttcouple));
-
- // This applies Leap-Frog, LINCS and SETTLE in succession
- integrator->integrate(stateGpu->getForcesReadyOnDeviceEvent(
- AtomLocality::Local, runScheduleWork->stepWork.useGpuFBufferOps),
- ir->delta_t, true, bCalcVir, shake_vir, doTemperatureScaling,
- ekind->tcstat, doParrinelloRahman, ir->nstpcouple * ir->delta_t, M);
-
- // Copy velocities D2H after update if:
- // - Globals are computed this step (includes the energy output steps).
- // - Temperature is needed for the next step.
- if (bGStat || needHalfStepKineticEnergy)
- {
- stateGpu->copyVelocitiesFromGpu(state->v, AtomLocality::Local);
- stateGpu->waitVelocitiesReadyOnHost(AtomLocality::Local);
- }
+ GMX_ASSERT(!useGpuForUpdate, "GPU update is not supported with VVAK integrator.");
+
+ integrateVVSecondStep(step,
+ ir,
+ fr,
+ cr,
+ state,
+ mdatoms,
+ fcdata,
+ &MassQ,
+ &vcm,
+ pull_work,
+ enerd,
+ ekind,
+ gstat,
+ &dvdl_constr,
+ bCalcVir,
+ total_vir,
+ shake_vir,
+ force_vir,
+ pres,
+ M,
+ lastbox,
+ do_log,
+ do_ene,
+ bGStat,
+ &bSumEkinhOld,
+ &f,
+ &cbuf,
+ &upd,
+ constr,
+ &nullSignaller,
+ trotter_seq,
+ nrnb,
+ wcycle);
}
else
{
- /* With multiple time stepping we need to do an additional normal
- * update step to obtain the virial, as the actual MTS integration
- * using an acceleration where the slow forces are multiplied by mtsFactor.
- * Using that acceleration would result in a virial with the slow
- * force contribution would be a factor mtsFactor too large.
- */
- if (fr->useMts && bCalcVir && constr != nullptr)
+ if (useGpuForUpdate)
{
- upd.update_for_constraint_virial(*ir, *mdatoms, *state, f.view().forceWithPadding(), *ekind);
- constrain_coordinates(constr, do_log, do_ene, step, state,
- upd.xp()->arrayRefWithPadding(), &dvdl_constr, bCalcVir, shake_vir);
- }
+ wallcycle_stop(wcycle, ewcUPDATE);
- ArrayRefWithPadding<const RVec> forceCombined =
- (fr->useMts && step % ir->mtsLevels[1].stepFactor == 0)
- ? f.view().forceMtsCombinedWithPadding()
- : f.view().forceWithPadding();
- upd.update_coords(*ir, step, mdatoms, state, forceCombined, fcdata, ekind, M,
- etrtPOSITION, cr, constr != nullptr);
+ if (bNS && (bFirstStep || DOMAINDECOMP(cr)))
+ {
+ integrator->set(stateGpu->getCoordinates(),
+ stateGpu->getVelocities(),
+ stateGpu->getForces(),
+ top.idef,
+ *mdatoms,
+ ekind->ngtc);
+
+ // Copy data to the GPU after buffers might have being reinitialized
+ stateGpu->copyVelocitiesToGpu(state->v, AtomLocality::Local);
+ stateGpu->copyCoordinatesToGpu(state->x, AtomLocality::Local);
+ }
- wallcycle_stop(wcycle, ewcUPDATE);
+ if (simulationWork.useGpuPme && !runScheduleWork->simulationWork.useGpuPmePpCommunication
+ && !thisRankHasDuty(cr, DUTY_PME))
+ {
+ // The PME forces were recieved to the host, so have to be copied
+ stateGpu->copyForcesToGpu(f.view().force(), AtomLocality::All);
+ }
+ else if (!runScheduleWork->stepWork.useGpuFBufferOps)
+ {
+ // The buffer ops were not offloaded this step, so the forces are on the
+ // host and have to be copied
+ stateGpu->copyForcesToGpu(f.view().force(), AtomLocality::Local);
+ }
- constrain_coordinates(constr, do_log, do_ene, step, state, upd.xp()->arrayRefWithPadding(),
- &dvdl_constr, bCalcVir && !fr->useMts, shake_vir);
+ const bool doTemperatureScaling =
+ (ir->etc != TemperatureCoupling::No
+ && do_per_step(step + ir->nsttcouple - 1, ir->nsttcouple));
+
+ // This applies Leap-Frog, LINCS and SETTLE in succession
+ integrator->integrate(
+ stateGpu->getForcesReadyOnDeviceEvent(
+ AtomLocality::Local, runScheduleWork->stepWork.useGpuFBufferOps),
+ ir->delta_t,
+ true,
+ bCalcVir,
+ shake_vir,
+ doTemperatureScaling,
+ ekind->tcstat,
+ doParrinelloRahman,
+ ir->nstpcouple * ir->delta_t,
+ M);
+
+ // Copy velocities D2H after update if:
+ // - Globals are computed this step (includes the energy output steps).
+ // - Temperature is needed for the next step.
+ if (bGStat || needHalfStepKineticEnergy)
+ {
+ stateGpu->copyVelocitiesFromGpu(state->v, AtomLocality::Local);
+ stateGpu->waitVelocitiesReadyOnHost(AtomLocality::Local);
+ }
+ }
+ else
+ {
+ /* With multiple time stepping we need to do an additional normal
+ * update step to obtain the virial, as the actual MTS integration
+ * using an acceleration where the slow forces are multiplied by mtsFactor.
+ * Using that acceleration would result in a virial with the slow
+ * force contribution would be a factor mtsFactor too large.
+ */
+ if (fr->useMts && bCalcVir && constr != nullptr)
+ {
+ upd.update_for_constraint_virial(
+ *ir, *mdatoms, *state, f.view().forceWithPadding(), *ekind);
+
+ constrain_coordinates(constr,
+ do_log,
+ do_ene,
+ step,
+ state,
+ upd.xp()->arrayRefWithPadding(),
+ &dvdl_constr,
+ bCalcVir,
+ shake_vir);
+ }
- upd.update_sd_second_half(*ir, step, &dvdl_constr, mdatoms, state, cr, nrnb, wcycle,
- constr, do_log, do_ene);
- upd.finish_update(*ir, mdatoms, state, wcycle, constr != nullptr);
- }
+ ArrayRefWithPadding<const RVec> forceCombined =
+ (fr->useMts && step % ir->mtsLevels[1].stepFactor == 0)
+ ? f.view().forceMtsCombinedWithPadding()
+ : f.view().forceWithPadding();
+ upd.update_coords(
+ *ir, step, mdatoms, state, forceCombined, fcdata, ekind, M, etrtPOSITION, cr, constr != nullptr);
- if (ir->bPull && ir->pull->bSetPbcRefToPrevStepCOM)
- {
- updatePrevStepPullCom(pull_work, state);
- }
+ wallcycle_stop(wcycle, ewcUPDATE);
- if (ir->eI == eiVVAK)
- {
- /* erase F_EKIN and F_TEMP here? */
- /* just compute the kinetic energy at the half step to perform a trotter step */
- compute_globals(gstat, cr, ir, fr, ekind, makeConstArrayRef(state->x),
- makeConstArrayRef(state->v), state->box, mdatoms, nrnb, &vcm, wcycle, enerd,
- force_vir, shake_vir, total_vir, pres, constr, &nullSignaller, lastbox,
- nullptr, &bSumEkinhOld, (bGStat ? CGLO_GSTAT : 0) | CGLO_TEMPERATURE);
- wallcycle_start(wcycle, ewcUPDATE);
- trotter_update(ir, step, ekind, enerd, state, total_vir, mdatoms, &MassQ, trotter_seq, ettTSEQ4);
- /* now we know the scaling, we can compute the positions again */
- std::copy(cbuf.begin(), cbuf.end(), state->x.begin());
+ constrain_coordinates(constr,
+ do_log,
+ do_ene,
+ step,
+ state,
+ upd.xp()->arrayRefWithPadding(),
+ &dvdl_constr,
+ bCalcVir && !fr->useMts,
+ shake_vir);
+
+ upd.update_sd_second_half(
+ *ir, step, &dvdl_constr, mdatoms, state, cr, nrnb, wcycle, constr, do_log, do_ene);
+ upd.finish_update(*ir, mdatoms, state, wcycle, constr != nullptr);
+ }
- upd.update_coords(*ir, step, mdatoms, state, f.view().forceWithPadding(), fcdata, ekind,
- M, etrtPOSITION, cr, constr != nullptr);
- wallcycle_stop(wcycle, ewcUPDATE);
+ if (ir->bPull && ir->pull->bSetPbcRefToPrevStepCOM)
+ {
+ updatePrevStepPullCom(pull_work, state);
+ }
- /* do we need an extra constraint here? just need to copy out of as_rvec_array(state->v.data()) to upd->xp? */
- /* are the small terms in the shake_vir here due
- * to numerical errors, or are they important
- * physically? I'm thinking they are just errors, but not completely sure.
- * For now, will call without actually constraining, constr=NULL*/
- upd.finish_update(*ir, mdatoms, state, wcycle, false);
- }
- if (EI_VV(ir->eI))
- {
- /* this factor or 2 correction is necessary
- because half of the constraint force is removed
- in the vv step, so we have to double it. See
- the Issue #1255. It is not yet clear
- if the factor of 2 is exact, or just a very
- good approximation, and this will be
- investigated. The next step is to see if this
- can be done adding a dhdl contribution from the
- rattle step, but this is somewhat more
- complicated with the current code. Will be
- investigated, hopefully for 4.6.3. However,
- this current solution is much better than
- having it completely wrong.
- */
- enerd->term[F_DVDL_CONSTR] += 2 * dvdl_constr;
- }
- else
- {
enerd->term[F_DVDL_CONSTR] += dvdl_constr;
}
- if (vsite != nullptr)
- {
- wallcycle_start(wcycle, ewcVSITECONSTR);
- vsite->construct(state->x, ir->delta_t, state->v, state->box);
- wallcycle_stop(wcycle, ewcVSITECONSTR);
- }
-
/* ############## IF NOT VV, Calculate globals HERE ############ */
/* With Leap-Frog we can skip compute_globals at
* non-communication steps, but we need to calculate
bool doIntraSimSignal = true;
SimulationSignaller signaller(&signals, cr, ms, doInterSimSignal, doIntraSimSignal);
- compute_globals(gstat, cr, ir, fr, ekind, makeConstArrayRef(state->x),
- makeConstArrayRef(state->v), state->box, mdatoms, nrnb, &vcm,
- wcycle, enerd, force_vir, shake_vir, total_vir, pres, constr,
- &signaller, lastbox, &totalNumberOfBondedInteractions, &bSumEkinhOld,
- (bGStat ? CGLO_GSTAT : 0) | (!EI_VV(ir->eI) && bCalcEner ? CGLO_ENERGY : 0)
- | (!EI_VV(ir->eI) && bStopCM ? CGLO_STOPCM : 0)
- | (!EI_VV(ir->eI) ? CGLO_TEMPERATURE : 0)
- | (!EI_VV(ir->eI) ? CGLO_PRESSURE : 0) | CGLO_CONSTRAINT
- | (shouldCheckNumberOfBondedInteractions ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS
- : 0));
- checkNumberOfBondedInteractions(mdlog, cr, totalNumberOfBondedInteractions,
- top_global, &top, makeConstArrayRef(state->x),
- state->box, &shouldCheckNumberOfBondedInteractions);
+ compute_globals(
+ gstat,
+ cr,
+ ir,
+ fr,
+ ekind,
+ makeConstArrayRef(state->x),
+ makeConstArrayRef(state->v),
+ state->box,
+ mdatoms,
+ nrnb,
+ &vcm,
+ wcycle,
+ enerd,
+ force_vir,
+ shake_vir,
+ total_vir,
+ pres,
+ (!EI_VV(ir->eI) && bCalcEner && constr != nullptr) ? constr->rmsdData()
+ : gmx::ArrayRef<real>{},
+ &signaller,
+ lastbox,
+ &totalNumberOfBondedInteractions,
+ &bSumEkinhOld,
+ (bGStat ? CGLO_GSTAT : 0) | (!EI_VV(ir->eI) && bCalcEner ? CGLO_ENERGY : 0)
+ | (!EI_VV(ir->eI) && bStopCM ? CGLO_STOPCM : 0)
+ | (!EI_VV(ir->eI) ? CGLO_TEMPERATURE : 0)
+ | (!EI_VV(ir->eI) ? CGLO_PRESSURE : 0) | CGLO_CONSTRAINT
+ | (shouldCheckNumberOfBondedInteractions ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS
+ : 0));
+ checkNumberOfBondedInteractions(mdlog,
+ cr,
+ totalNumberOfBondedInteractions,
+ top_global,
+ &top,
+ makeConstArrayRef(state->x),
+ state->box,
+ &shouldCheckNumberOfBondedInteractions);
if (!EI_VV(ir->eI) && bStopCM)
{
- process_and_stopcm_grp(fplog, &vcm, *mdatoms, makeArrayRef(state->x),
- makeArrayRef(state->v));
+ process_and_stopcm_grp(
+ fplog, &vcm, *mdatoms, makeArrayRef(state->x), makeArrayRef(state->v));
inc_nrnb(nrnb, eNR_STOPCM, mdatoms->homenr);
// TODO: The special case of removing CM motion should be dealt more gracefully
accumulateKineticLambdaComponents(enerd, state->lambda, *ir->fepvals);
}
- update_pcouple_after_coordinates(fplog, step, ir, mdatoms, pres, force_vir, shake_vir,
- pressureCouplingMu, state, nrnb, upd.deform(), !useGpuForUpdate);
+ update_pcouple_after_coordinates(
+ fplog, step, ir, mdatoms, pres, force_vir, shake_vir, pressureCouplingMu, state, nrnb, upd.deform(), !useGpuForUpdate);
- const bool doBerendsenPressureCoupling =
- (inputrec->epc == epcBERENDSEN && do_per_step(step, inputrec->nstpcouple));
- const bool doCRescalePressureCoupling =
- (inputrec->epc == epcCRESCALE && do_per_step(step, inputrec->nstpcouple));
+ const bool doBerendsenPressureCoupling = (inputrec->epc == PressureCoupling::Berendsen
+ && do_per_step(step, inputrec->nstpcouple));
+ const bool doCRescalePressureCoupling = (inputrec->epc == PressureCoupling::CRescale
+ && do_per_step(step, inputrec->nstpcouple));
if (useGpuForUpdate
&& (doBerendsenPressureCoupling || doCRescalePressureCoupling || doParrinelloRahman))
{
if (fplog && do_log && bDoExpanded)
{
/* only needed if doing expanded ensemble */
- PrintFreeEnergyInfoToFile(fplog, ir->fepvals, ir->expandedvals,
+ PrintFreeEnergyInfoToFile(fplog,
+ ir->fepvals,
+ ir->expandedvals,
ir->bSimTemp ? ir->simtempvals : nullptr,
- state_global->dfhist, state->fep_state, ir->nstlog, step);
+ state_global->dfhist,
+ state->fep_state,
+ ir->nstlog,
+ step);
}
if (bCalcEner)
{
- energyOutput.addDataAtEnergyStep(
- bDoDHDL, bCalcEnerStep, t, mdatoms->tmass, enerd, ir->fepvals,
- ir->expandedvals, lastbox,
- PTCouplingArrays{ state->boxv, state->nosehoover_xi, state->nosehoover_vxi,
- state->nhpres_xi, state->nhpres_vxi },
- state->fep_state, shake_vir, force_vir, total_vir, pres, ekind, mu_tot, constr);
+ energyOutput.addDataAtEnergyStep(bDoDHDL,
+ bCalcEnerStep,
+ t,
+ mdatoms->tmass,
+ enerd,
+ ir->fepvals,
+ ir->expandedvals,
+ lastbox,
+ PTCouplingArrays{ state->boxv,
+ state->nosehoover_xi,
+ state->nosehoover_vxi,
+ state->nhpres_xi,
+ state->nhpres_vxi },
+ state->fep_state,
+ shake_vir,
+ force_vir,
+ total_vir,
+ pres,
+ ekind,
+ mu_tot,
+ constr);
}
else
{
if (doSimulatedAnnealing)
{
- gmx::EnergyOutput::printAnnealingTemperatures(do_log ? fplog : nullptr, groups,
- &(ir->opts));
+ gmx::EnergyOutput::printAnnealingTemperatures(
+ do_log ? fplog : nullptr, groups, &(ir->opts));
}
if (do_log || do_ene || do_dr || do_or)
{
- energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), do_ene, do_dr, do_or,
- do_log ? fplog : nullptr, step, t,
- fr->fcdata.get(), awh.get());
+ energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf),
+ do_ene,
+ do_dr,
+ do_or,
+ do_log ? fplog : nullptr,
+ step,
+ t,
+ fr->fcdata.get(),
+ awh.get());
}
if (do_log && ir->bDoAwh && awh->hasFepLambdaDimension())
{
bNeedRepartition = FALSE;
if ((ir->eSwapCoords != eswapNO) && (step > 0) && !bLastStep && do_per_step(step, ir->swap->nstswap))
{
- bNeedRepartition =
- do_swapcoords(cr, step, t, ir, swap, wcycle, as_rvec_array(state->x.data()),
- state->box, MASTER(cr) && mdrunOptions.verbose, bRerunMD);
+ bNeedRepartition = do_swapcoords(cr,
+ step,
+ t,
+ ir,
+ swap,
+ wcycle,
+ as_rvec_array(state->x.data()),
+ state->box,
+ MASTER(cr) && mdrunOptions.verbose,
+ bRerunMD);
if (bNeedRepartition && DOMAINDECOMP(cr))
{
if ((bExchanged || bNeedRepartition) && DOMAINDECOMP(cr))
{
- dd_partition_system(fplog, mdlog, step, cr, TRUE, 1, state_global, *top_global, ir,
- imdSession, pull_work, state, &f, mdAtoms, &top, fr, vsite, constr,
- nrnb, wcycle, FALSE);
+ dd_partition_system(fplog,
+ mdlog,
+ step,
+ cr,
+ TRUE,
+ 1,
+ state_global,
+ *top_global,
+ ir,
+ imdSession,
+ pull_work,
+ state,
+ &f,
+ mdAtoms,
+ &top,
+ fr,
+ vsite,
+ constr,
+ nrnb,
+ wcycle,
+ FALSE);
shouldCheckNumberOfBondedInteractions = true;
upd.setNumAtoms(state->natoms);
}
}
#endif
- resetHandler->resetCounters(step, step_rel, mdlog, fplog, cr, fr->nbv.get(), nrnb,
- fr->pmedata, pme_loadbal, wcycle, walltime_accounting);
+ resetHandler->resetCounters(
+ step, step_rel, mdlog, fplog, cr, fr->nbv.get(), nrnb, fr->pmedata, pme_loadbal, wcycle, walltime_accounting);
/* If bIMD is TRUE, the master updates the IMD energy record and sends positions to VMD client */
imdSession->updateEnergyRecordAndSendPositionsAndEnergies(bInteractiveMDstep, step, bCalcEner);
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2016,2017,2018,2019,2020,2021, 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.
#ifndef GMX_MDRUN_MDMODULES_H
#define GMX_MDRUN_MDMODULES_H
-#include "gromacs/utility/classhelpers.h"
+#include <memory>
struct t_inputrec;
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
void gmx::LegacySimulator::do_mimic()
{
- t_inputrec* ir = inputrec;
+ const t_inputrec* ir = inputrec;
int64_t step, step_rel;
double t;
bool isLastStep = false;
{
gmx_fatal(FARGS, "Multiple simulations not supported by MiMiC.");
}
- if (std::any_of(ir->opts.annealing, ir->opts.annealing + ir->opts.ngtc,
- [](int i) { return i != eannNO; }))
+ if (std::any_of(ir->opts.annealing, ir->opts.annealing + ir->opts.ngtc, [](int i) {
+ return i != eannNO;
+ }))
{
gmx_fatal(FARGS, "Simulated annealing not supported by MiMiC.");
}
/* Settings for rerun */
- ir->nstlist = 1;
- ir->nstcalcenergy = 1;
+ {
+ // TODO: Avoid changing inputrec (#3854)
+ auto* nonConstInputrec = const_cast<t_inputrec*>(inputrec);
+ nonConstInputrec->nstlist = 1;
+ nonConstInputrec->nstcalcenergy = 1;
+ nonConstInputrec->nstxout_compressed = 0;
+ }
int nstglobalcomm = 1;
const bool bNS = true;
MimicCommunicator::init();
auto nonConstGlobalTopology = const_cast<gmx_mtop_t*>(top_global);
MimicCommunicator::sendInitData(nonConstGlobalTopology, state_global->x);
- ir->nsteps = MimicCommunicator::getStepNumber();
+ // TODO: Avoid changing inputrec (#3854)
+ auto* nonConstInputrec = const_cast<t_inputrec*>(inputrec);
+ nonConstInputrec->nsteps = MimicCommunicator::getStepNumber();
+ }
+ if (DOMAINDECOMP(cr))
+ {
+ // TODO: Avoid changing inputrec (#3854)
+ auto* nonConstInputrec = const_cast<t_inputrec*>(inputrec);
+ gmx_bcast(sizeof(ir->nsteps), &nonConstInputrec->nsteps, cr->mpi_comm_mygroup);
}
- ir->nstxout_compressed = 0;
const SimulationGroups* groups = &top_global->groups;
{
auto nonConstGlobalTopology = const_cast<gmx_mtop_t*>(top_global);
initialize_lambdas(fplog, *ir, MASTER(cr), &state_global->fep_state, state_global->lambda);
const bool simulationsShareState = false;
- gmx_mdoutf* outf = init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr, outputProvider,
- mdModulesNotifier, ir, top_global, oenv, wcycle,
- StartingBehavior::NewSimulation, simulationsShareState, ms);
- gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf), top_global, ir, pull_work,
- mdoutf_get_fp_dhdl(outf), true, StartingBehavior::NewSimulation,
- simulationsShareState, mdModulesNotifier);
+ gmx_mdoutf* outf = init_mdoutf(fplog,
+ nfile,
+ fnm,
+ mdrunOptions,
+ cr,
+ outputProvider,
+ mdModulesNotifier,
+ ir,
+ top_global,
+ oenv,
+ wcycle,
+ StartingBehavior::NewSimulation,
+ simulationsShareState,
+ ms);
+ gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf),
+ top_global,
+ ir,
+ pull_work,
+ mdoutf_get_fp_dhdl(outf),
+ true,
+ StartingBehavior::NewSimulation,
+ simulationsShareState,
+ mdModulesNotifier);
gstat = global_stat_init(ir);
/* Check for polarizable models and flexible constraints */
- shellfc = init_shell_flexcon(fplog, top_global, constr ? constr->numFlexibleConstraints() : 0,
- ir->nstcalcenergy, DOMAINDECOMP(cr),
+ shellfc = init_shell_flexcon(fplog,
+ top_global,
+ constr ? constr->numFlexibleConstraints() : 0,
+ ir->nstcalcenergy,
+ DOMAINDECOMP(cr),
runScheduleWork->simulationWork.useGpuPme);
{
dd_init_local_state(cr->dd, state_global, state);
/* Distribute the charge groups over the nodes from the master node */
- dd_partition_system(fplog, mdlog, ir->init_step, cr, TRUE, 1, state_global, *top_global, ir,
- imdSession, pull_work, state, &f, mdAtoms, &top, fr, vsite, constr,
- nrnb, nullptr, FALSE);
+ dd_partition_system(fplog,
+ mdlog,
+ ir->init_step,
+ cr,
+ TRUE,
+ 1,
+ state_global,
+ *top_global,
+ ir,
+ imdSession,
+ pull_work,
+ state,
+ &f,
+ mdAtoms,
+ &top,
+ fr,
+ vsite,
+ constr,
+ nrnb,
+ nullptr,
+ FALSE);
shouldCheckNumberOfBondedInteractions = true;
- gmx_bcast(sizeof(ir->nsteps), &ir->nsteps, cr->mpi_comm_mygroup);
}
else
{
| (shouldCheckNumberOfBondedInteractions ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS : 0));
bool bSumEkinhOld = false;
t_vcm* vcm = nullptr;
- compute_globals(gstat, cr, ir, fr, ekind, makeConstArrayRef(state->x),
- makeConstArrayRef(state->v), state->box, mdatoms, nrnb, vcm, nullptr, enerd,
- force_vir, shake_vir, total_vir, pres, constr, &nullSignaller, state->box,
- &totalNumberOfBondedInteractions, &bSumEkinhOld, cglo_flags);
+ compute_globals(gstat,
+ cr,
+ ir,
+ fr,
+ ekind,
+ makeConstArrayRef(state->x),
+ makeConstArrayRef(state->v),
+ state->box,
+ mdatoms,
+ nrnb,
+ vcm,
+ nullptr,
+ enerd,
+ force_vir,
+ shake_vir,
+ total_vir,
+ pres,
+ gmx::ArrayRef<real>{},
+ &nullSignaller,
+ state->box,
+ &totalNumberOfBondedInteractions,
+ &bSumEkinhOld,
+ cglo_flags);
}
- checkNumberOfBondedInteractions(mdlog, cr, totalNumberOfBondedInteractions, top_global, &top,
- makeConstArrayRef(state->x), state->box,
+ checkNumberOfBondedInteractions(mdlog,
+ cr,
+ totalNumberOfBondedInteractions,
+ top_global,
+ &top,
+ makeConstArrayRef(state->x),
+ state->box,
&shouldCheckNumberOfBondedInteractions);
if (MASTER(cr))
step_rel = 0;
auto stopHandler = stopHandlerBuilder->getStopHandlerMD(
- compat::not_null<SimulationSignal*>(&signals[eglsSTOPCOND]), false, MASTER(cr),
- ir->nstlist, mdrunOptions.reproducible, nstglobalcomm, mdrunOptions.maximumHoursToRun,
- ir->nstlist == 0, fplog, step, bNS, walltime_accounting);
+ compat::not_null<SimulationSignal*>(&signals[eglsSTOPCOND]),
+ false,
+ MASTER(cr),
+ ir->nstlist,
+ mdrunOptions.reproducible,
+ nstglobalcomm,
+ mdrunOptions.maximumHoursToRun,
+ ir->nstlist == 0,
+ fplog,
+ step,
+ bNS,
+ walltime_accounting);
// we don't do counter resetting in rerun - finish will always be valid
walltime_accounting_set_valid_finish(walltime_accounting);
"decomposition, "
"use a single rank");
}
+ if (constructVsites)
+ {
+ wallcycle_start(wcycle, ewcVSITECONSTR);
+ vsite->construct(state->x, ir->delta_t, state->v, state->box);
+ wallcycle_stop(wcycle, ewcVSITECONSTR);
+ }
}
if (DOMAINDECOMP(cr))
{
/* Repartition the domain decomposition */
const bool bMasterState = true;
- dd_partition_system(fplog, mdlog, step, cr, bMasterState, nstglobalcomm, state_global,
- *top_global, ir, imdSession, pull_work, state, &f, mdAtoms, &top,
- fr, vsite, constr, nrnb, wcycle, mdrunOptions.verbose);
+ dd_partition_system(fplog,
+ mdlog,
+ step,
+ cr,
+ bMasterState,
+ nstglobalcomm,
+ state_global,
+ *top_global,
+ ir,
+ imdSession,
+ pull_work,
+ state,
+ &f,
+ mdAtoms,
+ &top,
+ fr,
+ vsite,
+ constr,
+ nrnb,
+ wcycle,
+ mdrunOptions.verbose);
shouldCheckNumberOfBondedInteractions = true;
}
if (shellfc)
{
/* Now is the time to relax the shells */
- relax_shell_flexcon(fplog, cr, ms, mdrunOptions.verbose, enforcedRotation, step, ir,
- imdSession, pull_work, bNS, force_flags, &top, constr, enerd,
- state->natoms, state->x.arrayRefWithPadding(),
- state->v.arrayRefWithPadding(), state->box, state->lambda,
- &state->hist, &f.view(), force_vir, mdatoms, nrnb, wcycle, shellfc,
- fr, runScheduleWork, t, mu_tot, vsite, ddBalanceRegionHandler);
+ relax_shell_flexcon(fplog,
+ cr,
+ ms,
+ mdrunOptions.verbose,
+ enforcedRotation,
+ step,
+ ir,
+ imdSession,
+ pull_work,
+ bNS,
+ force_flags,
+ &top,
+ constr,
+ enerd,
+ state->natoms,
+ state->x.arrayRefWithPadding(),
+ state->v.arrayRefWithPadding(),
+ state->box,
+ state->lambda,
+ &state->hist,
+ &f.view(),
+ force_vir,
+ mdatoms,
+ nrnb,
+ wcycle,
+ shellfc,
+ fr,
+ runScheduleWork,
+ t,
+ mu_tot,
+ vsite,
+ ddBalanceRegionHandler);
}
else
{
*/
Awh* awh = nullptr;
gmx_edsam* ed = nullptr;
- do_force(fplog, cr, ms, ir, awh, enforcedRotation, imdSession, pull_work, step, nrnb,
- wcycle, &top, state->box, state->x.arrayRefWithPadding(), &state->hist,
- &f.view(), force_vir, mdatoms, enerd, state->lambda, fr, runScheduleWork,
- vsite, mu_tot, t, ed, GMX_FORCE_NS | force_flags, ddBalanceRegionHandler);
+ do_force(fplog,
+ cr,
+ ms,
+ ir,
+ awh,
+ enforcedRotation,
+ imdSession,
+ pull_work,
+ step,
+ nrnb,
+ wcycle,
+ &top,
+ state->box,
+ state->x.arrayRefWithPadding(),
+ &state->hist,
+ &f.view(),
+ force_vir,
+ mdatoms,
+ enerd,
+ state->lambda,
+ fr,
+ runScheduleWork,
+ vsite,
+ mu_tot,
+ t,
+ ed,
+ GMX_FORCE_NS | force_flags,
+ ddBalanceRegionHandler);
}
/* Now we have the energies and forces corresponding to the
const bool isCheckpointingStep = false;
const bool doRerun = false;
const bool bSumEkinhOld = false;
- do_md_trajectory_writing(fplog, cr, nfile, fnm, step, step_rel, t, ir, state,
- state_global, observablesHistory, top_global, fr, outf,
- energyOutput, ekind, f.view().force(), isCheckpointingStep,
- doRerun, isLastStep, mdrunOptions.writeConfout, bSumEkinhOld);
+ do_md_trajectory_writing(fplog,
+ cr,
+ nfile,
+ fnm,
+ step,
+ step_rel,
+ t,
+ ir,
+ state,
+ state_global,
+ observablesHistory,
+ top_global,
+ fr,
+ outf,
+ energyOutput,
+ ekind,
+ f.view().force(),
+ isCheckpointingStep,
+ doRerun,
+ isLastStep,
+ mdrunOptions.writeConfout,
+ bSumEkinhOld);
}
stopHandler->setSignal();
- if (vsite != nullptr)
- {
- wallcycle_start(wcycle, ewcVSITECONSTR);
- vsite->construct(state->x, ir->delta_t, state->v, state->box);
- wallcycle_stop(wcycle, ewcVSITECONSTR);
- }
-
{
const bool doInterSimSignal = false;
const bool doIntraSimSignal = true;
t_vcm* vcm = nullptr;
SimulationSignaller signaller(&signals, cr, ms, doInterSimSignal, doIntraSimSignal);
- compute_globals(gstat, cr, ir, fr, ekind, makeConstArrayRef(state->x),
- makeConstArrayRef(state->v), state->box, mdatoms, nrnb, vcm, wcycle,
- enerd, nullptr, nullptr, nullptr, nullptr, constr, &signaller,
- state->box, &totalNumberOfBondedInteractions, &bSumEkinhOld,
+ compute_globals(gstat,
+ cr,
+ ir,
+ fr,
+ ekind,
+ makeConstArrayRef(state->x),
+ makeConstArrayRef(state->v),
+ state->box,
+ mdatoms,
+ nrnb,
+ vcm,
+ wcycle,
+ enerd,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ constr != nullptr ? constr->rmsdData() : gmx::ArrayRef<real>{},
+ &signaller,
+ state->box,
+ &totalNumberOfBondedInteractions,
+ &bSumEkinhOld,
CGLO_GSTAT | CGLO_ENERGY
| (shouldCheckNumberOfBondedInteractions ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS
: 0));
- checkNumberOfBondedInteractions(mdlog, cr, totalNumberOfBondedInteractions, top_global,
- &top, makeConstArrayRef(state->x), state->box,
+ checkNumberOfBondedInteractions(mdlog,
+ cr,
+ totalNumberOfBondedInteractions,
+ top_global,
+ &top,
+ makeConstArrayRef(state->x),
+ state->box,
&shouldCheckNumberOfBondedInteractions);
}
if (DOMAINDECOMP(cr))
{
ftemp = gmx::makeArrayRef(fglobal);
- dd_collect_vec(cr->dd, state->ddp_count, state->ddp_count_cg_gl, state->cg_gl,
- flocal, ftemp);
+ dd_collect_vec(cr->dd, state->ddp_count, state->ddp_count_cg_gl, state->cg_gl, flocal, ftemp);
}
else
{
if (MASTER(cr))
{
const bool bCalcEnerStep = true;
- energyOutput.addDataAtEnergyStep(
- doFreeEnergyPerturbation, bCalcEnerStep, t, mdatoms->tmass, enerd, ir->fepvals,
- ir->expandedvals, state->box,
- PTCouplingArrays({ state->boxv, state->nosehoover_xi, state->nosehoover_vxi,
- state->nhpres_xi, state->nhpres_vxi }),
- state->fep_state, shake_vir, force_vir, total_vir, pres, ekind, mu_tot, constr);
+ energyOutput.addDataAtEnergyStep(doFreeEnergyPerturbation,
+ bCalcEnerStep,
+ t,
+ mdatoms->tmass,
+ enerd,
+ ir->fepvals,
+ ir->expandedvals,
+ state->box,
+ PTCouplingArrays({ state->boxv,
+ state->nosehoover_xi,
+ state->nosehoover_vxi,
+ state->nhpres_xi,
+ state->nhpres_vxi }),
+ state->fep_state,
+ shake_vir,
+ force_vir,
+ total_vir,
+ pres,
+ ekind,
+ mu_tot,
+ constr);
const bool do_ene = true;
const bool do_log = true;
const bool do_or = ir->nstorireout != 0;
EnergyOutput::printAnnealingTemperatures(do_log ? fplog : nullptr, groups, &(ir->opts));
- energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), do_ene, do_dr, do_or,
- do_log ? fplog : nullptr, step, t, fr->fcdata.get(), awh);
+ energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf),
+ do_ene,
+ do_dr,
+ do_or,
+ do_log ? fplog : nullptr,
+ step,
+ t,
+ fr->fcdata.get(),
+ awh);
if (do_per_step(step, ir->nstlog))
{
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 The GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
fprintf(fp,
"\n%s converged to machine precision in %s steps,\n"
"but did not reach the requested Fmax < %g.\n",
- alg, gmx_step_str(count, buf), ftol);
+ alg,
+ gmx_step_str(count, buf),
+ ftol);
}
else
{
- fprintf(fp, "\n%s did not converge to Fmax < %g in %s steps.\n", alg, ftol,
- gmx_step_str(count, buf));
+ fprintf(fp, "\n%s did not converge to Fmax < %g in %s steps.\n", alg, ftol, gmx_step_str(count, buf));
}
#if GMX_DOUBLE
//! Compute the norm and max of the force array in parallel
static void get_f_norm_max(const t_commrec* cr,
- t_grpopts* opts,
+ const t_grpopts* opts,
t_mdatoms* mdatoms,
gmx::ArrayRef<const gmx::RVec> f,
real* fnorm,
}
//! Compute the norm of the force
-static void get_state_f_norm_max(const t_commrec* cr, t_grpopts* opts, t_mdatoms* mdatoms, em_state_t* ems)
+static void get_state_f_norm_max(const t_commrec* cr, const t_grpopts* opts, t_mdatoms* mdatoms, em_state_t* ems)
{
get_f_norm_max(cr, opts, mdatoms, ems->f.view().force(), &ems->fnorm, &ems->fmax, &ems->a_fmax);
}
const gmx::MDLogger& mdlog,
const char* title,
const t_commrec* cr,
- t_inputrec* ir,
+ const t_inputrec* ir,
gmx::ImdSession* imdSession,
pull_t* pull_work,
t_state* state_global,
{
GMX_ASSERT(shellfc != nullptr, "With NM we always support shells");
- *shellfc =
- init_shell_flexcon(stdout, top_global, constr ? constr->numFlexibleConstraints() : 0,
- ir->nstcalcenergy, DOMAINDECOMP(cr), thisRankHasDuty(cr, DUTY_PME));
+ *shellfc = init_shell_flexcon(stdout,
+ top_global,
+ constr ? constr->numFlexibleConstraints() : 0,
+ ir->nstcalcenergy,
+ DOMAINDECOMP(cr),
+ thisRankHasDuty(cr, DUTY_PME));
}
else
{
dd_init_local_state(cr->dd, state_global, &ems->s);
/* Distribute the charge groups over the nodes from the master node */
- dd_partition_system(fplog, mdlog, ir->init_step, cr, TRUE, 1, state_global, *top_global, ir,
- imdSession, pull_work, &ems->s, &ems->f, mdAtoms, top, fr, vsite,
- constr, nrnb, nullptr, FALSE);
+ dd_partition_system(fplog,
+ mdlog,
+ ir->init_step,
+ cr,
+ TRUE,
+ 1,
+ state_global,
+ *top_global,
+ ir,
+ imdSession,
+ pull_work,
+ &ems->s,
+ &ems->f,
+ mdAtoms,
+ top,
+ fr,
+ vsite,
+ constr,
+ nrnb,
+ nullptr,
+ FALSE);
dd_store_state(cr->dd, &ems->s);
}
else
ems->s = *state_global;
state_change_natoms(&ems->s, ems->s.natoms);
- mdAlgorithmsSetupAtomData(cr, ir, *top_global, top, fr, &ems->f, mdAtoms, constr, vsite,
- shellfc ? *shellfc : nullptr);
+ mdAlgorithmsSetupAtomData(
+ cr, ir, *top_global, top, fr, &ems->f, mdAtoms, constr, vsite, shellfc ? *shellfc : nullptr);
}
update_mdatoms(mdAtoms->mdatoms(), ems->s.lambda[efptMASS]);
// TODO how should this cross-module support dependency be managed?
if (ir->eConstrAlg == econtSHAKE && gmx_mtop_ftype_count(top_global, F_CONSTR) > 0)
{
- gmx_fatal(FARGS, "Can not do energy minimization with %s, use %s\n",
- econstr_names[econtSHAKE], econstr_names[econtLINCS]);
+ gmx_fatal(FARGS,
+ "Can not do energy minimization with %s, use %s\n",
+ econstr_names[econtSHAKE],
+ econstr_names[econtLINCS]);
}
if (!ir->bContinuation)
bool computeEnergy = true;
bool computeVirial = false;
dvdl_constr = 0;
- constr->apply(needsLogging, computeEnergy, -1, 0, 1.0, ems->s.x.arrayRefWithPadding(),
- ems->s.x.arrayRefWithPadding(), ArrayRef<RVec>(), ems->s.box,
- ems->s.lambda[efptFEP], &dvdl_constr, gmx::ArrayRefWithPadding<RVec>(),
- computeVirial, nullptr, gmx::ConstraintVariable::Positions);
+ constr->apply(needsLogging,
+ computeEnergy,
+ -1,
+ 0,
+ 1.0,
+ ems->s.x.arrayRefWithPadding(),
+ ems->s.x.arrayRefWithPadding(),
+ ArrayRef<RVec>(),
+ ems->s.box,
+ ems->s.lambda[efptFEP],
+ &dvdl_constr,
+ gmx::ArrayRefWithPadding<RVec>(),
+ computeVirial,
+ nullptr,
+ gmx::ConstraintVariable::Positions);
}
}
gmx_bool bF,
const char* confout,
const gmx_mtop_t* top_global,
- t_inputrec* ir,
+ const t_inputrec* ir,
int64_t step,
em_state_t* state,
t_state* state_global,
}
gmx::WriteCheckpointDataHolder checkpointDataHolder;
- mdoutf_write_to_trajectory_files(fplog, cr, outf, mdof_flags, top_global->natoms, step,
- static_cast<double>(step), &state->s, state_global,
- observablesHistory, state->f.view().force(), &checkpointDataHolder);
+ mdoutf_write_to_trajectory_files(fplog,
+ cr,
+ outf,
+ mdof_flags,
+ top_global->natoms,
+ step,
+ static_cast<double>(step),
+ &state->s,
+ state_global,
+ observablesHistory,
+ state->f.view().force(),
+ &checkpointDataHolder);
if (confout != nullptr)
{
if (!bX)
{
auto globalXRef = MASTER(cr) ? state_global->x : gmx::ArrayRef<gmx::RVec>();
- dd_collect_vec(cr->dd, state->s.ddp_count, state->s.ddp_count_cg_gl, state->s.cg_gl,
- state->s.x, globalXRef);
+ dd_collect_vec(
+ cr->dd, state->s.ddp_count, state->s.ddp_count_cg_gl, state->s.cg_gl, state->s.x, globalXRef);
}
}
else
do_pbc_mtop(ir->pbcType, state->s.box, top_global, state_global->x.rvec_array());
}
- write_sto_conf_mtop(confout, *top_global->name, top_global,
- state_global->x.rvec_array(), nullptr, ir->pbcType, state->s.box);
+ write_sto_conf_mtop(confout,
+ *top_global->name,
+ top_global,
+ state_global->x.rvec_array(),
+ nullptr,
+ ir->pbcType,
+ state->s.box);
}
}
}
//
// \returns true when the step succeeded, false when a constraint error occurred
static bool do_em_step(const t_commrec* cr,
- t_inputrec* ir,
+ const t_inputrec* ir,
t_mdatoms* md,
em_state_t* ems1,
real a,
if (constr)
{
dvdl_constr = 0;
- validStep = constr->apply(
- TRUE, TRUE, count, 0, 1.0, s1->x.arrayRefWithPadding(), s2->x.arrayRefWithPadding(),
- ArrayRef<RVec>(), s2->box, s2->lambda[efptBONDED], &dvdl_constr,
- gmx::ArrayRefWithPadding<RVec>(), false, nullptr, gmx::ConstraintVariable::Positions);
+ validStep = constr->apply(TRUE,
+ TRUE,
+ count,
+ 0,
+ 1.0,
+ s1->x.arrayRefWithPadding(),
+ s2->x.arrayRefWithPadding(),
+ ArrayRef<RVec>(),
+ s2->box,
+ s2->lambda[efptBONDED],
+ &dvdl_constr,
+ gmx::ArrayRefWithPadding<RVec>(),
+ false,
+ nullptr,
+ gmx::ConstraintVariable::Positions);
if (cr->nnodes > 1)
{
gmx_fatal(FARGS,
"The coordinates could not be constrained. Minimizer '%s' can not handle "
"constraint failures, use minimizer '%s' before using '%s'.",
- EI(ir->eI), EI(eiSteep), EI(ir->eI));
+ EI(ir->eI),
+ EI(eiSteep),
+ EI(ir->eI));
}
}
int step,
const t_commrec* cr,
const gmx_mtop_t* top_global,
- t_inputrec* ir,
+ const t_inputrec* ir,
gmx::ImdSession* imdSession,
pull_t* pull_work,
em_state_t* ems,
gmx_wallcycle_t wcycle)
{
/* Repartition the domain decomposition */
- dd_partition_system(fplog, mdlog, step, cr, FALSE, 1, nullptr, *top_global, ir, imdSession, pull_work,
- &ems->s, &ems->f, mdAtoms, top, fr, vsite, constr, nrnb, wcycle, FALSE);
+ dd_partition_system(fplog,
+ mdlog,
+ step,
+ cr,
+ FALSE,
+ 1,
+ nullptr,
+ *top_global,
+ ir,
+ imdSession,
+ pull_work,
+ &ems->s,
+ &ems->f,
+ mdAtoms,
+ top,
+ fr,
+ vsite,
+ constr,
+ nrnb,
+ wcycle,
+ FALSE);
dd_store_state(cr->dd, &ems->s);
}
//! Holds the domain topology.
gmx_localtop_t* top;
//! User input options.
- t_inputrec* inputrec;
+ const t_inputrec* inputrec;
//! The Interactive Molecular Dynamics session.
gmx::ImdSession* imdSession;
//! The pull work object.
if (DOMAINDECOMP(cr) && bNS)
{
/* Repartition the domain decomposition */
- em_dd_partition_system(fplog, mdlog, count, cr, top_global, inputrec, imdSession, pull_work,
- ems, top, mdAtoms, fr, vsite, constr, nrnb, wcycle);
+ em_dd_partition_system(
+ fplog, mdlog, count, cr, top_global, inputrec, imdSession, pull_work, ems, top, mdAtoms, fr, vsite, constr, nrnb, wcycle);
}
/* Calc force & energy on new trial position */
/* do_force always puts the charge groups in the box and shifts again
* We do not unshift, so molecules are always whole in congrad.c
*/
- do_force(fplog, cr, ms, inputrec, nullptr, nullptr, imdSession, pull_work, count, nrnb, wcycle,
- top, ems->s.box, ems->s.x.arrayRefWithPadding(), &ems->s.hist, &ems->f.view(), force_vir,
- mdAtoms->mdatoms(), enerd, ems->s.lambda, fr, runScheduleWork, vsite, mu_tot, t, nullptr,
+ do_force(fplog,
+ cr,
+ ms,
+ inputrec,
+ nullptr,
+ nullptr,
+ imdSession,
+ pull_work,
+ count,
+ nrnb,
+ wcycle,
+ top,
+ ems->s.box,
+ ems->s.x.arrayRefWithPadding(),
+ &ems->s.hist,
+ &ems->f.view(),
+ force_vir,
+ mdAtoms->mdatoms(),
+ enerd,
+ ems->s.lambda,
+ fr,
+ runScheduleWork,
+ vsite,
+ mu_tot,
+ t,
+ nullptr,
GMX_FORCE_STATECHANGED | GMX_FORCE_ALLFORCES | GMX_FORCE_VIRIAL | GMX_FORCE_ENERGY
| (bNS ? GMX_FORCE_NS : 0),
DDBalanceRegionHandler(cr));
{
wallcycle_start(wcycle, ewcMoveE);
- global_stat(gstat, cr, enerd, force_vir, shake_vir, inputrec, nullptr, nullptr, nullptr, 1,
- &terminate, nullptr, FALSE, CGLO_ENERGY | CGLO_PRESSURE | CGLO_CONSTRAINT);
+ global_stat(gstat,
+ cr,
+ enerd,
+ force_vir,
+ shake_vir,
+ inputrec,
+ nullptr,
+ gmx::ArrayRef<real>{},
+ nullptr,
+ 1,
+ &terminate,
+ nullptr,
+ FALSE,
+ CGLO_ENERGY | CGLO_PRESSURE | CGLO_CONSTRAINT);
wallcycle_stop(wcycle, ewcMoveE);
}
bool computeVirial = true;
dvdl_constr = 0;
auto f = ems->f.view().forceWithPadding();
- constr->apply(needsLogging, computeEnergy, count, 0, 1.0, ems->s.x.arrayRefWithPadding(), f,
- f.unpaddedArrayRef(), ems->s.box, ems->s.lambda[efptBONDED], &dvdl_constr,
- gmx::ArrayRefWithPadding<RVec>(), computeVirial, shake_vir,
+ constr->apply(needsLogging,
+ computeEnergy,
+ count,
+ 0,
+ 1.0,
+ ems->s.x.arrayRefWithPadding(),
+ f,
+ f.unpaddedArrayRef(),
+ ems->s.box,
+ ems->s.lambda[efptBONDED],
+ &dvdl_constr,
+ gmx::ArrayRefWithPadding<RVec>(),
+ computeVirial,
+ shake_vir,
gmx::ConstraintVariable::ForceDispl);
enerd->term[F_DVDL_CONSTR] += dvdl_constr;
m_add(force_vir, shake_vir, vir);
//! Parallel utility summing energies and forces
static double reorder_partsum(const t_commrec* cr,
- t_grpopts* opts,
+ const t_grpopts* opts,
const gmx_mtop_t* top_global,
const em_state_t* s_min,
const em_state_t* s_b)
//! Print some stuff, like beta, whatever that means.
static real pr_beta(const t_commrec* cr,
- t_grpopts* opts,
+ const t_grpopts* opts,
t_mdatoms* mdatoms,
const gmx_mtop_t* top_global,
const em_state_t* s_min,
em_state_t* s_c = &s3;
/* Init em and store the local state in s_min */
- init_em(fplog, mdlog, CG, cr, inputrec, imdSession, pull_work, state_global, top_global, s_min,
- &top, nrnb, fr, mdAtoms, &gstat, vsite, constr, nullptr);
+ init_em(fplog,
+ mdlog,
+ CG,
+ cr,
+ inputrec,
+ imdSession,
+ pull_work,
+ state_global,
+ top_global,
+ s_min,
+ &top,
+ nrnb,
+ fr,
+ mdAtoms,
+ &gstat,
+ vsite,
+ constr,
+ nullptr);
const bool simulationsShareState = false;
- gmx_mdoutf* outf = init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr, outputProvider,
- mdModulesNotifier, inputrec, top_global, nullptr, wcycle,
- StartingBehavior::NewSimulation, simulationsShareState, ms);
- gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf), top_global, inputrec, pull_work,
- nullptr, false, StartingBehavior::NewSimulation,
- simulationsShareState, mdModulesNotifier);
+ gmx_mdoutf* outf = init_mdoutf(fplog,
+ nfile,
+ fnm,
+ mdrunOptions,
+ cr,
+ outputProvider,
+ mdModulesNotifier,
+ inputrec,
+ top_global,
+ nullptr,
+ wcycle,
+ StartingBehavior::NewSimulation,
+ simulationsShareState,
+ ms);
+ gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf),
+ top_global,
+ inputrec,
+ pull_work,
+ nullptr,
+ false,
+ StartingBehavior::NewSimulation,
+ simulationsShareState,
+ mdModulesNotifier);
/* Print to log file */
print_em_start(fplog, cr, walltime_accounting, wcycle, CG);
{
/* Copy stuff to the energy bin for easy printing etc. */
matrix nullBox = {};
- energyOutput.addDataAtEnergyStep(false, false, static_cast<double>(step), mdatoms->tmass,
- enerd, nullptr, nullptr, nullBox, PTCouplingArrays(), 0,
- nullptr, nullptr, vir, pres, nullptr, mu_tot, constr);
+ energyOutput.addDataAtEnergyStep(false,
+ false,
+ static_cast<double>(step),
+ mdatoms->tmass,
+ enerd,
+ nullptr,
+ nullptr,
+ nullBox,
+ PTCouplingArrays(),
+ 0,
+ nullptr,
+ nullptr,
+ vir,
+ pres,
+ nullptr,
+ mu_tot,
+ constr);
EnergyOutput::printHeader(fplog, step, step);
- energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), TRUE, FALSE, FALSE, fplog, step,
- step, fr->fcdata.get(), nullptr);
+ energyOutput.printStepToEnergyFile(
+ mdoutf_get_fp_ene(outf), TRUE, FALSE, FALSE, fplog, step, step, fr->fcdata.get(), nullptr);
}
/* Estimate/guess the initial stepsize */
do_x = do_per_step(step, inputrec->nstxout);
do_f = do_per_step(step, inputrec->nstfout);
- write_em_traj(fplog, cr, outf, do_x, do_f, nullptr, top_global, inputrec, step, s_min,
- state_global, observablesHistory);
+ write_em_traj(
+ fplog, cr, outf, do_x, do_f, nullptr, top_global, inputrec, step, s_min, state_global, observablesHistory);
/* Take a step downhill.
* In theory, we should minimize the function along this direction.
if (DOMAINDECOMP(cr) && s_min->s.ddp_count < cr->dd->ddp_count)
{
- em_dd_partition_system(fplog, mdlog, step, cr, top_global, inputrec, imdSession,
- pull_work, s_min, &top, mdAtoms, fr, vsite, constr, nrnb, wcycle);
+ em_dd_partition_system(fplog,
+ mdlog,
+ step,
+ cr,
+ top_global,
+ inputrec,
+ imdSession,
+ pull_work,
+ s_min,
+ &top,
+ mdAtoms,
+ fr,
+ vsite,
+ constr,
+ nrnb,
+ wcycle);
}
/* Take a trial step (new coords in s_c) */
- do_em_step(cr, inputrec, mdatoms, s_min, c, s_min->s.cg_p.constArrayRefWithPadding(), s_c,
- constr, -1);
+ do_em_step(cr, inputrec, mdatoms, s_min, c, s_min->s.cg_p.constArrayRefWithPadding(), s_c, constr, -1);
neval++;
/* Calculate energy for the trial step */
if (DOMAINDECOMP(cr) && s_min->s.ddp_count != cr->dd->ddp_count)
{
/* Reload the old state */
- em_dd_partition_system(fplog, mdlog, -1, cr, top_global, inputrec, imdSession, pull_work,
- s_min, &top, mdAtoms, fr, vsite, constr, nrnb, wcycle);
+ em_dd_partition_system(fplog,
+ mdlog,
+ -1,
+ cr,
+ top_global,
+ inputrec,
+ imdSession,
+ pull_work,
+ s_min,
+ &top,
+ mdAtoms,
+ fr,
+ vsite,
+ constr,
+ nrnb,
+ wcycle);
}
/* Take a trial step to this new point - new coords in s_b */
- do_em_step(cr, inputrec, mdatoms, s_min, b,
- s_min->s.cg_p.constArrayRefWithPadding(), s_b, constr, -1);
+ do_em_step(cr, inputrec, mdatoms, s_min, b, s_min->s.cg_p.constArrayRefWithPadding(), s_b, constr, -1);
neval++;
/* Calculate energy for the trial step */
if (debug)
{
- fprintf(debug, "CGE: EpotA %f EpotB %f EpotC %f gpb %f\n", s_a->epot, s_b->epot,
- s_c->epot, gpb);
+ fprintf(debug, "CGE: EpotA %f EpotB %f EpotC %f gpb %f\n", s_a->epot, s_b->epot, s_c->epot, gpb);
}
epot_repl = s_b->epot;
{
if (debug)
{
- fprintf(debug, "CGE: C (%f) is lower than A (%f), moving C to B\n", s_c->epot,
- s_a->epot);
+ fprintf(debug, "CGE: C (%f) is lower than A (%f), moving C to B\n", s_c->epot, s_a->epot);
}
swap_em_state(&s_b, &s_c);
gpb = gpc;
{
if (debug)
{
- fprintf(debug, "CGE: A (%f) is lower than C (%f), moving A to B\n", s_a->epot,
- s_c->epot);
+ fprintf(debug, "CGE: A (%f) is lower than C (%f), moving A to B\n", s_a->epot, s_c->epot);
}
swap_em_state(&s_b, &s_a);
gpb = gpa;
if (mdrunOptions.verbose)
{
double sqrtNumAtoms = sqrt(static_cast<double>(state_global->natoms));
- fprintf(stderr, "\rStep %d, Epot=%12.6e, Fnorm=%9.3e, Fmax=%9.3e (atom %d)\n", step,
- s_min->epot, s_min->fnorm / sqrtNumAtoms, s_min->fmax, s_min->a_fmax + 1);
+ fprintf(stderr,
+ "\rStep %d, Epot=%12.6e, Fnorm=%9.3e, Fmax=%9.3e (atom %d)\n",
+ step,
+ s_min->epot,
+ s_min->fnorm / sqrtNumAtoms,
+ s_min->fmax,
+ s_min->a_fmax + 1);
fflush(stderr);
}
/* Store the new (lower) energies */
matrix nullBox = {};
- energyOutput.addDataAtEnergyStep(false, false, static_cast<double>(step), mdatoms->tmass,
- enerd, nullptr, nullptr, nullBox, PTCouplingArrays(), 0,
- nullptr, nullptr, vir, pres, nullptr, mu_tot, constr);
+ energyOutput.addDataAtEnergyStep(false,
+ false,
+ static_cast<double>(step),
+ mdatoms->tmass,
+ enerd,
+ nullptr,
+ nullptr,
+ nullBox,
+ PTCouplingArrays(),
+ 0,
+ nullptr,
+ nullptr,
+ vir,
+ pres,
+ nullptr,
+ mu_tot,
+ constr);
do_log = do_per_step(step, inputrec->nstlog);
do_ene = do_per_step(step, inputrec->nstenergy);
{
EnergyOutput::printHeader(fplog, step, step);
}
- energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), do_ene, FALSE, FALSE,
- do_log ? fplog : nullptr, step, step,
- fr->fcdata.get(), nullptr);
+ energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf),
+ do_ene,
+ FALSE,
+ FALSE,
+ do_log ? fplog : nullptr,
+ step,
+ step,
+ fr->fcdata.get(),
+ nullptr);
}
/* Send energies and positions to the IMD client if bIMD is TRUE. */
if (!do_ene || !do_log)
{
/* Write final energy file entries */
- energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), !do_ene, FALSE, FALSE,
- !do_log ? fplog : nullptr, step, step,
- fr->fcdata.get(), nullptr);
+ energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf),
+ !do_ene,
+ FALSE,
+ FALSE,
+ !do_log ? fplog : nullptr,
+ step,
+ step,
+ fr->fcdata.get(),
+ nullptr);
}
}
do_x = !do_per_step(step, inputrec->nstxout);
do_f = (inputrec->nstfout > 0 && !do_per_step(step, inputrec->nstfout));
- write_em_traj(fplog, cr, outf, do_x, do_f, ftp2fn(efSTO, nfile, fnm), top_global, inputrec,
- step, s_min, state_global, observablesHistory);
+ write_em_traj(
+ fplog, cr, outf, do_x, do_f, ftp2fn(efSTO, nfile, fnm), top_global, inputrec, step, s_min, state_global, observablesHistory);
if (MASTER(cr))
neval = 0;
/* Init em */
- init_em(fplog, mdlog, LBFGS, cr, inputrec, imdSession, pull_work, state_global, top_global,
- &ems, &top, nrnb, fr, mdAtoms, &gstat, vsite, constr, nullptr);
+ init_em(fplog,
+ mdlog,
+ LBFGS,
+ cr,
+ inputrec,
+ imdSession,
+ pull_work,
+ state_global,
+ top_global,
+ &ems,
+ &top,
+ nrnb,
+ fr,
+ mdAtoms,
+ &gstat,
+ vsite,
+ constr,
+ nullptr);
const bool simulationsShareState = false;
- gmx_mdoutf* outf = init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr, outputProvider,
- mdModulesNotifier, inputrec, top_global, nullptr, wcycle,
- StartingBehavior::NewSimulation, simulationsShareState, ms);
- gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf), top_global, inputrec, pull_work,
- nullptr, false, StartingBehavior::NewSimulation,
- simulationsShareState, mdModulesNotifier);
+ gmx_mdoutf* outf = init_mdoutf(fplog,
+ nfile,
+ fnm,
+ mdrunOptions,
+ cr,
+ outputProvider,
+ mdModulesNotifier,
+ inputrec,
+ top_global,
+ nullptr,
+ wcycle,
+ StartingBehavior::NewSimulation,
+ simulationsShareState,
+ ms);
+ gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf),
+ top_global,
+ inputrec,
+ pull_work,
+ nullptr,
+ false,
+ StartingBehavior::NewSimulation,
+ simulationsShareState,
+ mdModulesNotifier);
start = 0;
end = mdatoms->homenr;
/* Print to log file */
print_em_start(fplog, cr, walltime_accounting, wcycle, LBFGS);
- do_log = do_ene = do_x = do_f = TRUE;
+ do_log = do_ene = do_f = TRUE;
/* Max number of steps */
number_steps = inputrec->nsteps;
{
/* Copy stuff to the energy bin for easy printing etc. */
matrix nullBox = {};
- energyOutput.addDataAtEnergyStep(false, false, static_cast<double>(step), mdatoms->tmass,
- enerd, nullptr, nullptr, nullBox, PTCouplingArrays(), 0,
- nullptr, nullptr, vir, pres, nullptr, mu_tot, constr);
+ energyOutput.addDataAtEnergyStep(false,
+ false,
+ static_cast<double>(step),
+ mdatoms->tmass,
+ enerd,
+ nullptr,
+ nullptr,
+ nullBox,
+ PTCouplingArrays(),
+ 0,
+ nullptr,
+ nullptr,
+ vir,
+ pres,
+ nullptr,
+ mu_tot,
+ constr);
EnergyOutput::printHeader(fplog, step, step);
- energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), TRUE, FALSE, FALSE, fplog, step,
- step, fr->fcdata.get(), nullptr);
+ energyOutput.printStepToEnergyFile(
+ mdoutf_get_fp_ene(outf), TRUE, FALSE, FALSE, fplog, step, step, fr->fcdata.get(), nullptr);
}
/* Set the initial step.
}
gmx::WriteCheckpointDataHolder checkpointDataHolder;
- mdoutf_write_to_trajectory_files(fplog, cr, outf, mdof_flags, top_global->natoms, step,
- static_cast<real>(step), &ems.s, state_global, observablesHistory,
- ems.f.view().force(), &checkpointDataHolder);
+ mdoutf_write_to_trajectory_files(fplog,
+ cr,
+ outf,
+ mdof_flags,
+ top_global->natoms,
+ step,
+ static_cast<real>(step),
+ &ems.s,
+ state_global,
+ observablesHistory,
+ ems.f.view().force(),
+ &checkpointDataHolder);
/* Do the linesearching in the direction dx[point][0..(n-1)] */
if (mdrunOptions.verbose)
{
double sqrtNumAtoms = sqrt(static_cast<double>(state_global->natoms));
- fprintf(stderr, "\rStep %d, Epot=%12.6e, Fnorm=%9.3e, Fmax=%9.3e (atom %d)\n", step,
- ems.epot, ems.fnorm / sqrtNumAtoms, ems.fmax, ems.a_fmax + 1);
+ fprintf(stderr,
+ "\rStep %d, Epot=%12.6e, Fnorm=%9.3e, Fmax=%9.3e (atom %d)\n",
+ step,
+ ems.epot,
+ ems.fnorm / sqrtNumAtoms,
+ ems.fmax,
+ ems.a_fmax + 1);
fflush(stderr);
}
/* Store the new (lower) energies */
matrix nullBox = {};
- energyOutput.addDataAtEnergyStep(false, false, static_cast<double>(step), mdatoms->tmass,
- enerd, nullptr, nullptr, nullBox, PTCouplingArrays(), 0,
- nullptr, nullptr, vir, pres, nullptr, mu_tot, constr);
+ energyOutput.addDataAtEnergyStep(false,
+ false,
+ static_cast<double>(step),
+ mdatoms->tmass,
+ enerd,
+ nullptr,
+ nullptr,
+ nullBox,
+ PTCouplingArrays(),
+ 0,
+ nullptr,
+ nullptr,
+ vir,
+ pres,
+ nullptr,
+ mu_tot,
+ constr);
do_log = do_per_step(step, inputrec->nstlog);
do_ene = do_per_step(step, inputrec->nstenergy);
{
EnergyOutput::printHeader(fplog, step, step);
}
- energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), do_ene, FALSE, FALSE,
- do_log ? fplog : nullptr, step, step,
- fr->fcdata.get(), nullptr);
+ energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf),
+ do_ene,
+ FALSE,
+ FALSE,
+ do_log ? fplog : nullptr,
+ step,
+ step,
+ fr->fcdata.get(),
+ nullptr);
}
/* Send x and E to IMD client, if bIMD is TRUE. */
}
if (!do_ene || !do_log) /* Write final energy file entries */
{
- energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), !do_ene, FALSE, FALSE,
- !do_log ? fplog : nullptr, step, step, fr->fcdata.get(),
+ energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf),
+ !do_ene,
+ FALSE,
+ FALSE,
+ !do_log ? fplog : nullptr,
+ step,
+ step,
+ fr->fcdata.get(),
nullptr);
}
*/
do_x = !do_per_step(step, inputrec->nstxout);
do_f = !do_per_step(step, inputrec->nstfout);
- write_em_traj(fplog, cr, outf, do_x, do_f, ftp2fn(efSTO, nfile, fnm), top_global, inputrec,
- step, &ems, state_global, observablesHistory);
+ write_em_traj(
+ fplog, cr, outf, do_x, do_f, ftp2fn(efSTO, nfile, fnm), top_global, inputrec, step, &ems, state_global, observablesHistory);
if (MASTER(cr))
{
em_state_t* s_try = &s1;
/* Init em and store the local state in s_try */
- init_em(fplog, mdlog, SD, cr, inputrec, imdSession, pull_work, state_global, top_global, s_try,
- &top, nrnb, fr, mdAtoms, &gstat, vsite, constr, nullptr);
+ init_em(fplog,
+ mdlog,
+ SD,
+ cr,
+ inputrec,
+ imdSession,
+ pull_work,
+ state_global,
+ top_global,
+ s_try,
+ &top,
+ nrnb,
+ fr,
+ mdAtoms,
+ &gstat,
+ vsite,
+ constr,
+ nullptr);
const bool simulationsShareState = false;
- gmx_mdoutf* outf = init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr, outputProvider,
- mdModulesNotifier, inputrec, top_global, nullptr, wcycle,
- StartingBehavior::NewSimulation, simulationsShareState, ms);
- gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf), top_global, inputrec, pull_work,
- nullptr, false, StartingBehavior::NewSimulation,
- simulationsShareState, mdModulesNotifier);
+ gmx_mdoutf* outf = init_mdoutf(fplog,
+ nfile,
+ fnm,
+ mdrunOptions,
+ cr,
+ outputProvider,
+ mdModulesNotifier,
+ inputrec,
+ top_global,
+ nullptr,
+ wcycle,
+ StartingBehavior::NewSimulation,
+ simulationsShareState,
+ ms);
+ gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf),
+ top_global,
+ inputrec,
+ pull_work,
+ nullptr,
+ false,
+ StartingBehavior::NewSimulation,
+ simulationsShareState,
+ mdModulesNotifier);
/* Print to log file */
print_em_start(fplog, cr, walltime_accounting, wcycle, SD);
bool validStep = true;
if (count > 0)
{
- validStep = do_em_step(cr, inputrec, mdatoms, s_min, stepsize,
- s_min->f.view().forceWithPadding(), s_try, constr, count);
+ validStep = do_em_step(
+ cr, inputrec, mdatoms, s_min, stepsize, s_min->f.view().forceWithPadding(), s_try, constr, count);
}
if (validStep)
{
if (mdrunOptions.verbose)
{
- fprintf(stderr, "Step=%5d, Dmax= %6.1e nm, Epot= %12.5e Fmax= %11.5e, atom= %d%c",
- count, ustep, s_try->epot, s_try->fmax, s_try->a_fmax + 1,
+ fprintf(stderr,
+ "Step=%5d, Dmax= %6.1e nm, Epot= %12.5e Fmax= %11.5e, atom= %d%c",
+ count,
+ ustep,
+ s_try->epot,
+ s_try->fmax,
+ s_try->a_fmax + 1,
((count == 0) || (s_try->epot < s_min->epot)) ? '\n' : '\r');
fflush(stderr);
}
{
/* Store the new (lower) energies */
matrix nullBox = {};
- energyOutput.addDataAtEnergyStep(false, false, static_cast<double>(count),
- mdatoms->tmass, enerd, nullptr, nullptr, nullBox,
- PTCouplingArrays(), 0, nullptr, nullptr, vir, pres,
- nullptr, mu_tot, constr);
+ energyOutput.addDataAtEnergyStep(false,
+ false,
+ static_cast<double>(count),
+ mdatoms->tmass,
+ enerd,
+ nullptr,
+ nullptr,
+ nullBox,
+ PTCouplingArrays(),
+ 0,
+ nullptr,
+ nullptr,
+ vir,
+ pres,
+ nullptr,
+ mu_tot,
+ constr);
imdSession->fillEnergyRecord(count, TRUE);
const bool do_dr = do_per_step(steps_accepted, inputrec->nstdisreout);
const bool do_or = do_per_step(steps_accepted, inputrec->nstorireout);
- energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), TRUE, do_dr, do_or,
- fplog, count, count, fr->fcdata.get(), nullptr);
+ energyOutput.printStepToEnergyFile(
+ mdoutf_get_fp_ene(outf), TRUE, do_dr, do_or, fplog, count, count, fr->fcdata.get(), nullptr);
fflush(fplog);
}
}
/* Write to trn, if necessary */
do_x = do_per_step(steps_accepted, inputrec->nstxout);
do_f = do_per_step(steps_accepted, inputrec->nstfout);
- write_em_traj(fplog, cr, outf, do_x, do_f, nullptr, top_global, inputrec, count, s_min,
- state_global, observablesHistory);
+ write_em_traj(
+ fplog, cr, outf, do_x, do_f, nullptr, top_global, inputrec, count, s_min, state_global, observablesHistory);
}
else
{
if (DOMAINDECOMP(cr) && s_min->s.ddp_count != cr->dd->ddp_count)
{
/* Reload the old state */
- em_dd_partition_system(fplog, mdlog, count, cr, top_global, inputrec, imdSession,
- pull_work, s_min, &top, mdAtoms, fr, vsite, constr, nrnb, wcycle);
+ em_dd_partition_system(fplog,
+ mdlog,
+ count,
+ cr,
+ top_global,
+ inputrec,
+ imdSession,
+ pull_work,
+ s_min,
+ &top,
+ mdAtoms,
+ fr,
+ vsite,
+ constr,
+ nrnb,
+ wcycle);
}
}
}
/* Send IMD energies and positions, if bIMD is TRUE. */
- if (imdSession->run(count, TRUE, MASTER(cr) ? state_global->box : nullptr,
- MASTER(cr) ? state_global->x.rvec_array() : nullptr, 0)
+ if (imdSession->run(count,
+ TRUE,
+ MASTER(cr) ? state_global->box : nullptr,
+ MASTER(cr) ? state_global->x.rvec_array() : nullptr,
+ 0)
&& MASTER(cr))
{
imdSession->sendPositionsAndEnergies();
{
fprintf(stderr, "\nwriting lowest energy coordinates.\n");
}
- write_em_traj(fplog, cr, outf, TRUE, inputrec->nstfout != 0, ftp2fn(efSTO, nfile, fnm),
- top_global, inputrec, count, s_min, state_global, observablesHistory);
+ write_em_traj(fplog,
+ cr,
+ outf,
+ TRUE,
+ inputrec->nstfout != 0,
+ ftp2fn(efSTO, nfile, fnm),
+ top_global,
+ inputrec,
+ count,
+ s_min,
+ state_global,
+ observablesHistory);
if (MASTER(cr))
{
finish_em(cr, outf, walltime_accounting, wcycle);
/* To print the actual number of steps we needed somewhere */
- inputrec->nsteps = count;
+ {
+ // TODO: Avoid changing inputrec (#3854)
+ auto* nonConstInputrec = const_cast<t_inputrec*>(inputrec);
+ nonConstInputrec->nsteps = count;
+ }
walltime_accounting_set_nsteps_done(walltime_accounting, count);
}
em_state_t state_work{};
/* Init em and store the local state in state_minimum */
- init_em(fplog, mdlog, NM, cr, inputrec, imdSession, pull_work, state_global, top_global,
- &state_work, &top, nrnb, fr, mdAtoms, &gstat, vsite, constr, &shellfc);
+ init_em(fplog,
+ mdlog,
+ NM,
+ cr,
+ inputrec,
+ imdSession,
+ pull_work,
+ state_global,
+ top_global,
+ &state_work,
+ &top,
+ nrnb,
+ fr,
+ mdAtoms,
+ &gstat,
+ vsite,
+ constr,
+ &shellfc);
const bool simulationsShareState = false;
- gmx_mdoutf* outf = init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr, outputProvider,
- mdModulesNotifier, inputrec, top_global, nullptr, wcycle,
- StartingBehavior::NewSimulation, simulationsShareState, ms);
+ gmx_mdoutf* outf = init_mdoutf(fplog,
+ nfile,
+ fnm,
+ mdrunOptions,
+ cr,
+ outputProvider,
+ mdModulesNotifier,
+ inputrec,
+ top_global,
+ nullptr,
+ wcycle,
+ StartingBehavior::NewSimulation,
+ simulationsShareState,
+ ms);
std::vector<int> atom_index = get_atom_index(top_global);
std::vector<gmx::RVec> fneg(atom_index.size(), { 0, 0, 0 });
print_em_start(fplog, cr, walltime_accounting, wcycle, NM);
/* fudge nr of steps to nr of atoms */
- inputrec->nsteps = atom_index.size() * 2;
+ {
+ // TODO: Avoid changing inputrec (#3854)
+ auto* nonConstInputrec = const_cast<t_inputrec*>(inputrec);
+ nonConstInputrec->nsteps = atom_index.size() * 2;
+ }
if (bIsMaster)
{
- fprintf(stderr, "starting normal mode calculation '%s'\n%" PRId64 " steps.\n\n",
- *(top_global->name), inputrec->nsteps);
+ fprintf(stderr,
+ "starting normal mode calculation '%s'\n%" PRId64 " steps.\n\n",
+ *(top_global->name),
+ inputrec->nsteps);
}
nnodes = cr->nnodes;
if (shellfc)
{
/* Now is the time to relax the shells */
- relax_shell_flexcon(fplog, cr, ms, mdrunOptions.verbose, nullptr, step, inputrec,
- imdSession, pull_work, bNS, force_flags, &top, constr, enerd,
- state_work.s.natoms, state_work.s.x.arrayRefWithPadding(),
- state_work.s.v.arrayRefWithPadding(), state_work.s.box,
- state_work.s.lambda, &state_work.s.hist, &state_work.f.view(),
- vir, mdatoms, nrnb, wcycle, shellfc, fr, runScheduleWork, t,
- mu_tot, vsite, DDBalanceRegionHandler(nullptr));
+ relax_shell_flexcon(fplog,
+ cr,
+ ms,
+ mdrunOptions.verbose,
+ nullptr,
+ step,
+ inputrec,
+ imdSession,
+ pull_work,
+ bNS,
+ force_flags,
+ &top,
+ constr,
+ enerd,
+ state_work.s.natoms,
+ state_work.s.x.arrayRefWithPadding(),
+ state_work.s.v.arrayRefWithPadding(),
+ state_work.s.box,
+ state_work.s.lambda,
+ &state_work.s.hist,
+ &state_work.f.view(),
+ vir,
+ mdatoms,
+ nrnb,
+ wcycle,
+ shellfc,
+ fr,
+ runScheduleWork,
+ t,
+ mu_tot,
+ vsite,
+ DDBalanceRegionHandler(nullptr));
bNS = false;
step++;
}
if (dx == 0)
{
- std::copy(state_work_f.begin(), state_work_f.begin() + atom_index.size(),
- fneg.begin());
+ std::copy(state_work_f.begin(), state_work_f.begin() + atom_index.size(), fneg.begin());
}
}
{
#if GMX_MPI
# define mpi_type GMX_MPI_REAL
- MPI_Send(dfdx[0], atom_index.size() * DIM, mpi_type, MASTER(cr), cr->nodeid,
- cr->mpi_comm_mygroup);
+ MPI_Send(dfdx[0], atom_index.size() * DIM, mpi_type, MASTER(cr), cr->nodeid, cr->mpi_comm_mygroup);
#endif
}
else
{
#if GMX_MPI
MPI_Status stat;
- MPI_Recv(dfdx[0], atom_index.size() * DIM, mpi_type, node, node,
- cr->mpi_comm_mygroup, &stat);
+ MPI_Recv(dfdx[0], atom_index.size() * DIM, mpi_type, node, node, cr->mpi_comm_mygroup, &stat);
# undef mpi_type
#endif
}
/* write progress */
if (bIsMaster && mdrunOptions.verbose)
{
- fprintf(stderr, "\rFinished step %d out of %td",
- std::min<int>(atom + nnodes, atom_index.size()), ssize(atom_index));
+ fprintf(stderr,
+ "\rFinished step %d out of %td",
+ std::min<int>(atom + nnodes, atom_index.size()),
+ ssize(atom_index));
fflush(stderr);
}
}
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2011-2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2011-2019,2020,2021, 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.
* 'lambda_and_pressure', 'temperature_lambda_pressure'?; Let's wait
* until we feel better about the pressure control methods giving
* exact ensembles. Right now, we assume constant pressure */
-static const char* erename[ereNR] = { "temperature", "lambda", "end_single_marker",
+static const char* erename[ereNR] = { "temperature",
+ "lambda",
+ "end_single_marker",
"temperature and lambda" };
//! Working data for replica exchange.
check_multi_int(fplog, ms, ir->eI, "the integrator", FALSE);
check_multi_int64(fplog, ms, ir->init_step + ir->nsteps, "init_step+nsteps", FALSE);
const int nst = replExParams.exchangeInterval;
- check_multi_int64(fplog, ms, (ir->init_step + nst - 1) / nst,
- "first exchange step: init_step/-replex", FALSE);
- check_multi_int(fplog, ms, ir->etc, "the temperature coupling", FALSE);
+ check_multi_int64(
+ fplog, ms, (ir->init_step + nst - 1) / nst, "first exchange step: init_step/-replex", FALSE);
+ check_multi_int(fplog, ms, static_cast<int>(ir->etc), "the temperature coupling", FALSE);
check_multi_int(fplog, ms, ir->opts.ngtc, "the number of temperature coupling groups", FALSE);
- check_multi_int(fplog, ms, ir->epc, "the pressure coupling", FALSE);
+ check_multi_int(fplog, ms, static_cast<int>(ir->epc), "the pressure coupling", FALSE);
check_multi_int(fplog, ms, ir->efep, "free energy", FALSE);
check_multi_int(fplog, ms, ir->fepvals->n_lambda, "number of lambda states", FALSE);
if (bTemp)
{
please_cite(fplog, "Sugita1999a");
- if (ir->epc != epcNO)
+ if (ir->epc != PressureCoupling::No)
{
re->bNPT = TRUE;
fprintf(fplog, "Repl Using Constant Pressure REMD.\n");
please_cite(fplog, "Okabe2001a");
}
- if (ir->etc == etcBERENDSEN)
+ if (ir->etc == TemperatureCoupling::Berendsen)
{
gmx_fatal(FARGS,
"REMD with the %s thermostat does not produce correct potential energy "
"distributions, consider using the %s thermostat instead",
- ETCOUPLTYPE(ir->etc), ETCOUPLTYPE(etcVRESCALE));
+ enumValueToString(ir->etc),
+ enumValueToString(TemperatureCoupling::VRescale));
}
}
if (bLambda)
gmx_fatal(FARGS,
"Replicas with indices %d < %d have %ss %g > %g, please order your "
"replicas on increasing %s",
- i, j, erename[re->type], re->q[re->type][i], re->q[re->type][j],
+ i,
+ j,
+ erename[re->type],
+ re->q[re->type][i],
+ re->q[re->type][j],
erename[re->type]);
}
else if (re->q[re->type][re->ind[j]] == re->q[re->type][re->ind[i]])
MPI_Request mpi_req;
MPI_Isend(v, n * sizeof(double), MPI_BYTE, MSRANK(ms, b), 0, ms->mastersComm_, &mpi_req);
- MPI_Recv(buf, n * sizeof(double), MPI_BYTE, MSRANK(ms, b), 0, ms->mastersComm_,
- MPI_STATUS_IGNORE);
+ MPI_Recv(buf, n * sizeof(double), MPI_BYTE, MSRANK(ms, b), 0, ms->mastersComm_, MPI_STATUS_IGNORE);
MPI_Wait(&mpi_req, MPI_STATUS_IGNORE);
}
#endif
MPI_Request mpi_req;
MPI_Isend(v[0], n * sizeof(rvec), MPI_BYTE, MSRANK(ms, b), 0, ms->mastersComm_, &mpi_req);
- MPI_Recv(buf[0], n * sizeof(rvec), MPI_BYTE, MSRANK(ms, b), 0, ms->mastersComm_,
- MPI_STATUS_IGNORE);
+ MPI_Recv(buf[0], n * sizeof(rvec), MPI_BYTE, MSRANK(ms, b), 0, ms->mastersComm_, MPI_STATUS_IGNORE);
MPI_Wait(&mpi_req, MPI_STATUS_IGNORE);
}
#endif
* the velocities. */
if (re->type == ereTEMP || re->type == ereTL)
{
- scale_velocities(state->v, std::sqrt(re->q[ereTEMP][replica_id]
- / re->q[ereTEMP][re->destinations[replica_id]]));
+ scale_velocities(state->v,
+ std::sqrt(re->q[ereTEMP][replica_id]
+ / re->q[ereTEMP][re->destinations[replica_id]]));
}
}
if (re->nex == 0)
{
- fprintf(fplog, "Repl %d attempts, %d odd, %d even\n", re->nattempt[0] + re->nattempt[1],
- re->nattempt[1], re->nattempt[0]);
+ fprintf(fplog,
+ "Repl %d attempts, %d odd, %d even\n",
+ re->nattempt[0] + re->nattempt[1],
+ re->nattempt[1],
+ re->nattempt[0]);
fprintf(fplog, "Repl average probabilities:\n");
for (i = 1; i < re->nrepl; i++)
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
// alias to avoid a large ripple of nearly useless changes.
// t_inputrec is being replaced by IMdpOptionsProvider, so this
// will go away eventually.
- t_inputrec* ir = inputrec;
+ const t_inputrec* ir = inputrec;
int64_t step, step_rel;
double t;
bool isLastStep = false;
{
gmx_fatal(FARGS, "Multiple simulations not supported by rerun.");
}
- if (std::any_of(ir->opts.annealing, ir->opts.annealing + ir->opts.ngtc,
- [](int i) { return i != eannNO; }))
+ if (std::any_of(ir->opts.annealing, ir->opts.annealing + ir->opts.ngtc, [](int i) {
+ return i != eannNO;
+ }))
{
gmx_fatal(FARGS, "Simulated annealing not supported by rerun.");
}
}
/* Settings for rerun */
- ir->nstlist = 1;
- ir->nstcalcenergy = 1;
+ {
+ // TODO: Avoid changing inputrec (#3854)
+ auto* nonConstInputrec = const_cast<t_inputrec*>(inputrec);
+ nonConstInputrec->nstlist = 1;
+ nonConstInputrec->nstcalcenergy = 1;
+ nonConstInputrec->nstxout_compressed = 0;
+ }
int nstglobalcomm = 1;
const bool bNS = true;
- ir->nstxout_compressed = 0;
const SimulationGroups* groups = &top_global->groups;
if (ir->eI == eiMimic)
{
gmx::ArrayRef<real> lambda = MASTER(cr) ? state_global->lambda : gmx::ArrayRef<real>();
initialize_lambdas(fplog, *ir, MASTER(cr), fep_state, lambda);
const bool simulationsShareState = false;
- gmx_mdoutf* outf = init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr, outputProvider,
- mdModulesNotifier, ir, top_global, oenv, wcycle,
- StartingBehavior::NewSimulation, simulationsShareState, ms);
- gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf), top_global, ir, pull_work,
- mdoutf_get_fp_dhdl(outf), true, StartingBehavior::NewSimulation,
- simulationsShareState, mdModulesNotifier);
+ gmx_mdoutf* outf = init_mdoutf(fplog,
+ nfile,
+ fnm,
+ mdrunOptions,
+ cr,
+ outputProvider,
+ mdModulesNotifier,
+ ir,
+ top_global,
+ oenv,
+ wcycle,
+ StartingBehavior::NewSimulation,
+ simulationsShareState,
+ ms);
+ gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf),
+ top_global,
+ ir,
+ pull_work,
+ mdoutf_get_fp_dhdl(outf),
+ true,
+ StartingBehavior::NewSimulation,
+ simulationsShareState,
+ mdModulesNotifier);
gstat = global_stat_init(ir);
/* Check for polarizable models and flexible constraints */
- shellfc = init_shell_flexcon(fplog, top_global, constr ? constr->numFlexibleConstraints() : 0,
- ir->nstcalcenergy, DOMAINDECOMP(cr),
+ shellfc = init_shell_flexcon(fplog,
+ top_global,
+ constr ? constr->numFlexibleConstraints() : 0,
+ ir->nstcalcenergy,
+ DOMAINDECOMP(cr),
runScheduleWork->simulationWork.useGpuPme);
{
dd_init_local_state(cr->dd, state_global, state);
/* Distribute the charge groups over the nodes from the master node */
- dd_partition_system(fplog, mdlog, ir->init_step, cr, TRUE, 1, state_global, *top_global, ir,
- imdSession, pull_work, state, &f, mdAtoms, &top, fr, vsite, constr,
- nrnb, nullptr, FALSE);
+ dd_partition_system(fplog,
+ mdlog,
+ ir->init_step,
+ cr,
+ TRUE,
+ 1,
+ state_global,
+ *top_global,
+ ir,
+ imdSession,
+ pull_work,
+ state,
+ &f,
+ mdAtoms,
+ &top,
+ fr,
+ vsite,
+ constr,
+ nrnb,
+ nullptr,
+ FALSE);
shouldCheckNumberOfBondedInteractions = true;
}
else
| (shouldCheckNumberOfBondedInteractions ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS : 0));
bool bSumEkinhOld = false;
t_vcm* vcm = nullptr;
- compute_globals(gstat, cr, ir, fr, ekind, makeConstArrayRef(state->x),
- makeConstArrayRef(state->v), state->box, mdatoms, nrnb, vcm, nullptr, enerd,
- force_vir, shake_vir, total_vir, pres, constr, &nullSignaller, state->box,
- &totalNumberOfBondedInteractions, &bSumEkinhOld, cglo_flags);
+ compute_globals(gstat,
+ cr,
+ ir,
+ fr,
+ ekind,
+ makeConstArrayRef(state->x),
+ makeConstArrayRef(state->v),
+ state->box,
+ mdatoms,
+ nrnb,
+ vcm,
+ nullptr,
+ enerd,
+ force_vir,
+ shake_vir,
+ total_vir,
+ pres,
+ gmx::ArrayRef<real>{},
+ &nullSignaller,
+ state->box,
+ &totalNumberOfBondedInteractions,
+ &bSumEkinhOld,
+ cglo_flags);
}
- checkNumberOfBondedInteractions(mdlog, cr, totalNumberOfBondedInteractions, top_global, &top,
- makeConstArrayRef(state->x), state->box,
+ checkNumberOfBondedInteractions(mdlog,
+ cr,
+ totalNumberOfBondedInteractions,
+ top_global,
+ &top,
+ makeConstArrayRef(state->x),
+ state->box,
&shouldCheckNumberOfBondedInteractions);
if (MASTER(cr))
fprintf(stderr,
"starting md rerun '%s', reading coordinates from"
" input trajectory '%s'\n\n",
- *(top_global->name), opt2fn("-rerun", nfile, fnm));
+ *(top_global->name),
+ opt2fn("-rerun", nfile, fnm));
if (mdrunOptions.verbose)
{
fprintf(stderr,
gmx_fatal(FARGS,
"Number of atoms in trajectory (%d) does not match the "
"run input file (%d)\n",
- rerun_fr.natoms, top_global->natoms);
+ rerun_fr.natoms,
+ top_global->natoms);
}
if (ir->pbcType != PbcType::No)
"Rerun trajectory frame step %" PRId64
" time %f "
"does not contain a box, while pbc is used",
- rerun_fr.step, rerun_fr.time);
+ rerun_fr.step,
+ rerun_fr.time);
}
if (max_cutoff2(ir->pbcType, rerun_fr.box) < gmx::square(fr->rlist))
{
"Rerun trajectory frame step %" PRId64
" time %f "
"has too small box dimensions",
- rerun_fr.step, rerun_fr.time);
+ rerun_fr.step,
+ rerun_fr.time);
}
}
}
step_rel = 0;
auto stopHandler = stopHandlerBuilder->getStopHandlerMD(
- compat::not_null<SimulationSignal*>(&signals[eglsSTOPCOND]), false, MASTER(cr),
- ir->nstlist, mdrunOptions.reproducible, nstglobalcomm, mdrunOptions.maximumHoursToRun,
- ir->nstlist == 0, fplog, step, bNS, walltime_accounting);
+ compat::not_null<SimulationSignal*>(&signals[eglsSTOPCOND]),
+ false,
+ MASTER(cr),
+ ir->nstlist,
+ mdrunOptions.reproducible,
+ nstglobalcomm,
+ mdrunOptions.maximumHoursToRun,
+ ir->nstlist == 0,
+ fplog,
+ step,
+ bNS,
+ walltime_accounting);
// we don't do counter resetting in rerun - finish will always be valid
walltime_accounting_set_valid_finish(walltime_accounting);
{
/* Repartition the domain decomposition */
const bool bMasterState = true;
- dd_partition_system(fplog, mdlog, step, cr, bMasterState, nstglobalcomm, state_global,
- *top_global, ir, imdSession, pull_work, state, &f, mdAtoms, &top,
- fr, vsite, constr, nrnb, wcycle, mdrunOptions.verbose);
+ dd_partition_system(fplog,
+ mdlog,
+ step,
+ cr,
+ bMasterState,
+ nstglobalcomm,
+ state_global,
+ *top_global,
+ ir,
+ imdSession,
+ pull_work,
+ state,
+ &f,
+ mdAtoms,
+ &top,
+ fr,
+ vsite,
+ constr,
+ nrnb,
+ wcycle,
+ mdrunOptions.verbose);
shouldCheckNumberOfBondedInteractions = true;
}
if (shellfc)
{
/* Now is the time to relax the shells */
- relax_shell_flexcon(fplog, cr, ms, mdrunOptions.verbose, enforcedRotation, step, ir,
- imdSession, pull_work, bNS, force_flags, &top, constr, enerd,
- state->natoms, state->x.arrayRefWithPadding(),
- state->v.arrayRefWithPadding(), state->box, state->lambda,
- &state->hist, &f.view(), force_vir, mdatoms, nrnb, wcycle, shellfc,
- fr, runScheduleWork, t, mu_tot, vsite, ddBalanceRegionHandler);
+ relax_shell_flexcon(fplog,
+ cr,
+ ms,
+ mdrunOptions.verbose,
+ enforcedRotation,
+ step,
+ ir,
+ imdSession,
+ pull_work,
+ bNS,
+ force_flags,
+ &top,
+ constr,
+ enerd,
+ state->natoms,
+ state->x.arrayRefWithPadding(),
+ state->v.arrayRefWithPadding(),
+ state->box,
+ state->lambda,
+ &state->hist,
+ &f.view(),
+ force_vir,
+ mdatoms,
+ nrnb,
+ wcycle,
+ shellfc,
+ fr,
+ runScheduleWork,
+ t,
+ mu_tot,
+ vsite,
+ ddBalanceRegionHandler);
}
else
{
*/
Awh* awh = nullptr;
gmx_edsam* ed = nullptr;
- do_force(fplog, cr, ms, ir, awh, enforcedRotation, imdSession, pull_work, step, nrnb,
- wcycle, &top, state->box, state->x.arrayRefWithPadding(), &state->hist,
- &f.view(), force_vir, mdatoms, enerd, state->lambda, fr, runScheduleWork,
- vsite, mu_tot, t, ed, GMX_FORCE_NS | force_flags, ddBalanceRegionHandler);
+ do_force(fplog,
+ cr,
+ ms,
+ ir,
+ awh,
+ enforcedRotation,
+ imdSession,
+ pull_work,
+ step,
+ nrnb,
+ wcycle,
+ &top,
+ state->box,
+ state->x.arrayRefWithPadding(),
+ &state->hist,
+ &f.view(),
+ force_vir,
+ mdatoms,
+ enerd,
+ state->lambda,
+ fr,
+ runScheduleWork,
+ vsite,
+ mu_tot,
+ t,
+ ed,
+ GMX_FORCE_NS | force_flags,
+ ddBalanceRegionHandler);
}
/* Now we have the energies and forces corresponding to the
const bool isCheckpointingStep = false;
const bool doRerun = true;
const bool bSumEkinhOld = false;
- do_md_trajectory_writing(fplog, cr, nfile, fnm, step, step_rel, t, ir, state,
- state_global, observablesHistory, top_global, fr, outf,
- energyOutput, ekind, f.view().force(), isCheckpointingStep,
- doRerun, isLastStep, mdrunOptions.writeConfout, bSumEkinhOld);
+ do_md_trajectory_writing(fplog,
+ cr,
+ nfile,
+ fnm,
+ step,
+ step_rel,
+ t,
+ ir,
+ state,
+ state_global,
+ observablesHistory,
+ top_global,
+ fr,
+ outf,
+ energyOutput,
+ ekind,
+ f.view().force(),
+ isCheckpointingStep,
+ doRerun,
+ isLastStep,
+ mdrunOptions.writeConfout,
+ bSumEkinhOld);
}
stopHandler->setSignal();
- if (vsite != nullptr)
- {
- wallcycle_start(wcycle, ewcVSITECONSTR);
- vsite->construct(state->x, ir->delta_t, state->v, state->box);
- wallcycle_stop(wcycle, ewcVSITECONSTR);
- }
-
{
const bool doInterSimSignal = false;
const bool doIntraSimSignal = true;
t_vcm* vcm = nullptr;
SimulationSignaller signaller(&signals, cr, ms, doInterSimSignal, doIntraSimSignal);
- compute_globals(gstat, cr, ir, fr, ekind, makeConstArrayRef(state->x),
- makeConstArrayRef(state->v), state->box, mdatoms, nrnb, vcm, wcycle,
- enerd, force_vir, shake_vir, total_vir, pres, constr, &signaller,
- state->box, &totalNumberOfBondedInteractions, &bSumEkinhOld,
+ compute_globals(gstat,
+ cr,
+ ir,
+ fr,
+ ekind,
+ makeConstArrayRef(state->x),
+ makeConstArrayRef(state->v),
+ state->box,
+ mdatoms,
+ nrnb,
+ vcm,
+ wcycle,
+ enerd,
+ force_vir,
+ shake_vir,
+ total_vir,
+ pres,
+ constr != nullptr ? constr->rmsdData() : gmx::ArrayRef<real>{},
+ &signaller,
+ state->box,
+ &totalNumberOfBondedInteractions,
+ &bSumEkinhOld,
CGLO_GSTAT | CGLO_ENERGY
| (shouldCheckNumberOfBondedInteractions ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS
: 0));
- checkNumberOfBondedInteractions(mdlog, cr, totalNumberOfBondedInteractions, top_global,
- &top, makeConstArrayRef(state->x), state->box,
+ checkNumberOfBondedInteractions(mdlog,
+ cr,
+ totalNumberOfBondedInteractions,
+ top_global,
+ &top,
+ makeConstArrayRef(state->x),
+ state->box,
&shouldCheckNumberOfBondedInteractions);
}
if (MASTER(cr))
{
const bool bCalcEnerStep = true;
- energyOutput.addDataAtEnergyStep(
- doFreeEnergyPerturbation, bCalcEnerStep, t, mdatoms->tmass, enerd, ir->fepvals,
- ir->expandedvals, state->box,
- PTCouplingArrays({ state->boxv, state->nosehoover_xi, state->nosehoover_vxi,
- state->nhpres_xi, state->nhpres_vxi }),
- state->fep_state, shake_vir, force_vir, total_vir, pres, ekind, mu_tot, constr);
+ energyOutput.addDataAtEnergyStep(doFreeEnergyPerturbation,
+ bCalcEnerStep,
+ t,
+ mdatoms->tmass,
+ enerd,
+ ir->fepvals,
+ ir->expandedvals,
+ state->box,
+ PTCouplingArrays({ state->boxv,
+ state->nosehoover_xi,
+ state->nosehoover_vxi,
+ state->nhpres_xi,
+ state->nhpres_vxi }),
+ state->fep_state,
+ shake_vir,
+ force_vir,
+ total_vir,
+ pres,
+ ekind,
+ mu_tot,
+ constr);
const bool do_ene = true;
const bool do_log = true;
const bool do_or = ir->nstorireout != 0;
EnergyOutput::printAnnealingTemperatures(do_log ? fplog : nullptr, groups, &(ir->opts));
- energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), do_ene, do_dr, do_or,
- do_log ? fplog : nullptr, step, t, fr->fcdata.get(), awh);
+ energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf),
+ do_ene,
+ do_dr,
+ do_or,
+ do_log ? fplog : nullptr,
+ step,
+ t,
+ fr->fcdata.get(),
+ awh);
if (do_per_step(step, ir->nstlog))
{
if ((ir->eSwapCoords != eswapNO) && (step > 0) && !isLastStep && do_per_step(step, ir->swap->nstswap))
{
const bool doRerun = true;
- do_swapcoords(cr, step, t, ir, swap, wcycle, rerun_fr.x, rerun_fr.box,
- MASTER(cr) && mdrunOptions.verbose, doRerun);
+ do_swapcoords(cr,
+ step,
+ t,
+ ir,
+ swap,
+ wcycle,
+ rerun_fr.x,
+ rerun_fr.box,
+ MASTER(cr) && mdrunOptions.verbose,
+ doRerun);
}
if (MASTER(cr))
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2011-2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2011-2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/domdec/localatomsetmanager.h"
#include "gromacs/domdec/partition.h"
#include "gromacs/ewald/ewald_utils.h"
+#include "gromacs/ewald/pme.h"
#include "gromacs/ewald/pme_gpu_program.h"
#include "gromacs/ewald/pme_only.h"
#include "gromacs/ewald/pme_pp_comm_gpu.h"
#if GMX_THREAD_MPI
/* now spawn new threads that start mdrunner_start_fn(), while
the main thread returns. Thread affinity is handled later. */
- if (tMPI_Init_fn(TRUE, numThreadsToLaunch, TMPI_AFFINITY_NONE, mdrunner_start_fn,
- static_cast<const void*>(this))
+ if (tMPI_Init_fn(TRUE, numThreadsToLaunch, TMPI_AFFINITY_NONE, mdrunner_start_fn, static_cast<const void*>(this))
!= TMPI_SUCCESS)
{
GMX_THROW(gmx::InternalError("Failed to spawn thread-MPI threads"));
"With Verlet lists and no PME rcoulomb and rvdw should be identical");
}
/* For NVE simulations, we will retain the initial list buffer */
- if (EI_DYNAMICS(ir->eI) && ir->verletbuf_tol > 0 && !(EI_MD(ir->eI) && ir->etc == etcNO))
+ if (EI_DYNAMICS(ir->eI) && ir->verletbuf_tol > 0
+ && !(EI_MD(ir->eI) && ir->etc == TemperatureCoupling::No))
{
/* Update the Verlet buffer size for the current run setup */
{
fprintf(fplog,
"\nChanging rlist from %g to %g for non-bonded %dx%d atom kernels\n\n",
- ir->rlist, rlist_new, listSetup.cluster_size_i, listSetup.cluster_size_j);
+ ir->rlist,
+ rlist_new,
+ listSetup.cluster_size_i,
+ listSetup.cluster_size_j);
}
ir->rlist = rlist_new;
}
if (nstlist_cmdline > 0 && (!EI_DYNAMICS(ir->eI) || ir->verletbuf_tol <= 0))
{
- gmx_fatal(FARGS, "Can not set nstlist without %s",
+ gmx_fatal(FARGS,
+ "Can not set nstlist without %s",
!EI_DYNAMICS(ir->eI) ? "dynamics" : "verlet-buffer-tolerance");
}
{
sprintf(sbuf_msg,
"Overriding nsteps with value passed on the command line: %s steps, %.3g ps",
- gmx_step_str(nsteps_cmdline, sbuf_steps), fabs(nsteps_cmdline * ir->delta_t));
+ gmx_step_str(nsteps_cmdline, sbuf_steps),
+ fabs(nsteps_cmdline * ir->delta_t));
}
else
{
- sprintf(sbuf_msg, "Overriding nsteps with value passed on the command line: %s steps",
+ sprintf(sbuf_msg,
+ "Overriding nsteps with value passed on the command line: %s steps",
gmx_step_str(nsteps_cmdline, sbuf_steps));
}
{
#if GMX_MPI
/* reduce elapsed_time over all MPI ranks in the current simulation */
- MPI_Allreduce(&elapsed_time, &elapsed_time_over_all_ranks, 1, MPI_DOUBLE, MPI_SUM,
- cr->mpi_comm_mysim);
+ MPI_Allreduce(&elapsed_time, &elapsed_time_over_all_ranks, 1, MPI_DOUBLE, MPI_SUM, cr->mpi_comm_mysim);
elapsed_time_over_all_ranks /= cr->nnodes;
/* Reduce elapsed_time_over_all_threads over all MPI ranks in the
* current simulation. */
- MPI_Allreduce(&elapsed_time_over_all_threads, &elapsed_time_over_all_threads_over_all_ranks,
- 1, MPI_DOUBLE, MPI_SUM, cr->mpi_comm_mysim);
+ MPI_Allreduce(&elapsed_time_over_all_threads,
+ &elapsed_time_over_all_threads_over_all_ranks,
+ 1,
+ MPI_DOUBLE,
+ MPI_SUM,
+ cr->mpi_comm_mysim);
#endif
}
else
* to task parallelism. */
int nthreads_pp = gmx_omp_nthreads_get(emntNonbonded);
int nthreads_pme = gmx_omp_nthreads_get(emntPME);
- wallcycle_scale_by_num_threads(wcycle, thisRankHasDuty(cr, DUTY_PME) && !thisRankHasDuty(cr, DUTY_PP),
- nthreads_pp, nthreads_pme);
+ wallcycle_scale_by_num_threads(
+ wcycle, thisRankHasDuty(cr, DUTY_PME) && !thisRankHasDuty(cr, DUTY_PP), nthreads_pp, nthreads_pme);
auto cycle_sum(wallcycle_sum(cr, wcycle));
if (printReport)
{
pme_gpu_get_timings(pme, &pme_gpu_timings);
}
- wallcycle_print(fplog, mdlog, cr->nnodes, cr->npmenodes, nthreads_pp, nthreads_pme,
- elapsed_time_over_all_ranks, wcycle, cycle_sum, nbnxn_gpu_timings,
+ wallcycle_print(fplog,
+ mdlog,
+ cr->nnodes,
+ cr->npmenodes,
+ nthreads_pp,
+ nthreads_pme,
+ elapsed_time_over_all_ranks,
+ wcycle,
+ cycle_sum,
+ nbnxn_gpu_timings,
&pme_gpu_timings);
if (EI_DYNAMICS(inputrec->eI))
if (fplog)
{
- print_perf(fplog, elapsed_time_over_all_threads_over_all_ranks, elapsed_time_over_all_ranks,
+ print_perf(fplog,
+ elapsed_time_over_all_threads_over_all_ranks,
+ elapsed_time_over_all_ranks,
walltime_accounting_get_nsteps_done_since_reset(walltime_accounting),
- delta_t, nbfs, mflop);
+ delta_t,
+ nbfs,
+ mflop);
}
if (bWriteStat)
{
- print_perf(stderr, elapsed_time_over_all_threads_over_all_ranks, elapsed_time_over_all_ranks,
+ print_perf(stderr,
+ elapsed_time_over_all_threads_over_all_ranks,
+ elapsed_time_over_all_ranks,
walltime_accounting_get_nsteps_done_since_reset(walltime_accounting),
- delta_t, nbfs, mflop);
+ delta_t,
+ nbfs,
+ mflop);
}
}
}
/* Read (nearly) all data required for the simulation
* and keep the partly serialized tpr contents to send to other ranks later
*/
- applyGlobalSimulationState(*inputHolder_.get(), partialDeserializedTpr.get(),
- globalState.get(), inputrec.get(), &mtop);
+ applyGlobalSimulationState(
+ *inputHolder_.get(), partialDeserializedTpr.get(), globalState.get(), inputrec.get(), &mtop);
}
/* Check and update the hardware options for internal consistency */
- checkAndUpdateHardwareOptions(mdlog, &hw_opt, isSimulationMasterRank, domdecOptions.numPmeRanks,
- inputrec.get());
+ checkAndUpdateHardwareOptions(
+ mdlog, &hw_opt, isSimulationMasterRank, domdecOptions.numPmeRanks, inputrec.get());
if (GMX_THREAD_MPI && isSimulationMasterRank)
{
// the number of GPUs to choose the number of ranks.
auto canUseGpuForNonbonded = buildSupportsNonbondedOnGpu(nullptr);
useGpuForNonbonded = decideWhetherToUseGpusForNonbondedWithThreadMpi(
- nonbondedTarget, numDevicesToUse, userGpuTaskAssignment, emulateGpuNonbonded,
+ nonbondedTarget,
+ numDevicesToUse,
+ userGpuTaskAssignment,
+ emulateGpuNonbonded,
canUseGpuForNonbonded,
gpuAccelerationOfNonbondedIsUseful(mdlog, *inputrec, GMX_THREAD_MPI),
hw_opt.nthreads_tmpi);
- useGpuForPme = decideWhetherToUseGpusForPmeWithThreadMpi(
- useGpuForNonbonded, pmeTarget, numDevicesToUse, userGpuTaskAssignment, *hwinfo_,
- *inputrec, hw_opt.nthreads_tmpi, domdecOptions.numPmeRanks);
+ useGpuForPme = decideWhetherToUseGpusForPmeWithThreadMpi(useGpuForNonbonded,
+ pmeTarget,
+ numDevicesToUse,
+ userGpuTaskAssignment,
+ *hwinfo_,
+ *inputrec,
+ hw_opt.nthreads_tmpi,
+ domdecOptions.numPmeRanks);
}
GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
* TODO Over-writing the user-supplied value here does
* prevent any possible subsequent checks from working
* correctly. */
- hw_opt.nthreads_tmpi =
- get_nthreads_mpi(hwinfo_, &hw_opt, numDevicesToUse, useGpuForNonbonded, useGpuForPme,
- inputrec.get(), &mtop, mdlog, membedHolder.doMembed());
+ hw_opt.nthreads_tmpi = get_nthreads_mpi(hwinfo_,
+ &hw_opt,
+ numDevicesToUse,
+ useGpuForNonbonded,
+ useGpuForPme,
+ inputrec.get(),
+ &mtop,
+ mdlog,
+ membedHolder.doMembed());
// Now start the threads for thread MPI.
spawnThreads(hw_opt.nthreads_tmpi);
// On non-master ranks, allocate the object that will receive data in the following call.
inputrec = std::make_unique<t_inputrec>();
}
- init_parallel(cr->mpiDefaultCommunicator, MASTER(cr), inputrec.get(), &mtop,
+ init_parallel(cr->mpiDefaultCommunicator,
+ MASTER(cr),
+ inputrec.get(),
+ &mtop,
partialDeserializedTpr.get());
}
GMX_RELEASE_ASSERT(inputrec != nullptr, "All ranks should have a valid inputrec now");
partialDeserializedTpr.reset(nullptr);
+ GMX_RELEASE_ASSERT(
+ !inputrec->useConstantAcceleration,
+ "Linear acceleration has been removed in GROMACS 2022, and was broken for many years "
+ "before that. Use GROMACS 4.5 or earlier if you need this feature.");
+
// Now the number of ranks is known to all ranks, and each knows
// the inputrec read by the master rank. The ranks can now all run
// the task-deciding functions and will agree on the result
// assignment.
auto canUseGpuForNonbonded = buildSupportsNonbondedOnGpu(nullptr);
useGpuForNonbonded = decideWhetherToUseGpusForNonbonded(
- nonbondedTarget, userGpuTaskAssignment, emulateGpuNonbonded, canUseGpuForNonbonded,
- gpuAccelerationOfNonbondedIsUseful(mdlog, *inputrec, !GMX_THREAD_MPI), gpusWereDetected);
- useGpuForPme = decideWhetherToUseGpusForPme(
- useGpuForNonbonded, pmeTarget, userGpuTaskAssignment, *hwinfo_, *inputrec,
- cr->sizeOfDefaultCommunicator, domdecOptions.numPmeRanks, gpusWereDetected);
- useGpuForBonded = decideWhetherToUseGpusForBonded(useGpuForNonbonded, useGpuForPme,
- bondedTarget, *inputrec, mtop,
- domdecOptions.numPmeRanks, gpusWereDetected);
+ nonbondedTarget,
+ userGpuTaskAssignment,
+ emulateGpuNonbonded,
+ canUseGpuForNonbonded,
+ gpuAccelerationOfNonbondedIsUseful(mdlog, *inputrec, !GMX_THREAD_MPI),
+ gpusWereDetected);
+ useGpuForPme = decideWhetherToUseGpusForPme(useGpuForNonbonded,
+ pmeTarget,
+ userGpuTaskAssignment,
+ *hwinfo_,
+ *inputrec,
+ cr->sizeOfDefaultCommunicator,
+ domdecOptions.numPmeRanks,
+ gpusWereDetected);
+ useGpuForBonded = decideWhetherToUseGpusForBonded(
+ useGpuForNonbonded, useGpuForPme, bondedTarget, *inputrec, mtop, domdecOptions.numPmeRanks, gpusWereDetected);
}
GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
const DevelopmentFeatureFlags devFlags =
manageDevelopmentFeatures(mdlog, useGpuForNonbonded, pmeRunMode);
- const bool useModularSimulator =
- checkUseModularSimulator(false, inputrec.get(), doRerun, mtop, ms, replExParams,
- nullptr, doEssentialDynamics, membedHolder.doMembed());
+ const bool useModularSimulator = checkUseModularSimulator(false,
+ inputrec.get(),
+ doRerun,
+ mtop,
+ ms,
+ replExParams,
+ nullptr,
+ doEssentialDynamics,
+ membedHolder.doMembed());
// Build restraints.
// TODO: hide restraint implementation details from Mdrunner.
{
globalState = std::make_unique<t_state>();
}
- broadcastStateWithoutDynamics(cr->mpiDefaultCommunicator, DOMAINDECOMP(cr), PAR(cr),
- globalState.get());
+ broadcastStateWithoutDynamics(
+ cr->mpiDefaultCommunicator, DOMAINDECOMP(cr), PAR(cr), globalState.get());
}
/* A parallel command line option consistency check that we can
"these are not compatible with mdrun -rerun");
}
+ /* Object for collecting reasons for not using PME-only ranks */
+ SeparatePmeRanksPermitted separatePmeRanksPermitted;
+
+ /* Permit MDModules to notify whether they want to use PME-only ranks */
+ mdModulesNotifier.notify(&separatePmeRanksPermitted);
+
+ /* If simulation is not using PME then disable PME-only ranks */
if (!(EEL_PME(inputrec->coulombtype) || EVDW_PME(inputrec->vdwtype)))
{
- if (domdecOptions.numPmeRanks > 0)
- {
- gmx_fatal_collective(FARGS, cr->mpiDefaultCommunicator, MASTER(cr),
- "PME-only ranks are requested, but the system does not use PME "
- "for electrostatics or LJ");
- }
-
- domdecOptions.numPmeRanks = 0;
+ separatePmeRanksPermitted.disablePmeRanks(
+ "PME-only ranks are requested, but the system does not use PME "
+ "for electrostatics or LJ");
}
+ /* With NB GPUs we don't automatically use PME-only CPU ranks. PME ranks can
+ * improve performance with many threads per GPU, since our OpenMP
+ * scaling is bad, but it's difficult to automate the setup.
+ */
if (useGpuForNonbonded && domdecOptions.numPmeRanks < 0)
{
- /* With NB GPUs we don't automatically use PME-only CPU ranks. PME ranks can
- * improve performance with many threads per GPU, since our OpenMP
- * scaling is bad, but it's difficult to automate the setup.
- */
+ separatePmeRanksPermitted.disablePmeRanks(
+ "PME-only CPU ranks are not automatically used when "
+ "non-bonded interactions are computed on GPUs");
+ }
+
+ /* If GPU is used for PME then only 1 PME rank is permitted */
+ if (useGpuForPme && (domdecOptions.numPmeRanks < 0 || domdecOptions.numPmeRanks > 1))
+ {
+ separatePmeRanksPermitted.disablePmeRanks(
+ "PME GPU decomposition is not supported. Only one separate PME-only GPU rank "
+ "can be used.");
+ }
+
+ /* Disable PME-only ranks if some parts of the code requested so and it's up to GROMACS to decide */
+ if (!separatePmeRanksPermitted.permitSeparatePmeRanks() && domdecOptions.numPmeRanks < 0)
+ {
domdecOptions.numPmeRanks = 0;
+ GMX_LOG(mdlog.info)
+ .asParagraph()
+ .appendText("Simulation will not use PME-only ranks because: "
+ + separatePmeRanksPermitted.reasonsWhyDisabled());
}
- if (useGpuForPme)
+
+ /* If some parts of the code could not use PME-only ranks and
+ * user explicitly used mdrun -npme option then throw an error */
+ if (!separatePmeRanksPermitted.permitSeparatePmeRanks() && domdecOptions.numPmeRanks > 0)
{
- if (domdecOptions.numPmeRanks < 0)
- {
- domdecOptions.numPmeRanks = 0;
- // TODO possibly print a note that one can opt-in for a separate PME GPU rank?
- }
- else
- {
- GMX_RELEASE_ASSERT(domdecOptions.numPmeRanks <= 1,
- "PME GPU decomposition is not supported");
- }
+ gmx_fatal_collective(FARGS,
+ cr->mpiDefaultCommunicator,
+ MASTER(cr),
+ "Requested -npme %d option is not viable because: %s",
+ domdecOptions.numPmeRanks,
+ separatePmeRanksPermitted.reasonsWhyDisabled().c_str());
}
/* NMR restraints must be initialized before load_checkpoint,
/* This needs to be called before read_checkpoint to extend the state */
t_disresdata* disresdata;
snew(disresdata, 1);
- init_disres(fplog, &mtop, inputrec.get(), DisResRunMode::MDRun,
+ init_disres(fplog,
+ &mtop,
+ inputrec.get(),
+ DisResRunMode::MDRun,
MASTER(cr) ? DDRole::Master : DDRole::Agent,
- PAR(cr) ? NumRanks::Multiple : NumRanks::Single, cr->mpi_comm_mysim, ms, disresdata,
- globalState.get(), replExParams.exchangeInterval > 0);
+ PAR(cr) ? NumRanks::Multiple : NumRanks::Single,
+ cr->mpi_comm_mysim,
+ ms,
+ disresdata,
+ globalState.get(),
+ replExParams.exchangeInterval > 0);
t_oriresdata* oriresdata;
snew(oriresdata, 1);
init_orires(fplog, &mtop, inputrec.get(), cr, ms, globalState.get(), oriresdata);
- auto deform = prepareBoxDeformation(
- globalState != nullptr ? globalState->box : box, MASTER(cr) ? DDRole::Master : DDRole::Agent,
- PAR(cr) ? NumRanks::Multiple : NumRanks::Single, cr->mpi_comm_mygroup, *inputrec);
+ auto deform = prepareBoxDeformation(globalState != nullptr ? globalState->box : box,
+ MASTER(cr) ? DDRole::Master : DDRole::Agent,
+ PAR(cr) ? NumRanks::Multiple : NumRanks::Single,
+ cr->mpi_comm_mygroup,
+ *inputrec);
#if GMX_FAHCORE
/* We have to remember the generation's first step before reading checkpoint.
// Finish applying initial simulation state information from external sources on all ranks.
// Reconcile checkpoint file data with Mdrunner state established up to this point.
- applyLocalState(*inputHolder_.get(), logFileHandle, cr, domdecOptions.numCells,
- inputrec.get(), globalState.get(), &observablesHistory,
- mdrunOptions.reproducible, mdModules_->notifier(),
- modularSimulatorCheckpointData.get(), useModularSimulator);
+ applyLocalState(*inputHolder_.get(),
+ logFileHandle,
+ cr,
+ domdecOptions.numCells,
+ inputrec.get(),
+ globalState.get(),
+ &observablesHistory,
+ mdrunOptions.reproducible,
+ mdModules_->notifier(),
+ modularSimulatorCheckpointData.get(),
+ useModularSimulator);
// TODO: (#3652) Synchronize filesystem state, SimulationInput contents, and program
// invariants
// on all code paths.
* increase rlist) tries to check if the newly chosen value fits with the DD scheme. As this is
* run before any DD scheme is set up, this check is never executed. See #3334 for more details.
*/
- prepare_verlet_scheme(fplog, cr, inputrec.get(), nstlist_cmdline, &mtop, box,
+ prepare_verlet_scheme(fplog,
+ cr,
+ inputrec.get(),
+ nstlist_cmdline,
+ &mtop,
+ box,
useGpuForNonbonded || (emulateGpuNonbonded == EmulateGpuNonbonded::Yes),
*hwinfo_->cpuInfo);
if (useDomainDecomposition)
{
ddBuilder = std::make_unique<DomainDecompositionBuilder>(
- mdlog, cr, domdecOptions, mdrunOptions, mtop, *inputrec, box,
+ mdlog,
+ cr,
+ domdecOptions,
+ mdrunOptions,
+ mtop,
+ *inputrec,
+ box,
positionsFromStatePointer(globalState.get()));
}
else
// Produce the task assignment for this rank - done after DD is constructed
GpuTaskAssignments gpuTaskAssignments = GpuTaskAssignmentsBuilder::build(
- gpuIdsToUse, userGpuTaskAssignment, *hwinfo_, simulationCommunicator, physicalNodeComm,
- nonbondedTarget, pmeTarget, bondedTarget, updateTarget, useGpuForNonbonded,
- useGpuForPme, thisRankHasDuty(cr, DUTY_PP),
+ gpuIdsToUse,
+ userGpuTaskAssignment,
+ *hwinfo_,
+ simulationCommunicator,
+ physicalNodeComm,
+ nonbondedTarget,
+ pmeTarget,
+ bondedTarget,
+ updateTarget,
+ useGpuForNonbonded,
+ useGpuForPme,
+ thisRankHasDuty(cr, DUTY_PP),
// TODO cr->duty & DUTY_PME should imply that a PME
// algorithm is active, but currently does not.
EEL_PME(inputrec->coulombtype) && thisRankHasDuty(cr, DUTY_PME));
{
const bool useUpdateGroups = cr->dd ? ddUsesUpdateGroups(*cr->dd) : false;
- useGpuForUpdate = decideWhetherToUseGpuForUpdate(
- useDomainDecomposition, useUpdateGroups, pmeRunMode, domdecOptions.numPmeRanks > 0,
- useGpuForNonbonded, updateTarget, gpusWereDetected, *inputrec, mtop,
- doEssentialDynamics, gmx_mtop_ftype_count(mtop, F_ORIRES) > 0,
- replExParams.exchangeInterval > 0, doRerun, devFlags, mdlog);
+ useGpuForUpdate = decideWhetherToUseGpuForUpdate(useDomainDecomposition,
+ useUpdateGroups,
+ pmeRunMode,
+ domdecOptions.numPmeRanks > 0,
+ useGpuForNonbonded,
+ updateTarget,
+ gpusWereDetected,
+ *inputrec,
+ mtop,
+ doEssentialDynamics,
+ gmx_mtop_ftype_count(mtop, F_ORIRES) > 0,
+ replExParams.exchangeInterval > 0,
+ doRerun,
+ devFlags,
+ mdlog);
}
GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
MdrunScheduleWorkload runScheduleWork;
- bool useGpuDirectHalo = decideWhetherToUseGpuForHalo(
- devFlags, havePPDomainDecomposition(cr), useGpuForNonbonded, useModularSimulator,
- doRerun, EI_ENERGY_MINIMIZATION(inputrec->eI));
+ bool useGpuDirectHalo = decideWhetherToUseGpuForHalo(devFlags,
+ havePPDomainDecomposition(cr),
+ useGpuForNonbonded,
+ useModularSimulator,
+ doRerun,
+ EI_ENERGY_MINIMIZATION(inputrec->eI));
// Also populates the simulation constant workload description.
- runScheduleWork.simulationWork = createSimulationWorkload(
- *inputrec, disableNonbondedCalculation, devFlags, useGpuForNonbonded, pmeRunMode,
- useGpuForBonded, useGpuForUpdate, useGpuDirectHalo);
+ runScheduleWork.simulationWork = createSimulationWorkload(*inputrec,
+ disableNonbondedCalculation,
+ devFlags,
+ useGpuForNonbonded,
+ pmeRunMode,
+ useGpuForBonded,
+ useGpuForUpdate,
+ useGpuDirectHalo);
std::unique_ptr<DeviceStreamManager> deviceStreamManager = nullptr;
.appendTextFormatted(
"This is simulation %d out of %d running as a composite GROMACS\n"
"multi-simulation job. Setup for this simulation:\n",
- ms->simulationIndex_, ms->numSimulations_);
+ ms->simulationIndex_,
+ ms->numSimulations_);
}
GMX_LOG(mdlog.warning)
- .appendTextFormatted("Using %d MPI %s\n", cr->nnodes,
+ .appendTextFormatted("Using %d MPI %s\n",
+ cr->nnodes,
# if GMX_THREAD_MPI
cr->nnodes == 1 ? "thread" : "threads"
# else
// the OpenMP support.
gmx_check_thread_affinity_set(mdlog, &hw_opt, hwinfo_->nthreads_hw_avail, FALSE);
/* Check and update the number of OpenMP threads requested */
- checkAndUpdateRequestedNumOpenmpThreads(&hw_opt, *hwinfo_, cr, ms, physicalNodeComm.size_,
- pmeRunMode, mtop, *inputrec);
-
- gmx_omp_nthreads_init(mdlog, cr, hwinfo_->nthreads_hw_avail, physicalNodeComm.size_,
- hw_opt.nthreads_omp, hw_opt.nthreads_omp_pme, !thisRankHasDuty(cr, DUTY_PP));
-
- // Enable FP exception detection, but not in
- // Release mode and not for compilers with known buggy FP
- // exception support (clang with any optimization) or suspected
- // buggy FP exception support (gcc 7.* with optimization).
-#if !defined NDEBUG \
- && !((defined __clang__ || (defined(__GNUC__) && !defined(__ICC) && __GNUC__ == 7)) \
- && defined __OPTIMIZE__)
- const bool bEnableFPE = true;
-#else
- const bool bEnableFPE = false;
-#endif
+ checkAndUpdateRequestedNumOpenmpThreads(
+ &hw_opt, *hwinfo_, cr, ms, physicalNodeComm.size_, pmeRunMode, mtop, *inputrec);
+
+ gmx_omp_nthreads_init(mdlog,
+ cr,
+ hwinfo_->nthreads_hw_avail,
+ physicalNodeComm.size_,
+ hw_opt.nthreads_omp,
+ hw_opt.nthreads_omp_pme,
+ !thisRankHasDuty(cr, DUTY_PP));
+
+ const bool bEnableFPE = gmxShouldEnableFPExceptions();
// FIXME - reconcile with gmx_feenableexcept() call from CommandLineModuleManager::run()
if (bEnableFPE)
{
}
/* Now that we know the setup is consistent, check for efficiency */
- check_resource_division_efficiency(hwinfo_, gpuTaskAssignments.thisRankHasAnyGpuTask(),
- mdrunOptions.ntompOptionIsSet, cr, mdlog);
+ check_resource_division_efficiency(
+ hwinfo_, gpuTaskAssignments.thisRankHasAnyGpuTask(), mdrunOptions.ntompOptionIsSet, cr, mdlog);
/* getting number of PP/PME threads on this MPI / tMPI rank.
PME: env variable should be read only on one node to make sure it is
*/
const int numThreadsOnThisRank = thisRankHasDuty(cr, DUTY_PP) ? gmx_omp_nthreads_get(emntNonbonded)
: gmx_omp_nthreads_get(emntPME);
- checkHardwareOversubscription(numThreadsOnThisRank, cr->nodeid, *hwinfo_->hardwareTopology,
- physicalNodeComm, mdlog);
+ checkHardwareOversubscription(
+ numThreadsOnThisRank, cr->nodeid, *hwinfo_->hardwareTopology, physicalNodeComm, mdlog);
// Enable Peer access between GPUs where available
// Only for DD, only master PP rank needs to perform setup, and only if thread MPI plus
gmx_check_thread_affinity_set(mdlog, &hw_opt, hwinfo_->nthreads_hw_avail, TRUE);
int numThreadsOnThisNode, intraNodeThreadOffset;
- analyzeThreadsOnThisNode(physicalNodeComm, numThreadsOnThisRank, &numThreadsOnThisNode,
- &intraNodeThreadOffset);
+ analyzeThreadsOnThisNode(
+ physicalNodeComm, numThreadsOnThisRank, &numThreadsOnThisNode, &intraNodeThreadOffset);
/* Set the CPU affinity */
- gmx_set_thread_affinity(mdlog, cr, &hw_opt, *hwinfo_->hardwareTopology, numThreadsOnThisRank,
- numThreadsOnThisNode, intraNodeThreadOffset, nullptr);
+ gmx_set_thread_affinity(mdlog,
+ cr,
+ &hw_opt,
+ *hwinfo_->hardwareTopology,
+ numThreadsOnThisRank,
+ numThreadsOnThisNode,
+ intraNodeThreadOffset,
+ nullptr);
}
if (mdrunOptions.timingOptions.resetStep > -1)
}
// Membrane embedding must be initialized before we call init_forcerec()
- membedHolder.initializeMembed(fplog, filenames.size(), filenames.data(), &mtop, inputrec.get(),
- globalState.get(), cr, &mdrunOptions.checkpointOptions.period);
+ membedHolder.initializeMembed(fplog,
+ filenames.size(),
+ filenames.data(),
+ &mtop,
+ inputrec.get(),
+ globalState.get(),
+ cr,
+ &mdrunOptions.checkpointOptions.period);
const bool thisRankHasPmeGpuTask = gpuTaskAssignments.thisRankHasPmeGpuTask();
std::unique_ptr<MDAtoms> mdAtoms;
{
mdModulesNotifier.notify(*cr);
mdModulesNotifier.notify(&atomSets);
+ mdModulesNotifier.notify(mtop);
mdModulesNotifier.notify(inputrec->pbcType);
mdModulesNotifier.notify(SimulationTimeStep{ inputrec->delta_t });
/* Initiate forcerecord */
fr = new t_forcerec;
fr->forceProviders = mdModules_->initForceProviders();
- init_forcerec(fplog, mdlog, fr, inputrec.get(), &mtop, cr, box,
+ init_forcerec(fplog,
+ mdlog,
+ fr,
+ inputrec.get(),
+ &mtop,
+ cr,
+ box,
opt2fn("-table", filenames.size(), filenames.data()),
opt2fn("-tablep", filenames.size(), filenames.data()),
- opt2fns("-tableb", filenames.size(), filenames.data()), pforce);
+ opt2fns("-tableb", filenames.size(), filenames.data()),
+ pforce);
// Dirty hack, for fixing disres and orires should be made mdmodules
fr->fcdata->disres = disresdata;
fr->fcdata->orires = oriresdata;
"GPU PP-PME stream should be valid in order to use GPU PME-PP direct "
"communications.");
fr->pmePpCommGpu = std::make_unique<gmx::PmePpCommGpu>(
- cr->mpi_comm_mysim, cr->dd->pme_nodeid, deviceStreamManager->context(),
+ cr->mpi_comm_mysim,
+ cr->dd->pme_nodeid,
+ deviceStreamManager->context(),
deviceStreamManager->stream(DeviceStreamType::PmePpTransfer));
}
- fr->nbv = Nbnxm::init_nb_verlet(mdlog, inputrec.get(), fr, cr, *hwinfo_,
+ fr->nbv = Nbnxm::init_nb_verlet(mdlog,
+ inputrec.get(),
+ fr,
+ cr,
+ *hwinfo_,
runScheduleWork.simulationWork.useGpuNonbonded,
- deviceStreamManager.get(), &mtop, box, wcycle);
+ deviceStreamManager.get(),
+ &mtop,
+ box,
+ wcycle);
// TODO: Move the logic below to a GPU bonded builder
if (runScheduleWork.simulationWork.useGpuBonded)
{
"GPU device stream manager should be valid in order to use GPU "
"version of bonded forces.");
gpuBonded = std::make_unique<GpuBonded>(
- mtop.ffparams, fr->ic->epsfac * fr->fudgeQQ, deviceStreamManager->context(),
- deviceStreamManager->bondedStream(havePPDomainDecomposition(cr)), wcycle);
+ mtop.ffparams,
+ fr->ic->epsfac * fr->fudgeQQ,
+ deviceStreamManager->context(),
+ deviceStreamManager->bondedStream(havePPDomainDecomposition(cr)),
+ wcycle);
fr->gpuBonded = gpuBonded.get();
}
? &deviceStreamManager->stream(DeviceStreamType::Pme)
: nullptr;
- pmedata = gmx_pme_init(cr, getNumPmeDomains(cr->dd), inputrec.get(),
- nChargePerturbed != 0, nTypePerturbed != 0,
- mdrunOptions.reproducible, ewaldcoeff_q, ewaldcoeff_lj,
- gmx_omp_nthreads_get(emntPME), pmeRunMode, nullptr,
- deviceContext, pmeStream, pmeGpuProgram.get(), mdlog);
+ pmedata = gmx_pme_init(cr,
+ getNumPmeDomains(cr->dd),
+ inputrec.get(),
+ nChargePerturbed != 0,
+ nTypePerturbed != 0,
+ mdrunOptions.reproducible,
+ ewaldcoeff_q,
+ ewaldcoeff_lj,
+ gmx_omp_nthreads_get(emntPME),
+ pmeRunMode,
+ nullptr,
+ deviceContext,
+ pmeStream,
+ pmeGpuProgram.get(),
+ mdlog);
}
GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
}
if (inputrec->bPull)
{
/* Initialize pull code */
- pull_work = init_pull(fplog, inputrec->pull.get(), inputrec.get(), &mtop, cr, &atomSets,
+ pull_work = init_pull(fplog,
+ inputrec->pull.get(),
+ inputrec.get(),
+ &mtop,
+ cr,
+ &atomSets,
inputrec->fepvals->init_lambda);
if (inputrec->pull->bXOutAverage || inputrec->pull->bFOutAverage)
{
if (inputrec->bRot)
{
/* Initialize enforced rotation code */
- enforcedRotation = init_rot(fplog, inputrec.get(), filenames.size(), filenames.data(),
- cr, &atomSets, globalState.get(), &mtop, oenv, mdrunOptions,
+ enforcedRotation = init_rot(fplog,
+ inputrec.get(),
+ filenames.size(),
+ filenames.data(),
+ cr,
+ &atomSets,
+ globalState.get(),
+ &mtop,
+ oenv,
+ mdrunOptions,
startingBehavior);
}
if (inputrec->eSwapCoords != eswapNO)
{
/* Initialize ion swapping code */
- swap = init_swapcoords(fplog, inputrec.get(),
+ swap = init_swapcoords(fplog,
+ inputrec.get(),
opt2fn_master("-swap", filenames.size(), filenames.data(), cr),
- &mtop, globalState.get(), &observablesHistory, cr, &atomSets,
- oenv, mdrunOptions, startingBehavior);
+ &mtop,
+ globalState.get(),
+ &observablesHistory,
+ cr,
+ &atomSets,
+ oenv,
+ mdrunOptions,
+ startingBehavior);
}
/* Let makeConstraints know whether we have essential dynamics constraints. */
- auto constr = makeConstraints(mtop, *inputrec, pull_work, doEssentialDynamics, fplog, cr,
- ms, &nrnb, wcycle, fr->bMolPBC);
+ auto constr = makeConstraints(
+ mtop, *inputrec, pull_work, doEssentialDynamics, fplog, cr, ms, &nrnb, wcycle, fr->bMolPBC);
/* Energy terms and groups */
gmx_enerdata_t enerd(mtop.groups.groups[SimulationAtomGroupType::EnergyOutput].size(),
inputrec->fepvals->n_lambda);
+ // cos acceleration is only supported by md, but older tpr
+ // files might still combine it with other integrators
+ GMX_RELEASE_ASSERT(inputrec->cos_accel == 0.0 || inputrec->eI == eiMD,
+ "cos_acceleration is only supported by integrator=md");
+
/* Kinetic energy data */
gmx_ekindata_t ekind;
- init_ekindata(fplog, &mtop, &(inputrec->opts), &ekind, inputrec->cos_accel);
+ init_ekindata(fplog, &(inputrec->opts), &ekind, inputrec->cos_accel);
/* Set up interactive MD (IMD) */
- auto imdSession =
- makeImdSession(inputrec.get(), cr, wcycle, &enerd, ms, &mtop, mdlog,
- MASTER(cr) ? globalState->x.rvec_array() : nullptr, filenames.size(),
- filenames.data(), oenv, mdrunOptions.imdOptions, startingBehavior);
+ auto imdSession = makeImdSession(inputrec.get(),
+ cr,
+ wcycle,
+ &enerd,
+ ms,
+ &mtop,
+ mdlog,
+ MASTER(cr) ? globalState->x.rvec_array() : nullptr,
+ filenames.size(),
+ filenames.data(),
+ oenv,
+ mdrunOptions.imdOptions,
+ startingBehavior);
if (DOMAINDECOMP(cr))
{
/* This call is not included in init_domain_decomposition mainly
* because fr->cginfo_mb is set later.
*/
- dd_init_bondeds(fplog, cr->dd, mtop, vsite.get(), inputrec.get(),
- domdecOptions.checkBondedInteractions, fr->cginfo_mb);
+ dd_init_bondeds(fplog,
+ cr->dd,
+ mtop,
+ vsite.get(),
+ inputrec.get(),
+ domdecOptions.checkBondedInteractions,
+ fr->cginfo_mb);
}
if (runScheduleWork.simulationWork.useGpuBufferOps)
{
fr->gpuForceReduction[gmx::AtomLocality::Local] = std::make_unique<gmx::GpuForceReduction>(
deviceStreamManager->context(),
- deviceStreamManager->stream(gmx::DeviceStreamType::NonBondedLocal), wcycle);
+ deviceStreamManager->stream(gmx::DeviceStreamType::NonBondedLocal),
+ wcycle);
fr->gpuForceReduction[gmx::AtomLocality::NonLocal] = std::make_unique<gmx::GpuForceReduction>(
deviceStreamManager->context(),
- deviceStreamManager->stream(gmx::DeviceStreamType::NonBondedNonLocal), wcycle);
+ deviceStreamManager->stream(gmx::DeviceStreamType::NonBondedNonLocal),
+ wcycle);
}
std::unique_ptr<gmx::StatePropagatorDataGpu> stateGpu;
simulatorBuilder.add(SimulatorEnv(fplog, cr, ms, mdlog, oenv));
simulatorBuilder.add(Profiling(&nrnb, walltime_accounting, wcycle));
simulatorBuilder.add(ConstraintsParam(
- constr.get(), enforcedRotation ? enforcedRotation->getLegacyEnfrot() : nullptr,
- vsite.get()));
+ constr.get(), enforcedRotation ? enforcedRotation->getLegacyEnfrot() : nullptr, vsite.get()));
// TODO: Separate `fr` to a separate add, and make the `build` handle the coupling sensibly.
- simulatorBuilder.add(LegacyInput(static_cast<int>(filenames.size()), filenames.data(),
- inputrec.get(), fr));
+ simulatorBuilder.add(LegacyInput(
+ static_cast<int>(filenames.size()), filenames.data(), inputrec.get(), fr));
simulatorBuilder.add(ReplicaExchangeParameters(replExParams));
simulatorBuilder.add(InteractiveMD(imdSession.get()));
simulatorBuilder.add(SimulatorModules(mdModules_->outputProvider(), mdModules_->notifier()));
GMX_RELEASE_ASSERT(pmedata, "pmedata was NULL while cr->duty was not DUTY_PP");
/* do PME only */
walltime_accounting = walltime_accounting_init(gmx_omp_nthreads_get(emntPME));
- gmx_pmeonly(pmedata, cr, &nrnb, wcycle, walltime_accounting, inputrec.get(), pmeRunMode,
+ gmx_pmeonly(pmedata,
+ cr,
+ &nrnb,
+ wcycle,
+ walltime_accounting,
+ inputrec.get(),
+ pmeRunMode,
deviceStreamManager.get());
}
/* Finish up, write some stuff
* if rerunMD, don't write last frame again
*/
- finish_run(fplog, mdlog, cr, inputrec.get(), &nrnb, wcycle, walltime_accounting,
- fr ? fr->nbv.get() : nullptr, pmedata, EI_DYNAMICS(inputrec->eI) && !isMultiSim(ms));
+ finish_run(fplog,
+ mdlog,
+ cr,
+ inputrec.get(),
+ &nrnb,
+ wcycle,
+ walltime_accounting,
+ fr ? fr->nbv.get() : nullptr,
+ pmedata,
+ EI_DYNAMICS(inputrec->eI) && !isMultiSim(ms));
// clean up cycle counter
wallcycle_destroy(wcycle);
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2008, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
gmx_fatal(FARGS,
"polarize can not be used with qA(%e) != qB(%e) for "
"atom %d of molecule block %zu",
- qS, atom[aS].qB, aS + 1, mb + 1);
+ qS,
+ atom[aS].qB,
+ aS + 1,
+ mb + 1);
}
shell[nsi].k += gmx::square(qS) * ONE_4PI_EPS0
/ ffparams->iparams[type].polarize.alpha;
gmx_fatal(FARGS,
"water_pol can not be used with qA(%e) != qB(%e) for "
"atom %d of molecule block %zu",
- qS, atom[aS].qB, aS + 1, mb + 1);
+ qS,
+ atom[aS].qB,
+ aS + 1,
+ mb + 1);
}
alpha = (ffparams->iparams[type].wpol.al_x
+ ffparams->iparams[type].wpol.al_y
ff2 = iprod(f[ind], f[ind]);
if (ff2 > ft2)
{
- fprintf(fp, "SHELL %5d, force %10.5f %10.5f %10.5f, |f| %10.5f\n", ind, f[ind][XX],
- f[ind][YY], f[ind][ZZ], std::sqrt(ff2));
+ fprintf(fp,
+ "SHELL %5d, force %10.5f %10.5f %10.5f, |f| %10.5f\n",
+ ind,
+ f[ind][XX],
+ f[ind][YY],
+ f[ind][ZZ],
+ std::sqrt(ff2));
}
}
}
dt = ir->delta_t;
- /* Does NOT work with freeze or acceleration groups (yet) */
+ /* Does NOT work with freeze groups (yet) */
for (n = 0; n < end; n++)
{
w_dt = md->invmass[n] * dt;
bool needsLogging = false;
bool computeEnergy = false;
bool computeVirial = false;
- constr->apply(needsLogging, computeEnergy, step, 0, 1.0, xCurrent,
- shfc->adir_xnold.arrayRefWithPadding(), {}, box, lambda[efptBONDED],
- &(dvdlambda[efptBONDED]), {}, computeVirial, nullptr,
+ constr->apply(needsLogging,
+ computeEnergy,
+ step,
+ 0,
+ 1.0,
+ xCurrent,
+ shfc->adir_xnold.arrayRefWithPadding(),
+ {},
+ box,
+ lambda[efptBONDED],
+ &(dvdlambda[efptBONDED]),
+ {},
+ computeVirial,
+ nullptr,
gmx::ConstraintVariable::Positions);
- constr->apply(needsLogging, computeEnergy, step, 0, 1.0, xCurrent,
- shfc->adir_xnew.arrayRefWithPadding(), {}, box, lambda[efptBONDED],
- &(dvdlambda[efptBONDED]), {}, computeVirial, nullptr,
+ constr->apply(needsLogging,
+ computeEnergy,
+ step,
+ 0,
+ 1.0,
+ xCurrent,
+ shfc->adir_xnew.arrayRefWithPadding(),
+ {},
+ box,
+ lambda[efptBONDED],
+ &(dvdlambda[efptBONDED]),
+ {},
+ computeVirial,
+ nullptr,
gmx::ConstraintVariable::Positions);
for (n = 0; n < end; n++)
}
/* Project the acceleration on the old bond directions */
- constr->apply(needsLogging, computeEnergy, step, 0, 1.0, xOld, shfc->adir_xnew.arrayRefWithPadding(),
- acc_dir, box, lambda[efptBONDED], &(dvdlambda[efptBONDED]), {}, computeVirial,
- nullptr, gmx::ConstraintVariable::Deriv_FlexCon);
+ constr->apply(needsLogging,
+ computeEnergy,
+ step,
+ 0,
+ 1.0,
+ xOld,
+ shfc->adir_xnew.arrayRefWithPadding(),
+ acc_dir,
+ box,
+ lambda[efptBONDED],
+ &(dvdlambda[efptBONDED]),
+ {},
+ computeVirial,
+ nullptr,
+ gmx::ConstraintVariable::Deriv_FlexCon);
}
void relax_shell_flexcon(FILE* fplog,
* before do_force is called, which normally puts all
* charge groups in the box.
*/
- put_atoms_in_box_omp(fr->pbcType, box, x.subArray(0, md->homenr),
- gmx_omp_nthreads_get(emntDefault));
+ put_atoms_in_box_omp(
+ fr->pbcType, box, x.subArray(0, md->homenr), gmx_omp_nthreads_get(emntDefault));
}
if (nflexcon)
}
int shellfc_flags = force_flags | (bVerbose ? GMX_FORCE_ENERGY : 0);
gmx::ForceBuffersView forceViewInit = gmx::ForceBuffersView(forceWithPadding[Min], {}, false);
- do_force(fplog, cr, ms, inputrec, nullptr, enforcedRotation, imdSession, pull_work, mdstep,
- nrnb, wcycle, top, box, xPadded, hist, &forceViewInit, force_vir, md, enerd, lambda,
- fr, runScheduleWork, vsite, mu_tot, t, nullptr,
- (bDoNS ? GMX_FORCE_NS : 0) | shellfc_flags, ddBalanceRegionHandler);
+ do_force(fplog,
+ cr,
+ ms,
+ inputrec,
+ nullptr,
+ enforcedRotation,
+ imdSession,
+ pull_work,
+ mdstep,
+ nrnb,
+ wcycle,
+ top,
+ box,
+ xPadded,
+ hist,
+ &forceViewInit,
+ force_vir,
+ md,
+ enerd,
+ lambda,
+ fr,
+ runScheduleWork,
+ vsite,
+ mu_tot,
+ t,
+ nullptr,
+ (bDoNS ? GMX_FORCE_NS : 0) | shellfc_flags,
+ ddBalanceRegionHandler);
sf_dir = 0;
if (nflexcon)
{
- init_adir(shfc, constr, inputrec, cr, dd_ac1, mdstep, md, end, shfc->x_old.arrayRefWithPadding(),
- x, xPadded, force[Min], shfc->acc_dir, box, lambda, &dum);
+ init_adir(shfc,
+ constr,
+ inputrec,
+ cr,
+ dd_ac1,
+ mdstep,
+ md,
+ end,
+ shfc->x_old.arrayRefWithPadding(),
+ x,
+ xPadded,
+ force[Min],
+ shfc->acc_dir,
+ box,
+ lambda,
+ &dum);
for (i = 0; i < end; i++)
{
* shell positions are updated, therefore the other particles must
* be set here, in advance.
*/
- std::copy(xPadded.paddedArrayRef().begin(), xPadded.paddedArrayRef().end(),
+ std::copy(xPadded.paddedArrayRef().begin(),
+ xPadded.paddedArrayRef().end(),
posWithPadding[Min].paddedArrayRef().begin());
- std::copy(xPadded.paddedArrayRef().begin(), xPadded.paddedArrayRef().end(),
+ std::copy(xPadded.paddedArrayRef().begin(),
+ xPadded.paddedArrayRef().end(),
posWithPadding[Try].paddedArrayRef().begin());
}
if (nflexcon)
{
- init_adir(shfc, constr, inputrec, cr, dd_ac1, mdstep, md, end,
- shfc->x_old.arrayRefWithPadding(), x, posWithPadding[Min], force[Min],
- shfc->acc_dir, box, lambda, &dum);
+ init_adir(shfc,
+ constr,
+ inputrec,
+ cr,
+ dd_ac1,
+ mdstep,
+ md,
+ end,
+ shfc->x_old.arrayRefWithPadding(),
+ x,
+ posWithPadding[Min],
+ force[Min],
+ shfc->acc_dir,
+ box,
+ lambda,
+ &dum);
directional_sd(pos[Min], pos[Try], shfc->acc_dir, end, fr->fc_stepsize);
}
}
/* Try the new positions */
gmx::ForceBuffersView forceViewTry = gmx::ForceBuffersView(forceWithPadding[Try], {}, false);
- do_force(fplog, cr, ms, inputrec, nullptr, enforcedRotation, imdSession, pull_work, 1, nrnb, wcycle,
- top, box, posWithPadding[Try], hist, &forceViewTry, force_vir, md, enerd, lambda, fr,
- runScheduleWork, vsite, mu_tot, t, nullptr, shellfc_flags, ddBalanceRegionHandler);
+ do_force(fplog,
+ cr,
+ ms,
+ inputrec,
+ nullptr,
+ enforcedRotation,
+ imdSession,
+ pull_work,
+ 1,
+ nrnb,
+ wcycle,
+ top,
+ box,
+ posWithPadding[Try],
+ hist,
+ &forceViewTry,
+ force_vir,
+ md,
+ enerd,
+ lambda,
+ fr,
+ runScheduleWork,
+ vsite,
+ mu_tot,
+ t,
+ nullptr,
+ shellfc_flags,
+ ddBalanceRegionHandler);
accumulatePotentialEnergies(enerd, lambda, inputrec->fepvals);
if (gmx_debug_at)
{
sf_dir = 0;
if (nflexcon)
{
- init_adir(shfc, constr, inputrec, cr, dd_ac1, mdstep, md, end,
- shfc->x_old.arrayRefWithPadding(), x, posWithPadding[Try], force[Try],
- shfc->acc_dir, box, lambda, &dum);
+ init_adir(shfc,
+ constr,
+ inputrec,
+ cr,
+ dd_ac1,
+ mdstep,
+ md,
+ end,
+ shfc->x_old.arrayRefWithPadding(),
+ x,
+ posWithPadding[Try],
+ force[Try],
+ shfc->acc_dir,
+ box,
+ lambda,
+ &dum);
ArrayRef<const RVec> acc_dir = shfc->acc_dir;
for (i = 0; i < end; i++)
/* Note that the energies and virial are incorrect when not converged */
if (fplog)
{
- fprintf(fplog, "step %s: EM did not converge in %d iterations, RMS force %6.2e\n",
- gmx_step_str(mdstep, sbuf), number_steps, df[Min]);
+ fprintf(fplog,
+ "step %s: EM did not converge in %d iterations, RMS force %6.2e\n",
+ gmx_step_str(mdstep, sbuf),
+ number_steps,
+ df[Min]);
}
- fprintf(stderr, "step %s: EM did not converge in %d iterations, RMS force %6.2e\n",
- gmx_step_str(mdstep, sbuf), number_steps, df[Min]);
+ fprintf(stderr,
+ "step %s: EM did not converge in %d iterations, RMS force %6.2e\n",
+ gmx_step_str(mdstep, sbuf),
+ number_steps,
+ df[Min]);
}
/* Copy back the coordinates and the forces */
if (shfc && fplog && numSteps > 0)
{
double numStepsAsDouble = static_cast<double>(numSteps);
- fprintf(fplog, "Fraction of iterations that converged: %.2f %%\n",
+ fprintf(fplog,
+ "Fraction of iterations that converged: %.2f %%\n",
(shfc->numConvergedIterations * 100.0) / numStepsAsDouble);
- fprintf(fplog, "Average number of force evaluations per MD step: %.2f\n\n",
+ fprintf(fplog,
+ "Average number of force evaluations per MD step: %.2f\n\n",
shfc->numForceEvaluations / numStepsAsDouble);
}
t_inputrec* inputRecord,
gmx_mtop_t* molecularTopology)
{
- *partialDeserializedTpr = read_tpx_state(simulationInput.tprFilename_.c_str(), inputRecord,
- globalState, molecularTopology);
+ *partialDeserializedTpr = read_tpx_state(
+ simulationInput.tprFilename_.c_str(), inputRecord, globalState, molecularTopology);
}
void applyLocalState(const SimulationInput& simulationInput,
gmx::ReadCheckpointDataHolder* modularSimulatorCheckpointData,
const bool useModularSimulator)
{
- load_checkpoint(simulationInput.cpiFilename_.c_str(), logfio, cr, dd_nc, inputRecord, state,
- observablesHistory, reproducibilityRequested, mdModulesNotifier,
- modularSimulatorCheckpointData, useModularSimulator);
+ load_checkpoint(simulationInput.cpiFilename_.c_str(),
+ logfio,
+ cr,
+ dd_nc,
+ inputRecord,
+ state,
+ observablesHistory,
+ reproducibilityRequested,
+ mdModulesNotifier,
+ modularSimulatorCheckpointData,
+ useModularSimulator);
}
} // end namespace gmx
{
// NOLINTNEXTLINE(modernize-make-unique): make_unique does not work with private constructor
return std::unique_ptr<ModularSimulator>(new ModularSimulator(
- std::make_unique<LegacySimulatorData>(
- simulatorEnv_->fplog_, simulatorEnv_->commRec_, simulatorEnv_->multisimCommRec_,
- simulatorEnv_->logger_, legacyInput_->numFile, legacyInput_->filenames,
- simulatorEnv_->outputEnv_, simulatorConfig_->mdrunOptions_,
- simulatorConfig_->startingBehavior_, constraintsParam_->vsite,
- constraintsParam_->constr, constraintsParam_->enforcedRotation,
- boxDeformation_->deform, simulatorModules_->outputProvider,
- simulatorModules_->mdModulesNotifier, legacyInput_->inputrec,
- interactiveMD_->imdSession, centerOfMassPulling_->pull_work, ionSwapping_->ionSwap,
- topologyData_->top_global, simulatorStateData_->globalState_p,
- simulatorStateData_->observablesHistory_p, topologyData_->mdAtoms,
- profiling_->nrnb, profiling_->wallCycle, legacyInput_->forceRec,
- simulatorStateData_->enerdata_p, simulatorStateData_->ekindata_p,
- simulatorConfig_->runScheduleWork_, *replicaExchangeParameters_,
- membedHolder_->membed(), profiling_->walltimeAccounting,
- std::move(stopHandlerBuilder_), simulatorConfig_->mdrunOptions_.rerun),
+ std::make_unique<LegacySimulatorData>(simulatorEnv_->fplog_,
+ simulatorEnv_->commRec_,
+ simulatorEnv_->multisimCommRec_,
+ simulatorEnv_->logger_,
+ legacyInput_->numFile,
+ legacyInput_->filenames,
+ simulatorEnv_->outputEnv_,
+ simulatorConfig_->mdrunOptions_,
+ simulatorConfig_->startingBehavior_,
+ constraintsParam_->vsite,
+ constraintsParam_->constr,
+ constraintsParam_->enforcedRotation,
+ boxDeformation_->deform,
+ simulatorModules_->outputProvider,
+ simulatorModules_->mdModulesNotifier,
+ legacyInput_->inputrec,
+ interactiveMD_->imdSession,
+ centerOfMassPulling_->pull_work,
+ ionSwapping_->ionSwap,
+ topologyData_->top_global,
+ simulatorStateData_->globalState_p,
+ simulatorStateData_->observablesHistory_p,
+ topologyData_->mdAtoms,
+ profiling_->nrnb,
+ profiling_->wallCycle,
+ legacyInput_->forceRec,
+ simulatorStateData_->enerdata_p,
+ simulatorStateData_->ekindata_p,
+ simulatorConfig_->runScheduleWork_,
+ *replicaExchangeParameters_,
+ membedHolder_->membed(),
+ profiling_->walltimeAccounting,
+ std::move(stopHandlerBuilder_),
+ simulatorConfig_->mdrunOptions_.rerun),
std::move(modularSimulatorCheckpointData_)));
}
// NOLINTNEXTLINE(modernize-make-unique): make_unique does not work with private constructor
- return std::unique_ptr<LegacySimulator>(new LegacySimulator(
- simulatorEnv_->fplog_, simulatorEnv_->commRec_, simulatorEnv_->multisimCommRec_,
- simulatorEnv_->logger_, legacyInput_->numFile, legacyInput_->filenames,
- simulatorEnv_->outputEnv_, simulatorConfig_->mdrunOptions_,
- simulatorConfig_->startingBehavior_, constraintsParam_->vsite,
- constraintsParam_->constr, constraintsParam_->enforcedRotation, boxDeformation_->deform,
- simulatorModules_->outputProvider, simulatorModules_->mdModulesNotifier,
- legacyInput_->inputrec, interactiveMD_->imdSession, centerOfMassPulling_->pull_work,
- ionSwapping_->ionSwap, topologyData_->top_global, simulatorStateData_->globalState_p,
- simulatorStateData_->observablesHistory_p, topologyData_->mdAtoms, profiling_->nrnb,
- profiling_->wallCycle, legacyInput_->forceRec, simulatorStateData_->enerdata_p,
- simulatorStateData_->ekindata_p, simulatorConfig_->runScheduleWork_,
- *replicaExchangeParameters_, membedHolder_->membed(), profiling_->walltimeAccounting,
- std::move(stopHandlerBuilder_), simulatorConfig_->mdrunOptions_.rerun));
+ return std::unique_ptr<LegacySimulator>(new LegacySimulator(simulatorEnv_->fplog_,
+ simulatorEnv_->commRec_,
+ simulatorEnv_->multisimCommRec_,
+ simulatorEnv_->logger_,
+ legacyInput_->numFile,
+ legacyInput_->filenames,
+ simulatorEnv_->outputEnv_,
+ simulatorConfig_->mdrunOptions_,
+ simulatorConfig_->startingBehavior_,
+ constraintsParam_->vsite,
+ constraintsParam_->constr,
+ constraintsParam_->enforcedRotation,
+ boxDeformation_->deform,
+ simulatorModules_->outputProvider,
+ simulatorModules_->mdModulesNotifier,
+ legacyInput_->inputrec,
+ interactiveMD_->imdSession,
+ centerOfMassPulling_->pull_work,
+ ionSwapping_->ionSwap,
+ topologyData_->top_global,
+ simulatorStateData_->globalState_p,
+ simulatorStateData_->observablesHistory_p,
+ topologyData_->mdAtoms,
+ profiling_->nrnb,
+ profiling_->wallCycle,
+ legacyInput_->forceRec,
+ simulatorStateData_->enerdata_p,
+ simulatorStateData_->ekindata_p,
+ simulatorConfig_->runScheduleWork_,
+ *replicaExchangeParameters_,
+ membedHolder_->membed(),
+ profiling_->walltimeAccounting,
+ std::move(stopHandlerBuilder_),
+ simulatorConfig_->mdrunOptions_.rerun));
}
void SimulatorBuilder::add(MembedHolder&& membedHolder)
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
if (fplog)
{
- fprintf(fplog, "\nWill insert %d atoms %s partial charges\n", a_tp1 - a_tp0,
- bCharge ? "with" : "without");
+ fprintf(fplog, "\nWill insert %d atoms %s partial charges\n", a_tp1 - a_tp0, bCharge ? "with" : "without");
- fprintf(fplog, "\nWill insert %" PRId64 " times in each frame of %s\n", nsteps,
+ fprintf(fplog,
+ "\nWill insert %" PRId64 " times in each frame of %s\n",
+ nsteps,
opt2fn("-rerun", nfile, fnm));
}
gmx_fatal(FARGS,
"Re-using the neighborlist %d times for insertions of a single atom in a "
"sphere of radius %f does not make sense",
- inputrec->nstlist, drmax);
+ inputrec->nstlist,
+ drmax);
}
if (fplog)
{
fprintf(fplog,
"Will use the same neighborlist for %d insertions in a sphere of radius "
"%f\n",
- inputrec->nstlist, drmax);
+ inputrec->nstlist,
+ drmax);
}
}
}
* inserted atoms located in the center of the sphere, so we need
* a buffer of size of the sphere and molecule radius.
*/
- inputrec->rlist = maxCutoff + 2 * inputrec->rtpi + 2 * molRadius;
- fr->rlist = inputrec->rlist;
+ {
+ // TODO: Avoid changing inputrec (#3854)
+ auto* nonConstInputrec = const_cast<t_inputrec*>(inputrec);
+ nonConstInputrec->rlist = maxCutoff + 2 * inputrec->rtpi + 2 * molRadius;
+ }
+ fr->rlist = inputrec->rlist;
fr->nbv->changePairlistRadii(inputrec->rlist, inputrec->rlist);
ngid = groups->groups[SimulationAtomGroupType::EnergyOutput].size();
if (MASTER(cr))
{
- fp_tpi = xvgropen(opt2fn("-tpi", nfile, fnm), "TPI energies", "Time (ps)",
- "(kJ mol\\S-1\\N) / (nm\\S3\\N)", oenv);
+ fp_tpi = xvgropen(opt2fn("-tpi", nfile, fnm),
+ "TPI energies",
+ "Time (ps)",
+ "(kJ mol\\S-1\\N) / (nm\\S3\\N)",
+ oenv);
xvgr_subtitle(fp_tpi, "f. are averages over one frame", oenv);
snew(leg, 4 + nener);
e = 0;
leg[e++] = gmx_strdup(str);
for (i = 0; i < ngid; i++)
{
- sprintf(str, "f. <U\\sVdW %s\\Ne\\S-\\betaU\\N>",
+ sprintf(str,
+ "f. <U\\sVdW %s\\Ne\\S-\\betaU\\N>",
*(groups->groupNames[groups->groups[SimulationAtomGroupType::EnergyOutput][i]]));
leg[e++] = gmx_strdup(str);
}
{
for (i = 0; i < ngid; i++)
{
- sprintf(str, "f. <U\\sCoul %s\\Ne\\S-\\betaU\\N>",
+ sprintf(str,
+ "f. <U\\sCoul %s\\Ne\\S-\\betaU\\N>",
*(groups->groupNames[groups->groups[SimulationAtomGroupType::EnergyOutput][i]]));
leg[e++] = gmx_strdup(str);
}
"Number of atoms in trajectory (%d)%s "
"is not equal the number in the run input file (%d) "
"minus the number of atoms to insert (%d)\n",
- rerun_fr.natoms, bCavity ? " minus one" : "", mdatoms->nr, a_tp1 - a_tp0);
+ rerun_fr.natoms,
+ bCavity ? " minus one" : "",
+ mdatoms->nr,
+ a_tp1 - a_tp0);
}
refvolshift = log(det(rerun_fr.box));
/* Put all atoms except for the inserted ones on the grid */
rvec vzero = { 0, 0, 0 };
rvec boxDiagonal = { box[XX][XX], box[YY][YY], box[ZZ][ZZ] };
- nbnxn_put_on_grid(fr->nbv.get(), box, 0, vzero, boxDiagonal, nullptr, { 0, a_tp0 }, -1,
- fr->cginfo, x, 0, nullptr);
+ nbnxn_put_on_grid(
+ fr->nbv.get(), box, 0, vzero, boxDiagonal, nullptr, { 0, a_tp0 }, -1, fr->cginfo, x, 0, nullptr);
step = cr->nodeid * stepblocksize;
while (step < nsteps)
}
/* Put the inserted molecule on it's own search grid */
- nbnxn_put_on_grid(fr->nbv.get(), box, 1, x_init, x_init, nullptr, { a_tp0, a_tp1 },
- -1, fr->cginfo, x, 0, nullptr);
+ nbnxn_put_on_grid(
+ fr->nbv.get(), box, 1, x_init, x_init, nullptr, { a_tp0, a_tp1 }, -1, fr->cginfo, x, 0, nullptr);
/* TODO: Avoid updating all atoms at every bNS step */
fr->nbv->setAtomProperties(gmx::constArrayRefFromArray(mdatoms->typeA, mdatoms->nr),
real angleX = 2 * M_PI * dist(rng);
real angleY = 2 * M_PI * dist(rng);
real angleZ = 2 * M_PI * dist(rng);
- rotate_conf(a_tp1 - a_tp0, state_global->x.rvec_array() + a_tp0, nullptr, angleX,
- angleY, angleZ);
+ rotate_conf(a_tp1 - a_tp0, state_global->x.rvec_array() + a_tp0, nullptr, angleX, angleY, angleZ);
/* Shift to the insertion location */
for (i = a_tp0; i < a_tp1; i++)
{
// might raise, then restore the old behaviour.
std::fenv_t floatingPointEnvironment;
std::feholdexcept(&floatingPointEnvironment);
- do_force(fplog, cr, ms, inputrec, nullptr, nullptr, imdSession, pull_work, step, nrnb,
- wcycle, &top, state_global->box, state_global->x.arrayRefWithPadding(),
- &state_global->hist, &f.view(), force_vir, mdatoms, enerd,
- state_global->lambda, fr, runScheduleWork, nullptr, mu_tot, t, nullptr,
+ do_force(fplog,
+ cr,
+ ms,
+ inputrec,
+ nullptr,
+ nullptr,
+ imdSession,
+ pull_work,
+ step,
+ nrnb,
+ wcycle,
+ &top,
+ state_global->box,
+ state_global->x.arrayRefWithPadding(),
+ &state_global->hist,
+ &f.view(),
+ force_vir,
+ mdatoms,
+ enerd,
+ state_global->lambda,
+ fr,
+ runScheduleWork,
+ nullptr,
+ mu_tot,
+ t,
+ nullptr,
GMX_FORCE_NONBONDED | GMX_FORCE_ENERGY | (bStateChanged ? GMX_FORCE_STATECHANGED : 0),
DDBalanceRegionHandler(nullptr));
std::feclearexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
if (debug)
{
fprintf(debug,
- "\n time %.3f, step %d: non-finite energy %f, using exp(-bU)=0\n", t,
- static_cast<int>(step), epot);
+ "\n time %.3f, step %d: non-finite energy %f, using exp(-bU)=0\n",
+ t,
+ static_cast<int>(step),
+ epot);
}
embU = 0;
}
if (debug)
{
- fprintf(debug, "TPI %7d %12.5e %12.5f %12.5f %12.5f\n", static_cast<int>(step),
- epot, x_tp[XX], x_tp[YY], x_tp[ZZ]);
+ fprintf(debug,
+ "TPI %7d %12.5e %12.5f %12.5f %12.5f\n",
+ static_cast<int>(step),
+ epot,
+ x_tp[XX],
+ x_tp[YY],
+ x_tp[ZZ]);
}
if (dump_pdb && epot <= dump_ener)
{
sprintf(str, "t%g_step%d.pdb", t, static_cast<int>(step));
sprintf(str2, "t: %f step %d ener: %f", t, static_cast<int>(step), epot);
- write_sto_conf_mtop(str, str2, top_global, state_global->x.rvec_array(),
- state_global->v.rvec_array(), inputrec->pbcType, state_global->box);
+ write_sto_conf_mtop(str,
+ str2,
+ top_global,
+ state_global->x.rvec_array(),
+ state_global->v.rvec_array(),
+ inputrec->pbcType,
+ state_global->box);
}
step++;
{
if (mdrunOptions.verbose || frame % 10 == 0 || frame < 10)
{
- fprintf(stderr, "mu %10.3e <mu> %10.3e\n", -log(sum_embU / nsteps) / beta,
+ fprintf(stderr,
+ "mu %10.3e <mu> %10.3e\n",
+ -log(sum_embU / nsteps) / beta,
-log(VembU_all / V_all) / beta);
}
- fprintf(fp_tpi, "%10.3f %12.5e %12.5e %12.5e %12.5e", t,
+ fprintf(fp_tpi,
+ "%10.3f %12.5e %12.5e %12.5e %12.5e",
+ t,
VembU_all == 0 ? 20 / beta : -log(VembU_all / V_all) / beta,
- sum_embU == 0 ? 20 / beta : -log(sum_embU / nsteps) / beta, sum_embU / nsteps, V);
+ sum_embU == 0 ? 20 / beta : -log(sum_embU / nsteps) / beta,
+ sum_embU / nsteps,
+ V);
for (e = 0; e < nener; e++)
{
fprintf(fp_tpi, " %12.5e", sum_UgembU[e] / nsteps);
}
if (MASTER(cr))
{
- fp_tpi = xvgropen(opt2fn("-tpid", nfile, fnm), "TPI energy distribution",
- "\\betaU - log(V/<V>)", "count", oenv);
+ fp_tpi = xvgropen(opt2fn("-tpid", nfile, fnm),
+ "TPI energy distribution",
+ "\\betaU - log(V/<V>)",
+ "count",
+ oenv);
sprintf(str, "number \\betaU > %g: %9.3e", bU_bin_limit, bin[0]);
xvgr_subtitle(fp_tpi, str, oenv);
xvgr_legend(fp_tpi, 2, tpid_leg, oenv);
for (i = nbin - 1; i > 0; i--)
{
bUlogV = -i / invbinw + bU_logV_bin_limit - refvolshift + log(V_all / frame);
- fprintf(fp_tpi, "%6.2f %10d %12.5e\n", bUlogV, roundToInt(bin[i]),
- bin[i] * exp(-bUlogV) * V_all / VembU_all);
+ fprintf(fp_tpi, "%6.2f %10d %12.5e\n", bUlogV, roundToInt(bin[i]), bin[i] * exp(-bUlogV) * V_all / VembU_all);
}
xvgrclose(fp_tpi);
}
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2015,2016,2019, by the GROMACS development team, led by
+# Copyright (c) 2015,2016,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.
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+add_library(mdrunutility INTERFACE)
gmx_add_libgromacs_sources(
handlerestart.cpp
logging.cpp
threadaffinity.cpp
)
+# Source files have the following private module dependencies.
+target_link_libraries(mdrunutility PRIVATE
+# gmxlib
+# math
+# mdtypes
+# tng_io
+ )
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(mdrunutility PUBLIC
+target_include_directories(mdrunutility INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(mdrunutility PUBLIC
+target_link_libraries(mdrunutility INTERFACE
+ legacy_api
+ )
+
+# TODO: when mdrunutility is an OBJECT target
+#target_link_libraries(mdrunutility PUBLIC legacy_api)
+#target_link_libraries(mdrunutility PRIVATE common)
+
+# Module dependencies
+# mdrunutility interfaces convey transitive dependence on these modules.
+#target_link_libraries(mdrunutility PUBLIC
+target_link_libraries(mdrunutility INTERFACE
+ utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(mdrunutility PRIVATE tng_io)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(mdrunutility PRIVATE legacy_modules)
+
if (BUILD_TESTING)
add_subdirectory(tests)
endif()
"part), or instruct mdrun to write new output files with mdrun -noappend. In "
"the last case, you will not be able to use appending in future for this "
"simulation.",
- numFilesMissing, outputfiles.size());
+ numFilesMissing,
+ outputfiles.size());
GMX_THROW(InconsistentInputError(stream.toString()));
}
GMX_RELEASE_ASSERT(Path::extensionMatches(logFilename, ftp2ext(efLOG)),
formatString("The checkpoint file or its reading is broken, the first "
"output file '%s' must be a log file with extension '%s'",
- logFilename, ftp2ext(efLOG))
+ logFilename,
+ ftp2ext(efLOG))
.c_str());
if (appendingBehavior != AppendingBehavior::NoAppending)
"Cannot restart with appending because the previous simulation part used "
"%s precision which does not match the %s precision used by this build "
"of GROMACS. Either use matching precision or use mdrun -noappend.",
- precisionToString(headerContents.double_prec), precisionToString(GMX_DOUBLE))));
+ precisionToString(headerContents.double_prec),
+ precisionToString(GMX_DOUBLE))));
}
}
// If the previous log filename had a part number, then we
"Can't read %d bytes of '%s' to compute checksum. The file "
"has been replaced or its contents have been modified. Cannot "
"do appending because of this condition.",
- outputfile.checksumSize, outputfile.filename);
+ outputfile.checksumSize,
+ outputfile.filename);
GMX_THROW(InconsistentInputError(message));
}
}
auto startingBehaviors = gatherIntFromMultiSimulation(ms, static_cast<int>(startingBehavior));
bool identicalStartingBehaviors =
- (std::adjacent_find(std::begin(startingBehaviors), std::end(startingBehaviors),
- std::not_equal_to<>())
+ (std::adjacent_find(
+ std::begin(startingBehaviors), std::end(startingBehaviors), std::not_equal_to<>())
== std::end(startingBehaviors));
const EnumerationArray<StartingBehavior, std::string> behaviorStrings = {
for (index simIndex = 0; simIndex != ssize(startingBehaviors); ++simIndex)
{
auto behavior = static_cast<StartingBehavior>(startingBehaviors[simIndex]);
- message += formatString(" Simulation %6zd: %s\n", simIndex,
- behaviorStrings[behavior].c_str());
+ message += formatString(
+ " Simulation %6zd: %s\n", simIndex, behaviorStrings[behavior].c_str());
}
GMX_THROW(InconsistentInputError(message));
}
// describes the same simulation part. If those don't match, then
// the simulation cannot proceed.
auto simulationParts = gatherIntFromMultiSimulation(ms, headerContents->simulation_part);
- bool identicalSimulationParts = (std::adjacent_find(std::begin(simulationParts),
- std::end(simulationParts), std::not_equal_to<>())
- == std::end(simulationParts));
+ bool identicalSimulationParts =
+ (std::adjacent_find(
+ std::begin(simulationParts), std::end(simulationParts), std::not_equal_to<>())
+ == std::end(simulationParts));
if (!identicalSimulationParts)
{
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
{
auto message = gmx::formatString(
"The number of ranks (%d) is not a multiple of the number of simulations (%td)",
- numRanks, multidirs.ssize());
+ numRanks,
+ multidirs.ssize());
GMX_THROW(gmx::InconsistentInputError(message));
}
if (debug)
{
- fprintf(debug, "We have %td simulations, %d ranks per simulation, local simulation is %d\n",
- multidirs.ssize(), numRanksPerSimulation, rankWithinWorldComm / numRanksPerSimulation);
+ fprintf(debug,
+ "We have %td simulations, %d ranks per simulation, local simulation is %d\n",
+ multidirs.ssize(),
+ numRanksPerSimulation,
+ rankWithinWorldComm / numRanksPerSimulation);
}
int numSimulations = multidirs.size();
#if GMX_MPI
static void gmx_sumd_comm(int nr, double r[], MPI_Comm mpi_comm)
{
-# if MPI_IN_PLACE_EXISTS
MPI_Allreduce(MPI_IN_PLACE, r, nr, MPI_DOUBLE, MPI_SUM, mpi_comm);
-# else
- /* this function is only used in code that is not performance critical,
- (during setup, when comm_rec is not the appropriate communication
- structure), so this isn't as bad as it looks. */
- double* buf;
- int i;
-
- snew(buf, nr);
- MPI_Allreduce(r, buf, nr, MPI_DOUBLE, MPI_SUM, mpi_comm);
- for (i = 0; i < nr; i++)
- {
- r[i] = buf[i];
- }
- sfree(buf);
-# endif
}
#endif
#if GMX_MPI
static void gmx_sumf_comm(int nr, float r[], MPI_Comm mpi_comm)
{
-# if MPI_IN_PLACE_EXISTS
MPI_Allreduce(MPI_IN_PLACE, r, nr, MPI_FLOAT, MPI_SUM, mpi_comm);
-# else
- /* this function is only used in code that is not performance critical,
- (during setup, when comm_rec is not the appropriate communication
- structure), so this isn't as bad as it looks. */
- float* buf;
- int i;
-
- snew(buf, nr);
- MPI_Allreduce(r, buf, nr, MPI_FLOAT, MPI_SUM, mpi_comm);
- for (i = 0; i < nr; i++)
- {
- r[i] = buf[i];
- }
- sfree(buf);
-# endif
}
#endif
#if !GMX_MPI
GMX_RELEASE_ASSERT(false, "Invalid call to gmx_sumi_sim");
#else
-# if MPI_IN_PLACE_EXISTS
MPI_Allreduce(MPI_IN_PLACE, r, nr, MPI_INT, MPI_SUM, ms->mastersComm_);
-# else
- /* this is thread-unsafe, but it will do for now: */
- ms->intBuffer.resize(nr);
- MPI_Allreduce(r, ms->intBuffer.data(), ms->intBuffer.size(), MPI_INT, MPI_SUM, ms->mastersComm_);
- std::copy(std::begin(ms->intBuffer), std::end(ms->intBuffer), r);
-# endif
#endif
}
#if !GMX_MPI
GMX_RELEASE_ASSERT(false, "Invalid call to gmx_sumli_sim");
#else
-# if MPI_IN_PLACE_EXISTS
MPI_Allreduce(MPI_IN_PLACE, r, nr, MPI_INT64_T, MPI_SUM, ms->mastersComm_);
-# else
- /* this is thread-unsafe, but it will do for now: */
- ms->int64Buffer.resize(nr);
- MPI_Allreduce(r, ms->int64Buffer.data(), ms->int64Buffer.size(), MPI_INT64_T, MPI_SUM, ms->mastersComm_);
- std::copy(std::begin(ms->int64Buffer), std::end(ms->int64Buffer), r);
-# endif
#endif
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
MPI_Comm mastersComm_ = MPI_COMM_NULL;
//! The MPI communicator between ranks of this simulation.
MPI_Comm simulationComm_ = MPI_COMM_NULL;
- /*! \brief Communication buffers needed if MPI_IN_PLACE isn't supported
- *
- * Other types could be added as needed.
- *
- * These vectors are unused when MPI_IN_PLACE is available
- * and could be removed with preprocessing (or perhaps
- * templating) or simply requiring MPI 2.0 (the standard
- * introduced in 1997). However, the additional cache pressure
- * introduced by the extra size of this type is not of great
- * concern, since we have at most one per MPI rank.
- * See issue #3591. */
- //! \{
- std::vector<int> intBuffer_;
- std::vector<int64_t> int64Buffer_;
- //! \}
};
//! Calculate the sum over the simulations of an array of ints
char buf[STRLEN];
sprintf(buf, "Started %s", name);
- print_date_and_time(fplog, cr->nodeid, buf,
- walltime_accounting_get_start_time_stamp(walltime_accounting));
+ print_date_and_time(
+ fplog, cr->nodeid, buf, walltime_accounting_get_start_time_stamp(walltime_accounting));
}
gmx_add_unit_test_library(mdrunutility-test-shared
threadaffinitytest.cpp)
+target_link_libraries(mdrunutility-test-shared PRIVATE common)
+target_link_libraries(mdrunutility-test-shared PUBLIC legacy_api)
gmx_add_unit_test(MdrunUtilityUnitTests mdrunutility-test
CPP_SOURCE_FILES
}
void expectPinningMessage(bool userSpecifiedStride, int stride)
{
- std::string pattern = formatString("Pinning threads .* %s.* stride of %d",
- userSpecifiedStride ? "user" : "auto", stride);
+ std::string pattern = formatString(
+ "Pinning threads .* %s.* stride of %d", userSpecifiedStride ? "user" : "auto", stride);
expectInfoMatchingRegex(pattern.c_str());
}
void expectLogMessageMatchingRegexIf(MDLogger::LogLevel level, const char* re, bool condition)
}
gmx::PhysicalNodeCommunicator comm(MPI_COMM_WORLD, physicalNodeId_);
int numThreadsOnThisNode, indexWithinNodeOfFirstThreadOnThisRank;
- analyzeThreadsOnThisNode(comm, numThreadsOnThisRank, &numThreadsOnThisNode,
- &indexWithinNodeOfFirstThreadOnThisRank);
- gmx_set_thread_affinity(logHelper_.logger(), cr_, &hwOpt_, *hwTop_, numThreadsOnThisRank,
- numThreadsOnThisNode, indexWithinNodeOfFirstThreadOnThisRank,
+ analyzeThreadsOnThisNode(
+ comm, numThreadsOnThisRank, &numThreadsOnThisNode, &indexWithinNodeOfFirstThreadOnThisRank);
+ gmx_set_thread_affinity(logHelper_.logger(),
+ cr_,
+ &hwOpt_,
+ *hwTop_,
+ numThreadsOnThisRank,
+ numThreadsOnThisNode,
+ indexWithinNodeOfFirstThreadOnThisRank,
&affinityAccess_);
}
{
GMX_LOG(mdlog.info)
.appendTextFormatted("Pinning threads with a%s logical core stride of %d",
- bPickPinStride ? "n auto-selected" : " user-specified", *pin_stride);
+ bPickPinStride ? "n auto-selected" : " user-specified",
+ *pin_stride);
}
*issuedWarning = alreadyWarned;
fprintf(debug,
"On rank %2d, thread %2d, index %2d, core %2d the affinity setting "
"returned %d\n",
- cr->nodeid, gmx_omp_get_thread_num(), index, core, ret ? 1 : 0);
+ cr->nodeid,
+ gmx_omp_get_thread_num(),
+ index,
+ core,
+ ret ? 1 : 0);
}
}
GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
sprintf(msg,
"Looks like we have set affinity for more threads than "
"we have (%d > %d)!\n",
- nth_affinity_set, nthread_local);
+ nth_affinity_set,
+ nthread_local);
gmx_incons(msg);
}
if (nthread_local > 1)
{
- sprintf(sbuf2, "for %d/%d thread%s ", nthread_local - nth_affinity_set, nthread_local,
+ sprintf(sbuf2,
+ "for %d/%d thread%s ",
+ nthread_local - nth_affinity_set,
+ nthread_local,
nthread_local > 1 ? "s" : "");
}
/* MPI_Scan is inclusive, but here we need exclusive */
*intraNodeThreadOffset -= numThreadsOnThisRank;
/* Get the total number of threads on this physical node */
- MPI_Allreduce(&numThreadsOnThisRank, numThreadsOnThisNode, 1, MPI_INT, MPI_SUM,
- physicalNodeComm.comm_);
+ MPI_Allreduce(
+ &numThreadsOnThisRank, numThreadsOnThisNode, 1, MPI_INT, MPI_SUM, physicalNodeComm.comm_);
}
#else
GMX_UNUSED_VALUE(physicalNodeComm);
bool affinityIsAutoAndNumThreadsIsNotAuto =
(hw_opt->threadAffinity == ThreadAffinity::Auto && !hw_opt->totNumThreadsIsAuto);
- bool issuedWarning;
- bool validLayout = get_thread_affinity_layout(
- mdlog, cr, hwTop, numThreadsOnThisNode, affinityIsAutoAndNumThreadsIsNotAuto, offset,
- &core_pinning_stride, &localityOrder, &issuedWarning);
+ bool issuedWarning;
+ bool validLayout = get_thread_affinity_layout(mdlog,
+ cr,
+ hwTop,
+ numThreadsOnThisNode,
+ affinityIsAutoAndNumThreadsIsNotAuto,
+ offset,
+ &core_pinning_stride,
+ &localityOrder,
+ &issuedWarning);
const gmx::sfree_guard localityOrderGuard(localityOrder);
bool allAffinitiesSet;
if (validLayout)
{
- allAffinitiesSet = set_affinity(cr, numThreadsOnThisRank, intraNodeThreadOffset, offset,
- core_pinning_stride, localityOrder, affinityAccess);
+ allAffinitiesSet = set_affinity(
+ cr, numThreadsOnThisRank, intraNodeThreadOffset, offset, core_pinning_stride, localityOrder, affinityAccess);
}
else
{
{
if (debug)
{
- fprintf(debug, "%d hardware threads detected, but %d was returned by CPU_COUNT",
- nthreads_hw_avail, CPU_COUNT(&mask_current));
+ fprintf(debug,
+ "%d hardware threads detected, but %d was returned by CPU_COUNT",
+ nthreads_hw_avail,
+ CPU_COUNT(&mask_current));
}
detectedDefaultAffinityMask = false;
}
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2018, by the GROMACS development team, led by
+# Copyright (c) 2018,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.
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+# Set up the module library
+add_library(mdspan INTERFACE)
+
+# Public interface for modules, including dependencies and interfaces
+target_include_directories(mdspan INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+
if (BUILD_TESTING)
add_subdirectory(tests)
endif()
constexpr BasicMdspan addElementwise(const BasicMdspan& span1, const BasicMdspan& span2)
{
BasicMdspan result(span1);
- std::transform(begin(span1), end(span1), begin(span2), begin(result),
+ std::transform(begin(span1),
+ end(span1),
+ begin(span2),
+ begin(result),
std::plus<typename BasicMdspan::element_type>());
return result;
}
constexpr BasicMdspan subtractElementwise(const BasicMdspan& span1, const BasicMdspan& span2)
{
BasicMdspan result(span1);
- std::transform(begin(span1), end(span1), begin(span2), begin(result),
+ std::transform(begin(span1),
+ end(span1),
+ begin(span2),
+ begin(result),
std::minus<typename BasicMdspan::element_type>());
return result;
}
constexpr BasicMdspan multiplyElementwise(const BasicMdspan& span1, const BasicMdspan& span2)
{
BasicMdspan result(span1);
- std::transform(begin(span1), end(span1), begin(span2), begin(result),
+ std::transform(begin(span1),
+ end(span1),
+ begin(span2),
+ begin(result),
std::multiplies<typename BasicMdspan::element_type>());
return result;
}
constexpr BasicMdspan divideElementwise(const BasicMdspan& span1, const BasicMdspan& span2)
{
BasicMdspan result(span1);
- std::transform(begin(span1), end(span1), begin(span2), begin(result),
+ std::transform(begin(span1),
+ end(span1),
+ begin(span2),
+ begin(result),
std::divides<typename BasicMdspan::element_type>());
return result;
}
layouts.cpp
mdspan.cpp
)
+target_link_libraries(mdspan-test PRIVATE mdspan)
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
bool contiguous,
bool strided)
{
- check_properties_internal(my_mdspan_mapping, always_unique, always_contiguous,
- always_strided, unique, contiguous, strided);
- check_properties_internal(my_mdspan_map_acc, always_unique, always_contiguous,
- always_strided, unique, contiguous, strided);
- check_properties_internal(my_mdspan_extents, always_unique, always_contiguous,
- always_strided, unique, contiguous, strided);
- check_properties_internal(my_mdspan_copy, always_unique, always_contiguous, always_strided,
- unique, contiguous, strided);
+ check_properties_internal(
+ my_mdspan_mapping, always_unique, always_contiguous, always_strided, unique, contiguous, strided);
+ check_properties_internal(
+ my_mdspan_map_acc, always_unique, always_contiguous, always_strided, unique, contiguous, strided);
+ check_properties_internal(
+ my_mdspan_extents, always_unique, always_contiguous, always_strided, unique, contiguous, strided);
+ check_properties_internal(
+ my_mdspan_copy, always_unique, always_contiguous, always_strided, unique, contiguous, strided);
}
void check_operator()
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+# Set up the module library
+add_library(mdtypes INTERFACE)
+
file(GLOB MDTYPES_SOURCES
checkpointdata.cpp
df_history.cpp
)
endif()
+# Source files have the following private module dependencies.
+target_link_libraries(mdtypes PRIVATE
+ # gmxlib
+ # math
+ # mdtypes
+ # tng_io
+ )
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(mdtypes PUBLIC
+target_include_directories(mdtypes INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(mdtypes PUBLIC
+target_link_libraries(mdtypes INTERFACE
+ legacy_api
+ )
+
+# TODO: when fileio is an OBJECT target
+#target_link_libraries(mdtypes PUBLIC legacy_api)
+#target_link_libraries(mdtypes PRIVATE common)
+
+# Module dependencies
+# fileio interfaces convey transitive dependence on these modules.
+#target_link_libraries(mdtypes PUBLIC
+target_link_libraries(mdtypes INTERFACE
+ utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(mdtypes PRIVATE tng_io)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(mdtypes PRIVATE legacy_modules)
+
if (BUILD_TESTING)
add_subdirectory(tests)
endif()
for (; outputIt != outputEnd && inputIt != inputEnd; outputIt++, inputIt++)
{
auto storedRVec = inputIt->asObject()["RVec"].asArray().values();
- *outputIt = { storedRVec[XX].cast<real>(), storedRVec[YY].cast<real>(),
- storedRVec[ZZ].cast<real>() };
+ *outputIt = { storedRVec[XX].cast<real>(), storedRVec[YY].cast<real>(), storedRVec[ZZ].cast<real>() };
}
}
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2017,2018 by the GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/gmxmpi.h"
-struct mpi_in_place_buf_t;
struct gmx_domdec_t;
#define DUTY_PP (1U << 0U)
* This should be read through thisRankHasDuty() or getThisRankDuties().
*/
int duty;
-
- /* these buffers are used as destination buffers if MPI_IN_PLACE isn't
- supported.*/
- mpi_in_place_buf_t* mpb;
};
/*! \brief
{
forceMtsCombined_.resizeWithPadding(numAtoms);
}
- view_ = ForceBuffersView(force_.arrayRefWithPadding(), forceMtsCombined_.arrayRefWithPadding(),
- useForceMtsCombined_);
+ view_ = ForceBuffersView(
+ force_.arrayRefWithPadding(), forceMtsCombined_.arrayRefWithPadding(), useForceMtsCombined_);
}
} // namespace gmx
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2020, by the GROMACS development team, led by
+ * Copyright (c) 2020,2021, 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.
#ifndef GMX_MDTYPES_FORCEBUFFERS_H
#define GMX_MDTYPES_FORCEBUFFERS_H
+#include <memory>
+
#include "gromacs/gpu_utils/hostallocator.h"
#include "gromacs/math/arrayrefwithpadding.h"
#include "gromacs/math/vectypes.h"
#include "gromacs/utility/arrayref.h"
-#include "gromacs/utility/classhelpers.h"
namespace gmx
{
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
gmx_bool bcoultab = FALSE;
gmx_bool bvdwtab = FALSE;
- t_forcetable* pairsTable = nullptr; /* for 1-4 interactions, [pairs] and [pairs_nb] */
+ std::unique_ptr<t_forcetable> pairsTable; /* for 1-4 interactions, [pairs] and [pairs_nb] */
/* Free energy */
int efep = 0;
std::unique_ptr<nonbonded_verlet_t> nbv;
/* The wall tables (if used) */
- int nwall = 0;
- t_forcetable*** wall_tab = nullptr;
+ int nwall = 0;
+ std::vector<std::vector<std::unique_ptr<t_forcetable>>> wall_tab;
/* The number of atoms participating in do_force_lowlevel */
int natoms_force = 0;
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2018,2019,2021, 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.
double vscale_nhc = 0;
};
-struct t_grp_acc
-{
- //! Number of atoms in this group
- int nat = 0;
- //! Mean velocities of home particles
- rvec u = { 0 };
- //! Previous mean velocities of home particles
- rvec uold = { 0 };
- //! Mass for topology A
- double mA = 0;
- //! Mass for topology B
- double mB = 0;
-};
-
struct t_cos_acc
{
//! The acceleration for the cosine profile
struct gmx_ekindata_t
{
- //! Whether non-equilibrium MD is active (ie. constant or cosine acceleration)
- gmx_bool bNEMD;
//! The number of T-coupling groups
int ngtc = 0;
//! For size of ekin_work
tensor** ekin_work = nullptr;
//! Work location for dekindl per thread
real** dekindl_work = nullptr;
- //! The number of acceleration groups
- int ngacc = 0;
- //! Acceleration data
- std::vector<t_grp_acc> grpstat;
//! overall kinetic energy
tensor ekin = { { 0 } };
//! overall 1/2 step kinetic energy
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2016,2017,2018,2019,2021, 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.
#ifndef GMX_MDTYPES_IFORCEPROVIDER_H
#define GMX_MDTYPES_IFORCEPROVIDER_H
+#include <memory>
+
#include "gromacs/math/vec.h"
#include "gromacs/utility/arrayref.h"
-#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/gmxassert.h"
struct gmx_enerdata_t;
private:
class Impl;
- gmx::PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2010, The GROMACS development team.
* Copyright (c) 2012,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
return nst;
}
-int tcouple_min_integration_steps(int etc)
+int tcouple_min_integration_steps(TemperatureCoupling etc)
{
int n;
switch (etc)
{
- case etcNO: n = 0; break;
- case etcBERENDSEN:
- case etcYES: n = nstmin_berendsen_tcouple; break;
- case etcVRESCALE:
+ case TemperatureCoupling::No: n = 0; break;
+ case TemperatureCoupling::Berendsen:
+ case TemperatureCoupling::Yes: n = nstmin_berendsen_tcouple; break;
+ case TemperatureCoupling::VRescale:
/* V-rescale supports instantaneous rescaling */
n = 0;
break;
- case etcNOSEHOOVER: n = nstmin_harmonic; break;
- case etcANDERSEN:
- case etcANDERSENMASSIVE: n = 1; break;
+ case TemperatureCoupling::NoseHoover: n = nstmin_harmonic; break;
+ case TemperatureCoupling::Andersen:
+ case TemperatureCoupling::AndersenMassive: n = 1; break;
default: gmx_incons("Unknown etc value");
}
nwanted = c_defaultNstTCouple;
tau_min = 1e20;
- if (ir->etc != etcNO)
+ if (ir->etc != TemperatureCoupling::No)
{
for (g = 0; g < ir->opts.ngtc; g++)
{
return n;
}
-int pcouple_min_integration_steps(int epc)
+int pcouple_min_integration_steps(PressureCoupling epc)
{
int n;
switch (epc)
{
- case epcNO: n = 0; break;
- case epcBERENDSEN:
- case epcCRESCALE:
- case epcISOTROPIC: n = nstmin_berendsen_pcouple; break;
- case epcPARRINELLORAHMAN:
- case epcMTTK: n = nstmin_harmonic; break;
+ case PressureCoupling::No: n = 0; break;
+ case PressureCoupling::Berendsen:
+ case PressureCoupling::CRescale:
+ case PressureCoupling::Isotropic: n = nstmin_berendsen_pcouple; break;
+ case PressureCoupling::ParrinelloRahman:
+ case PressureCoupling::Mttk: n = nstmin_harmonic; break;
default: gmx_incons("Unknown epc value");
}
sfree(ir->opts.anneal_time);
sfree(ir->opts.anneal_temp);
sfree(ir->opts.tau_t);
- sfree(ir->opts.acc);
sfree(ir->opts.nFreeze);
sfree(ir->opts.egp_flags);
done_lambdas(ir->fepvals);
}
}
- pr_indent(out, indent);
- fprintf(out, "acc:\t");
- for (i = 0; (i < opts->ngacc); i++)
- {
- for (m = 0; (m < DIM); m++)
- {
- fprintf(out, " %10g", opts->acc[i][m]);
- }
- }
- fprintf(out, "\n");
-
pr_indent(out, indent);
fprintf(out, "nfreeze:");
for (i = 0; (i < opts->ngfrz); i++)
{
if (bMDPformat)
{
- fprintf(fp, "%-10s = %g %g %g %g %g %g\n", title, m[XX][XX], m[YY][YY], m[ZZ][ZZ],
- m[XX][YY], m[XX][ZZ], m[YY][ZZ]);
+ fprintf(fp,
+ "%-10s = %g %g %g %g %g %g\n",
+ title,
+ m[XX][XX],
+ m[YY][YY],
+ m[ZZ][ZZ],
+ m[XX][YY],
+ m[XX][ZZ],
+ m[YY][ZZ]);
}
else
{
PR("epsilon-surface", ir->epsilon_surface);
/* Options for weak coupling algorithms */
- PS("tcoupl", ETCOUPLTYPE(ir->etc));
+ PS("tcoupl", enumValueToString(ir->etc));
PI("nsttcouple", ir->nsttcouple);
PI("nh-chain-length", ir->opts.nhchainlength);
PS("print-nose-hoover-chain-variables", EBOOL(ir->bPrintNHChains));
- PS("pcoupl", EPCOUPLTYPE(ir->epc));
+ PS("pcoupl", enumValueToString(ir->epc));
PS("pcoupltype", EPCOUPLTYPETYPE(ir->epct));
PI("nstpcouple", ir->nstpcouple);
PR("tau-p", ir->tau_p);
if (bMDPformat)
{
- fprintf(fp, "posres-com = %g %g %g\n", ir->posres_com[XX], ir->posres_com[YY],
- ir->posres_com[ZZ]);
- fprintf(fp, "posres-comB = %g %g %g\n", ir->posres_comB[XX], ir->posres_comB[YY],
- ir->posres_comB[ZZ]);
+ fprintf(fp, "posres-com = %g %g %g\n", ir->posres_com[XX], ir->posres_com[YY], ir->posres_com[ZZ]);
+ fprintf(fp, "posres-comB = %g %g %g\n", ir->posres_comB[XX], ir->posres_comB[YY], ir->posres_comB[ZZ]);
}
else
{
char buf1[256], buf2[256];
cmp_int(fp, "inputrec->grpopts.ngtc", -1, opt1->ngtc, opt2->ngtc);
- cmp_int(fp, "inputrec->grpopts.ngacc", -1, opt1->ngacc, opt2->ngacc);
cmp_int(fp, "inputrec->grpopts.ngfrz", -1, opt1->ngfrz, opt2->ngfrz);
cmp_int(fp, "inputrec->grpopts.ngener", -1, opt1->ngener, opt2->ngener);
for (i = 0; (i < std::min(opt1->ngtc, opt2->ngtc)); i++)
cmp_real(fp, "inputrec->grpopts.ref_t", i, opt1->ref_t[i], opt2->ref_t[i], ftol, abstol);
cmp_real(fp, "inputrec->grpopts.tau_t", i, opt1->tau_t[i], opt2->tau_t[i], ftol, abstol);
cmp_int(fp, "inputrec->grpopts.annealing", i, opt1->annealing[i], opt2->annealing[i]);
- cmp_int(fp, "inputrec->grpopts.anneal_npoints", i, opt1->anneal_npoints[i],
- opt2->anneal_npoints[i]);
+ cmp_int(fp, "inputrec->grpopts.anneal_npoints", i, opt1->anneal_npoints[i], opt2->anneal_npoints[i]);
if (opt1->anneal_npoints[i] == opt2->anneal_npoints[i])
{
sprintf(buf1, "inputrec->grpopts.anneal_time[%d]", i);
for (j = i; j < opt1->ngener; j++)
{
sprintf(buf1, "inputrec->grpopts.egp_flags[%d]", i);
- cmp_int(fp, buf1, j, opt1->egp_flags[opt1->ngener * i + j],
- opt2->egp_flags[opt1->ngener * i + j]);
+ cmp_int(fp, buf1, j, opt1->egp_flags[opt1->ngener * i + j], opt2->egp_flags[opt1->ngener * i + j]);
}
}
}
- for (i = 0; (i < std::min(opt1->ngacc, opt2->ngacc)); i++)
- {
- cmp_rvec(fp, "inputrec->grpopts.acc", i, opt1->acc[i], opt2->acc[i], ftol, abstol);
- }
for (i = 0; (i < std::min(opt1->ngfrz, opt2->ngfrz)); i++)
{
cmp_ivec(fp, "inputrec->grpopts.nFreeze", i, opt1->nFreeze[i], opt2->nFreeze[i]);
/* Note that we have double index here, but the compare functions only
* support one index, so here we only print the dim index and not the bias.
*/
- cmp_int(fp, "inputrec.awhParams->bias?->dim->coord_index", dimIndex, dimp1->coordIndex,
- dimp2->coordIndex);
- cmp_double(fp, "inputrec->awhParams->bias?->dim->period", dimIndex, dimp1->period,
- dimp2->period, ftol, abstol);
- cmp_double(fp, "inputrec->awhParams->bias?->dim->diffusion", dimIndex, dimp1->diffusion,
- dimp2->diffusion, ftol, abstol);
- cmp_double(fp, "inputrec->awhParams->bias?->dim->origin", dimIndex, dimp1->origin,
- dimp2->origin, ftol, abstol);
+ cmp_int(fp, "inputrec.awhParams->bias?->dim->coord_index", dimIndex, dimp1->coordIndex, dimp2->coordIndex);
+ cmp_double(fp, "inputrec->awhParams->bias?->dim->period", dimIndex, dimp1->period, dimp2->period, ftol, abstol);
+ cmp_double(fp, "inputrec->awhParams->bias?->dim->diffusion", dimIndex, dimp1->diffusion, dimp2->diffusion, ftol, abstol);
+ cmp_double(fp, "inputrec->awhParams->bias?->dim->origin", dimIndex, dimp1->origin, dimp2->origin, ftol, abstol);
cmp_double(fp, "inputrec->awhParams->bias?->dim->end", dimIndex, dimp1->end, dimp2->end, ftol, abstol);
- cmp_double(fp, "inputrec->awhParams->bias?->dim->coord_value_init", dimIndex,
- dimp1->coordValueInit, dimp2->coordValueInit, ftol, abstol);
- cmp_double(fp, "inputrec->awhParams->bias?->dim->coverDiameter", dimIndex, dimp1->coverDiameter,
- dimp2->coverDiameter, ftol, abstol);
+ cmp_double(fp,
+ "inputrec->awhParams->bias?->dim->coord_value_init",
+ dimIndex,
+ dimp1->coordValueInit,
+ dimp2->coordValueInit,
+ ftol,
+ abstol);
+ cmp_double(fp,
+ "inputrec->awhParams->bias?->dim->coverDiameter",
+ dimIndex,
+ dimp1->coverDiameter,
+ dimp2->coverDiameter,
+ ftol,
+ abstol);
}
static void cmp_awhBiasParams(FILE* fp,
{
cmp_int(fp, "inputrec->awhParams->ndim", biasIndex, bias1->ndim, bias2->ndim);
cmp_int(fp, "inputrec->awhParams->biaseTarget", biasIndex, bias1->eTarget, bias2->eTarget);
- cmp_double(fp, "inputrec->awhParams->biastargetBetaScaling", biasIndex,
- bias1->targetBetaScaling, bias2->targetBetaScaling, ftol, abstol);
- cmp_double(fp, "inputrec->awhParams->biastargetCutoff", biasIndex, bias1->targetCutoff,
- bias2->targetCutoff, ftol, abstol);
+ cmp_double(fp,
+ "inputrec->awhParams->biastargetBetaScaling",
+ biasIndex,
+ bias1->targetBetaScaling,
+ bias2->targetBetaScaling,
+ ftol,
+ abstol);
+ cmp_double(fp,
+ "inputrec->awhParams->biastargetCutoff",
+ biasIndex,
+ bias1->targetCutoff,
+ bias2->targetCutoff,
+ ftol,
+ abstol);
cmp_int(fp, "inputrec->awhParams->biaseGrowth", biasIndex, bias1->eGrowth, bias2->eGrowth);
- cmp_bool(fp, "inputrec->awhParams->biasbUserData", biasIndex, bias1->bUserData != 0,
- bias2->bUserData != 0);
- cmp_double(fp, "inputrec->awhParams->biaserror_initial", biasIndex, bias1->errorInitial,
- bias2->errorInitial, ftol, abstol);
+ cmp_bool(fp, "inputrec->awhParams->biasbUserData", biasIndex, bias1->bUserData != 0, bias2->bUserData != 0);
+ cmp_double(fp,
+ "inputrec->awhParams->biaserror_initial",
+ biasIndex,
+ bias1->errorInitial,
+ bias2->errorInitial,
+ ftol,
+ abstol);
cmp_int(fp, "inputrec->awhParams->biasShareGroup", biasIndex, bias1->shareGroup, bias2->shareGroup);
for (int dim = 0; dim < std::min(bias1->ndim, bias2->ndim); dim++)
cmp_int64(fp, "inputrec->awhParams->seed", awh1->seed, awh2->seed);
cmp_int(fp, "inputrec->awhParams->nstout", -1, awh1->nstOut, awh2->nstOut);
cmp_int(fp, "inputrec->awhParams->nstsample_coord", -1, awh1->nstSampleCoord, awh2->nstSampleCoord);
- cmp_int(fp, "inputrec->awhParams->nsamples_update_free_energy", -1,
- awh1->numSamplesUpdateFreeEnergy, awh2->numSamplesUpdateFreeEnergy);
+ cmp_int(fp,
+ "inputrec->awhParams->nsamples_update_free_energy",
+ -1,
+ awh1->numSamplesUpdateFreeEnergy,
+ awh2->numSamplesUpdateFreeEnergy);
cmp_int(fp, "inputrec->awhParams->ePotential", -1, awh1->ePotential, awh2->ePotential);
- cmp_bool(fp, "inputrec->awhParams->shareBiasMultisim", -1, awh1->shareBiasMultisim,
- awh2->shareBiasMultisim);
+ cmp_bool(fp, "inputrec->awhParams->shareBiasMultisim", -1, awh1->shareBiasMultisim, awh2->shareBiasMultisim);
if (awh1->numBias == awh2->numBias)
{
{
int i;
cmp_int(fp, "inputrec->simtempvals->eSimTempScale", -1, simtemp1->eSimTempScale, simtemp2->eSimTempScale);
- cmp_real(fp, "inputrec->simtempvals->simtemp_high", -1, simtemp1->simtemp_high,
- simtemp2->simtemp_high, ftol, abstol);
- cmp_real(fp, "inputrec->simtempvals->simtemp_low", -1, simtemp1->simtemp_low,
- simtemp2->simtemp_low, ftol, abstol);
+ cmp_real(fp, "inputrec->simtempvals->simtemp_high", -1, simtemp1->simtemp_high, simtemp2->simtemp_high, ftol, abstol);
+ cmp_real(fp, "inputrec->simtempvals->simtemp_low", -1, simtemp1->simtemp_low, simtemp2->simtemp_low, ftol, abstol);
for (i = 0; i < n_lambda; i++)
{
- cmp_real(fp, "inputrec->simtempvals->temperatures", -1, simtemp1->temperatures[i],
- simtemp2->temperatures[i], ftol, abstol);
+ cmp_real(fp,
+ "inputrec->simtempvals->temperatures",
+ -1,
+ simtemp1->temperatures[i],
+ simtemp2->temperatures[i],
+ ftol,
+ abstol);
}
}
for (i = 0; i < n_lambda; i++)
{
- cmp_real(fp, "inputrec->expandedvals->init_lambda_weights", -1,
- expand1->init_lambda_weights[i], expand2->init_lambda_weights[i], ftol, abstol);
+ cmp_real(fp,
+ "inputrec->expandedvals->init_lambda_weights",
+ -1,
+ expand1->init_lambda_weights[i],
+ expand2->init_lambda_weights[i],
+ ftol,
+ abstol);
}
cmp_int(fp, "inputrec->expandedvals->lambda-stats", -1, expand1->elamstats, expand2->elamstats);
cmp_int(fp, "inputrec->expandedvals->lambda-mc-move", -1, expand1->elmcmove, expand2->elmcmove);
cmp_int(fp, "inputrec->expandedvals->lmc-repeats", -1, expand1->lmc_repeats, expand2->lmc_repeats);
cmp_int(fp, "inputrec->expandedvals->lmc-gibbsdelta", -1, expand1->gibbsdeltalam, expand2->gibbsdeltalam);
- cmp_int(fp, "inputrec->expandedvals->lmc-forced-nstart", -1, expand1->lmc_forced_nstart,
- expand2->lmc_forced_nstart);
+ cmp_int(fp, "inputrec->expandedvals->lmc-forced-nstart", -1, expand1->lmc_forced_nstart, expand2->lmc_forced_nstart);
cmp_int(fp, "inputrec->expandedvals->lambda-weights-equil", -1, expand1->elmceq, expand2->elmceq);
- cmp_int(fp, "inputrec->expandedvals->,weight-equil-number-all-lambda", -1,
- expand1->equil_n_at_lam, expand2->equil_n_at_lam);
- cmp_int(fp, "inputrec->expandedvals->weight-equil-number-samples", -1, expand1->equil_samples,
- expand2->equil_samples);
- cmp_int(fp, "inputrec->expandedvals->weight-equil-number-steps", -1, expand1->equil_steps,
- expand2->equil_steps);
- cmp_real(fp, "inputrec->expandedvals->weight-equil-wl-delta", -1, expand1->equil_wl_delta,
- expand2->equil_wl_delta, ftol, abstol);
- cmp_real(fp, "inputrec->expandedvals->weight-equil-count-ratio", -1, expand1->equil_ratio,
- expand2->equil_ratio, ftol, abstol);
- cmp_bool(fp, "inputrec->expandedvals->symmetrized-transition-matrix", -1,
- expand1->bSymmetrizedTMatrix, expand2->bSymmetrizedTMatrix);
+ cmp_int(fp,
+ "inputrec->expandedvals->,weight-equil-number-all-lambda",
+ -1,
+ expand1->equil_n_at_lam,
+ expand2->equil_n_at_lam);
+ cmp_int(fp, "inputrec->expandedvals->weight-equil-number-samples", -1, expand1->equil_samples, expand2->equil_samples);
+ cmp_int(fp, "inputrec->expandedvals->weight-equil-number-steps", -1, expand1->equil_steps, expand2->equil_steps);
+ cmp_real(fp,
+ "inputrec->expandedvals->weight-equil-wl-delta",
+ -1,
+ expand1->equil_wl_delta,
+ expand2->equil_wl_delta,
+ ftol,
+ abstol);
+ cmp_real(fp,
+ "inputrec->expandedvals->weight-equil-count-ratio",
+ -1,
+ expand1->equil_ratio,
+ expand2->equil_ratio,
+ ftol,
+ abstol);
+ cmp_bool(fp,
+ "inputrec->expandedvals->symmetrized-transition-matrix",
+ -1,
+ expand1->bSymmetrizedTMatrix,
+ expand2->bSymmetrizedTMatrix);
cmp_int(fp, "inputrec->expandedvals->nstTij", -1, expand1->nstTij, expand2->nstTij);
- cmp_int(fp, "inputrec->expandedvals->mininum-var-min", -1, expand1->minvarmin,
- expand2->minvarmin); /*default is reasonable */
+ cmp_int(fp, "inputrec->expandedvals->mininum-var-min", -1, expand1->minvarmin, expand2->minvarmin); /*default is reasonable */
cmp_int(fp, "inputrec->expandedvals->weight-c-range", -1, expand1->c_range, expand2->c_range); /* default is just C=0 */
cmp_real(fp, "inputrec->expandedvals->wl-scale", -1, expand1->wl_scale, expand2->wl_scale, ftol, abstol);
- cmp_real(fp, "inputrec->expandedvals->init-wl-delta", -1, expand1->init_wl_delta,
- expand2->init_wl_delta, ftol, abstol);
+ cmp_real(fp, "inputrec->expandedvals->init-wl-delta", -1, expand1->init_wl_delta, expand2->init_wl_delta, ftol, abstol);
cmp_real(fp, "inputrec->expandedvals->wl-ratio", -1, expand1->wl_ratio, expand2->wl_ratio, ftol, abstol);
cmp_int(fp, "inputrec->expandedvals->nstexpanded", -1, expand1->nstexpanded, expand2->nstexpanded);
cmp_int(fp, "inputrec->expandedvals->lmc-seed", -1, expand1->lmc_seed, expand2->lmc_seed);
- cmp_real(fp, "inputrec->expandedvals->mc-temperature", -1, expand1->mc_temp, expand2->mc_temp,
- ftol, abstol);
+ cmp_real(fp, "inputrec->expandedvals->mc-temperature", -1, expand1->mc_temp, expand2->mc_temp, ftol, abstol);
}
static void cmp_fepvals(FILE* fp, const t_lambda* fep1, const t_lambda* fep2, real ftol, real abstol)
{
int i, j;
cmp_int(fp, "inputrec->nstdhdl", -1, fep1->nstdhdl, fep2->nstdhdl);
- cmp_double(fp, "inputrec->fepvals->init_fep_state", -1, fep1->init_fep_state,
- fep2->init_fep_state, ftol, abstol);
- cmp_double(fp, "inputrec->fepvals->delta_lambda", -1, fep1->delta_lambda, fep2->delta_lambda,
- ftol, abstol);
+ cmp_double(fp, "inputrec->fepvals->init_fep_state", -1, fep1->init_fep_state, fep2->init_fep_state, ftol, abstol);
+ cmp_double(fp, "inputrec->fepvals->delta_lambda", -1, fep1->delta_lambda, fep2->delta_lambda, ftol, abstol);
cmp_int(fp, "inputrec->fepvals->n_lambda", -1, fep1->n_lambda, fep2->n_lambda);
for (i = 0; i < efptNR; i++)
{
for (j = 0; j < std::min(fep1->n_lambda, fep2->n_lambda); j++)
{
- cmp_double(fp, "inputrec->fepvals->all_lambda", -1, fep1->all_lambda[i][j],
- fep2->all_lambda[i][j], ftol, abstol);
+ cmp_double(fp,
+ "inputrec->fepvals->all_lambda",
+ -1,
+ fep1->all_lambda[i][j],
+ fep2->all_lambda[i][j],
+ ftol,
+ abstol);
}
}
cmp_int(fp, "inputrec->fepvals->lambda_neighbors", 1, fep1->lambda_neighbors, fep2->lambda_neighbors);
cmp_int(fp, "inputrec->separate_dhdl_file", -1, fep1->separate_dhdl_file, fep2->separate_dhdl_file);
cmp_int(fp, "inputrec->dhdl_derivatives", -1, fep1->dhdl_derivatives, fep2->dhdl_derivatives);
cmp_int(fp, "inputrec->dh_hist_size", -1, fep1->dh_hist_size, fep2->dh_hist_size);
- cmp_double(fp, "inputrec->dh_hist_spacing", -1, fep1->dh_hist_spacing, fep2->dh_hist_spacing,
- ftol, abstol);
+ cmp_double(fp, "inputrec->dh_hist_spacing", -1, fep1->dh_hist_spacing, fep2->dh_hist_spacing, ftol, abstol);
}
void cmp_inputrec(FILE* fp, const t_inputrec* ir1, const t_inputrec* ir2, real ftol, real abstol)
if (ir1->useMts && ir2->useMts)
{
cmp_int(fp, "inputrec->mts-levels", -1, ir1->mtsLevels.size(), ir2->mtsLevels.size());
- cmp_int(fp, "inputrec->mts-level2-forces", -1, ir1->mtsLevels[1].forceGroups.to_ulong(),
+ cmp_int(fp,
+ "inputrec->mts-level2-forces",
+ -1,
+ ir1->mtsLevels[1].forceGroups.to_ulong(),
ir2->mtsLevels[1].forceGroups.to_ulong());
- cmp_int(fp, "inputrec->mts-level2-factor", -1, ir1->mtsLevels[1].stepFactor,
+ cmp_int(fp,
+ "inputrec->mts-level2-factor",
+ -1,
+ ir1->mtsLevels[1].stepFactor,
ir2->mtsLevels[1].stepFactor);
}
cmp_int(fp, "inputrec->pbcType", -1, static_cast<int>(ir1->pbcType), static_cast<int>(ir2->pbcType));
cmp_int(fp, "inputrec->nstxout_compressed", -1, ir1->nstxout_compressed, ir2->nstxout_compressed);
cmp_double(fp, "inputrec->init_t", -1, ir1->init_t, ir2->init_t, ftol, abstol);
cmp_double(fp, "inputrec->delta_t", -1, ir1->delta_t, ir2->delta_t, ftol, abstol);
- cmp_real(fp, "inputrec->x_compression_precision", -1, ir1->x_compression_precision,
- ir2->x_compression_precision, ftol, abstol);
+ cmp_real(fp,
+ "inputrec->x_compression_precision",
+ -1,
+ ir1->x_compression_precision,
+ ir2->x_compression_precision,
+ ftol,
+ abstol);
cmp_real(fp, "inputrec->fourierspacing", -1, ir1->fourier_spacing, ir2->fourier_spacing, ftol, abstol);
cmp_int(fp, "inputrec->nkx", -1, ir1->nkx, ir2->nkx);
cmp_int(fp, "inputrec->nky", -1, ir1->nky, ir2->nky);
cmp_real(fp, "inputrec->ewald_rtol", -1, ir1->ewald_rtol, ir2->ewald_rtol, ftol, abstol);
cmp_int(fp, "inputrec->ewald_geometry", -1, ir1->ewald_geometry, ir2->ewald_geometry);
cmp_real(fp, "inputrec->epsilon_surface", -1, ir1->epsilon_surface, ir2->epsilon_surface, ftol, abstol);
- cmp_int(fp, "inputrec->bContinuation", -1, static_cast<int>(ir1->bContinuation),
+ cmp_int(fp,
+ "inputrec->bContinuation",
+ -1,
+ static_cast<int>(ir1->bContinuation),
static_cast<int>(ir2->bContinuation));
- cmp_int(fp, "inputrec->bShakeSOR", -1, static_cast<int>(ir1->bShakeSOR),
- static_cast<int>(ir2->bShakeSOR));
- cmp_int(fp, "inputrec->etc", -1, ir1->etc, ir2->etc);
- cmp_int(fp, "inputrec->bPrintNHChains", -1, static_cast<int>(ir1->bPrintNHChains),
+ cmp_int(fp, "inputrec->bShakeSOR", -1, static_cast<int>(ir1->bShakeSOR), static_cast<int>(ir2->bShakeSOR));
+ cmpEnum(fp, "inputrec->etc", ir1->etc, ir2->etc);
+ cmp_int(fp,
+ "inputrec->bPrintNHChains",
+ -1,
+ static_cast<int>(ir1->bPrintNHChains),
static_cast<int>(ir2->bPrintNHChains));
- cmp_int(fp, "inputrec->epc", -1, ir1->epc, ir2->epc);
+ cmpEnum(fp, "inputrec->epc", ir1->epc, ir2->epc);
cmp_int(fp, "inputrec->epct", -1, ir1->epct, ir2->epct);
cmp_real(fp, "inputrec->tau_p", -1, ir1->tau_p, ir2->tau_p, ftol, abstol);
cmp_rvec(fp, "inputrec->ref_p(x)", -1, ir1->ref_p[XX], ir2->ref_p[XX], ftol, abstol);
cmp_int(fp, "inputrec->bSimTemp", -1, static_cast<int>(ir1->bSimTemp), static_cast<int>(ir2->bSimTemp));
if ((ir1->bSimTemp == ir2->bSimTemp) && (ir1->bSimTemp))
{
- cmp_simtempvals(fp, ir1->simtempvals, ir2->simtempvals,
- std::min(ir1->fepvals->n_lambda, ir2->fepvals->n_lambda), ftol, abstol);
+ cmp_simtempvals(fp,
+ ir1->simtempvals,
+ ir2->simtempvals,
+ std::min(ir1->fepvals->n_lambda, ir2->fepvals->n_lambda),
+ ftol,
+ abstol);
}
- cmp_int(fp, "inputrec->bExpanded", -1, static_cast<int>(ir1->bExpanded),
- static_cast<int>(ir2->bExpanded));
+ cmp_int(fp, "inputrec->bExpanded", -1, static_cast<int>(ir1->bExpanded), static_cast<int>(ir2->bExpanded));
if ((ir1->bExpanded == ir2->bExpanded) && (ir1->bExpanded))
{
- cmp_expandedvals(fp, ir1->expandedvals, ir2->expandedvals,
- std::min(ir1->fepvals->n_lambda, ir2->fepvals->n_lambda), ftol, abstol);
+ cmp_expandedvals(fp,
+ ir1->expandedvals,
+ ir2->expandedvals,
+ std::min(ir1->fepvals->n_lambda, ir2->fepvals->n_lambda),
+ ftol,
+ abstol);
}
cmp_int(fp, "inputrec->nwall", -1, ir1->nwall, ir2->nwall);
cmp_int(fp, "inputrec->wall_type", -1, ir1->wall_type, ir2->wall_type);
cmp_int(fp, "inputrec->eDisre", -1, ir1->eDisre, ir2->eDisre);
cmp_real(fp, "inputrec->dr_fc", -1, ir1->dr_fc, ir2->dr_fc, ftol, abstol);
cmp_int(fp, "inputrec->eDisreWeighting", -1, ir1->eDisreWeighting, ir2->eDisreWeighting);
- cmp_int(fp, "inputrec->bDisreMixed", -1, static_cast<int>(ir1->bDisreMixed),
- static_cast<int>(ir2->bDisreMixed));
+ cmp_int(fp, "inputrec->bDisreMixed", -1, static_cast<int>(ir1->bDisreMixed), static_cast<int>(ir2->bDisreMixed));
cmp_int(fp, "inputrec->nstdisreout", -1, ir1->nstdisreout, ir2->nstdisreout);
cmp_real(fp, "inputrec->dr_tau", -1, ir1->dr_tau, ir2->dr_tau, ftol, abstol);
cmp_real(fp, "inputrec->orires_fc", -1, ir1->orires_fc, ir2->orires_fc, ftol, abstol);
gmx_bool inputrecDynamicBox(const t_inputrec* ir)
{
- return (ir->epc != epcNO || ir->eI == eiTPI || inputrecDeform(ir));
+ return (ir->epc != PressureCoupling::No || ir->eI == eiTPI || inputrecDeform(ir));
}
gmx_bool inputrecPreserveShape(const t_inputrec* ir)
{
- return (ir->epc != epcNO && ir->deform[XX][XX] == 0
+ return (ir->epc != PressureCoupling::No && ir->deform[XX][XX] == 0
&& (ir->epct == epctISOTROPIC || ir->epct == epctSEMIISOTROPIC));
}
gmx_bool inputrecNptTrotter(const t_inputrec* ir)
{
- return (((ir->eI == eiVV) || (ir->eI == eiVVAK)) && (ir->epc == epcMTTK) && (ir->etc == etcNOSEHOOVER));
+ return (((ir->eI == eiVV) || (ir->eI == eiVVAK)) && (ir->epc == PressureCoupling::Mttk)
+ && (ir->etc == TemperatureCoupling::NoseHoover));
}
gmx_bool inputrecNvtTrotter(const t_inputrec* ir)
{
- return (((ir->eI == eiVV) || (ir->eI == eiVVAK)) && (ir->epc != epcMTTK) && (ir->etc == etcNOSEHOOVER));
+ return (((ir->eI == eiVV) || (ir->eI == eiVVAK)) && (ir->epc != PressureCoupling::Mttk)
+ && (ir->etc == TemperatureCoupling::NoseHoover));
}
gmx_bool inputrecNphTrotter(const t_inputrec* ir)
{
- return (((ir->eI == eiVV) || (ir->eI == eiVVAK)) && (ir->epc == epcMTTK) && (ir->etc != etcNOSEHOOVER));
+ return (((ir->eI == eiVV) || (ir->eI == eiVVAK)) && (ir->epc == PressureCoupling::Mttk)
+ && (ir->etc != TemperatureCoupling::NoseHoover));
}
bool inputrecPbcXY2Walls(const t_inputrec* ir)
// Energy minimization or stochastic integrator: no conservation
return false;
}
- else if (ir->etc == etcNO && ir->epc == epcNO)
+ else if (ir->etc == TemperatureCoupling::No && ir->epc == PressureCoupling::No)
{
// The total energy is conserved, no additional conserved quanitity
return false;
{
// Shear stress with Parrinello-Rahman is not supported (tedious)
bool shearWithPR =
- ((ir->epc == epcPARRINELLORAHMAN || ir->epc == epcMTTK)
+ ((ir->epc == PressureCoupling::ParrinelloRahman || ir->epc == PressureCoupling::Mttk)
&& (ir->ref_p[YY][XX] != 0 || ir->ref_p[ZZ][XX] != 0 || ir->ref_p[ZZ][YY] != 0));
return !ETC_ANDERSEN(ir->etc) && !shearWithPR;
bool integratorHasReferenceTemperature(const t_inputrec* ir)
{
- return ((ir->etc != etcNO) || EI_SD(ir->eI) || (ir->eI == eiBD) || EI_TPI(ir->eI));
+ return ((ir->etc != TemperatureCoupling::No) || EI_SD(ir->eI) || (ir->eI == eiBD) || EI_TPI(ir->eI));
}
int inputrec2nboundeddim(const t_inputrec* ir)
return 0;
}
- if (EI_MD(ir.eI) && ir.etc == etcNO)
+ if (EI_MD(ir.eI) && ir.etc == TemperatureCoupling::No)
{
return -1;
}
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
int ngtc;
//! Number of of Nose-Hoover chains per group
int nhchainlength;
- //! Number of Accelerate groups
- int ngacc;
//! Number of Freeze groups
int ngfrz;
//! Number of Energy groups
real** anneal_temp;
//! Tau coupling time
real* tau_t;
- //! Acceleration per group
- rvec* acc;
//! Whether the group will be frozen in each direction
ivec* nFreeze;
//! Exclusions/tables of energy group pairs
//! Continuation run: starting state is correct (ie. constrained)
gmx_bool bContinuation;
//! Temperature coupling
- int etc;
+ TemperatureCoupling etc;
//! Interval in steps for temperature coupling
int nsttcouple;
//! Whether to print nose-hoover chains
gmx_bool bPrintNHChains;
//! Pressure coupling
- int epc;
+ PressureCoupling epc;
//! Pressure coupling type
int epct;
//! Interval in steps for pressure coupling
gmx_bool bAdress;
//! Whether twin-range scheme is active - always false if a valid .tpr was read
gmx_bool useTwinRange;
+ //! Whether we have constant acceleration - removed in GROMACS 2022
+ bool useConstantAcceleration;
//! KVT object that contains input parameters converted to the new style.
gmx::KeyValueTreeObject* params;
int ir_optimal_nstcalcenergy(const t_inputrec* ir);
-int tcouple_min_integration_steps(int etc);
+int tcouple_min_integration_steps(TemperatureCoupling etc);
int ir_optimal_nsttcouple(const t_inputrec* ir);
-int pcouple_min_integration_steps(int epc);
+int pcouple_min_integration_steps(PressureCoupling epc);
int ir_optimal_nstpcouple(const t_inputrec* ir);
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "md_enums.h"
-const char* enum_name(int index, int max_index, const char* names[])
+#include "gromacs/utility/enumerationhelpers.h"
+
+const char* enum_name(int index, int max_index, const char* const names[])
{
if (index < 0 || index >= max_index)
{
"Exact-cutoff", "Force-switch", nullptr
};
-const char* etcoupl_names[etcNR + 1] = {
- "No", "Berendsen", "Nose-Hoover", "yes", "Andersen", "Andersen-massive", "V-rescale", nullptr
-}; /* yes is alias for berendsen */
+const char* enumValueToString(TemperatureCoupling enumValue)
+{
+ static constexpr gmx::EnumerationArray<TemperatureCoupling, const char*> temperatureCouplingNames = {
+ "No", "Berendsen", "Nose-Hoover", "yes", "Andersen", "Andersen-massive", "V-rescale"
+ }; /* yes is alias for berendsen */
+ return temperatureCouplingNames[enumValue];
+}
-const char* epcoupl_names[epcNR + 1] = { "No", "Berendsen", "Parrinello-Rahman",
- "Isotropic", "MTTK", "C-rescale",
- nullptr }; /* isotropic is alias for berendsen */
+const char* enumValueToString(PressureCoupling enumValue)
+{
+ static constexpr gmx::EnumerationArray<PressureCoupling, const char*> pressureCouplingNames = {
+ "No", "Berendsen", "Parrinello-Rahman", "Isotropic", "MTTK", "C-rescale"
+ }; /* isotropic is alias for berendsen */
+ return pressureCouplingNames[enumValue];
+}
-const char* epcoupltype_names[epctNR + 1] = { "Isotropic", "Semiisotropic", "Anisotropic",
- "Surface-Tension", nullptr };
+const char* epcoupltype_names[epctNR + 1] = { "Isotropic",
+ "Semiisotropic",
+ "Anisotropic",
+ "Surface-Tension",
+ nullptr };
const char* edisre_names[edrNR + 1] = { "No", "Simple", "Ensemble", nullptr };
};
const char* gmx_nblist_interaction_names[GMX_NBLIST_INTERACTION_NR + 1] = { "Standard",
- "Free_Energy", nullptr };
+ "Free_Energy",
+ nullptr };
const char* gmx_nbkernel_elec_names[GMX_NBKERNEL_ELEC_NR + 1] = {
"None", "Coulomb", "Reaction-Field", "Cubic-Spline-Table", "Ewald", nullptr
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
* \param[in] names The array
* \return the correct string or "no name defined"
*/
-const char* enum_name(int index, int max_index, const char* names[]);
+const char* enum_name(int index, int max_index, const char* const names[]);
//! Boolean strings no or yes
extern const char* yesno_names[BOOL_NR + 1];
/*! \brief Temperature coupling type
*
* yes is an alias for berendsen
+ *
+ * Note: Keep `Count` as the second-to-last entry, and `Default` as the last entry -
+ * this is needed to keep EnumerationWrapper, EnumerationArray and (de)serialization
+ * working.
*/
-enum
-{
- etcNO,
- etcBERENDSEN,
- etcNOSEHOOVER,
- etcYES,
- etcANDERSEN,
- etcANDERSENMASSIVE,
- etcVRESCALE,
- etcNR
-};
-//! Strings corresponding to temperatyre coupling types
-extern const char* etcoupl_names[etcNR + 1];
-//! Macro for selecting t coupling string
-#define ETCOUPLTYPE(e) enum_name(e, etcNR, etcoupl_names)
+enum class TemperatureCoupling : int
+{
+ No,
+ Berendsen,
+ NoseHoover,
+ Yes,
+ Andersen,
+ AndersenMassive,
+ VRescale,
+ Count,
+ Default = No
+};
+//! Return names of temperature coupling schemes
+const char* enumValueToString(TemperatureCoupling enumValue);
//! Return whether this is andersen coupling
-#define ETC_ANDERSEN(e) (((e) == etcANDERSENMASSIVE) || ((e) == etcANDERSEN))
+#define ETC_ANDERSEN(e) \
+ (((e) == TemperatureCoupling::AndersenMassive) || ((e) == TemperatureCoupling::Andersen))
/*! \brief Pressure coupling types
*
* isotropic is an alias for berendsen
+ *
+ * Note: Keep `Count` as the second-to-last entry, and `Default` as the last entry -
+ * this is needed to keep EnumerationWrapper, EnumerationArray and (de)serialization
+ * working.
*/
-enum
-{
- epcNO,
- epcBERENDSEN,
- epcPARRINELLORAHMAN,
- epcISOTROPIC,
- epcMTTK,
- epcCRESCALE,
- epcNR
-};
-//! String corresponding to pressure coupling algorithm
-extern const char* epcoupl_names[epcNR + 1];
-//! Macro to return the correct pcoupling string
-#define EPCOUPLTYPE(e) enum_name(e, epcNR, epcoupl_names)
+enum class PressureCoupling : int
+{
+ No,
+ Berendsen,
+ ParrinelloRahman,
+ Isotropic,
+ Mttk,
+ CRescale,
+ Count,
+ Default = No
+};
+//! Return names of pressure coupling schemes
+const char* enumValueToString(PressureCoupling enumValue);
//! Flat-bottom posres geometries
enum
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team.
- * Copyright (c) 2017,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2017,2019,2020,2021, 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.
unsigned short* cTC;
//! Group index for energy matrix
unsigned short* cENER;
- //! Group index for acceleration
- unsigned short* cACC;
//! Group index for freezing
unsigned short* cFREEZE;
//! Group index for center of mass motion removal
#include "multipletimestepping.h"
+#include <optional>
+
#include "gromacs/mdtypes/inputrec.h"
+#include "gromacs/mdtypes/pull_params.h"
+#include "gromacs/utility/arrayref.h"
#include "gromacs/utility/gmxassert.h"
+#include "gromacs/utility/stringutil.h"
namespace gmx
{
}
}
-void assertMtsRequirements(const t_inputrec& ir)
+std::vector<MtsLevel> setupMtsLevels(const GromppMtsOpts& mtsOpts, std::vector<std::string>* errorMessages)
+{
+ std::vector<MtsLevel> mtsLevels;
+
+ if (mtsOpts.numLevels != 2)
+ {
+ if (errorMessages)
+ {
+ errorMessages->push_back("Only mts-levels = 2 is supported");
+ }
+ }
+ else
+ {
+ mtsLevels.resize(2);
+
+ const std::vector<std::string> inputForceGroups = gmx::splitString(mtsOpts.level2Forces);
+ auto& forceGroups = mtsLevels[1].forceGroups;
+ for (const auto& inputForceGroup : inputForceGroups)
+ {
+ bool found = false;
+ int nameIndex = 0;
+ for (const auto& forceGroupName : gmx::mtsForceGroupNames)
+ {
+ if (gmx::equalCaseInsensitive(inputForceGroup, forceGroupName))
+ {
+ forceGroups.set(nameIndex);
+ found = true;
+ }
+ nameIndex++;
+ }
+ if (!found && errorMessages)
+ {
+ errorMessages->push_back(
+ gmx::formatString("Unknown MTS force group '%s'", inputForceGroup.c_str()));
+ }
+ }
+
+ // Make the level 0 use the complement of the force groups of group 1
+ mtsLevels[0].forceGroups = ~mtsLevels[1].forceGroups;
+ mtsLevels[0].stepFactor = 1;
+
+ mtsLevels[1].stepFactor = mtsOpts.level2Factor;
+
+ if (errorMessages && mtsLevels[1].stepFactor <= 1)
+ {
+ errorMessages->push_back("mts-factor should be larger than 1");
+ }
+ }
+
+ return mtsLevels;
+}
+
+bool haveValidMtsSetup(const t_inputrec& ir)
+{
+ return (ir.useMts && ir.mtsLevels.size() == 2 && ir.mtsLevels[1].stepFactor > 1);
+}
+
+namespace
+{
+
+//! Checks whether \p nstValue is a multiple of the largest MTS step, returns an error string for parameter \p param when this is not the case
+std::optional<std::string> checkMtsInterval(ArrayRef<const MtsLevel> mtsLevels, const char* param, const int nstValue)
+{
+ GMX_RELEASE_ASSERT(mtsLevels.size() >= 2, "Need at least two levels for MTS");
+
+ const int mtsFactor = mtsLevels.back().stepFactor;
+ if (nstValue % mtsFactor == 0)
+ {
+ return {};
+ }
+ else
+ {
+ return gmx::formatString(
+ "With MTS, %s = %d should be a multiple of mts-factor = %d", param, nstValue, mtsFactor);
+ }
+}
+
+} // namespace
+
+std::vector<std::string> checkMtsRequirements(const t_inputrec& ir)
{
+ std::vector<std::string> errorMessages;
+
if (!ir.useMts)
{
- return;
+ return errorMessages;
}
- GMX_RELEASE_ASSERT(ir.mtsLevels.size() >= 2, "Need at least two levels for MTS");
+ GMX_RELEASE_ASSERT(haveValidMtsSetup(ir), "MTS setup should be valid here");
+
+ ArrayRef<const MtsLevel> mtsLevels = ir.mtsLevels;
+
+ if (!(ir.eI == eiMD || ir.eI == eiSD1))
+ {
+ errorMessages.push_back(gmx::formatString(
+ "Multiple time stepping is only supported with integrators %s and %s",
+ ei_names[eiMD],
+ ei_names[eiSD1]));
+ }
- GMX_RELEASE_ASSERT(ir.mtsLevels[0].stepFactor == 1, "Base MTS step should be 1");
+ if ((EEL_FULL(ir.coulombtype) || EVDW_PME(ir.vdwtype))
+ && forceGroupMtsLevel(ir.mtsLevels, MtsForceGroups::LongrangeNonbonded) == 0)
+ {
+ errorMessages.emplace_back(
+ "With long-range electrostatics and/or LJ treatment, the long-range part "
+ "has to be part of the mts-level2-forces");
+ }
- GMX_RELEASE_ASSERT((!EEL_FULL(ir.coulombtype) && !EVDW_PME(ir.vdwtype))
- || forceGroupMtsLevel(ir.mtsLevels, MtsForceGroups::LongrangeNonbonded) > 0,
- "Long-range nonbondeds should be in the highest MTS level");
+ std::optional<std::string> mesg;
+ if (ir.nstcalcenergy > 0)
+ {
+ if ((mesg = checkMtsInterval(mtsLevels, "nstcalcenergy", ir.nstcalcenergy)))
+ {
+ errorMessages.push_back(mesg.value());
+ }
+ }
+ if ((mesg = checkMtsInterval(mtsLevels, "nstenergy", ir.nstenergy)))
+ {
+ errorMessages.push_back(mesg.value());
+ }
+ if ((mesg = checkMtsInterval(mtsLevels, "nstlog", ir.nstlog)))
+ {
+ errorMessages.push_back(mesg.value());
+ }
+ if ((mesg = checkMtsInterval(mtsLevels, "nstfout", ir.nstfout)))
+ {
+ errorMessages.push_back(mesg.value());
+ }
+ if (ir.efep != efepNO)
+ {
+ if ((mesg = checkMtsInterval(mtsLevels, "nstdhdl", ir.fepvals->nstdhdl)))
+ {
+ errorMessages.push_back(mesg.value());
+ }
+ }
+ if (mtsLevels.back().forceGroups[static_cast<int>(gmx::MtsForceGroups::Nonbonded)])
+ {
+ if ((mesg = checkMtsInterval(mtsLevels, "nstlist", ir.nstlist)))
+ {
+ errorMessages.push_back(mesg.value());
+ }
+ }
- for (const auto& mtsLevel : ir.mtsLevels)
+ if (ir.bPull)
{
- const int mtsFactor = mtsLevel.stepFactor;
- GMX_RELEASE_ASSERT(ir.nstcalcenergy % mtsFactor == 0,
- "nstcalcenergy should be a multiple of mtsFactor");
- GMX_RELEASE_ASSERT(ir.nstenergy % mtsFactor == 0,
- "nstenergy should be a multiple of mtsFactor");
- GMX_RELEASE_ASSERT(ir.nstlog % mtsFactor == 0, "nstlog should be a multiple of mtsFactor");
- GMX_RELEASE_ASSERT(ir.epc == epcNO || ir.nstpcouple % mtsFactor == 0,
- "nstpcouple should be a multiple of mtsFactor");
- GMX_RELEASE_ASSERT(ir.efep == efepNO || ir.fepvals->nstdhdl % mtsFactor == 0,
- "nstdhdl should be a multiple of mtsFactor");
- if (ir.mtsLevels.back().forceGroups[static_cast<int>(gmx::MtsForceGroups::Nonbonded)])
+ const int pullMtsLevel = gmx::forceGroupMtsLevel(ir.mtsLevels, gmx::MtsForceGroups::Pull);
+ const int mtsStepFactor = ir.mtsLevels[pullMtsLevel].stepFactor;
+ if (ir.pull->nstxout % mtsStepFactor != 0)
+ {
+ errorMessages.emplace_back("pull-nstxout should be a multiple of mts-factor");
+ }
+ if (ir.pull->nstfout % mtsStepFactor != 0)
{
- GMX_RELEASE_ASSERT(ir.nstlist % ir.mtsLevels.back().stepFactor == 0,
- "With multiple time stepping for the non-bonded pair interactions, "
- "nstlist should be a "
- "multiple of mtsFactor");
+ errorMessages.emplace_back("pull-nstfout should be a multiple of mts-factor");
}
}
+
+ return errorMessages;
}
} // namespace gmx
#ifndef GMX_MULTIPLETIMESTEPPING_H
#define GMX_MULTIPLETIMESTEPPING_H
+#include <string>
+#include <vector>
+
#include <bitset>
#include "gromacs/utility/arrayref.h"
Count //!< The number of groups above
};
+//! Names for the MTS force groups
static const gmx::EnumerationArray<MtsForceGroups, std::string> mtsForceGroupNames = {
"longrange-nonbonded", "nonbonded", "pair", "dihedral", "angle", "pull", "awh"
};
*/
int nonbondedMtsFactor(const t_inputrec& ir);
-//! (Release) Asserts that all multiple time-stepping requirements on \p ir are fulfilled
-void assertMtsRequirements(const t_inputrec& ir);
+//! Struct for passing the MTS mdp options to setupMtsLevels()
+struct GromppMtsOpts
+{
+ //! The number of MTS levels
+ int numLevels = 0;
+ //! The names of the force groups assigned by the user to level 2, internal index 1
+ std::string level2Forces;
+ //! The step factor assigned by the user to level 2, internal index 1
+ int level2Factor = 0;
+};
+
+/*! \brief Sets up and returns the MTS levels and checks requirements of MTS
+ *
+ * Appends errors about allowed input values ir to errorMessages, when not nullptr.
+ *
+ * \param[in] mtsOpts Options for setting the MTS levels
+ * \param[in,out] errorMessages List of error messages, can be nullptr
+ */
+std::vector<MtsLevel> setupMtsLevels(const GromppMtsOpts& mtsOpts, std::vector<std::string>* errorMessages);
+
+/*! \brief Returns whether we use MTS and the MTS setup is internally valid
+ *
+ * Note that setupMtsLevels would have returned at least one error message
+ * when this function returns false
+ */
+bool haveValidMtsSetup(const t_inputrec& ir);
+
+/*! \brief Checks whether the MTS requirements on other algorithms and output frequencies are met
+ *
+ * Note: exits with an assertion failure when
+ * ir.useMts == true && haveValidMtsSetup(ir) == false
+ *
+ * \param[in] ir Complete input record
+ * \returns list of error messages, empty when all MTS requirements are met
+ */
+std::vector<std::string> checkMtsRequirements(const t_inputrec& ir);
} // namespace gmx
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2012,2014,2015,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2012,2014,2015,2019,2020,2021, 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.
{
t_forcetable(enum gmx_table_interaction interaction, enum gmx_table_format format);
+ ~t_forcetable();
+
enum gmx_table_interaction interaction; /* Types of interactions stored in this table */
enum gmx_table_format format; /* Interpolation type and data format */
nc = i * st1->nhchainlength;
for (j = 0; j < nc; j++)
{
- cmp_real(stdout, "nosehoover_xi", i, st1->nosehoover_xi[nc + j],
- st2->nosehoover_xi[nc + j], ftol, abstol);
+ cmp_real(stdout, "nosehoover_xi", i, st1->nosehoover_xi[nc + j], st2->nosehoover_xi[nc + j], ftol, abstol);
}
}
}
nc = i * st1->nhchainlength;
for (j = 0; j < nc; j++)
{
- cmp_real(stdout, "nosehoover_xi", i, st1->nhpres_xi[nc + j], st2->nhpres_xi[nc + j],
- ftol, abstol);
+ cmp_real(stdout, "nosehoover_xi", i, st1->nhpres_xi[nc + j], st2->nhpres_xi[nc + j], ftol, abstol);
}
}
}
if ((st1->flags & (1 << estX)) && (st2->flags & (1 << estX)))
{
fprintf(stdout, "comparing x\n");
- cmp_rvecs(stdout, "x", st1->natoms, st1->x.rvec_array(), st2->x.rvec_array(), bRMSD,
- ftol, abstol);
+ cmp_rvecs(stdout, "x", st1->natoms, st1->x.rvec_array(), st2->x.rvec_array(), bRMSD, ftol, abstol);
}
if ((st1->flags & (1 << estV)) && (st2->flags & (1 << estV)))
{
fprintf(stdout, "comparing v\n");
- cmp_rvecs(stdout, "v", st1->natoms, st1->v.rvec_array(), st2->v.rvec_array(), bRMSD,
- ftol, abstol);
+ cmp_rvecs(stdout, "v", st1->natoms, st1->v.rvec_array(), st2->v.rvec_array(), bRMSD, ftol, abstol);
}
}
}
}
}
-void printLambdaStateToLog(FILE* fplog, const gmx::ArrayRef<real> lambda, const bool isInitialOutput)
+void printLambdaStateToLog(FILE* fplog, gmx::ArrayRef<const real> lambda, const bool isInitialOutput)
{
if (fplog != nullptr)
{
* \param[in] lambda The array of lambda values.
* \param[in] isInitialOutput Whether this output is the initial lambda state or not.
*/
-void printLambdaStateToLog(FILE* fplog, gmx::ArrayRef<real> lambda, bool isInitialOutput);
+void printLambdaStateToLog(FILE* fplog, gmx::ArrayRef<const real> lambda, bool isInitialOutput);
/*! \brief Fills fep_state and lambda if needed
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
#ifndef GMX_MDTYPES_STATE_PROPAGATOR_DATA_GPU_H
#define GMX_MDTYPES_STATE_PROPAGATOR_DATA_GPU_H
+#include <memory>
#include <tuple>
#include "gromacs/gpu_utils/devicebuffer_datatype.h"
private:
class Impl;
- gmx::PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
GMX_DISALLOW_COPY_AND_ASSIGN(StatePropagatorDataGpu);
};
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "config.h"
+#include <memory>
+
#include "gromacs/gpu_utils/devicebuffer.h"
#if GMX_GPU_CUDA
# include "gromacs/gpu_utils/gpueventsynchronizer.cuh"
#elif GMX_GPU_SYCL
# include "gromacs/gpu_utils/gpueventsynchronizer_sycl.h"
#endif
+
#include "gromacs/math/vectypes.h"
#include "gromacs/mdtypes/state_propagator_data_gpu.h"
-#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/enumerationhelpers.h"
struct gmx_wallcycle;
GMX_ASSERT(atomsStartAt + numAtomsToCopy <= h_data.ssize(),
"The host buffer is smaller than the requested copy range.");
- copyToDeviceBuffer(&d_data, reinterpret_cast<const RVec*>(&h_data.data()[atomsStartAt]),
- atomsStartAt, numAtomsToCopy, deviceStream, transferKind_, nullptr);
+ copyToDeviceBuffer(&d_data,
+ reinterpret_cast<const RVec*>(&h_data.data()[atomsStartAt]),
+ atomsStartAt,
+ numAtomsToCopy,
+ deviceStream,
+ transferKind_,
+ nullptr);
}
}
GMX_ASSERT(atomsStartAt + numAtomsToCopy <= h_data.ssize(),
"The host buffer is smaller than the requested copy range.");
- copyFromDeviceBuffer(reinterpret_cast<RVec*>(&h_data.data()[atomsStartAt]), &d_data,
- atomsStartAt, numAtomsToCopy, deviceStream, transferKind_, nullptr);
+ copyFromDeviceBuffer(reinterpret_cast<RVec*>(&h_data.data()[atomsStartAt]),
+ &d_data,
+ atomsStartAt,
+ numAtomsToCopy,
+ deviceStream,
+ transferKind_,
+ nullptr);
}
}
CPP_SOURCE_FILES
checkpointdata.cpp
forcebuffers.cpp
+ multipletimestepping.cpp
)
--- /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 the MultipleTimeStepping class and stand-alone functions.
+ *
+ * \author berk Hess <hess@kth.se>
+ * \ingroup module_mdtypes
+ */
+#include "gmxpre.h"
+
+#include "gromacs/mdtypes/multipletimestepping.h"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "gromacs/mdtypes/inputrec.h"
+#include "gromacs/utility/gmxassert.h"
+#include "gromacs/utility/smalloc.h"
+
+#include "testutils/testasserts.h"
+
+namespace gmx
+{
+
+namespace test
+{
+
+namespace
+{
+
+//! brief Sets up the MTS levels in \p ir and tests whether the number of errors matches \p numExpectedErrors
+void setAndCheckMtsLevels(const GromppMtsOpts& mtsOpts, t_inputrec* ir, const int numExpectedErrors)
+{
+ std::vector<std::string> errorMessages;
+ ir->useMts = true;
+ ir->mtsLevels = setupMtsLevels(mtsOpts, &errorMessages);
+
+ if (haveValidMtsSetup(*ir))
+ {
+ std::vector<std::string> errorMessagesCheck = checkMtsRequirements(*ir);
+
+ // Concatenate the two lists with error messages
+ errorMessages.insert(errorMessages.end(), errorMessagesCheck.begin(), errorMessagesCheck.end());
+ }
+
+ EXPECT_EQ(errorMessages.size(), numExpectedErrors);
+}
+
+} // namespace
+
+//! Checks that only numLevels = 2 does not produce an error
+TEST(MultipleTimeStepping, ChecksNumLevels)
+{
+ for (int numLevels = 0; numLevels <= 3; numLevels++)
+ {
+ GromppMtsOpts mtsOpts;
+ mtsOpts.numLevels = numLevels;
+ mtsOpts.level2Factor = 2;
+
+ t_inputrec ir;
+
+ setAndCheckMtsLevels(mtsOpts, &ir, numLevels != 2 ? 1 : 0);
+ }
+}
+
+//! Test that each force group works
+TEST(MultipleTimeStepping, SelectsForceGroups)
+{
+ for (int forceGroupIndex = 0; forceGroupIndex < static_cast<int>(MtsForceGroups::Count);
+ forceGroupIndex++)
+ {
+ const MtsForceGroups forceGroup = static_cast<MtsForceGroups>(forceGroupIndex);
+ SCOPED_TRACE("Testing force group " + mtsForceGroupNames[forceGroup]);
+
+ GromppMtsOpts mtsOpts;
+ mtsOpts.numLevels = 2;
+ mtsOpts.level2Forces = mtsForceGroupNames[forceGroup];
+ mtsOpts.level2Factor = 2;
+
+ t_inputrec ir;
+
+ setAndCheckMtsLevels(mtsOpts, &ir, 0);
+
+ EXPECT_EQ(ir.mtsLevels[1].forceGroups.count(), 1);
+ EXPECT_EQ(ir.mtsLevels[1].forceGroups[forceGroupIndex], true);
+ }
+}
+
+//! Checks that factor is checked
+TEST(MultipleTimeStepping, ChecksStepFactor)
+{
+ for (int stepFactor = 0; stepFactor <= 3; stepFactor++)
+ {
+ GromppMtsOpts mtsOpts;
+ mtsOpts.numLevels = 2;
+ mtsOpts.level2Factor = stepFactor;
+
+ t_inputrec ir;
+
+ setAndCheckMtsLevels(mtsOpts, &ir, stepFactor < 2 ? 1 : 0);
+ }
+}
+
+namespace
+{
+
+GromppMtsOpts simpleMtsOpts()
+{
+ GromppMtsOpts mtsOpts;
+ mtsOpts.numLevels = 2;
+ mtsOpts.level2Forces = "nonbonded";
+ mtsOpts.level2Factor = 4;
+
+ return mtsOpts;
+}
+
+} // namespace
+
+TEST(MultipleTimeStepping, ChecksPmeIsAtLastLevel)
+{
+ const GromppMtsOpts mtsOpts = simpleMtsOpts();
+
+ t_inputrec ir;
+ ir.coulombtype = eelPME;
+
+ setAndCheckMtsLevels(mtsOpts, &ir, 1);
+}
+
+//! Test fixture base for parametrizing interval tests
+using MtsIntervalTestParams = std::tuple<std::string, int>;
+class MtsIntervalTest : public ::testing::Test, public ::testing::WithParamInterface<MtsIntervalTestParams>
+{
+public:
+ MtsIntervalTest()
+ {
+ const auto params = GetParam();
+ const auto& parameterName = std::get<0>(params);
+ const auto interval = std::get<1>(params);
+ numExpectedErrors_ = (interval == 4 ? 0 : 1);
+
+ if (parameterName == "nstcalcenergy")
+ {
+ ir_.nstcalcenergy = interval;
+ }
+ else if (parameterName == "nstenergy")
+ {
+ ir_.nstenergy = interval;
+ }
+ else if (parameterName == "nstfout")
+ {
+ ir_.nstfout = interval;
+ }
+ else if (parameterName == "nstlist")
+ {
+ ir_.nstlist = interval;
+ }
+ else if (parameterName == "nstdhdl")
+ {
+ ir_.efep = efepYES;
+ ir_.fepvals->nstdhdl = interval;
+ }
+ else
+
+ {
+ GMX_RELEASE_ASSERT(false, "unknown parameter name");
+ }
+ }
+
+ t_inputrec ir_;
+ int numExpectedErrors_;
+};
+
+TEST_P(MtsIntervalTest, Works)
+{
+ const GromppMtsOpts mtsOpts = simpleMtsOpts();
+
+ setAndCheckMtsLevels(mtsOpts, &ir_, numExpectedErrors_);
+}
+
+INSTANTIATE_TEST_CASE_P(
+ ChecksStepInterval,
+ MtsIntervalTest,
+ ::testing::Combine(
+ ::testing::Values("nstcalcenergy", "nstenergy", "nstfout", "nstlist", "nstdhdl"),
+ ::testing::Values(3, 4, 5)));
+
+// Check that correct input does not produce errors
+TEST(MultipleTimeStepping, ChecksIntegrator)
+{
+ const GromppMtsOpts mtsOpts = simpleMtsOpts();
+
+ t_inputrec ir;
+ ir.eI = eiBD;
+
+ setAndCheckMtsLevels(mtsOpts, &ir, 1);
+}
+
+} // namespace test
+} // namespace gmx
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2018,2019, by the GROMACS development team, led by
+# Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
# and including many others, as listed in the AUTHORS file in the
# top-level source directory and 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.
-gmx_add_libgromacs_sources(
- communicator.cpp
- utilities.cpp
+# Set up the module library
+add_library(mimic INTERFACE)
+file(GLOB MIMIC_SOURCES *.cpp)
+set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${MIMIC_SOURCES} PARENT_SCOPE)
+
+# Source files have the following dependencies on library infrastructure.
+#target_link_libraries(mimic PRIVATE
+# common
+# legacy_modules
+#)
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(mimic PUBLIC
+target_include_directories(mimic INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(mimic PUBLIC
+target_link_libraries(mimic INTERFACE
+ legacy_api
)
+# TODO: when mimic is an OBJECT target
+#target_link_libraries(mimic PUBLIC legacy_api)
+#target_link_libraries(mimic PRIVATE common)
+
+# Module dependencies
+# mimic interfaces convey transitive dependence on these modules.
+#target_link_libraries(mimic PUBLIC
+target_link_libraries(mimic INTERFACE
+ utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(mimic PRIVATE NOTHING)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(mimic PRIVATE legacy_modules)
+
file(GLOB MODULARSIMULATOR_SOURCES *.cpp)
add_library(modularsimulator OBJECT ${MODULARSIMULATOR_SOURCES})
-target_include_directories(modularsimulator SYSTEM PRIVATE ${PROJECT_SOURCE_DIR}/src/external)
-gmx_target_compile_options(modularsimulator)
-target_compile_definitions(modularsimulator PRIVATE HAVE_CONFIG_H)
-# Should be possible to remove this when resolving #3290
-target_include_directories(modularsimulator SYSTEM BEFORE PRIVATE ${PROJECT_SOURCE_DIR}/src/external/thread_mpi/include)
-if(GMX_OPENMP)
+if (GMX_OPENMP)
# Explicitly set properties for modular simulator module to compile with openmp
set_target_properties(modularsimulator PROPERTIES COMPILE_OPTIONS $<TARGET_PROPERTY:OpenMP::OpenMP_CXX,INTERFACE_COMPILE_OPTIONS>)
-endif()
+endif ()
if (WIN32)
gmx_target_warning_suppression(modularsimulator /wd4244 HAS_NO_MSVC_LOSSY_CONVERSION)
gmx_target_warning_suppression(modularsimulator /wd4996 HAS_NO_MSVC_UNSAFE_FUNCTION)
-else()
+else ()
# Several std::move uses are redundant in C++14, but clang before
# 3.9 had a bug that needed them. gcc 9 can warn about their use,
# which we need to supress. This suppression should be removed
# when GROMACS requires clang 3.9 or higher.
gmx_target_warning_suppression(modularsimulator "-Wno-redundant-move" HAS_NO_REDUNDANT_MOVE)
-endif()
+endif ()
+
+target_include_directories(modularsimulator SYSTEM PRIVATE ${PROJECT_SOURCE_DIR}/src/external)
+gmx_target_compile_options(modularsimulator)
+target_compile_definitions(modularsimulator PRIVATE HAVE_CONFIG_H)
+# Should be possible to remove this when resolving #3290
+target_include_directories(modularsimulator SYSTEM BEFORE PRIVATE ${PROJECT_SOURCE_DIR}/src/external/thread_mpi/include)
+
+# Source files have the following private external dependencies.
+target_link_libraries(modularsimulator PRIVATE tng_io)
+
+# Source files have the following private infrastructure dependencies.
+target_link_libraries(modularsimulator PRIVATE common)
+
+# Source files have the following private module dependencies.
+# TODO: Explicitly link specific modules.
+target_link_libraries(modularsimulator PRIVATE legacy_modules)
+target_link_libraries(modularsimulator PRIVATE
+ gmxlib
+ math
+ mdtypes
+ tng_io
+ )
+
+# Public interface for modules, including dependencies and interfaces
+target_include_directories(modularsimulator PUBLIC
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+target_link_libraries(modularsimulator PUBLIC
+ legacy_api
+ )
+
+# Module dependencies
+# This module convey transitive dependence on these modules.
+target_link_libraries(modularsimulator PUBLIC
+ utility
+ )
list(APPEND libgromacs_object_library_dependencies modularsimulator)
set(libgromacs_object_library_dependencies ${libgromacs_object_library_dependencies} PARENT_SCOPE)
if (MASTER(cr_))
{
- mdoutf_write_checkpoint(trajectoryElement_->outf_, fplog_, cr_, step, time, state_global_,
- observablesHistory_, &checkpointDataHolder);
+ mdoutf_write_checkpoint(
+ trajectoryElement_->outf_, fplog_, cr_, step, time, state_global_, observablesHistory_, &checkpointDataHolder);
}
}
formatString(
"CheckpointHelper client with key %s registered for checkpointing, "
"but %s does not exist in the input checkpoint file.",
- key.c_str(), key.c_str())
+ key.c_str(),
+ key.c_str())
.c_str());
}
client->restoreCheckpointState(
std::vector<std::tuple<std::string, ICheckpointHelperClient*>>&& clients = { clientsMap_.begin(),
clientsMap_.end() };
- return std::make_unique<CheckpointHelper>(std::move(clients), std::move(checkpointHandler_),
- std::forward<Args>(args)...);
+ return std::make_unique<CheckpointHelper>(
+ std::move(clients), std::move(checkpointHandler_), std::forward<Args>(args)...);
}
} // namespace gmx
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/gmxlib/network.h"
#include "gromacs/gmxlib/nrnb.h"
#include "gromacs/math/vec.h"
+#include "gromacs/mdlib/constr.h"
#include "gromacs/mdlib/md_support.h"
#include "gromacs/mdlib/mdatoms.h"
#include "gromacs/mdlib/stat.h"
// to avoid (incorrect) correction of the initial coordinates.
auto x = vcm_.mode == ecmLINEAR_ACCELERATION_CORRECTION ? ArrayRefWithPadding<RVec>()
: statePropagatorData_->positionsView();
- process_and_stopcm_grp(fplog_, &vcm_, *mdAtoms_->mdatoms(), x.unpaddedArrayRef(),
- v.unpaddedArrayRef());
+ process_and_stopcm_grp(
+ fplog_, &vcm_, *mdAtoms_->mdatoms(), x.unpaddedArrayRef(), v.unpaddedArrayRef());
inc_nrnb(nrnb_, eNR_STOPCM, mdAtoms_->mdatoms()->homenr);
}
const bool doInterSimSignal = false;
// Make signaller to signal stop / reset / checkpointing signals
- auto signaller = std::make_shared<SimulationSignaller>(signals_, cr_, nullptr,
- doInterSimSignal, doIntraSimSignal);
+ auto signaller = std::make_shared<SimulationSignaller>(
+ signals_, cr_, nullptr, doInterSimSignal, doIntraSimSignal);
registerRunFunction([this, step, flags, signaller = std::move(signaller)]() {
compute(step, flags, signaller.get(), true);
: statePropagatorData_->constBox();
compute_globals(
- gstat_, cr_, inputrec_, fr_, energyData_->ekindata(), x, v, box, mdAtoms_->mdatoms(),
- nrnb_, &vcm_, step != -1 ? wcycle_ : nullptr, energyData_->enerdata(),
- energyData_->forceVirial(step), energyData_->constraintVirial(step),
- energyData_->totalVirial(step), energyData_->pressure(step), constr_, signaller,
- lastbox, &totalNumberOfBondedInteractions_, energyData_->needToSumEkinhOld(),
+ gstat_,
+ cr_,
+ inputrec_,
+ fr_,
+ energyData_->ekindata(),
+ x,
+ v,
+ box,
+ mdAtoms_->mdatoms(),
+ nrnb_,
+ &vcm_,
+ step != -1 ? wcycle_ : nullptr,
+ energyData_->enerdata(),
+ energyData_->forceVirial(step),
+ energyData_->constraintVirial(step),
+ energyData_->totalVirial(step),
+ energyData_->pressure(step),
+ (((flags & CGLO_ENERGY) != 0) && constr_ != nullptr) ? constr_->rmsdData()
+ : gmx::ArrayRef<real>{},
+ signaller,
+ lastbox,
+ &totalNumberOfBondedInteractions_,
+ energyData_->needToSumEkinhOld(),
flags | (shouldCheckNumberOfBondedInteractions_ ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS : 0));
- checkNumberOfBondedInteractions(mdlog_, cr_, totalNumberOfBondedInteractions_, top_global_,
- localTopology_, x, box, &shouldCheckNumberOfBondedInteractions_);
+ checkNumberOfBondedInteractions(
+ mdlog_, cr_, totalNumberOfBondedInteractions_, top_global_, localTopology_, x, box, &shouldCheckNumberOfBondedInteractions_);
if (flags & CGLO_STOPCM && !isInit)
{
process_and_stopcm_grp(fplog_, &vcm_, *mdAtoms_->mdatoms(), x, v);
{
auto* element = builderHelper->storeElement(
std::make_unique<ComputeGlobalsElement<ComputeGlobalsAlgorithm::LeapFrog>>(
- statePropagatorData, energyData, freeEnergyPerturbationData,
+ statePropagatorData,
+ energyData,
+ freeEnergyPerturbationData,
globalCommunicationHelper->simulationSignals(),
- globalCommunicationHelper->nstglobalcomm(), legacySimulatorData->fplog,
- legacySimulatorData->mdlog, legacySimulatorData->cr,
- legacySimulatorData->inputrec, legacySimulatorData->mdAtoms,
- legacySimulatorData->nrnb, legacySimulatorData->wcycle, legacySimulatorData->fr,
- legacySimulatorData->top_global, legacySimulatorData->constr));
+ globalCommunicationHelper->nstglobalcomm(),
+ legacySimulatorData->fplog,
+ legacySimulatorData->mdlog,
+ legacySimulatorData->cr,
+ legacySimulatorData->inputrec,
+ legacySimulatorData->mdAtoms,
+ legacySimulatorData->nrnb,
+ legacySimulatorData->wcycle,
+ legacySimulatorData->fr,
+ legacySimulatorData->top_global,
+ legacySimulatorData->constr));
// TODO: Remove this when DD can reduce bonded interactions independently (#3421)
auto* castedElement = static_cast<ComputeGlobalsElement<ComputeGlobalsAlgorithm::LeapFrog>*>(element);
{
ISimulatorElement* vvComputeGlobalsElement = builderHelper->storeElement(
std::make_unique<ComputeGlobalsElement<ComputeGlobalsAlgorithm::VelocityVerlet>>(
- statePropagatorData, energyData, freeEnergyPerturbationData,
+ statePropagatorData,
+ energyData,
+ freeEnergyPerturbationData,
globalCommunicationHelper->simulationSignals(),
- globalCommunicationHelper->nstglobalcomm(), simulator->fplog, simulator->mdlog,
- simulator->cr, simulator->inputrec, simulator->mdAtoms, simulator->nrnb,
- simulator->wcycle, simulator->fr, simulator->top_global, simulator->constr));
+ globalCommunicationHelper->nstglobalcomm(),
+ simulator->fplog,
+ simulator->mdlog,
+ simulator->cr,
+ simulator->inputrec,
+ simulator->mdAtoms,
+ simulator->nrnb,
+ simulator->wcycle,
+ simulator->fr,
+ simulator->top_global,
+ simulator->constr));
// TODO: Remove this when DD can reduce bonded interactions independently (#3421)
auto* castedElement =
? freeEnergyPerturbationData_->constLambdaView()[efptBONDED]
: 0;
// Constrain the initial coordinates and velocities
- do_constrain_first(
- fplog_, constr_, inputrec_, statePropagatorData_->totalNumAtoms(),
- statePropagatorData_->localNumAtoms(), statePropagatorData_->positionsView(),
- statePropagatorData_->velocitiesView(), statePropagatorData_->box(), lambdaBonded);
+ do_constrain_first(fplog_,
+ constr_,
+ inputrec_,
+ statePropagatorData_->totalNumAtoms(),
+ statePropagatorData_->localNumAtoms(),
+ statePropagatorData_->positionsView(),
+ statePropagatorData_->velocitiesView(),
+ statePropagatorData_->box(),
+ lambdaBonded);
if (isMasterRank_)
{
if (inputrec_->eConstrAlg == econtLINCS)
{
- fprintf(fplog_, "RMS relative constraint deviation after constraining: %.2e\n",
+ fprintf(fplog_,
+ "RMS relative constraint deviation after constraining: %.2e\n",
constr_->rmsd());
}
}
default: gmx_fatal(FARGS, "Constraint algorithm not implemented for modular simulator.");
}
- constr_->apply(writeLog, writeEnergy, step, 1, 1.0, x, xprime, min_proj, statePropagatorData_->box(),
- lambdaBonded, &dvdlambda, v, calculateVirial, vir_con, variable);
+ constr_->apply(writeLog,
+ writeEnergy,
+ step,
+ 1,
+ 1.0,
+ x,
+ xprime,
+ min_proj,
+ statePropagatorData_->box(),
+ lambdaBonded,
+ &dvdlambda,
+ v,
+ calculateVirial,
+ vir_con,
+ variable);
if (calculateVirial)
{
FreeEnergyPerturbationData* freeEnergyPerturbationData,
GlobalCommunicationHelper gmx_unused* globalCommunicationHelper)
{
- return builderHelper->storeElement(std::make_unique<ConstraintsElement<variable>>(
- legacySimulatorData->constr, statePropagatorData, energyData,
- freeEnergyPerturbationData, MASTER(legacySimulatorData->cr), legacySimulatorData->fplog,
- legacySimulatorData->inputrec, legacySimulatorData->mdAtoms->mdatoms()));
+ return builderHelper->storeElement(
+ std::make_unique<ConstraintsElement<variable>>(legacySimulatorData->constr,
+ statePropagatorData,
+ energyData,
+ freeEnergyPerturbationData,
+ MASTER(legacySimulatorData->cr),
+ legacySimulatorData->fplog,
+ legacySimulatorData->inputrec,
+ legacySimulatorData->mdAtoms->mdatoms()));
}
// Explicit template initializations
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
t_commrec* cr,
const MDLogger& mdlog,
Constraints* constr,
- t_inputrec* inputrec,
+ const t_inputrec* inputrec,
MDAtoms* mdAtoms,
t_nrnb* nrnb,
gmx_wallcycle* wcycle,
gmx_wallcycle* wcycle = nullptr;
// Distribute the charge groups over the nodes from the master node
- partitionSystem(verbose, isMasterState, nstglobalcomm, wcycle,
- statePropagatorData_->localState(), statePropagatorData_->globalState());
+ partitionSystem(verbose,
+ isMasterState,
+ nstglobalcomm,
+ wcycle,
+ statePropagatorData_->localState(),
+ statePropagatorData_->globalState());
}
void DomDecHelper::run(Step step, Time gmx_unused time)
ForceBuffers* forcePointer = statePropagatorData_->forcePointer();
// Distribute the charge groups over the nodes from the master node
- dd_partition_system(fplog_, mdlog_, inputrec_->init_step, cr_, isMasterState, nstglobalcomm,
- globalState, topologyHolder_->globalTopology(), inputrec_, imdSession_,
- pull_work_, localState.get(), forcePointer, mdAtoms_,
- topologyHolder_->localTopology_.get(), fr_, vsite_, constr_, nrnb_, wcycle,
+ dd_partition_system(fplog_,
+ mdlog_,
+ inputrec_->init_step,
+ cr_,
+ isMasterState,
+ nstglobalcomm,
+ globalState,
+ topologyHolder_->globalTopology(),
+ inputrec_,
+ imdSession_,
+ pull_work_,
+ localState.get(),
+ forcePointer,
+ mdAtoms_,
+ topologyHolder_->localTopology_.get(),
+ fr_,
+ vsite_,
+ constr_,
+ nrnb_,
+ wcycle,
verbose);
topologyHolder_->updateLocalTopology();
checkBondedInteractionsCallback_();
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
t_commrec* cr,
const MDLogger& mdlog,
Constraints* constr,
- t_inputrec* inputrec,
+ const t_inputrec* inputrec,
MDAtoms* mdAtoms,
t_nrnb* nrnb,
gmx_wallcycle* wcycle,
//! Handles constraints.
Constraints* constr_;
//! Contains user input mdp options.
- t_inputrec* inputrec_;
+ const t_inputrec* inputrec_;
//! Atom parameters for this domain.
MDAtoms* mdAtoms_;
//! Manages flop accounting.
void EnergyData::setup(gmx_mdoutf* outf)
{
pull_t* pull_work = nullptr;
- energyOutput_ = std::make_unique<EnergyOutput>(
- mdoutf_get_fp_ene(outf), top_global_, inputrec_, pull_work, mdoutf_get_fp_dhdl(outf),
- false, startingBehavior_, simulationsShareState_, mdModulesNotifier_);
+ energyOutput_ = std::make_unique<EnergyOutput>(mdoutf_get_fp_ene(outf),
+ top_global_,
+ inputrec_,
+ pull_work,
+ mdoutf_get_fp_dhdl(outf),
+ false,
+ startingBehavior_,
+ simulationsShareState_,
+ mdModulesNotifier_);
if (!isMasterRank_)
{
enerd_->term[F_ETOT] = enerd_->term[F_EPOT] + enerd_->term[F_EKIN];
if (freeEnergyPerturbationData_)
{
- accumulateKineticLambdaComponents(enerd_, freeEnergyPerturbationData_->constLambdaView(),
- *inputrec_->fepvals);
+ accumulateKineticLambdaComponents(
+ enerd_, freeEnergyPerturbationData_->constLambdaView(), *inputrec_->fepvals);
}
if (integratorHasConservedEnergyQuantity(inputrec_))
{
}
matrix nullMatrix = {};
energyOutput_->addDataAtEnergyStep(
- isFreeEnergyCalculationStep, isEnergyCalculationStep, time, mdAtoms_->mdatoms()->tmass, enerd_,
- inputrec_->fepvals, inputrec_->expandedvals, statePropagatorData_->constPreviousBox(),
+ isFreeEnergyCalculationStep,
+ isEnergyCalculationStep,
+ time,
+ mdAtoms_->mdatoms()->tmass,
+ enerd_,
+ inputrec_->fepvals,
+ inputrec_->expandedvals,
+ statePropagatorData_->constPreviousBox(),
PTCouplingArrays({ parrinelloRahmanBarostat_ ? parrinelloRahmanBarostat_->boxVelocities() : nullMatrix,
{},
{},
{},
{} }),
freeEnergyPerturbationData_ ? freeEnergyPerturbationData_->currentFEPState() : 0,
- shakeVirial_, forceVirial_, totalVirial_, pressure_, ekind_, muTot_, constr_);
+ shakeVirial_,
+ forceVirial_,
+ totalVirial_,
+ pressure_,
+ ekind_,
+ muTot_,
+ constr_);
}
void EnergyData::write(gmx_mdoutf* outf, Step step, Time time, bool writeTrajectory, bool writeLog)
// energyOutput_->printAnnealingTemperatures(writeLog ? fplog_ : nullptr, groups_, &(inputrec_->opts));
Awh* awh = nullptr;
- energyOutput_->printStepToEnergyFile(mdoutf_get_fp_ene(outf), writeTrajectory, do_dr, do_or,
- writeLog ? fplog_ : nullptr, step, time, fcd_, awh);
+ energyOutput_->printStepToEnergyFile(
+ mdoutf_get_fp_ene(outf), writeTrajectory, do_dr, do_or, writeLog ? fplog_ : nullptr, step, time, fcd_, awh);
}
void EnergyData::addToForceVirial(const tensor virial, Step step)
pressureStep_ = step;
clear_mat(pressure_);
}
- GMX_ASSERT(step >= pressureStep_ || pressureStep_ == -1,
- "Asked for pressure of previous step.");
+ GMX_ASSERT(step >= pressureStep_ || pressureStep_ == -1, "Asked for pressure of previous step.");
return pressure_;
}
energyData_->hasReadEkinFromCheckpoint_ = MASTER(cr) ? energyData_->ekinstate_.bUpToDate : false;
if (PAR(cr))
{
- gmx_bcast(sizeof(hasReadEkinFromCheckpoint_), &energyData_->hasReadEkinFromCheckpoint_,
+ gmx_bcast(sizeof(hasReadEkinFromCheckpoint_),
+ &energyData_->hasReadEkinFromCheckpoint_,
cr->mpi_comm_mygroup);
}
if (energyData_->hasReadEkinFromCheckpoint_)
{
auto v = statePropagatorData_->velocitiesView();
- relax_shell_flexcon(
- fplog_, cr_, ms, isVerbose_, enforcedRotation_, step, inputrec_, imdSession_,
- pull_work_, step == nextNSStep_, static_cast<int>(flags), localTopology_, constr_,
- energyData_->enerdata(), statePropagatorData_->localNumAtoms(), x, v, box, lambda,
- hist, &forces, force_vir, mdAtoms_->mdatoms(), nrnb_, wcycle_, shellfc_, fr_,
- runScheduleWork_, time, energyData_->muTot(), vsite_, ddBalanceRegionHandler_);
+ relax_shell_flexcon(fplog_,
+ cr_,
+ ms,
+ isVerbose_,
+ enforcedRotation_,
+ step,
+ inputrec_,
+ imdSession_,
+ pull_work_,
+ step == nextNSStep_,
+ static_cast<int>(flags),
+ localTopology_,
+ constr_,
+ energyData_->enerdata(),
+ statePropagatorData_->localNumAtoms(),
+ x,
+ v,
+ box,
+ lambda,
+ hist,
+ &forces,
+ force_vir,
+ mdAtoms_->mdatoms(),
+ nrnb_,
+ wcycle_,
+ shellfc_,
+ fr_,
+ runScheduleWork_,
+ time,
+ energyData_->muTot(),
+ vsite_,
+ ddBalanceRegionHandler_);
nShellRelaxationSteps_++;
}
else
Awh* awh = nullptr;
gmx_edsam* ed = nullptr;
- do_force(fplog_, cr_, ms, inputrec_, awh, enforcedRotation_, imdSession_, pull_work_, step,
- nrnb_, wcycle_, localTopology_, box, x, hist, &forces, force_vir,
- mdAtoms_->mdatoms(), energyData_->enerdata(), lambda, fr_, runScheduleWork_, vsite_,
- energyData_->muTot(), time, ed, static_cast<int>(flags), ddBalanceRegionHandler_);
+ do_force(fplog_,
+ cr_,
+ ms,
+ inputrec_,
+ awh,
+ enforcedRotation_,
+ imdSession_,
+ pull_work_,
+ step,
+ nrnb_,
+ wcycle_,
+ localTopology_,
+ box,
+ x,
+ hist,
+ &forces,
+ force_vir,
+ mdAtoms_->mdatoms(),
+ energyData_->enerdata(),
+ lambda,
+ fr_,
+ runScheduleWork_,
+ vsite_,
+ energyData_->muTot(),
+ time,
+ ed,
+ static_cast<int>(flags),
+ ddBalanceRegionHandler_);
}
energyData_->addToForceVirial(force_vir, step);
}
{
const bool isVerbose = legacySimulatorData->mdrunOptions.verbose;
const bool isDynamicBox = inputrecDynamicBox(legacySimulatorData->inputrec);
- return builderHelper->storeElement(std::make_unique<ForceElement>(
- statePropagatorData, energyData, freeEnergyPerturbationData, isVerbose, isDynamicBox,
- legacySimulatorData->fplog, legacySimulatorData->cr, legacySimulatorData->inputrec,
- legacySimulatorData->mdAtoms, legacySimulatorData->nrnb, legacySimulatorData->fr,
- legacySimulatorData->wcycle, legacySimulatorData->runScheduleWork, legacySimulatorData->vsite,
- legacySimulatorData->imdSession, legacySimulatorData->pull_work, legacySimulatorData->constr,
- legacySimulatorData->top_global, legacySimulatorData->enforcedRotation));
+ return builderHelper->storeElement(
+ std::make_unique<ForceElement>(statePropagatorData,
+ energyData,
+ freeEnergyPerturbationData,
+ isVerbose,
+ isDynamicBox,
+ legacySimulatorData->fplog,
+ legacySimulatorData->cr,
+ legacySimulatorData->inputrec,
+ legacySimulatorData->mdAtoms,
+ legacySimulatorData->nrnb,
+ legacySimulatorData->fr,
+ legacySimulatorData->wcycle,
+ legacySimulatorData->runScheduleWork,
+ legacySimulatorData->vsite,
+ legacySimulatorData->imdSession,
+ legacySimulatorData->pull_work,
+ legacySimulatorData->constr,
+ legacySimulatorData->top_global,
+ legacySimulatorData->enforcedRotation));
}
} // namespace gmx
if (DOMAINDECOMP(cr))
{
dd_bcast(cr->dd, sizeof(int), &freeEnergyPerturbationData_->currentFEPState_);
- dd_bcast(cr->dd, ssize(freeEnergyPerturbationData_->lambda_) * int(sizeof(real)),
+ dd_bcast(cr->dd,
+ ssize(freeEnergyPerturbationData_->lambda_) * int(sizeof(real)),
freeEnergyPerturbationData_->lambda_.data());
}
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
// The leap frog integration algorithm
builder->add<ForceElement>();
builder->add<StatePropagatorData::Element>();
- if (legacySimulatorData_->inputrec->etc == etcVRESCALE
- || legacySimulatorData_->inputrec->etc == etcBERENDSEN)
+ if (legacySimulatorData_->inputrec->etc == TemperatureCoupling::VRescale
+ || legacySimulatorData_->inputrec->etc == TemperatureCoupling::Berendsen)
{
- builder->add<VelocityScalingTemperatureCoupling>(-1, UseFullStepKE::No,
- ReportPreviousStepConservedEnergy::No);
+ builder->add<VelocityScalingTemperatureCoupling>(
+ -1, UseFullStepKE::No, ReportPreviousStepConservedEnergy::No);
}
builder->add<Propagator<IntegrationStep::LeapFrog>>(legacySimulatorData_->inputrec->delta_t,
RegisterWithThermostat::True,
}
builder->add<ComputeGlobalsElement<ComputeGlobalsAlgorithm::LeapFrog>>();
builder->add<EnergyData::Element>();
- if (legacySimulatorData_->inputrec->epc == epcPARRINELLORAHMAN)
+ if (legacySimulatorData_->inputrec->epc == PressureCoupling::ParrinelloRahman)
{
builder->add<ParrinelloRahmanBarostat>(-1);
}
// The velocity verlet integration algorithm
builder->add<ForceElement>();
builder->add<Propagator<IntegrationStep::VelocitiesOnly>>(
- 0.5 * legacySimulatorData_->inputrec->delta_t, RegisterWithThermostat::False,
+ 0.5 * legacySimulatorData_->inputrec->delta_t,
+ RegisterWithThermostat::False,
RegisterWithBarostat::True);
if (legacySimulatorData_->constr)
{
}
builder->add<ComputeGlobalsElement<ComputeGlobalsAlgorithm::VelocityVerlet>>();
builder->add<StatePropagatorData::Element>();
- if (legacySimulatorData_->inputrec->etc == etcVRESCALE
- || legacySimulatorData_->inputrec->etc == etcBERENDSEN)
+ if (legacySimulatorData_->inputrec->etc == TemperatureCoupling::VRescale
+ || legacySimulatorData_->inputrec->etc == TemperatureCoupling::Berendsen)
{
builder->add<VelocityScalingTemperatureCoupling>(
0, UseFullStepKE::Yes, ReportPreviousStepConservedEnergy::Yes);
}
builder->add<Propagator<IntegrationStep::VelocityVerletPositionsAndVelocities>>(
- legacySimulatorData_->inputrec->delta_t, RegisterWithThermostat::True,
+ legacySimulatorData_->inputrec->delta_t,
+ RegisterWithThermostat::True,
RegisterWithBarostat::False);
if (legacySimulatorData_->constr)
{
}
builder->add<ComputeGlobalsElement<ComputeGlobalsAlgorithm::VelocityVerlet>>();
builder->add<EnergyData::Element>();
- if (legacySimulatorData_->inputrec->epc == epcPARRINELLORAHMAN)
+ if (legacySimulatorData_->inputrec->epc == PressureCoupling::ParrinelloRahman)
{
builder->add<ParrinelloRahmanBarostat>(-1);
}
GMX_RELEASE_ASSERT(
!(modularSimulatorExplicitlyTurnedOff && inputrec->eI == eiVV
- && inputrec->epc == epcPARRINELLORAHMAN),
+ && inputrec->epc == PressureCoupling::ParrinelloRahman),
"Cannot use a Parrinello-Rahman barostat with md-vv and "
"GMX_DISABLE_MODULAR_SIMULATOR=ON, "
"as the Parrinello-Rahman barostat is not implemented in the legacy simulator. Unset "
isInputCompatible
&& conditionalAssert(!doRerun, "Rerun is not supported by the modular simulator.");
isInputCompatible = isInputCompatible
- && conditionalAssert(inputrec->etc == etcNO || inputrec->etc == etcVRESCALE
- || inputrec->etc == etcBERENDSEN,
+ && conditionalAssert(inputrec->etc == TemperatureCoupling::No
+ || inputrec->etc == TemperatureCoupling::VRescale
+ || inputrec->etc == TemperatureCoupling::Berendsen,
"Only v-rescale and Berendsen thermostat are "
"supported by the modular simulator.");
isInputCompatible =
isInputCompatible
&& conditionalAssert(
- inputrec->epc == epcNO || inputrec->epc == epcPARRINELLORAHMAN,
+ inputrec->epc == PressureCoupling::No
+ || inputrec->epc == PressureCoupling::ParrinelloRahman,
"Only Parrinello-Rahman barostat is supported by the modular simulator.");
isInputCompatible =
isInputCompatible
"Pulling is not supported by the modular simulator.");
isInputCompatible =
isInputCompatible
- && conditionalAssert(inputrec->opts.ngacc == 1 && inputrec->opts.acc[0][XX] == 0.0
- && inputrec->opts.acc[0][YY] == 0.0
- && inputrec->opts.acc[0][ZZ] == 0.0 && inputrec->cos_accel == 0.0,
+ && conditionalAssert(inputrec->cos_accel == 0.0,
"Acceleration 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),
+ isInputCompatible
+ || !(inputrec->eI == eiVV && inputrec->epc == PressureCoupling::ParrinelloRahman),
"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.");
void ModularSimulator::checkInputForDisabledFunctionality()
{
- isInputCompatible(true, legacySimulatorData_->inputrec, legacySimulatorData_->mdrunOptions.rerun,
- *legacySimulatorData_->top_global, legacySimulatorData_->ms,
- legacySimulatorData_->replExParams, legacySimulatorData_->fr->fcdata.get(),
+ isInputCompatible(true,
+ legacySimulatorData_->inputrec,
+ legacySimulatorData_->mdrunOptions.rerun,
+ *legacySimulatorData_->top_global,
+ legacySimulatorData_->ms,
+ legacySimulatorData_->replExParams,
+ legacySimulatorData_->fr->fcdata.get(),
opt2bSet("-ei", legacySimulatorData_->nfile, legacySimulatorData_->fnm),
legacySimulatorData_->membed != nullptr);
if (legacySimulatorData_->observablesHistory->edsamHistory)
"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->step = int64_to_int(checkpointHeaderContents.step, "conversion of checkpoint to trajectory");
fr->bTime = true;
fr->time = checkpointHeaderContents.t;
void ParrinelloRahmanBarostat::integrateBoxVelocityEquations(Step step)
{
auto box = statePropagatorData_->constBox();
- parrinellorahman_pcoupl(fplog_, step, inputrec_, couplingTimeStep_, energyData_->pressure(step),
- box, boxRel_, boxVelocity_, scalingTensor_.data(), mu_, false);
+ parrinellorahman_pcoupl(fplog_,
+ step,
+ inputrec_,
+ couplingTimeStep_,
+ energyData_->pressure(step),
+ box,
+ boxRel_,
+ boxVelocity_,
+ scalingTensor_.data(),
+ mu_,
+ false);
// multiply matrix by the coupling time step to avoid having the propagator needing to know about that
msmul(scalingTensor_.data(), couplingTimeStep_, scalingTensor_.data());
}
// The call to parrinellorahman_pcoupl is using nullptr for fplog (since we don't expect any
// output here) and for the pressure (since it might not be calculated yet, and we don't need it).
auto box = statePropagatorData_->constBox();
- parrinellorahman_pcoupl(nullptr, initStep_, inputrec_, couplingTimeStep_, nullptr, box,
- boxRel_, boxVelocity_, scalingTensor_.data(), mu_, true);
+ parrinellorahman_pcoupl(nullptr,
+ initStep_,
+ inputrec_,
+ couplingTimeStep_,
+ nullptr,
+ box,
+ boxRel_,
+ boxVelocity_,
+ scalingTensor_.data(),
+ mu_,
+ true);
// multiply matrix by the coupling time step to avoid having the propagator needing to know about that
msmul(scalingTensor_.data(), couplingTimeStep_, scalingTensor_.data());
int offset)
{
auto* element = builderHelper->storeElement(std::make_unique<ParrinelloRahmanBarostat>(
- legacySimulatorData->inputrec->nstpcouple, offset,
+ legacySimulatorData->inputrec->nstpcouple,
+ offset,
legacySimulatorData->inputrec->delta_t * legacySimulatorData->inputrec->nstpcouple,
- legacySimulatorData->inputrec->init_step, statePropagatorData, energyData,
- legacySimulatorData->fplog, legacySimulatorData->inputrec, legacySimulatorData->mdAtoms));
+ legacySimulatorData->inputrec->init_step,
+ statePropagatorData,
+ energyData,
+ legacySimulatorData->fplog,
+ legacySimulatorData->inputrec,
+ legacySimulatorData->mdAtoms));
auto* barostat = static_cast<ParrinelloRahmanBarostat*>(element);
builderHelper->registerBarostat([barostat](const PropagatorBarostatConnection& connection) {
barostat->connectWithPropagator(connection);
auto box = statePropagatorData_->constBox();
GMX_RELEASE_ASSERT(box[0][0] != 0 && box[1][1] != 0 && box[2][2] != 0,
"PmeLoadBalanceHelper cannot be initialized with zero box.");
- pme_loadbal_init(&pme_loadbal_, cr_, mdlog_, *inputrec_, box, *fr_->ic, *fr_->nbv, fr_->pmedata,
- fr_->nbv->useGpu());
+ pme_loadbal_init(
+ &pme_loadbal_, cr_, mdlog_, *inputrec_, box, *fr_->ic, *fr_->nbv, fr_->pmedata, fr_->nbv->useGpu());
}
void PmeLoadBalanceHelper::run(gmx::Step step, gmx::Time gmx_unused time)
// PME grid + cut-off optimization with GPUs or PME nodes
// TODO pass SimulationWork object into this function, such that last argument can be set as
// simulationWork.useGpuPmePpCommunication as is done in main MD loop.
- pme_loadbal_do(pme_loadbal_, cr_, (isVerbose_ && MASTER(cr_)) ? stderr : nullptr, fplog_,
- mdlog_, *inputrec_, fr_, statePropagatorData_->constBox(),
- statePropagatorData_->constPositionsView().paddedArrayRef(), wcycle_, step,
- step - inputrec_->init_step, &bPMETunePrinting_, false);
+ pme_loadbal_do(pme_loadbal_,
+ cr_,
+ (isVerbose_ && MASTER(cr_)) ? stderr : nullptr,
+ fplog_,
+ mdlog_,
+ *inputrec_,
+ fr_,
+ statePropagatorData_->constBox(),
+ statePropagatorData_->constPositionsView().paddedArrayRef(),
+ wcycle_,
+ step,
+ step - inputrec_->init_step,
+ &bPMETunePrinting_,
+ false);
}
void PmeLoadBalanceHelper::teardown()
if (isFullScalingMatrixDiagonal)
{
updateVelocities<numVelocityScalingValues, ParrinelloRahmanVelocityScaling::Diagonal>(
- a, timestep_,
+ a,
+ timestep_,
numVelocityScalingValues == NumVelocityScalingValues::Multiple
? velocityScaling_[mdAtoms_->mdatoms()->cTC[a]]
: lambda,
- invMassPerDim, v, f, diagPR_, matrixPR_);
+ invMassPerDim,
+ v,
+ f,
+ diagPR_,
+ matrixPR_);
}
else
{
updateVelocities<numVelocityScalingValues, parrinelloRahmanVelocityScaling>(
- a, timestep_,
+ a,
+ timestep_,
numVelocityScalingValues == NumVelocityScalingValues::Multiple
? velocityScaling_[mdAtoms_->mdatoms()->cTC[a]]
: lambda,
- invMassPerDim, v, f, diagPR_, matrixPR_);
+ invMassPerDim,
+ v,
+ f,
+ diagPR_,
+ matrixPR_);
}
}
}
if (isFullScalingMatrixDiagonal)
{
updateVelocities<numVelocityScalingValues, ParrinelloRahmanVelocityScaling::Diagonal>(
- a, timestep_,
+ a,
+ timestep_,
numVelocityScalingValues == NumVelocityScalingValues::Multiple
? velocityScaling_[mdAtoms_->mdatoms()->cTC[a]]
: lambda,
- invMassPerDim, v, f, diagPR_, matrixPR_);
+ invMassPerDim,
+ v,
+ f,
+ diagPR_,
+ matrixPR_);
}
else
{
updateVelocities<numVelocityScalingValues, parrinelloRahmanVelocityScaling>(
- a, timestep_,
+ a,
+ timestep_,
numVelocityScalingValues == NumVelocityScalingValues::Multiple
? velocityScaling_[mdAtoms_->mdatoms()->cTC[a]]
: lambda,
- invMassPerDim, v, f, diagPR_, matrixPR_);
+ invMassPerDim,
+ v,
+ f,
+ diagPR_,
+ matrixPR_);
}
updatePositions(a, timestep_, x, xp, v);
}
if (isFullScalingMatrixDiagonal)
{
updateVelocities<numVelocityScalingValues, ParrinelloRahmanVelocityScaling::Diagonal>(
- a, 0.5 * timestep_,
+ a,
+ 0.5 * timestep_,
numVelocityScalingValues == NumVelocityScalingValues::Multiple
? velocityScaling_[mdAtoms_->mdatoms()->cTC[a]]
: lambda,
- invMassPerDim, v, f, diagPR_, matrixPR_);
+ invMassPerDim,
+ v,
+ f,
+ diagPR_,
+ matrixPR_);
}
else
{
updateVelocities<numVelocityScalingValues, parrinelloRahmanVelocityScaling>(
- a, 0.5 * timestep_,
+ a,
+ 0.5 * timestep_,
numVelocityScalingValues == NumVelocityScalingValues::Multiple
? velocityScaling_[mdAtoms_->mdatoms()->cTC[a]]
: lambda,
- invMassPerDim, v, f, diagPR_, matrixPR_);
+ invMassPerDim,
+ v,
+ f,
+ diagPR_,
+ matrixPR_);
}
updatePositions(a, timestep_, x, xp, v);
}
auto calculateFreeEnergyCallbacks =
buildCallbackVector(EnergySignallerEvent::FreeEnergyCalculationStep);
// NOLINTNEXTLINE(modernize-make-unique): make_unique does not work with private constructor
- return std::unique_ptr<EnergySignaller>(new EnergySignaller(
- std::move(calculateEnergyCallbacks), std::move(calculateVirialCallbacks),
- std::move(calculateFreeEnergyCallbacks), std::forward<Args>(args)...));
+ return std::unique_ptr<EnergySignaller>(new EnergySignaller(std::move(calculateEnergyCallbacks),
+ std::move(calculateVirialCallbacks),
+ std::move(calculateFreeEnergyCallbacks),
+ std::forward<Args>(args)...));
}
//! Helper function to get the callbacks from the clients
t_commrec* cr,
const MDLogger& mdlog,
const MdrunOptions& mdrunOptions,
- t_inputrec* inputrec,
+ const t_inputrec* inputrec,
t_nrnb* nrnb,
gmx_wallcycle* wcycle,
t_forcerec* fr,
fprintf(stderr, "starting mdrun '%s'\n", topologyName_.c_str());
if (inputrec->nsteps >= 0)
{
- timeString = formatString("%8.1f", static_cast<double>(inputrec->init_step + inputrec->nsteps)
- * inputrec->delta_t);
+ timeString = formatString(
+ "%8.1f", static_cast<double>(inputrec->init_step + inputrec->nsteps) * inputrec->delta_t);
}
else
{
}
if (inputrec->init_step > 0)
{
- fprintf(stderr, "%s steps, %s ps (continuing from step %s, %8.1f ps).\n",
- gmx_step_str(inputrec->init_step + inputrec->nsteps, sbuf), timeString.c_str(),
- gmx_step_str(inputrec->init_step, sbuf2), inputrec->init_step * inputrec->delta_t);
+ fprintf(stderr,
+ "%s steps, %s ps (continuing from step %s, %8.1f ps).\n",
+ gmx_step_str(inputrec->init_step + inputrec->nsteps, sbuf),
+ timeString.c_str(),
+ gmx_step_str(inputrec->init_step, sbuf2),
+ inputrec->init_step * inputrec->delta_t);
}
else
{
- fprintf(stderr, "%s steps, %s ps.\n", gmx_step_str(inputrec->nsteps, sbuf),
- timeString.c_str());
+ fprintf(stderr, "%s steps, %s ps.\n", gmx_step_str(inputrec->nsteps, sbuf), timeString.c_str());
}
fprintf(fplog, "\n");
}
dd_cycles_add(cr->dd, static_cast<float>(cycles), ddCyclStep);
}
- resetHandler_->resetCounters(
- step, step - inputrec->init_step, mdlog, fplog, cr, fr->nbv.get(), nrnb, fr->pmedata,
- pmeLoadBalanceHelper_ ? pmeLoadBalanceHelper_->loadBalancingObject() : nullptr, wcycle,
- walltime_accounting);
+ resetHandler_->resetCounters(step,
+ step - inputrec->init_step,
+ mdlog,
+ fplog,
+ cr,
+ fr->nbv.get(),
+ nrnb,
+ fr->pmedata,
+ pmeLoadBalanceHelper_ ? pmeLoadBalanceHelper_->loadBalancingObject() : nullptr,
+ wcycle,
+ walltime_accounting);
}
void ModularSimulatorAlgorithm::populateTaskQueue()
}
statePropagatorData_ = std::make_unique<StatePropagatorData>(
- legacySimulatorData->top_global->natoms, legacySimulatorData->fplog, legacySimulatorData->cr,
- legacySimulatorData->state_global, legacySimulatorData->fr->nbv->useGpu(),
- legacySimulatorData->fr->bMolPBC, legacySimulatorData->mdrunOptions.writeConfout,
- opt2fn("-c", legacySimulatorData->nfile, legacySimulatorData->fnm), legacySimulatorData->inputrec,
- legacySimulatorData->mdAtoms->mdatoms(), legacySimulatorData->top_global);
+ legacySimulatorData->top_global->natoms,
+ legacySimulatorData->fplog,
+ legacySimulatorData->cr,
+ legacySimulatorData->state_global,
+ legacySimulatorData->fr->nbv->useGpu(),
+ legacySimulatorData->fr->bMolPBC,
+ legacySimulatorData->mdrunOptions.writeConfout,
+ opt2fn("-c", legacySimulatorData->nfile, legacySimulatorData->fnm),
+ legacySimulatorData->inputrec,
+ legacySimulatorData->mdAtoms->mdatoms(),
+ legacySimulatorData->top_global);
// Multi sim is turned off
const bool simulationsShareState = false;
- energyData_ = std::make_unique<EnergyData>(
- statePropagatorData_.get(), freeEnergyPerturbationData_.get(), legacySimulatorData->top_global,
- legacySimulatorData->inputrec, legacySimulatorData->mdAtoms, legacySimulatorData->enerd,
- legacySimulatorData->ekind, legacySimulatorData->constr, legacySimulatorData->fplog,
- legacySimulatorData->fr->fcdata.get(), legacySimulatorData->mdModulesNotifier,
- MASTER(legacySimulatorData->cr), legacySimulatorData->observablesHistory,
- legacySimulatorData->startingBehavior, simulationsShareState);
+ energyData_ = std::make_unique<EnergyData>(statePropagatorData_.get(),
+ freeEnergyPerturbationData_.get(),
+ legacySimulatorData->top_global,
+ legacySimulatorData->inputrec,
+ legacySimulatorData->mdAtoms,
+ legacySimulatorData->enerd,
+ legacySimulatorData->ekind,
+ legacySimulatorData->constr,
+ legacySimulatorData->fplog,
+ legacySimulatorData->fr->fcdata.get(),
+ legacySimulatorData->mdModulesNotifier,
+ MASTER(legacySimulatorData->cr),
+ legacySimulatorData->observablesHistory,
+ legacySimulatorData->startingBehavior,
+ simulationsShareState);
}
ModularSimulatorAlgorithm ModularSimulatorAlgorithmBuilder::build()
}
}
- ModularSimulatorAlgorithm algorithm(
- *(legacySimulatorData_->top_global->name), legacySimulatorData_->fplog,
- legacySimulatorData_->cr, legacySimulatorData_->mdlog, legacySimulatorData_->mdrunOptions,
- legacySimulatorData_->inputrec, legacySimulatorData_->nrnb, legacySimulatorData_->wcycle,
- legacySimulatorData_->fr, legacySimulatorData_->walltime_accounting);
+ ModularSimulatorAlgorithm algorithm(*(legacySimulatorData_->top_global->name),
+ legacySimulatorData_->fplog,
+ legacySimulatorData_->cr,
+ legacySimulatorData_->mdlog,
+ legacySimulatorData_->mdrunOptions,
+ legacySimulatorData_->inputrec,
+ legacySimulatorData_->nrnb,
+ legacySimulatorData_->wcycle,
+ legacySimulatorData_->fr,
+ legacySimulatorData_->walltime_accounting);
registerWithInfrastructureAndSignallers(algorithm.signalHelper_.get());
algorithm.statePropagatorData_ = std::move(statePropagatorData_);
algorithm.energyData_ = std::move(energyData_);
algorithm.stopHandler_ = legacySimulatorData_->stopHandlerBuilder->getStopHandlerMD(
compat::not_null<SimulationSignal*>(
&(*globalCommunicationHelper_.simulationSignals())[eglsSTOPCOND]),
- simulationsShareState, MASTER(legacySimulatorData_->cr),
- legacySimulatorData_->inputrec->nstlist, legacySimulatorData_->mdrunOptions.reproducible,
- globalCommunicationHelper_.nstglobalcomm(), legacySimulatorData_->mdrunOptions.maximumHoursToRun,
- legacySimulatorData_->inputrec->nstlist == 0, legacySimulatorData_->fplog,
- algorithm.stophandlerCurrentStep_, algorithm.stophandlerIsNSStep_,
+ simulationsShareState,
+ MASTER(legacySimulatorData_->cr),
+ legacySimulatorData_->inputrec->nstlist,
+ legacySimulatorData_->mdrunOptions.reproducible,
+ globalCommunicationHelper_.nstglobalcomm(),
+ legacySimulatorData_->mdrunOptions.maximumHoursToRun,
+ legacySimulatorData_->inputrec->nstlist == 0,
+ legacySimulatorData_->fplog,
+ algorithm.stophandlerCurrentStep_,
+ algorithm.stophandlerIsNSStep_,
legacySimulatorData_->walltime_accounting);
// Build reset handler
algorithm.resetHandler_ = std::make_unique<ResetHandler>(
compat::make_not_null<SimulationSignal*>(
&(*globalCommunicationHelper_.simulationSignals())[eglsRESETCOUNTERS]),
- simulationsShareResetCounters, legacySimulatorData_->inputrec->nsteps,
- MASTER(legacySimulatorData_->cr), legacySimulatorData_->mdrunOptions.timingOptions.resetHalfway,
- legacySimulatorData_->mdrunOptions.maximumHoursToRun, legacySimulatorData_->mdlog,
- legacySimulatorData_->wcycle, legacySimulatorData_->walltime_accounting);
+ simulationsShareResetCounters,
+ legacySimulatorData_->inputrec->nsteps,
+ MASTER(legacySimulatorData_->cr),
+ legacySimulatorData_->mdrunOptions.timingOptions.resetHalfway,
+ legacySimulatorData_->mdrunOptions.maximumHoursToRun,
+ legacySimulatorData_->mdlog,
+ legacySimulatorData_->wcycle,
+ legacySimulatorData_->walltime_accounting);
// Build topology holder
- algorithm.topologyHolder_ = topologyHolderBuilder_.build(
- *legacySimulatorData_->top_global, legacySimulatorData_->cr,
- legacySimulatorData_->inputrec, legacySimulatorData_->fr, legacySimulatorData_->mdAtoms,
- legacySimulatorData_->constr, legacySimulatorData_->vsite);
+ algorithm.topologyHolder_ = topologyHolderBuilder_.build(*legacySimulatorData_->top_global,
+ legacySimulatorData_->cr,
+ legacySimulatorData_->inputrec,
+ legacySimulatorData_->fr,
+ legacySimulatorData_->mdAtoms,
+ legacySimulatorData_->constr,
+ legacySimulatorData_->vsite);
// Build PME load balance helper
if (PmeLoadBalanceHelper::doPmeLoadBalancing(legacySimulatorData_->mdrunOptions,
legacySimulatorData_->inputrec,
legacySimulatorData_->fr))
{
- algorithm.pmeLoadBalanceHelper_ = std::make_unique<PmeLoadBalanceHelper>(
- legacySimulatorData_->mdrunOptions.verbose, algorithm.statePropagatorData_.get(),
- legacySimulatorData_->fplog, legacySimulatorData_->cr, legacySimulatorData_->mdlog,
- legacySimulatorData_->inputrec, legacySimulatorData_->wcycle, legacySimulatorData_->fr);
+ algorithm.pmeLoadBalanceHelper_ =
+ std::make_unique<PmeLoadBalanceHelper>(legacySimulatorData_->mdrunOptions.verbose,
+ algorithm.statePropagatorData_.get(),
+ legacySimulatorData_->fplog,
+ legacySimulatorData_->cr,
+ legacySimulatorData_->mdlog,
+ legacySimulatorData_->inputrec,
+ legacySimulatorData_->wcycle,
+ legacySimulatorData_->fr);
registerWithInfrastructureAndSignallers(algorithm.pmeLoadBalanceHelper_.get());
}
// Build domdec helper
algorithm.domDecHelper_ = std::make_unique<DomDecHelper>(
legacySimulatorData_->mdrunOptions.verbose,
legacySimulatorData_->mdrunOptions.verboseStepPrintInterval,
- algorithm.statePropagatorData_.get(), algorithm.freeEnergyPerturbationData_.get(),
+ algorithm.statePropagatorData_.get(),
+ algorithm.freeEnergyPerturbationData_.get(),
algorithm.topologyHolder_.get(),
globalCommunicationHelper_.moveCheckBondedInteractionsCallback(),
- globalCommunicationHelper_.nstglobalcomm(), legacySimulatorData_->fplog,
- legacySimulatorData_->cr, legacySimulatorData_->mdlog, legacySimulatorData_->constr,
- legacySimulatorData_->inputrec, legacySimulatorData_->mdAtoms, legacySimulatorData_->nrnb,
- legacySimulatorData_->wcycle, legacySimulatorData_->fr, legacySimulatorData_->vsite,
- legacySimulatorData_->imdSession, legacySimulatorData_->pull_work);
+ globalCommunicationHelper_.nstglobalcomm(),
+ legacySimulatorData_->fplog,
+ legacySimulatorData_->cr,
+ legacySimulatorData_->mdlog,
+ legacySimulatorData_->constr,
+ legacySimulatorData_->inputrec,
+ legacySimulatorData_->mdAtoms,
+ legacySimulatorData_->nrnb,
+ legacySimulatorData_->wcycle,
+ legacySimulatorData_->fr,
+ legacySimulatorData_->vsite,
+ legacySimulatorData_->imdSession,
+ legacySimulatorData_->pull_work);
registerWithInfrastructureAndSignallers(algorithm.domDecHelper_.get());
}
// Build trajectory element
- auto trajectoryElement = trajectoryElementBuilder_.build(
- legacySimulatorData_->fplog, legacySimulatorData_->nfile, legacySimulatorData_->fnm,
- legacySimulatorData_->mdrunOptions, legacySimulatorData_->cr,
- legacySimulatorData_->outputProvider, legacySimulatorData_->mdModulesNotifier,
- legacySimulatorData_->inputrec, legacySimulatorData_->top_global,
- legacySimulatorData_->oenv, legacySimulatorData_->wcycle,
- legacySimulatorData_->startingBehavior, simulationsShareState);
+ auto trajectoryElement = trajectoryElementBuilder_.build(legacySimulatorData_->fplog,
+ legacySimulatorData_->nfile,
+ legacySimulatorData_->fnm,
+ legacySimulatorData_->mdrunOptions,
+ legacySimulatorData_->cr,
+ legacySimulatorData_->outputProvider,
+ legacySimulatorData_->mdModulesNotifier,
+ legacySimulatorData_->inputrec,
+ legacySimulatorData_->top_global,
+ legacySimulatorData_->oenv,
+ legacySimulatorData_->wcycle,
+ legacySimulatorData_->startingBehavior,
+ simulationsShareState);
registerWithInfrastructureAndSignallers(trajectoryElement.get());
// Build free energy element
{
checkpointHelperBuilder_.setCheckpointHandler(std::make_unique<CheckpointHandler>(
compat::make_not_null<SimulationSignal*>(&(*algorithm.signals_)[eglsCHKPT]),
- simulationsShareState, legacySimulatorData_->inputrec->nstlist == 0,
- MASTER(legacySimulatorData_->cr), legacySimulatorData_->mdrunOptions.writeConfout,
+ simulationsShareState,
+ legacySimulatorData_->inputrec->nstlist == 0,
+ MASTER(legacySimulatorData_->cr),
+ legacySimulatorData_->mdrunOptions.writeConfout,
legacySimulatorData_->mdrunOptions.checkpointOptions.period));
- algorithm.checkpointHelper_ = checkpointHelperBuilder_.build(
- legacySimulatorData_->inputrec->init_step, trajectoryElement.get(),
- legacySimulatorData_->fplog, legacySimulatorData_->cr,
- legacySimulatorData_->observablesHistory, legacySimulatorData_->walltime_accounting,
- legacySimulatorData_->state_global, legacySimulatorData_->mdrunOptions.writeConfout);
+ algorithm.checkpointHelper_ =
+ checkpointHelperBuilder_.build(legacySimulatorData_->inputrec->init_step,
+ trajectoryElement.get(),
+ legacySimulatorData_->fplog,
+ legacySimulatorData_->cr,
+ legacySimulatorData_->observablesHistory,
+ legacySimulatorData_->walltime_accounting,
+ legacySimulatorData_->state_global,
+ legacySimulatorData_->mdrunOptions.writeConfout);
registerWithInfrastructureAndSignallers(algorithm.checkpointHelper_.get());
}
const auto* inputrec = legacySimulatorData_->inputrec;
addSignaller(energySignallerBuilder_.build(
inputrec->nstcalcenergy, inputrec->fepvals->nstdhdl, inputrec->nstpcouple));
- addSignaller(trajectorySignallerBuilder_.build(
- inputrec->nstxout, inputrec->nstvout, inputrec->nstfout,
- inputrec->nstxout_compressed, trajectoryElement->tngBoxOut(),
- trajectoryElement->tngLambdaOut(), trajectoryElement->tngBoxOutCompressed(),
- trajectoryElement->tngLambdaOutCompressed(), inputrec->nstenergy));
- addSignaller(loggingSignallerBuilder_.build(inputrec->nstlog, inputrec->init_step,
- legacySimulatorData_->startingBehavior));
- addSignaller(lastStepSignallerBuilder_.build(inputrec->nsteps, inputrec->init_step,
- algorithm.stopHandler_.get()));
- addSignaller(neighborSearchSignallerBuilder_.build(inputrec->nstlist, inputrec->init_step,
- inputrec->init_t));
+ addSignaller(trajectorySignallerBuilder_.build(inputrec->nstxout,
+ inputrec->nstvout,
+ inputrec->nstfout,
+ inputrec->nstxout_compressed,
+ trajectoryElement->tngBoxOut(),
+ trajectoryElement->tngLambdaOut(),
+ trajectoryElement->tngBoxOutCompressed(),
+ trajectoryElement->tngLambdaOutCompressed(),
+ inputrec->nstenergy));
+ addSignaller(loggingSignallerBuilder_.build(
+ inputrec->nstlog, inputrec->init_step, legacySimulatorData_->startingBehavior));
+ addSignaller(lastStepSignallerBuilder_.build(
+ inputrec->nsteps, inputrec->init_step, algorithm.stopHandler_.get()));
+ addSignaller(neighborSearchSignallerBuilder_.build(
+ inputrec->nstlist, inputrec->init_step, inputrec->init_t));
}
// Create element list
bool ModularSimulatorAlgorithmBuilder::elementExists(const ISimulatorElement* element) const
{
// Check whether element exists in element list
- if (std::any_of(elements_.begin(), elements_.end(),
- [element](auto& existingElement) { return element == existingElement.get(); }))
+ if (std::any_of(elements_.begin(), elements_.end(), [element](auto& existingElement) {
+ return element == existingElement.get();
+ }))
{
return true;
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2020, by the GROMACS development team, led by
+ * Copyright (c) 2020,2021, 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.
t_commrec* cr,
const MDLogger& mdlog,
const MdrunOptions& mdrunOptions,
- t_inputrec* inputrec,
+ const t_inputrec* inputrec,
t_nrnb* nrnb,
gmx_wallcycle* wcycle,
t_forcerec* fr,
//! Contains command-line options to mdrun.
const MdrunOptions& mdrunOptions;
//! Contains user input mdp options.
- t_inputrec* inputrec;
+ const t_inputrec* inputrec;
//! Manages flop accounting.
t_nrnb* nrnb;
//! Manages wall cycle accounting.
GlobalCommunicationHelper* globalCommunicationHelper,
Args&&... args)
{
- return Element::getElementPointerImpl(legacySimulatorData, builderHelper, statePropagatorData,
- energyData, freeEnergyPerturbationData,
- globalCommunicationHelper, std::forward<Args>(args)...);
+ return Element::getElementPointerImpl(legacySimulatorData,
+ builderHelper,
+ statePropagatorData,
+ energyData,
+ freeEnergyPerturbationData,
+ globalCommunicationHelper,
+ std::forward<Args>(args)...);
}
template<typename Element, typename... Args>
}
// Get element from factory method
- auto* element = static_cast<Element*>(getElementPointer<Element>(
- legacySimulatorData_, &elementAdditionHelper_, statePropagatorData_.get(),
- energyData_.get(), freeEnergyPerturbationData_.get(), &globalCommunicationHelper_,
- std::forward<Args>(args)...));
+ auto* element = static_cast<Element*>(getElementPointer<Element>(legacySimulatorData_,
+ &elementAdditionHelper_,
+ statePropagatorData_.get(),
+ energyData_.get(),
+ freeEnergyPerturbationData_.get(),
+ &globalCommunicationHelper_,
+ std::forward<Args>(args)...));
// Make sure returned element pointer is owned by *this
// Ensuring this makes sure we can control the life time
// TODO: This is only used for CPT - needs to be filled when we turn CPT back on
ObservablesHistory* observablesHistory = nullptr;
- mdoutf_write_to_trajectory_files(
- fplog_, cr_, outf, static_cast<int>(mdof_flags), statePropagatorData_->totalNumAtoms_,
- currentStep, currentTime, localStateBackup_.get(), statePropagatorData_->globalState_,
- observablesHistory, statePropagatorData_->f_.view().force(), &dummyCheckpointDataHolder_);
+ mdoutf_write_to_trajectory_files(fplog_,
+ cr_,
+ outf,
+ static_cast<int>(mdof_flags),
+ statePropagatorData_->totalNumAtoms_,
+ currentStep,
+ currentTime,
+ localStateBackup_.get(),
+ statePropagatorData_->globalState_,
+ observablesHistory,
+ statePropagatorData_->f_.view().force(),
+ &dummyCheckpointDataHolder_);
if (currentStep != lastStep_ || !isRegularSimulationEnd_)
{
if (DOMAINDECOMP(cr))
{
// Collect state from all ranks into global vectors
- dd_collect_vec(cr->dd, statePropagatorData_->ddpCount_, statePropagatorData_->ddpCountCgGl_,
- statePropagatorData_->cgGl_, statePropagatorData_->x_,
+ 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_,
+ dd_collect_vec(cr->dd,
+ statePropagatorData_->ddpCount_,
+ statePropagatorData_->ddpCountCgGl_,
+ statePropagatorData_->cgGl_,
+ statePropagatorData_->v_,
statePropagatorData_->vGlobal_);
}
else
// 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(),
+ std::copy(statePropagatorData_->x_.begin(),
+ statePropagatorData_->x_.end(),
statePropagatorData_->xGlobal_.begin());
- std::copy(statePropagatorData_->v_.begin(), statePropagatorData_->v_.end(),
+ std::copy(statePropagatorData_->v_.begin(),
+ statePropagatorData_->v_.end(),
statePropagatorData_->vGlobal_.begin());
}
if (MASTER(cr))
// Copy data to global state to be distributed by DD at setup stage
if (DOMAINDECOMP(cr) && MASTER(cr))
{
- updateGlobalState(statePropagatorData_->globalState_, statePropagatorData_->xGlobal_,
- statePropagatorData_->vGlobal_, statePropagatorData_->box_,
- statePropagatorData_->ddpCount_, statePropagatorData_->ddpCountCgGl_,
+ updateGlobalState(statePropagatorData_->globalState_,
+ statePropagatorData_->xGlobal_,
+ statePropagatorData_->vGlobal_,
+ statePropagatorData_->box_,
+ statePropagatorData_->ddpCount_,
+ statePropagatorData_->ddpCountCgGl_,
statePropagatorData_->cgGl_);
}
// Everything is local - copy global vectors to local ones
{
statePropagatorData_->x_.resizeWithPadding(statePropagatorData_->totalNumAtoms_);
statePropagatorData_->v_.resizeWithPadding(statePropagatorData_->totalNumAtoms_);
- std::copy(statePropagatorData_->xGlobal_.begin(), statePropagatorData_->xGlobal_.end(),
+ std::copy(statePropagatorData_->xGlobal_.begin(),
+ statePropagatorData_->xGlobal_.end(),
statePropagatorData_->x_.begin());
- std::copy(statePropagatorData_->vGlobal_.begin(), statePropagatorData_->vGlobal_.end(),
+ std::copy(statePropagatorData_->vGlobal_.begin(),
+ statePropagatorData_->vGlobal_.end(),
statePropagatorData_->v_.begin());
}
}
{
auto globalXRef =
MASTER(cr_) ? statePropagatorData_->globalState_->x : gmx::ArrayRef<gmx::RVec>();
- dd_collect_vec(cr_->dd, localStateBackup_->ddp_count, localStateBackup_->ddp_count_cg_gl,
- localStateBackup_->cg_gl, localStateBackup_->x, globalXRef);
+ dd_collect_vec(cr_->dd,
+ localStateBackup_->ddp_count,
+ localStateBackup_->ddp_count_cg_gl,
+ localStateBackup_->cg_gl,
+ localStateBackup_->x,
+ globalXRef);
auto globalVRef =
MASTER(cr_) ? statePropagatorData_->globalState_->v : gmx::ArrayRef<gmx::RVec>();
- dd_collect_vec(cr_->dd, localStateBackup_->ddp_count, localStateBackup_->ddp_count_cg_gl,
- localStateBackup_->cg_gl, localStateBackup_->v, globalVRef);
+ dd_collect_vec(cr_->dd,
+ localStateBackup_->ddp_count,
+ localStateBackup_->ddp_count_cg_gl,
+ localStateBackup_->cg_gl,
+ localStateBackup_->v,
+ globalVRef);
}
else
{
if (canMoleculesBeDistributedOverPBC_ && !systemHasPeriodicMolecules_)
{
// Make molecules whole only for confout writing
- do_pbc_mtop(pbcType_, localStateBackup_->box, top_global_,
+ do_pbc_mtop(pbcType_,
+ localStateBackup_->box,
+ top_global_,
statePropagatorData_->globalState_->x.rvec_array());
}
- write_sto_conf_mtop(finalConfigurationFilename_.c_str(), *top_global_->name, top_global_,
+ write_sto_conf_mtop(finalConfigurationFilename_.c_str(),
+ *top_global_->name,
+ top_global_,
statePropagatorData_->globalState_->x.rvec_array(),
- statePropagatorData_->globalState_->v.rvec_array(), pbcType_,
+ statePropagatorData_->globalState_->v.rvec_array(),
+ pbcType_,
localStateBackup_->box);
}
wallcycle_stop(mdoutf_get_wcycle(outf), ewcTRAJ);
// Note: Legacy mdrun resizes the force buffer in mdAlgorithmsSetupAtomData()
// TopologyHolder has no access to the forces, so we are passing a nullptr
// TODO: Find a unique approach to resizing the forces in modular simulator (#3461)
- mdAlgorithmsSetupAtomData(cr, inputrec, globalTopology, localTopology_.get(), fr, nullptr,
- mdAtoms, constr, vsite, nullptr);
+ mdAlgorithmsSetupAtomData(
+ cr, inputrec, globalTopology, localTopology_.get(), fr, nullptr, mdAtoms, constr, vsite, nullptr);
}
// Send copy of initial topology to clients
updateLocalTopology();
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
* temperatureCouplingData.numDegreesOfFreedom[temperatureGroup];
const real newKineticEnergy =
- vrescale_resamplekin(currentKineticEnergy, referenceKineticEnergy,
+ vrescale_resamplekin(currentKineticEnergy,
+ referenceKineticEnergy,
temperatureCouplingData.numDegreesOfFreedom[temperatureGroup],
temperatureCouplingData.couplingTime[temperatureGroup]
/ temperatureCouplingData.couplingTimeStep,
- step, seed_);
+ step,
+ seed_);
// Analytically newKineticEnergy >= 0, but we check for rounding errors
if (newKineticEnergy <= 0)
if (debug)
{
- fprintf(debug, "TC: group %d: Ekr %g, Ek %g, Ek_new %g, Lambda: %g\n", temperatureGroup,
- referenceKineticEnergy, currentKineticEnergy, newKineticEnergy,
+ fprintf(debug,
+ "TC: group %d: Ekr %g, Ek %g, Ek_new %g, Lambda: %g\n",
+ temperatureGroup,
+ referenceKineticEnergy,
+ currentKineticEnergy,
+ newKineticEnergy,
lambdaStartVelocities_[temperatureGroup]);
}
std::max<real>(std::min<real>(lambda, 1.25_real), 0.8_real);
if (debug)
{
- fprintf(debug, "TC: group %d: T: %g, Lambda: %g\n", temperatureGroup,
- currentTemperature, lambdaStartVelocities_[temperatureGroup]);
+ fprintf(debug,
+ "TC: group %d: T: %g, Lambda: %g\n",
+ temperatureGroup,
+ currentTemperature,
+ lambdaStartVelocities_[temperatureGroup]);
}
return temperatureCouplingData.temperatureCouplingIntegral[temperatureGroup]
- (lambdaStartVelocities_[temperatureGroup] * lambdaStartVelocities_[temperatureGroup]
const real* couplingTime,
const real* numDegreesOfFreedom,
EnergyData* energyData,
- TemperatureCouplingType couplingType) :
+ TemperatureCoupling couplingType) :
nstcouple_(nstcouple),
offset_(offset),
useFullStepKE_(useFullStepKE),
temperatureCouplingIntegralPreviousStep_ = temperatureCouplingIntegral_;
}
energyData->setVelocityScalingTemperatureCoupling(this);
- if (couplingType == etcVRESCALE)
+ if (couplingType == TemperatureCoupling::VRescale)
{
temperatureCouplingImpl_ = std::make_unique<VRescaleTemperatureCoupling>(seed);
}
- else if (couplingType == etcBERENDSEN)
+ else if (couplingType == TemperatureCoupling::Berendsen)
{
temperatureCouplingImpl_ = std::make_unique<BerendsenTemperatureCoupling>();
}
else
{
- throw NotImplementedError("Temperature coupling " + std::string(ETCOUPLTYPE(couplingType))
+ throw NotImplementedError("Temperature coupling " + std::string(enumValueToString(couplingType))
+ " is not implemented for modular simulator.");
}
}
}
const auto* ekind = energyData_->ekindata();
- TemperatureCouplingData thermostatData = { couplingTimeStep_, referenceTemperature_, couplingTime_,
- numDegreesOfFreedom_, temperatureCouplingIntegral_ };
+ TemperatureCouplingData thermostatData = {
+ couplingTimeStep_, referenceTemperature_, couplingTime_, numDegreesOfFreedom_, temperatureCouplingIntegral_
+ };
for (int temperatureGroup = 0; (temperatureGroup < numTemperatureGroups_); temperatureGroup++)
{
}
if (DOMAINDECOMP(cr))
{
- dd_bcast(cr->dd, ssize(temperatureCouplingIntegral_) * int(sizeof(double)),
+ dd_bcast(cr->dd,
+ ssize(temperatureCouplingIntegral_) * int(sizeof(double)),
temperatureCouplingIntegral_.data());
}
temperatureCouplingImpl_->readCheckpoint(
if (reportPreviousConservedEnergy_ == ReportPreviousStepConservedEnergy::Yes)
{
return std::accumulate(temperatureCouplingIntegralPreviousStep_.begin(),
- temperatureCouplingIntegralPreviousStep_.end(), 0.0);
+ temperatureCouplingIntegralPreviousStep_.end(),
+ 0.0);
}
else
{
- return std::accumulate(temperatureCouplingIntegral_.begin(),
- temperatureCouplingIntegral_.end(), 0.0);
+ return std::accumulate(
+ temperatureCouplingIntegral_.begin(), temperatureCouplingIntegral_.end(), 0.0);
}
}
{
// Element is now owned by the caller of this method, who will handle lifetime (see ModularSimulatorAlgorithm)
auto* element = builderHelper->storeElement(std::make_unique<VelocityScalingTemperatureCoupling>(
- legacySimulatorData->inputrec->nsttcouple, offset, useFullStepKE, reportPreviousStepConservedEnergy,
- legacySimulatorData->inputrec->ld_seed, legacySimulatorData->inputrec->opts.ngtc,
+ legacySimulatorData->inputrec->nsttcouple,
+ offset,
+ useFullStepKE,
+ reportPreviousStepConservedEnergy,
+ legacySimulatorData->inputrec->ld_seed,
+ legacySimulatorData->inputrec->opts.ngtc,
legacySimulatorData->inputrec->delta_t * legacySimulatorData->inputrec->nsttcouple,
- legacySimulatorData->inputrec->opts.ref_t, legacySimulatorData->inputrec->opts.tau_t,
- legacySimulatorData->inputrec->opts.nrdf, energyData, legacySimulatorData->inputrec->etc));
+ legacySimulatorData->inputrec->opts.ref_t,
+ legacySimulatorData->inputrec->opts.tau_t,
+ legacySimulatorData->inputrec->opts.nrdf,
+ energyData,
+ legacySimulatorData->inputrec->etc));
auto* thermostat = static_cast<VelocityScalingTemperatureCoupling*>(element);
// Capturing pointer is safe because lifetime is handled by caller
builderHelper->registerThermostat([thermostat](const PropagatorThermostatConnection& connection) {
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
Count
};
-//! Typedef to match current use of ints as types.
-using TemperatureCouplingType = int;
-
/*! \internal
* \ingroup module_modularsimulator
* \brief Element implementing the a velocity-scaling thermostat
const real* couplingTime,
const real* numDegreesOfFreedom,
EnergyData* energyData,
- TemperatureCouplingType couplingType);
+ TemperatureCoupling couplingType);
/*! \brief Register run function for step / time
*
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+# Set up the module library
+add_library(nbnxm INTERFACE)
+
add_subdirectory(kernels_simd_4xm)
add_subdirectory(kernels_simd_2xmm)
endif()
set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${NBNXM_SOURCES} PARENT_SCOPE)
+
+
+# Source files have the following private module dependencies.
+target_link_libraries(nbnxm PRIVATE
+ )
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(nbnxm PUBLIC
+target_include_directories(nbnxm INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(nbnxm PUBLIC
+target_link_libraries(nbnxm INTERFACE
+ legacy_api
+ )
+
+# TODO: when nbnxm is an OBJECT target
+#target_link_libraries(nbnxm PUBLIC legacy_api)
+#target_link_libraries(nbnxm PRIVATE common)
+
+# Module dependencies
+# nbnxm interfaces convey transitive dependence on these modules.
+#target_link_libraries(nbnxm PUBLIC
+target_link_libraries(nbnxm INTERFACE
+ utility
+ )
\ No newline at end of file
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012-2018, The GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "atomdata.h"
-#include <cassert>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <algorithm>
-#include "thread_mpi/atomic.h"
-
#include "gromacs/math/functions.h"
#include "gromacs/math/utilities.h"
#include "gromacs/math/vec.h"
#include "gromacs/mdlib/gmx_omp_nthreads.h"
#include "gromacs/mdtypes/forcerec.h" // only for GET_CGINFO_*
+#include "gromacs/mdtypes/md_enums.h"
#include "gromacs/nbnxm/nbnxm.h"
#include "gromacs/pbcutil/ishift.h"
#include "gromacs/simd/simd.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/gmxomp.h"
#include "gromacs/utility/logger.h"
-#include "gromacs/utility/smalloc.h"
#include "gromacs/utility/strconvert.h"
#include "gromacs/utility/stringutil.h"
using namespace gmx; // TODO: Remove when this file is moved into gmx namespace
+
+const char* enumValueToString(LJCombinationRule enumValue)
+{
+ static constexpr gmx::EnumerationArray<LJCombinationRule, const char*> s_ljCombinationRuleNames = {
+ "Geometric", "Lorentz-Berthelot", "None"
+ };
+ return s_ljCombinationRuleNames[enumValue];
+}
+
void nbnxn_atomdata_t::resizeCoordinateBuffer(int numAtoms)
{
numAtoms_ = numAtoms;
static void copy_int_to_nbat_int(const int* a, int na, int na_round, const int* in, int fill, int* innb)
{
- int i, j;
-
- j = 0;
- for (i = 0; i < na; i++)
+ int j = 0;
+ for (int i = 0; i < na; i++)
{
innb[j++] = in[a[i]];
}
/* Complete the partially filled last cell with fill */
- for (; i < na_round; i++)
+ for (int i = na; i < na_round; i++)
{
innb[j++] = fill;
}
*/
const real farAway = -1000000;
- int i, j, c;
-
- switch (nbatFormat)
+ if (nbatFormat == nbatXYZ)
{
- case nbatXYZ:
- j = a0 * STRIDE_XYZ;
- for (i = 0; i < na; i++)
- {
- xnb[j++] = x[a[i]][XX];
- xnb[j++] = x[a[i]][YY];
- xnb[j++] = x[a[i]][ZZ];
- }
- /* Complete the partially filled last cell with farAway elements */
- for (; i < na_round; i++)
- {
- xnb[j++] = farAway;
- xnb[j++] = farAway;
- xnb[j++] = farAway;
- }
- break;
- case nbatXYZQ:
- j = a0 * STRIDE_XYZQ;
- for (i = 0; i < na; i++)
- {
- xnb[j++] = x[a[i]][XX];
- xnb[j++] = x[a[i]][YY];
- xnb[j++] = x[a[i]][ZZ];
- j++;
- }
- /* Complete the partially filled last cell with zeros */
- for (; i < na_round; i++)
- {
- xnb[j++] = farAway;
- xnb[j++] = farAway;
- xnb[j++] = farAway;
- j++;
- }
- break;
- case nbatX4:
- j = atom_to_x_index<c_packX4>(a0);
- c = a0 & (c_packX4 - 1);
- for (i = 0; i < na; i++)
+ int i = 0;
+ int j = a0 * STRIDE_XYZ;
+ for (; i < na; i++)
+ {
+ xnb[j++] = x[a[i]][XX];
+ xnb[j++] = x[a[i]][YY];
+ xnb[j++] = x[a[i]][ZZ];
+ }
+ /* Complete the partially filled last cell with farAway elements */
+ for (; i < na_round; i++)
+ {
+ xnb[j++] = farAway;
+ xnb[j++] = farAway;
+ xnb[j++] = farAway;
+ }
+ }
+ else if (nbatFormat == nbatXYZQ)
+ {
+ int i = 0;
+ int j = a0 * STRIDE_XYZQ;
+ for (; i < na; i++)
+ {
+ xnb[j++] = x[a[i]][XX];
+ xnb[j++] = x[a[i]][YY];
+ xnb[j++] = x[a[i]][ZZ];
+ j++;
+ }
+ /* Complete the partially filled last cell with zeros */
+ for (; i < na_round; i++)
+ {
+ xnb[j++] = farAway;
+ xnb[j++] = farAway;
+ xnb[j++] = farAway;
+ j++;
+ }
+ }
+ else if (nbatFormat == nbatX4)
+ {
+ int i = 0;
+ int j = atom_to_x_index<c_packX4>(a0);
+ int c = a0 & (c_packX4 - 1);
+ for (; i < na; i++)
+ {
+ xnb[j + XX * c_packX4] = x[a[i]][XX];
+ xnb[j + YY * c_packX4] = x[a[i]][YY];
+ xnb[j + ZZ * c_packX4] = x[a[i]][ZZ];
+ j++;
+ c++;
+ if (c == c_packX4)
{
- xnb[j + XX * c_packX4] = x[a[i]][XX];
- xnb[j + YY * c_packX4] = x[a[i]][YY];
- xnb[j + ZZ * c_packX4] = x[a[i]][ZZ];
- j++;
- c++;
- if (c == c_packX4)
- {
- j += (DIM - 1) * c_packX4;
- c = 0;
- }
+ j += (DIM - 1) * c_packX4;
+ c = 0;
}
- /* Complete the partially filled last cell with zeros */
- for (; i < na_round; i++)
+ }
+ /* Complete the partially filled last cell with zeros */
+ for (; i < na_round; i++)
+ {
+ xnb[j + XX * c_packX4] = farAway;
+ xnb[j + YY * c_packX4] = farAway;
+ xnb[j + ZZ * c_packX4] = farAway;
+ j++;
+ c++;
+ if (c == c_packX4)
{
- xnb[j + XX * c_packX4] = farAway;
- xnb[j + YY * c_packX4] = farAway;
- xnb[j + ZZ * c_packX4] = farAway;
- j++;
- c++;
- if (c == c_packX4)
- {
- j += (DIM - 1) * c_packX4;
- c = 0;
- }
+ j += (DIM - 1) * c_packX4;
+ c = 0;
}
- break;
- case nbatX8:
- j = atom_to_x_index<c_packX8>(a0);
- c = a0 & (c_packX8 - 1);
- for (i = 0; i < na; i++)
+ }
+ }
+ else if (nbatFormat == nbatX8)
+ {
+ int i = 0;
+ int j = atom_to_x_index<c_packX8>(a0);
+ int c = a0 & (c_packX8 - 1);
+ for (; i < na; i++)
+ {
+ xnb[j + XX * c_packX8] = x[a[i]][XX];
+ xnb[j + YY * c_packX8] = x[a[i]][YY];
+ xnb[j + ZZ * c_packX8] = x[a[i]][ZZ];
+ j++;
+ c++;
+ if (c == c_packX8)
{
- xnb[j + XX * c_packX8] = x[a[i]][XX];
- xnb[j + YY * c_packX8] = x[a[i]][YY];
- xnb[j + ZZ * c_packX8] = x[a[i]][ZZ];
- j++;
- c++;
- if (c == c_packX8)
- {
- j += (DIM - 1) * c_packX8;
- c = 0;
- }
+ j += (DIM - 1) * c_packX8;
+ c = 0;
}
- /* Complete the partially filled last cell with zeros */
- for (; i < na_round; i++)
+ }
+ /* Complete the partially filled last cell with zeros */
+ for (; i < na_round; i++)
+ {
+ xnb[j + XX * c_packX8] = farAway;
+ xnb[j + YY * c_packX8] = farAway;
+ xnb[j + ZZ * c_packX8] = farAway;
+ j++;
+ c++;
+ if (c == c_packX8)
{
- xnb[j + XX * c_packX8] = farAway;
- xnb[j + YY * c_packX8] = farAway;
- xnb[j + ZZ * c_packX8] = farAway;
- j++;
- c++;
- if (c == c_packX8)
- {
- j += (DIM - 1) * c_packX8;
- c = 0;
- }
+ j += (DIM - 1) * c_packX8;
+ c = 0;
}
- break;
- default: gmx_incons("Unsupported nbnxn_atomdata_t format");
+ }
+ }
+ else
+ {
+ gmx_incons("Unsupported nbnxn_atomdata_t format");
}
}
* not per pair of atom types.
*/
params->nbfp_comb.resize(nt * 2);
- switch (params->comb_rule)
+ switch (params->ljCombinationRule)
{
- case ljcrGEOM:
- params->comb_rule = ljcrGEOM;
-
+ case LJCombinationRule::Geometric:
for (int i = 0; i < nt; i++)
{
/* Store the sqrt of the diagonal from the nbfp matrix */
params->nbfp_comb[i * 2 + 1] = std::sqrt(params->nbfp[(i * nt + i) * 2 + 1]);
}
break;
- case ljcrLB:
+ case LJCombinationRule::LorentzBerthelot:
for (int i = 0; i < nt; i++)
{
/* Get 6*C6 and 12*C12 from the diagonal of the nbfp matrix */
}
}
break;
- case ljcrNONE:
+ case LJCombinationRule::None:
/* We always store the full matrix (see code above) */
break;
default: gmx_incons("Unknown combination rule");
/* Set the diagonal cluster pair exclusion mask setup data.
* In the kernel we check 0 < j - i to generate the masks.
* Here we store j - i for generating the mask for the first i,
- * we substract 0.5 to avoid rounding issues.
+ * we subtract 0.5 to avoid rounding issues.
* In the kernel we can subtract 1 to generate the subsequent mask.
*/
const int simd_4xn_diag_size = std::max(c_nbnxnCpuIClusterSize, simd_width);
shift_vec({}, { pinningPolicy }),
x_({}, { pinningPolicy }),
simdMasks(),
- bUseBufferFlags(FALSE),
- bUseTreeReduce(FALSE)
+ bUseBufferFlags(FALSE)
{
}
ArrayRef<const real> nbfp,
int n_energygroups)
{
- real c6, c12, tol;
- char* ptr;
- gmx_bool simple, bCombGeom, bCombLB, bSIMD;
-
if (debug)
{
fprintf(debug, "There are %d atom types in the system, adding one for nbnxn_atomdata_t\n", ntype);
/* A tolerance of 1e-5 seems reasonable for (possibly hand-typed)
* force-field floating point parameters.
*/
- tol = 1e-5;
- ptr = getenv("GMX_LJCOMB_TOL");
- if (ptr != nullptr)
+ real tol = 1e-5;
+ const char* tolOverrideString = getenv("GMX_LJCOMB_TOL");
+ if (tolOverrideString != nullptr)
{
- double dbl;
-
- sscanf(ptr, "%lf", &dbl);
- tol = dbl;
+ double tolOverride = std::strtod(tolOverrideString, nullptr);
+ tol = tolOverride;
}
- bCombGeom = TRUE;
- bCombLB = TRUE;
+ bool bCombGeom = true;
+ bool bCombLB = true;
/* Temporarily fill params->nbfp_comb with sigma and epsilon
* to check for the LB rule.
*/
for (int i = 0; i < ntype; i++)
{
- c6 = nbfp[(i * ntype + i) * 2] / 6.0;
- c12 = nbfp[(i * ntype + i) * 2 + 1] / 12.0;
+ const real c6 = nbfp[(i * ntype + i) * 2] / 6.0;
+ const real c12 = nbfp[(i * ntype + i) * 2 + 1] / 12.0;
if (c6 > 0 && c12 > 0)
{
params->nbfp_comb[i * 2] = gmx::sixthroot(c12 / c6);
else
{
/* Can not use LB rule with only dispersion or repulsion */
- bCombLB = FALSE;
+ bCombLB = false;
}
}
/* fr->nbfp has been updated, so that array too now stores c6/c12 including
* the 6.0/12.0 prefactors to save 2 flops in the most common case (force-only).
*/
- c6 = nbfp[(i * ntype + j) * 2];
- c12 = nbfp[(i * ntype + j) * 2 + 1];
+ real c6 = nbfp[(i * ntype + j) * 2];
+ real c12 = nbfp[(i * ntype + j) * 2 + 1];
+
params->nbfp[(i * params->numTypes + j) * 2] = c6;
params->nbfp[(i * params->numTypes + j) * 2 + 1] = c12;
/* Compare 6*C6 and 12*C12 for geometric cobination rule */
bCombGeom =
bCombGeom
- && gmx_within_tol(c6 * c6,
- nbfp[(i * ntype + i) * 2] * nbfp[(j * ntype + j) * 2], tol)
+ && gmx_within_tol(c6 * c6, nbfp[(i * ntype + i) * 2] * nbfp[(j * ntype + j) * 2], tol)
&& gmx_within_tol(c12 * c12,
nbfp[(i * ntype + i) * 2 + 1] * nbfp[(j * ntype + j) * 2 + 1],
tol);
&& ((c6 == 0 && c12 == 0
&& (params->nbfp_comb[i * 2 + 1] == 0 || params->nbfp_comb[j * 2 + 1] == 0))
|| (c6 > 0 && c12 > 0
- && gmx_within_tol(
- gmx::sixthroot(c12 / c6),
- 0.5 * (params->nbfp_comb[i * 2] + params->nbfp_comb[j * 2]), tol)
+ && gmx_within_tol(gmx::sixthroot(c12 / c6),
+ 0.5 * (params->nbfp_comb[i * 2] + params->nbfp_comb[j * 2]),
+ tol)
&& gmx_within_tol(0.25 * c6 * c6 / c12,
std::sqrt(params->nbfp_comb[i * 2 + 1]
* params->nbfp_comb[j * 2 + 1]),
}
if (debug)
{
- fprintf(debug, "Combination rules: geometric %s Lorentz-Berthelot %s\n",
- gmx::boolToString(bCombGeom), gmx::boolToString(bCombLB));
+ fprintf(debug,
+ "Combination rules: geometric %s Lorentz-Berthelot %s\n",
+ gmx::boolToString(bCombGeom),
+ gmx::boolToString(bCombLB));
}
- simple = Nbnxm::kernelTypeUsesSimplePairlist(kernelType);
+ const bool simple = Nbnxm::kernelTypeUsesSimplePairlist(kernelType);
switch (enbnxninitcombrule)
{
case enbnxninitcombruleDETECT:
- /* We prefer the geometic combination rule,
+ /* We prefer the geometric combination rule,
* as that gives a slightly faster kernel than the LB rule.
*/
if (bCombGeom)
{
- params->comb_rule = ljcrGEOM;
+ params->ljCombinationRule = LJCombinationRule::Geometric;
}
else if (bCombLB)
{
- params->comb_rule = ljcrLB;
+ params->ljCombinationRule = LJCombinationRule::LorentzBerthelot;
}
else
{
- params->comb_rule = ljcrNONE;
+ params->ljCombinationRule = LJCombinationRule::None;
params->nbfp_comb.clear();
}
{
std::string mesg;
- if (params->comb_rule == ljcrNONE)
+ if (params->ljCombinationRule == LJCombinationRule::None)
{
mesg = "Using full Lennard-Jones parameter combination matrix";
}
else
{
- mesg = gmx::formatString(
- "Using %s Lennard-Jones combination rule",
- params->comb_rule == ljcrGEOM ? "geometric" : "Lorentz-Berthelot");
+ mesg = gmx::formatString("Using %s Lennard-Jones combination rule",
+ enumValueToString(params->ljCombinationRule));
}
GMX_LOG(mdlog.info).asParagraph().appendText(mesg);
}
break;
- case enbnxninitcombruleGEOM: params->comb_rule = ljcrGEOM; break;
- case enbnxninitcombruleLB: params->comb_rule = ljcrLB; break;
+ case enbnxninitcombruleGEOM:
+ params->ljCombinationRule = LJCombinationRule::Geometric;
+ break;
+ case enbnxninitcombruleLB:
+ params->ljCombinationRule = LJCombinationRule::LorentzBerthelot;
+ break;
case enbnxninitcombruleNONE:
- params->comb_rule = ljcrNONE;
+ params->ljCombinationRule = LJCombinationRule::None;
params->nbfp_comb.clear();
break;
default: gmx_incons("Unknown enbnxninitcombrule");
}
- bSIMD = Nbnxm::kernelTypeIsSimd(kernelType);
+ const bool bSIMD = Nbnxm::kernelTypeIsSimd(kernelType);
set_lj_parameter_data(params, bSIMD);
int n_energygroups,
int nout)
{
- nbnxn_atomdata_params_init(mdlog, &nbat->paramsDeprecated(), kernelType, enbnxninitcombrule,
- ntype, nbfp, n_energygroups);
+ nbnxn_atomdata_params_init(
+ mdlog, &nbat->paramsDeprecated(), kernelType, enbnxninitcombrule, ntype, nbfp, n_energygroups);
const bool simple = Nbnxm::kernelTypeUsesSimplePairlist(kernelType);
const bool bSIMD = Nbnxm::kernelTypeIsSimd(kernelType);
if (simple)
{
- int pack_x;
-
if (bSIMD)
{
- pack_x = std::max(c_nbnxnCpuIClusterSize, Nbnxm::JClusterSizePerKernelType[kernelType]);
+ int pack_x = std::max(c_nbnxnCpuIClusterSize, Nbnxm::JClusterSizePerKernelType[kernelType]);
switch (pack_x)
{
case 4: nbat->XFormat = nbatX4; break;
for (int i = 0; i < nout; i++)
{
const auto& pinningPolicy = nbat->params().type.get_allocator().pinningPolicy();
- nbat->out.emplace_back(kernelType, nbat->params().nenergrp, 1 << nbat->params().neg_2log,
- pinningPolicy);
+ nbat->out.emplace_back(
+ kernelType, nbat->params().nenergrp, 1 << nbat->params().neg_2log, pinningPolicy);
}
nbat->buffer_flags.clear();
-
- const int nth = gmx_omp_nthreads_get(emntNonbonded);
-
- const char* ptr = getenv("GMX_USE_TREEREDUCE");
- if (ptr != nullptr)
- {
- nbat->bUseTreeReduce = (strtol(ptr, nullptr, 10) != 0);
- }
-#if defined __MIC__
- else if (nth > 8) /*on the CPU we currently don't benefit even at 32*/
- {
- nbat->bUseTreeReduce = 1;
- }
-#endif
- else
- {
- nbat->bUseTreeReduce = false;
- }
- if (nbat->bUseTreeReduce)
- {
- GMX_LOG(mdlog.info).asParagraph().appendText("Using tree force reduction");
-
- nbat->syncStep = new tMPI_Atomic[nth];
- }
}
template<int packSize>
const int atomOffset = grid.firstAtomInColumn(i);
copy_int_to_nbat_int(gridSet.atomIndices().data() + atomOffset,
- grid.numAtomsInColumn(i), numAtoms, atomTypes.data(),
- params->numTypes - 1, params->type.data() + atomOffset);
+ grid.numAtomsInColumn(i),
+ numAtoms,
+ atomTypes.data(),
+ params->numTypes - 1,
+ params->type.data() + atomOffset);
}
}
}
{
params->lj_comb.resize(gridSet.numGridAtomsTotal() * 2);
- if (params->comb_rule != ljcrNONE)
+ if (params->ljCombinationRule != LJCombinationRule::None)
{
for (const Nbnxm::Grid& grid : gridSet.grids())
{
if (XFormat == nbatX4)
{
copy_lj_to_nbat_lj_comb<c_packX4>(params->nbfp_comb,
- params->type.data() + atomOffset, numAtoms,
+ params->type.data() + atomOffset,
+ numAtoms,
params->lj_comb.data() + atomOffset * 2);
}
else if (XFormat == nbatX8)
{
copy_lj_to_nbat_lj_comb<c_packX8>(params->nbfp_comb,
- params->type.data() + atomOffset, numAtoms,
+ params->type.data() + atomOffset,
+ numAtoms,
params->lj_comb.data() + atomOffset * 2);
}
else if (XFormat == nbatXYZQ)
{
- copy_lj_to_nbat_lj_comb<1>(params->nbfp_comb, params->type.data() + atomOffset,
- numAtoms, params->lj_comb.data() + atomOffset * 2);
+ copy_lj_to_nbat_lj_comb<1>(params->nbfp_comb,
+ params->type.data() + atomOffset,
+ numAtoms,
+ params->lj_comb.data() + atomOffset * 2);
}
}
}
if (nbat->XFormat == nbatXYZQ)
{
real* q = nbat->x().data() + atomOffset * STRIDE_XYZQ + ZZ + 1;
- int i;
- for (i = 0; i < numAtoms; i++)
+ for (int i = 0; i < numAtoms; i++)
{
*q = charges[gridSet.atomIndices()[atomOffset + i]];
q += STRIDE_XYZQ;
}
/* Complete the partially filled last cell with zeros */
- for (; i < paddedNumAtoms; i++)
+ for (int i = numAtoms; i < paddedNumAtoms; i++)
{
*q = 0;
q += STRIDE_XYZQ;
else
{
real* q = nbat->paramsDeprecated().q.data() + atomOffset;
- int i;
- for (i = 0; i < numAtoms; i++)
+ for (int i = 0; i < numAtoms; i++)
{
*q = charges[gridSet.atomIndices()[atomOffset + i]];
q++;
}
/* Complete the partially filled last cell with zeros */
- for (; i < paddedNumAtoms; i++)
+ for (int i = numAtoms; i < paddedNumAtoms; i++)
{
*q = 0;
q++;
static void nbnxn_atomdata_mask_fep(nbnxn_atomdata_t* nbat, const Nbnxm::GridSet& gridSet)
{
nbnxn_atomdata_t::Params& params = nbat->paramsDeprecated();
- real* q;
- int stride_q;
- if (nbat->XFormat == nbatXYZQ)
- {
- q = nbat->x().data() + ZZ + 1;
- stride_q = STRIDE_XYZQ;
- }
- else
- {
- q = params.q.data();
- stride_q = 1;
- }
+ const bool formatIsXYZQ = (nbat->XFormat == nbatXYZQ);
+
+ real* q = formatIsXYZQ ? (nbat->x().data() + ZZ + 1) : params.q.data();
+ int stride_q = formatIsXYZQ ? STRIDE_XYZQ : 1;
for (const Nbnxm::Grid& grid : gridSet.grids())
{
- int nsubc;
- if (grid.geometry().isSimple)
- {
- nsubc = 1;
- }
- else
- {
- nsubc = c_gpuNumClusterPerCell;
- }
+ const int nsubc = (grid.geometry().isSimple) ? 1 : c_gpuNumClusterPerCell;
- int c_offset = grid.firstAtomInColumn(0);
+ const int c_offset = grid.firstAtomInColumn(0);
/* Loop over all columns and copy and fill */
for (int c = 0; c < grid.numCells() * nsubc; c++)
static void
copy_egp_to_nbat_egps(const int* a, int na, int na_round, int na_c, int bit_shift, const int* in, int* innb)
{
- int i;
- int comb;
-
- int j = 0;
- for (i = 0; i < na; i += na_c)
+ int i = 0, j = 0;
+ for (; i < na; i += na_c)
{
/* Store na_c energy group numbers into one int */
- comb = 0;
+ int comb = 0;
for (int sa = 0; sa < na_c; sa++)
{
int at = a[i + sa];
const int numAtoms = grid.paddedNumAtomsInColumn(i);
const int atomOffset = grid.firstAtomInColumn(i);
- copy_egp_to_nbat_egps(gridSet.atomIndices().data() + atomOffset, grid.numAtomsInColumn(i),
- numAtoms, c_nbnxnCpuIClusterSize, params->neg_2log, atomInfo.data(),
+ copy_egp_to_nbat_egps(gridSet.atomIndices().data() + atomOffset,
+ grid.numAtomsInColumn(i),
+ numAtoms,
+ c_nbnxnCpuIClusterSize,
+ params->neg_2log,
+ atomInfo.data(),
params->energrp.data() + grid.atomToCluster(atomOffset));
}
}
/* Copies the shift vector array to nbnxn_atomdata_t */
void nbnxn_atomdata_copy_shiftvec(gmx_bool bDynamicBox, rvec* shift_vec, nbnxn_atomdata_t* nbat)
{
- int i;
-
nbat->bDynamicBox = bDynamicBox;
- for (i = 0; i < SHIFTS; i++)
+ for (int i = 0; i < SHIFTS; i++)
{
copy_rvec(shift_vec[i], nbat->shift_vec[i]);
}
const int na = grid.numAtomsInColumn(cxy);
const int ash = grid.firstAtomInColumn(cxy);
- int na_fill;
- if (g == 0 && fillLocal)
- {
- na_fill = grid.paddedNumAtomsInColumn(cxy);
- }
- else
- {
- /* We fill only the real particle locations.
- * We assume the filling entries at the end have been
- * properly set before during pair-list generation.
- */
- na_fill = na;
- }
- copy_rvec_to_nbat_real(gridSet.atomIndices().data() + ash, na, na_fill,
- coordinates, nbat->XFormat, nbat->x().data(), ash);
+ const bool mustFillPadding = (g == 0 && fillLocal);
+ /* When false, we fill only the real particle locations.
+ * We assume the filling entries at the end have been
+ * properly set before during pair-list generation.
+ */
+ const int na_fill = mustFillPadding ? grid.paddedNumAtomsInColumn(cxy) : na;
+
+ copy_rvec_to_nbat_real(gridSet.atomIndices().data() + ash,
+ na,
+ na_fill,
+ coordinates,
+ nbat->XFormat,
+ nbat->x().data(),
+ ash);
}
}
}
for (int g = gridBegin; g < gridEnd; g++)
{
- nbnxn_gpu_x_to_nbat_x(gridSet.grids()[g], fillLocal && g == 0, gpu_nbv, d_x, xReadyOnDevice,
- locality, g, gridSet.numColumnsMax());
+ nbnxn_gpu_x_to_nbat_x(gridSet.grids()[g],
+ fillLocal && g == 0,
+ gpu_nbv,
+ d_x,
+ xReadyOnDevice,
+ locality,
+ g,
+ gridSet.numColumnsMax());
}
}
}
else
{
- /* The destination buffer is unitialized, set it first */
+ /* The destination buffer is uninitialized, set it first */
for (int i = i0; i < i1; i++)
{
dest[i] = src[0][i];
}
}
-static inline unsigned char reverse_bits(unsigned char b)
-{
- /* http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith64BitsDiv */
- return (b * 0x0202020202ULL & 0x010884422010ULL) % 1023;
-}
-
-static void nbnxn_atomdata_add_nbat_f_to_f_treereduce(nbnxn_atomdata_t* nbat, int nth)
-{
- gmx::ArrayRef<const gmx_bitmask_t> flags = nbat->buffer_flags;
-
- int next_pow2 = 1 << (gmx::log2I(nth - 1) + 1);
-
- const int numOutputBuffers = nbat->out.size();
- GMX_ASSERT(numOutputBuffers == nth,
- "tree-reduce currently only works for numOutputBuffers==nth");
-
- memset(nbat->syncStep, 0, sizeof(*(nbat->syncStep)) * nth);
-
-#pragma omp parallel num_threads(nth)
- {
- try
- {
- int b0, b1, b;
- int i0, i1;
- int group_size, th;
-
- th = gmx_omp_get_thread_num();
-
- for (group_size = 2; group_size < 2 * next_pow2; group_size *= 2)
- {
- int index[2], group_pos, partner_pos, wu;
- int partner_th = th ^ (group_size / 2);
-
- if (group_size > 2)
- {
-#ifdef TMPI_ATOMICS
- /* wait on partner thread - replaces full barrier */
- int sync_th, sync_group_size;
-
-# if defined(__clang__) && __clang_major__ >= 8
- // Suppress warnings that the use of memory_barrier may be excessive
- // Only exists beginning with clang-8
-# pragma clang diagnostic push
-# pragma clang diagnostic ignored "-Watomic-implicit-seq-cst"
-# endif
-
- tMPI_Atomic_memory_barrier(); /* guarantee data is saved before marking work as done */
- tMPI_Atomic_set(&(nbat->syncStep[th]), group_size / 2); /* mark previous step as completed */
-
- /* find thread to sync with. Equal to partner_th unless nth is not a power of two. */
- for (sync_th = partner_th, sync_group_size = group_size;
- sync_th >= nth && sync_group_size > 2; sync_group_size /= 2)
- {
- sync_th &= ~(sync_group_size / 4);
- }
- if (sync_th < nth) /* otherwise nothing to sync index[1] will be >=nout */
- {
- /* wait on the thread which computed input data in previous step */
- while (tMPI_Atomic_get(static_cast<volatile tMPI_Atomic_t*>(&(nbat->syncStep[sync_th])))
- < group_size / 2)
- {
- gmx_pause();
- }
- /* guarantee that no later load happens before wait loop is finisehd */
- tMPI_Atomic_memory_barrier();
- }
-# if defined(__clang__) && __clang_major__ >= 8
-# pragma clang diagnostic pop
-# endif
-#else /* TMPI_ATOMICS */
-# pragma omp barrier
-#endif
- }
-
- /* Calculate buffers to sum (result goes into first buffer) */
- group_pos = th % group_size;
- index[0] = th - group_pos;
- index[1] = index[0] + group_size / 2;
-
- /* If no second buffer, nothing to do */
- if (index[1] >= numOutputBuffers && group_size > 2)
- {
- continue;
- }
-
-#if NBNXN_BUFFERFLAG_MAX_THREADS > 256
-# error reverse_bits assumes max 256 threads
-#endif
- /* Position is permuted so that one of the 2 vectors being added was computed on the same thread in the previous step.
- This improves locality and enables to sync with just a single thread between steps (=the levels in the btree).
- The permutation which allows this corresponds to reversing the bits of the group position.
- */
- group_pos = reverse_bits(group_pos) / (256 / group_size);
-
- partner_pos = group_pos ^ 1;
-
- /* loop over two work-units (own and partner) */
- for (wu = 0; wu < 2; wu++)
- {
- if (wu == 1)
- {
- if (partner_th < nth)
- {
- break; /* partner exists we don't have to do his work */
- }
- else
- {
- group_pos = partner_pos;
- }
- }
-
- /* Calculate the cell-block range for our thread */
- b0 = (flags.size() * group_pos) / group_size;
- b1 = (flags.size() * (group_pos + 1)) / group_size;
-
- for (b = b0; b < b1; b++)
- {
- i0 = b * NBNXN_BUFFERFLAG_SIZE * nbat->fstride;
- i1 = (b + 1) * NBNXN_BUFFERFLAG_SIZE * nbat->fstride;
-
- if (bitmask_is_set(flags[b], index[1]) || group_size > 2)
- {
- const real* fIndex1 = nbat->out[index[1]].f.data();
-#if GMX_SIMD
- nbnxn_atomdata_reduce_reals_simd
-#else
- nbnxn_atomdata_reduce_reals
-#endif
- (nbat->out[index[0]].f.data(),
- bitmask_is_set(flags[b], index[0]) || group_size > 2, &fIndex1,
- 1, i0, i1);
- }
- else if (!bitmask_is_set(flags[b], index[0]))
- {
- nbnxn_atomdata_clear_reals(nbat->out[index[0]].f, i0, i1);
- }
- }
- }
- }
- }
- GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
- }
-}
-
-
-static void nbnxn_atomdata_add_nbat_f_to_f_stdreduce(nbnxn_atomdata_t* nbat, int nth)
+static void nbnxn_atomdata_add_nbat_f_to_f_reduce(nbnxn_atomdata_t* nbat, int nth)
{
#pragma omp parallel for num_threads(nth) schedule(static)
for (int th = 0; th < nth; th++)
{
try
{
- int nfptr;
const real* fptr[NBNXN_BUFFERFLAG_MAX_THREADS];
gmx::ArrayRef<const gmx_bitmask_t> flags = nbat->buffer_flags;
/* Calculate the cell-block range for our thread */
- int b0 = (flags.size() * th) / nth;
- int b1 = (flags.size() * (th + 1)) / nth;
+ const int b0 = (flags.size() * th) / nth;
+ const int b1 = (flags.size() * (th + 1)) / nth;
for (int b = b0; b < b1; b++)
{
- int i0 = b * NBNXN_BUFFERFLAG_SIZE * nbat->fstride;
- int i1 = (b + 1) * NBNXN_BUFFERFLAG_SIZE * nbat->fstride;
+ const int i0 = b * NBNXN_BUFFERFLAG_SIZE * nbat->fstride;
+ const int i1 = (b + 1) * NBNXN_BUFFERFLAG_SIZE * nbat->fstride;
- nfptr = 0;
+ int nfptr = 0;
for (gmx::index out = 1; out < gmx::ssize(nbat->out); out++)
{
if (bitmask_is_set(flags[b], out))
/* Reduce the force thread output buffers into buffer 0, before adding
* them to the, differently ordered, "real" force buffer.
*/
- if (nbat->bUseTreeReduce)
- {
- nbnxn_atomdata_add_nbat_f_to_f_treereduce(nbat, nth);
- }
- else
- {
- nbnxn_atomdata_add_nbat_f_to_f_stdreduce(nbat, nth);
- }
+ nbnxn_atomdata_add_nbat_f_to_f_reduce(nbat, nth);
}
#pragma omp parallel for num_threads(nth) schedule(static)
for (int th = 0; th < nth; th++)
{
try
{
- nbnxn_atomdata_add_nbat_f_to_f_part(gridSet, *nbat, nbat->out[0], a0 + ((th + 0) * na) / nth,
- a0 + ((th + 1) * na) / nth, f);
+ nbnxn_atomdata_add_nbat_f_to_f_part(
+ gridSet, *nbat, nbat->out[0], a0 + ((th + 0) * na) / nth, a0 + ((th + 1) * na) / nth, f);
}
GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
}
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team.
- * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2020,2021, 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.
struct NbnxmGpu;
struct nbnxn_atomdata_t;
struct nonbonded_verlet_t;
-struct tMPI_Atomic;
class GpuEventSynchronizer;
#define NBNXN_BUFFERFLAG_MAX_THREADS (BITMASK_SIZE)
-/*! \brief LJ combination rules: geometric, Lorentz-Berthelot, none */
-enum
+//! LJ combination rules
+enum class LJCombinationRule : int
{
- ljcrGEOM,
- ljcrLB,
- ljcrNONE,
- ljcrNR
+ //! Geometric
+ Geometric,
+ //! Lorentz-Berthelot
+ LorentzBerthelot,
+ //! No rule
+ None,
+ //! Size of the enum
+ Count
};
+//! String corresponding to LJ combination rule
+const char* enumValueToString(LJCombinationRule enumValue);
+
/*! \internal
* \brief Struct that stores atom related data for the nbnxn module
*
//! Lennard-Jone 6*C6 and 12*C12 parameters, size numTypes*2*2
gmx::HostVector<real> nbfp;
//! Combination rule, see enum defined above
- int comb_rule;
+ LJCombinationRule ljCombinationRule;
//! LJ parameters per atom type, size numTypes*2
gmx::HostVector<real> nbfp_comb;
//! As nbfp, but with a stride for the present SIMD architecture
/*! \brief Constructor
*
- * \param[in] pinningPolicy Sets the pinning policy for all data that might be transfered to a GPU
+ * \param[in] pinningPolicy Sets the pinning policy for all data that might be transferred to a GPU
*/
nbnxn_atomdata_t(gmx::PinningPolicy pinningPolicy);
gmx_bool bUseBufferFlags;
//! Flags for buffer zeroing+reduc.
std::vector<gmx_bitmask_t> buffer_flags;
- //! Use tree for force reduction
- gmx_bool bUseTreeReduce;
- //! Synchronization step for tree reduce
- tMPI_Atomic* syncStep;
//! \}
};
PairlistParams pairlistParams(kernelSetup.kernelType, false, options.pairlistCutoff, false);
- GridSet gridSet(PbcType::Xyz, false, nullptr, nullptr, pairlistParams.pairlistType, false,
- numThreads, pinPolicy);
+ GridSet gridSet(
+ PbcType::Xyz, false, nullptr, nullptr, pairlistParams.pairlistType, false, numThreads, pinPolicy);
auto pairlistSets = std::make_unique<PairlistSets>(pairlistParams, false, 0);
- auto pairSearch =
- std::make_unique<PairSearch>(PbcType::Xyz, false, nullptr, nullptr,
- pairlistParams.pairlistType, false, numThreads, pinPolicy);
+ auto pairSearch = std::make_unique<PairSearch>(
+ PbcType::Xyz, false, nullptr, nullptr, pairlistParams.pairlistType, false, numThreads, pinPolicy);
auto atomData = std::make_unique<nbnxn_atomdata_t>(pinPolicy);
// Put everything together
- auto nbv = std::make_unique<nonbonded_verlet_t>(std::move(pairlistSets), std::move(pairSearch),
- std::move(atomData), kernelSetup, nullptr, nullptr);
-
- nbnxn_atomdata_init(gmx::MDLogger(), nbv->nbat.get(), kernelSetup.kernelType, combinationRule,
- system.numAtomTypes, system.nonbondedParameters, 1, numThreads);
+ auto nbv = std::make_unique<nonbonded_verlet_t>(
+ std::move(pairlistSets), std::move(pairSearch), std::move(atomData), kernelSetup, nullptr, nullptr);
+
+ nbnxn_atomdata_init(gmx::MDLogger(),
+ nbv->nbat.get(),
+ kernelSetup.kernelType,
+ combinationRule,
+ system.numAtomTypes,
+ system.nonbondedParameters,
+ 1,
+ numThreads);
t_nrnb nrnb;
const real atomDensity = system.coordinates.size() / det(system.box);
- nbnxn_put_on_grid(nbv.get(), system.box, 0, lowerCorner, upperCorner, nullptr,
- { 0, int(system.coordinates.size()) }, atomDensity, atomInfo,
- system.coordinates, 0, nullptr);
+ nbnxn_put_on_grid(nbv.get(),
+ system.box,
+ 0,
+ lowerCorner,
+ upperCorner,
+ nullptr,
+ { 0, int(system.coordinates.size()) },
+ atomDensity,
+ atomInfo,
+ system.coordinates,
+ 0,
+ nullptr);
nbv->constructPairlist(gmx::InteractionLocality::Local, system.excls, 0, &nrnb);
stepWork.computeEnergy = true;
}
- const gmx::EnumerationArray<BenchMarkKernels, std::string> kernelNames = { "auto", "no", "4xM",
- "2xMM" };
+ const gmx::EnumerationArray<BenchMarkKernels, std::string> kernelNames = {
+ "auto", "no", "4xM", "2xMM"
+ };
- const gmx::EnumerationArray<BenchMarkCombRule, std::string> combruleNames = { "geom.", "LB",
+ const gmx::EnumerationArray<BenchMarkCombRule, std::string> combruleNames = { "geom.",
+ "LB",
"none" };
if (!doWarmup)
{
- fprintf(stdout, "%-7s %-4s %-5s %-4s ",
+ fprintf(stdout,
+ "%-7s %-4s %-5s %-4s ",
options.coulombType == BenchMarkCoulomb::Pme ? "Ewald" : "RF",
options.useHalfLJOptimization ? "half" : "all",
- combruleNames[options.ljCombinationRule].c_str(), kernelNames[options.nbnxmSimd].c_str());
+ combruleNames[options.ljCombinationRule].c_str(),
+ kernelNames[options.nbnxmSimd].c_str());
if (!options.outputFile.empty())
{
fprintf(system.csv,
#else
0,
#endif
- system.coordinates.size(), options.pairlistCutoff, options.numThreads,
- options.numIterations, options.computeVirialAndEnergy ? "yes" : "no",
+ system.coordinates.size(),
+ options.pairlistCutoff,
+ options.numThreads,
+ options.numIterations,
+ options.computeVirialAndEnergy ? "yes" : "no",
(options.coulombType != BenchMarkCoulomb::ReactionField)
? ((options.nbnxmSimd == BenchMarkKernels::SimdNo || options.useTabulatedEwaldCorr)
? "table"
// Run pre-iteration to avoid cache misses
for (int iter = 0; iter < options.numPreIterations; iter++)
{
- nbv->dispatchNonbondedKernel(gmx::InteractionLocality::Local, ic, stepWork, enbvClearFYes,
- system.forceRec, &enerd, &nrnb);
+ nbv->dispatchNonbondedKernel(
+ gmx::InteractionLocality::Local, ic, stepWork, enbvClearFYes, system.forceRec, &enerd, &nrnb);
}
const int numIterations = (doWarmup ? options.numWarmupIterations : options.numIterations);
for (int iter = 0; iter < numIterations; iter++)
{
// Run the kernel without force clearing
- nbv->dispatchNonbondedKernel(gmx::InteractionLocality::Local, ic, stepWork, enbvClearFNo,
- system.forceRec, &enerd, &nrnb);
+ nbv->dispatchNonbondedKernel(
+ gmx::InteractionLocality::Local, ic, stepWork, enbvClearFNo, system.forceRec, &enerd, &nrnb);
}
cycles = gmx_cycles_read() - cycles;
if (!doWarmup)
const double uSec = static_cast<double>(cycles) * gmx_cycles_calibrate(1.0) * 1.e6;
if (options.cyclesPerPair)
{
- fprintf(stdout, "%13.2f %13.3f %10.3f %10.3f\n", uSec, uSec / options.numIterations,
+ fprintf(stdout,
+ "%13.2f %13.3f %10.3f %10.3f\n",
+ uSec,
+ uSec / options.numIterations,
uSec / (options.numIterations * numPairs),
uSec / (options.numIterations * numUsefulPairs));
if (!options.outputFile.empty())
{
- fprintf(system.csv, "\"%.3f\",\"%.4f\",\"%.4f\",\"%.4f\"\n", uSec,
- uSec / options.numIterations, uSec / (options.numIterations * numPairs),
+ fprintf(system.csv,
+ "\"%.3f\",\"%.4f\",\"%.4f\",\"%.4f\"\n",
+ uSec,
+ uSec / options.numIterations,
+ uSec / (options.numIterations * numPairs),
uSec / (options.numIterations * numUsefulPairs));
}
}
else
{
- fprintf(stdout, "%13.2f %13.3f %10.3f %10.3f\n", uSec, uSec / options.numIterations,
+ fprintf(stdout,
+ "%13.2f %13.3f %10.3f %10.3f\n",
+ uSec,
+ uSec / options.numIterations,
options.numIterations * numPairs / uSec,
options.numIterations * numUsefulPairs / uSec);
if (!options.outputFile.empty())
{
- fprintf(system.csv, "\"%.3f\",\"%.4f\",\"%.4f\",\"%.4f\"\n", uSec,
- uSec / options.numIterations, options.numIterations * numPairs / uSec,
+ fprintf(system.csv,
+ "\"%.3f\",\"%.4f\",\"%.4f\",\"%.4f\"\n",
+ uSec,
+ uSec / options.numIterations,
+ options.numIterations * numPairs / uSec,
options.numIterations * numUsefulPairs / uSec);
}
}
const double dCycles = static_cast<double>(cycles);
if (options.cyclesPerPair)
{
- fprintf(stdout, "%10.3f %10.4f %8.4f %8.4f\n", cycles * 1e-6,
+ fprintf(stdout,
+ "%10.3f %10.4f %8.4f %8.4f\n",
+ cycles * 1e-6,
dCycles / options.numIterations * 1e-6,
dCycles / (options.numIterations * numPairs),
dCycles / (options.numIterations * numUsefulPairs));
}
else
{
- fprintf(stdout, "%10.3f %10.4f %8.4f %8.4f\n", dCycles * 1e-6,
- dCycles / options.numIterations * 1e-6, options.numIterations * numPairs / dCycles,
+ fprintf(stdout,
+ "%10.3f %10.4f %8.4f %8.4f\n",
+ dCycles * 1e-6,
+ dCycles / options.numIterations * 1e-6,
+ options.numIterations * numPairs / dCycles,
options.numIterations * numUsefulPairs / dCycles);
}
}
fprintf(stdout, "Compute energies: %s\n", options.computeVirialAndEnergy ? "yes" : "no");
if (options.coulombType != BenchMarkCoulomb::ReactionField)
{
- fprintf(stdout, "Ewald excl. corr.: %s\n",
+ fprintf(stdout,
+ "Ewald excl. corr.: %s\n",
options.nbnxmSimd == BenchMarkKernels::SimdNo || options.useTabulatedEwaldCorr
? "table"
: "analytical");
if (options.reportTime)
{
- fprintf(stdout, "Coulomb LJ comb. SIMD usec usec/it. %s\n",
+ fprintf(stdout,
+ "Coulomb LJ comb. SIMD usec usec/it. %s\n",
options.cyclesPerPair ? "usec/pair" : "pairs/usec");
if (!options.outputFile.empty())
{
}
else
{
- fprintf(stdout, "Coulomb LJ comb. SIMD Mcycles Mcycles/it. %s\n",
+ fprintf(stdout,
+ "Coulomb LJ comb. SIMD Mcycles Mcycles/it. %s\n",
options.cyclesPerPair ? "cycles/pair" : "pairs/cycle");
if (!options.outputFile.empty())
{
dim = 0;
}
}
- printf("Stacking a box of %zu atoms %d x %d x %d times\n", coordinates1000.size(), factors[XX],
- factors[YY], factors[ZZ]);
+ printf("Stacking a box of %zu atoms %d x %d x %d times\n",
+ coordinates1000.size(),
+ factors[XX],
+ factors[YY],
+ factors[ZZ]);
coordinates->resize(factors[XX] * factors[YY] * factors[ZZ] * coordinates1000.size());
#elif GMX_SIMD && GMX_SIMD_REAL_WIDTH == 8
return ClusterDistanceKernelType::CpuSimd_2xMM;
#else
- GMX_RELEASE_ASSERT(false,
- "Expect 4-wide or 8-wide SIMD with 4x4 list and nbat SIMD layout");
+ GMX_RELEASE_ASSERT(false, "Expect 4-wide or 8-wide SIMD with 4x4 list and nbat SIMD layout");
#endif
}
else
"Watch out, the input system is too large to simulate!\n"
"The number of nonbonded work units (=number of super-clusters) exceeds the"
"maximum grid size in x dimension (%d > %d)!",
- nwork_units, max_grid_x_size);
+ nwork_units,
+ max_grid_x_size);
}
return nwork_units;
*/
/*! Force-only kernel function pointers. */
-static const nbnxn_cu_kfunc_ptr_t nb_kfunc_noener_noprune_ptr[eelTypeNR][evdwTypeNR] = {
- { nbnxn_kernel_ElecCut_VdwLJ_F_cuda, nbnxn_kernel_ElecCut_VdwLJCombGeom_F_cuda,
- nbnxn_kernel_ElecCut_VdwLJCombLB_F_cuda, nbnxn_kernel_ElecCut_VdwLJFsw_F_cuda,
- nbnxn_kernel_ElecCut_VdwLJPsw_F_cuda, nbnxn_kernel_ElecCut_VdwLJEwCombGeom_F_cuda,
+static const nbnxn_cu_kfunc_ptr_t nb_kfunc_noener_noprune_ptr[c_numElecTypes][c_numVdwTypes] = {
+ { nbnxn_kernel_ElecCut_VdwLJ_F_cuda,
+ nbnxn_kernel_ElecCut_VdwLJCombGeom_F_cuda,
+ nbnxn_kernel_ElecCut_VdwLJCombLB_F_cuda,
+ nbnxn_kernel_ElecCut_VdwLJFsw_F_cuda,
+ nbnxn_kernel_ElecCut_VdwLJPsw_F_cuda,
+ nbnxn_kernel_ElecCut_VdwLJEwCombGeom_F_cuda,
nbnxn_kernel_ElecCut_VdwLJEwCombLB_F_cuda },
- { nbnxn_kernel_ElecRF_VdwLJ_F_cuda, nbnxn_kernel_ElecRF_VdwLJCombGeom_F_cuda,
- nbnxn_kernel_ElecRF_VdwLJCombLB_F_cuda, nbnxn_kernel_ElecRF_VdwLJFsw_F_cuda,
- nbnxn_kernel_ElecRF_VdwLJPsw_F_cuda, nbnxn_kernel_ElecRF_VdwLJEwCombGeom_F_cuda,
+ { nbnxn_kernel_ElecRF_VdwLJ_F_cuda,
+ nbnxn_kernel_ElecRF_VdwLJCombGeom_F_cuda,
+ nbnxn_kernel_ElecRF_VdwLJCombLB_F_cuda,
+ nbnxn_kernel_ElecRF_VdwLJFsw_F_cuda,
+ nbnxn_kernel_ElecRF_VdwLJPsw_F_cuda,
+ nbnxn_kernel_ElecRF_VdwLJEwCombGeom_F_cuda,
nbnxn_kernel_ElecRF_VdwLJEwCombLB_F_cuda },
- { nbnxn_kernel_ElecEwQSTab_VdwLJ_F_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJCombGeom_F_cuda,
- nbnxn_kernel_ElecEwQSTab_VdwLJCombLB_F_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJFsw_F_cuda,
- nbnxn_kernel_ElecEwQSTab_VdwLJPsw_F_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJEwCombGeom_F_cuda,
+ { nbnxn_kernel_ElecEwQSTab_VdwLJ_F_cuda,
+ nbnxn_kernel_ElecEwQSTab_VdwLJCombGeom_F_cuda,
+ nbnxn_kernel_ElecEwQSTab_VdwLJCombLB_F_cuda,
+ nbnxn_kernel_ElecEwQSTab_VdwLJFsw_F_cuda,
+ nbnxn_kernel_ElecEwQSTab_VdwLJPsw_F_cuda,
+ nbnxn_kernel_ElecEwQSTab_VdwLJEwCombGeom_F_cuda,
nbnxn_kernel_ElecEwQSTab_VdwLJEwCombLB_F_cuda },
- { nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJ_F_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombGeom_F_cuda,
- nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombLB_F_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJFsw_F_cuda,
- nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJPsw_F_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombGeom_F_cuda,
+ { nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJ_F_cuda,
+ nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombGeom_F_cuda,
+ nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombLB_F_cuda,
+ nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJFsw_F_cuda,
+ nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJPsw_F_cuda,
+ nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombGeom_F_cuda,
nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombLB_F_cuda },
- { nbnxn_kernel_ElecEw_VdwLJ_F_cuda, nbnxn_kernel_ElecEw_VdwLJCombGeom_F_cuda,
- nbnxn_kernel_ElecEw_VdwLJCombLB_F_cuda, nbnxn_kernel_ElecEw_VdwLJFsw_F_cuda,
- nbnxn_kernel_ElecEw_VdwLJPsw_F_cuda, nbnxn_kernel_ElecEw_VdwLJEwCombGeom_F_cuda,
+ { nbnxn_kernel_ElecEw_VdwLJ_F_cuda,
+ nbnxn_kernel_ElecEw_VdwLJCombGeom_F_cuda,
+ nbnxn_kernel_ElecEw_VdwLJCombLB_F_cuda,
+ nbnxn_kernel_ElecEw_VdwLJFsw_F_cuda,
+ nbnxn_kernel_ElecEw_VdwLJPsw_F_cuda,
+ nbnxn_kernel_ElecEw_VdwLJEwCombGeom_F_cuda,
nbnxn_kernel_ElecEw_VdwLJEwCombLB_F_cuda },
- { nbnxn_kernel_ElecEwTwinCut_VdwLJ_F_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJCombGeom_F_cuda,
- nbnxn_kernel_ElecEwTwinCut_VdwLJCombLB_F_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJFsw_F_cuda,
- nbnxn_kernel_ElecEwTwinCut_VdwLJPsw_F_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombGeom_F_cuda,
+ { nbnxn_kernel_ElecEwTwinCut_VdwLJ_F_cuda,
+ nbnxn_kernel_ElecEwTwinCut_VdwLJCombGeom_F_cuda,
+ nbnxn_kernel_ElecEwTwinCut_VdwLJCombLB_F_cuda,
+ nbnxn_kernel_ElecEwTwinCut_VdwLJFsw_F_cuda,
+ nbnxn_kernel_ElecEwTwinCut_VdwLJPsw_F_cuda,
+ nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombGeom_F_cuda,
nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombLB_F_cuda }
};
/*! Force + energy kernel function pointers. */
-static const nbnxn_cu_kfunc_ptr_t nb_kfunc_ener_noprune_ptr[eelTypeNR][evdwTypeNR] = {
- { nbnxn_kernel_ElecCut_VdwLJ_VF_cuda, nbnxn_kernel_ElecCut_VdwLJCombGeom_VF_cuda,
- nbnxn_kernel_ElecCut_VdwLJCombLB_VF_cuda, nbnxn_kernel_ElecCut_VdwLJFsw_VF_cuda,
- nbnxn_kernel_ElecCut_VdwLJPsw_VF_cuda, nbnxn_kernel_ElecCut_VdwLJEwCombGeom_VF_cuda,
+static const nbnxn_cu_kfunc_ptr_t nb_kfunc_ener_noprune_ptr[c_numElecTypes][c_numVdwTypes] = {
+ { nbnxn_kernel_ElecCut_VdwLJ_VF_cuda,
+ nbnxn_kernel_ElecCut_VdwLJCombGeom_VF_cuda,
+ nbnxn_kernel_ElecCut_VdwLJCombLB_VF_cuda,
+ nbnxn_kernel_ElecCut_VdwLJFsw_VF_cuda,
+ nbnxn_kernel_ElecCut_VdwLJPsw_VF_cuda,
+ nbnxn_kernel_ElecCut_VdwLJEwCombGeom_VF_cuda,
nbnxn_kernel_ElecCut_VdwLJEwCombLB_VF_cuda },
- { nbnxn_kernel_ElecRF_VdwLJ_VF_cuda, nbnxn_kernel_ElecRF_VdwLJCombGeom_VF_cuda,
- nbnxn_kernel_ElecRF_VdwLJCombLB_VF_cuda, nbnxn_kernel_ElecRF_VdwLJFsw_VF_cuda,
- nbnxn_kernel_ElecRF_VdwLJPsw_VF_cuda, nbnxn_kernel_ElecRF_VdwLJEwCombGeom_VF_cuda,
+ { nbnxn_kernel_ElecRF_VdwLJ_VF_cuda,
+ nbnxn_kernel_ElecRF_VdwLJCombGeom_VF_cuda,
+ nbnxn_kernel_ElecRF_VdwLJCombLB_VF_cuda,
+ nbnxn_kernel_ElecRF_VdwLJFsw_VF_cuda,
+ nbnxn_kernel_ElecRF_VdwLJPsw_VF_cuda,
+ nbnxn_kernel_ElecRF_VdwLJEwCombGeom_VF_cuda,
nbnxn_kernel_ElecRF_VdwLJEwCombLB_VF_cuda },
- { nbnxn_kernel_ElecEwQSTab_VdwLJ_VF_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJCombGeom_VF_cuda,
- nbnxn_kernel_ElecEwQSTab_VdwLJCombLB_VF_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJFsw_VF_cuda,
- nbnxn_kernel_ElecEwQSTab_VdwLJPsw_VF_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJEwCombGeom_VF_cuda,
+ { nbnxn_kernel_ElecEwQSTab_VdwLJ_VF_cuda,
+ nbnxn_kernel_ElecEwQSTab_VdwLJCombGeom_VF_cuda,
+ nbnxn_kernel_ElecEwQSTab_VdwLJCombLB_VF_cuda,
+ nbnxn_kernel_ElecEwQSTab_VdwLJFsw_VF_cuda,
+ nbnxn_kernel_ElecEwQSTab_VdwLJPsw_VF_cuda,
+ nbnxn_kernel_ElecEwQSTab_VdwLJEwCombGeom_VF_cuda,
nbnxn_kernel_ElecEwQSTab_VdwLJEwCombLB_VF_cuda },
- { nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJ_VF_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombGeom_VF_cuda,
- nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombLB_VF_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJFsw_VF_cuda,
- nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJPsw_VF_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombGeom_VF_cuda,
+ { nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJ_VF_cuda,
+ nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombGeom_VF_cuda,
+ nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombLB_VF_cuda,
+ nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJFsw_VF_cuda,
+ nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJPsw_VF_cuda,
+ nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombGeom_VF_cuda,
nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombLB_VF_cuda },
- { nbnxn_kernel_ElecEw_VdwLJ_VF_cuda, nbnxn_kernel_ElecEw_VdwLJCombGeom_VF_cuda,
- nbnxn_kernel_ElecEw_VdwLJCombLB_VF_cuda, nbnxn_kernel_ElecEw_VdwLJFsw_VF_cuda,
- nbnxn_kernel_ElecEw_VdwLJPsw_VF_cuda, nbnxn_kernel_ElecEw_VdwLJEwCombGeom_VF_cuda,
+ { nbnxn_kernel_ElecEw_VdwLJ_VF_cuda,
+ nbnxn_kernel_ElecEw_VdwLJCombGeom_VF_cuda,
+ nbnxn_kernel_ElecEw_VdwLJCombLB_VF_cuda,
+ nbnxn_kernel_ElecEw_VdwLJFsw_VF_cuda,
+ nbnxn_kernel_ElecEw_VdwLJPsw_VF_cuda,
+ nbnxn_kernel_ElecEw_VdwLJEwCombGeom_VF_cuda,
nbnxn_kernel_ElecEw_VdwLJEwCombLB_VF_cuda },
- { nbnxn_kernel_ElecEwTwinCut_VdwLJ_VF_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJCombGeom_VF_cuda,
- nbnxn_kernel_ElecEwTwinCut_VdwLJCombLB_VF_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJFsw_VF_cuda,
- nbnxn_kernel_ElecEwTwinCut_VdwLJPsw_VF_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF_cuda,
+ { nbnxn_kernel_ElecEwTwinCut_VdwLJ_VF_cuda,
+ nbnxn_kernel_ElecEwTwinCut_VdwLJCombGeom_VF_cuda,
+ nbnxn_kernel_ElecEwTwinCut_VdwLJCombLB_VF_cuda,
+ nbnxn_kernel_ElecEwTwinCut_VdwLJFsw_VF_cuda,
+ nbnxn_kernel_ElecEwTwinCut_VdwLJPsw_VF_cuda,
+ nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF_cuda,
nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombLB_VF_cuda }
};
/*! Force + pruning kernel function pointers. */
-static const nbnxn_cu_kfunc_ptr_t nb_kfunc_noener_prune_ptr[eelTypeNR][evdwTypeNR] = {
- { nbnxn_kernel_ElecCut_VdwLJ_F_prune_cuda, nbnxn_kernel_ElecCut_VdwLJCombGeom_F_prune_cuda,
- nbnxn_kernel_ElecCut_VdwLJCombLB_F_prune_cuda, nbnxn_kernel_ElecCut_VdwLJFsw_F_prune_cuda,
- nbnxn_kernel_ElecCut_VdwLJPsw_F_prune_cuda, nbnxn_kernel_ElecCut_VdwLJEwCombGeom_F_prune_cuda,
+static const nbnxn_cu_kfunc_ptr_t nb_kfunc_noener_prune_ptr[c_numElecTypes][c_numVdwTypes] = {
+ { nbnxn_kernel_ElecCut_VdwLJ_F_prune_cuda,
+ nbnxn_kernel_ElecCut_VdwLJCombGeom_F_prune_cuda,
+ nbnxn_kernel_ElecCut_VdwLJCombLB_F_prune_cuda,
+ nbnxn_kernel_ElecCut_VdwLJFsw_F_prune_cuda,
+ nbnxn_kernel_ElecCut_VdwLJPsw_F_prune_cuda,
+ nbnxn_kernel_ElecCut_VdwLJEwCombGeom_F_prune_cuda,
nbnxn_kernel_ElecCut_VdwLJEwCombLB_F_prune_cuda },
- { nbnxn_kernel_ElecRF_VdwLJ_F_prune_cuda, nbnxn_kernel_ElecRF_VdwLJCombGeom_F_prune_cuda,
- nbnxn_kernel_ElecRF_VdwLJCombLB_F_prune_cuda, nbnxn_kernel_ElecRF_VdwLJFsw_F_prune_cuda,
- nbnxn_kernel_ElecRF_VdwLJPsw_F_prune_cuda, nbnxn_kernel_ElecRF_VdwLJEwCombGeom_F_prune_cuda,
+ { nbnxn_kernel_ElecRF_VdwLJ_F_prune_cuda,
+ nbnxn_kernel_ElecRF_VdwLJCombGeom_F_prune_cuda,
+ nbnxn_kernel_ElecRF_VdwLJCombLB_F_prune_cuda,
+ nbnxn_kernel_ElecRF_VdwLJFsw_F_prune_cuda,
+ nbnxn_kernel_ElecRF_VdwLJPsw_F_prune_cuda,
+ nbnxn_kernel_ElecRF_VdwLJEwCombGeom_F_prune_cuda,
nbnxn_kernel_ElecRF_VdwLJEwCombLB_F_prune_cuda },
- { nbnxn_kernel_ElecEwQSTab_VdwLJ_F_prune_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJCombGeom_F_prune_cuda,
- nbnxn_kernel_ElecEwQSTab_VdwLJCombLB_F_prune_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJFsw_F_prune_cuda,
- nbnxn_kernel_ElecEwQSTab_VdwLJPsw_F_prune_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJEwCombGeom_F_prune_cuda,
+ { nbnxn_kernel_ElecEwQSTab_VdwLJ_F_prune_cuda,
+ nbnxn_kernel_ElecEwQSTab_VdwLJCombGeom_F_prune_cuda,
+ nbnxn_kernel_ElecEwQSTab_VdwLJCombLB_F_prune_cuda,
+ nbnxn_kernel_ElecEwQSTab_VdwLJFsw_F_prune_cuda,
+ nbnxn_kernel_ElecEwQSTab_VdwLJPsw_F_prune_cuda,
+ nbnxn_kernel_ElecEwQSTab_VdwLJEwCombGeom_F_prune_cuda,
nbnxn_kernel_ElecEwQSTab_VdwLJEwCombLB_F_prune_cuda },
{ nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJ_F_prune_cuda,
nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombGeom_F_prune_cuda,
nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombLB_F_prune_cuda,
- nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJFsw_F_prune_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJPsw_F_prune_cuda,
+ nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJFsw_F_prune_cuda,
+ nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJPsw_F_prune_cuda,
nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombGeom_F_prune_cuda,
nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombLB_F_prune_cuda },
- { nbnxn_kernel_ElecEw_VdwLJ_F_prune_cuda, nbnxn_kernel_ElecEw_VdwLJCombGeom_F_prune_cuda,
- nbnxn_kernel_ElecEw_VdwLJCombLB_F_prune_cuda, nbnxn_kernel_ElecEw_VdwLJFsw_F_prune_cuda,
- nbnxn_kernel_ElecEw_VdwLJPsw_F_prune_cuda, nbnxn_kernel_ElecEw_VdwLJEwCombGeom_F_prune_cuda,
+ { nbnxn_kernel_ElecEw_VdwLJ_F_prune_cuda,
+ nbnxn_kernel_ElecEw_VdwLJCombGeom_F_prune_cuda,
+ nbnxn_kernel_ElecEw_VdwLJCombLB_F_prune_cuda,
+ nbnxn_kernel_ElecEw_VdwLJFsw_F_prune_cuda,
+ nbnxn_kernel_ElecEw_VdwLJPsw_F_prune_cuda,
+ nbnxn_kernel_ElecEw_VdwLJEwCombGeom_F_prune_cuda,
nbnxn_kernel_ElecEw_VdwLJEwCombLB_F_prune_cuda },
- { nbnxn_kernel_ElecEwTwinCut_VdwLJ_F_prune_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJCombGeom_F_prune_cuda,
- nbnxn_kernel_ElecEwTwinCut_VdwLJCombLB_F_prune_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJFsw_F_prune_cuda,
- nbnxn_kernel_ElecEwTwinCut_VdwLJPsw_F_prune_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombGeom_F_prune_cuda,
+ { nbnxn_kernel_ElecEwTwinCut_VdwLJ_F_prune_cuda,
+ nbnxn_kernel_ElecEwTwinCut_VdwLJCombGeom_F_prune_cuda,
+ nbnxn_kernel_ElecEwTwinCut_VdwLJCombLB_F_prune_cuda,
+ nbnxn_kernel_ElecEwTwinCut_VdwLJFsw_F_prune_cuda,
+ nbnxn_kernel_ElecEwTwinCut_VdwLJPsw_F_prune_cuda,
+ nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombGeom_F_prune_cuda,
nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombLB_F_prune_cuda }
};
/*! Force + energy + pruning kernel function pointers. */
-static const nbnxn_cu_kfunc_ptr_t nb_kfunc_ener_prune_ptr[eelTypeNR][evdwTypeNR] = {
- { nbnxn_kernel_ElecCut_VdwLJ_VF_prune_cuda, nbnxn_kernel_ElecCut_VdwLJCombGeom_VF_prune_cuda,
- nbnxn_kernel_ElecCut_VdwLJCombLB_VF_prune_cuda, nbnxn_kernel_ElecCut_VdwLJFsw_VF_prune_cuda,
- nbnxn_kernel_ElecCut_VdwLJPsw_VF_prune_cuda, nbnxn_kernel_ElecCut_VdwLJEwCombGeom_VF_prune_cuda,
+static const nbnxn_cu_kfunc_ptr_t nb_kfunc_ener_prune_ptr[c_numElecTypes][c_numVdwTypes] = {
+ { nbnxn_kernel_ElecCut_VdwLJ_VF_prune_cuda,
+ nbnxn_kernel_ElecCut_VdwLJCombGeom_VF_prune_cuda,
+ nbnxn_kernel_ElecCut_VdwLJCombLB_VF_prune_cuda,
+ nbnxn_kernel_ElecCut_VdwLJFsw_VF_prune_cuda,
+ nbnxn_kernel_ElecCut_VdwLJPsw_VF_prune_cuda,
+ nbnxn_kernel_ElecCut_VdwLJEwCombGeom_VF_prune_cuda,
nbnxn_kernel_ElecCut_VdwLJEwCombLB_VF_prune_cuda },
- { nbnxn_kernel_ElecRF_VdwLJ_VF_prune_cuda, nbnxn_kernel_ElecRF_VdwLJCombGeom_VF_prune_cuda,
- nbnxn_kernel_ElecRF_VdwLJCombLB_VF_prune_cuda, nbnxn_kernel_ElecRF_VdwLJFsw_VF_prune_cuda,
- nbnxn_kernel_ElecRF_VdwLJPsw_VF_prune_cuda, nbnxn_kernel_ElecRF_VdwLJEwCombGeom_VF_prune_cuda,
+ { nbnxn_kernel_ElecRF_VdwLJ_VF_prune_cuda,
+ nbnxn_kernel_ElecRF_VdwLJCombGeom_VF_prune_cuda,
+ nbnxn_kernel_ElecRF_VdwLJCombLB_VF_prune_cuda,
+ nbnxn_kernel_ElecRF_VdwLJFsw_VF_prune_cuda,
+ nbnxn_kernel_ElecRF_VdwLJPsw_VF_prune_cuda,
+ nbnxn_kernel_ElecRF_VdwLJEwCombGeom_VF_prune_cuda,
nbnxn_kernel_ElecRF_VdwLJEwCombLB_VF_prune_cuda },
- { nbnxn_kernel_ElecEwQSTab_VdwLJ_VF_prune_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJCombGeom_VF_prune_cuda,
- nbnxn_kernel_ElecEwQSTab_VdwLJCombLB_VF_prune_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJFsw_VF_prune_cuda,
- nbnxn_kernel_ElecEwQSTab_VdwLJPsw_VF_prune_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJEwCombGeom_VF_prune_cuda,
+ { nbnxn_kernel_ElecEwQSTab_VdwLJ_VF_prune_cuda,
+ nbnxn_kernel_ElecEwQSTab_VdwLJCombGeom_VF_prune_cuda,
+ nbnxn_kernel_ElecEwQSTab_VdwLJCombLB_VF_prune_cuda,
+ nbnxn_kernel_ElecEwQSTab_VdwLJFsw_VF_prune_cuda,
+ nbnxn_kernel_ElecEwQSTab_VdwLJPsw_VF_prune_cuda,
+ nbnxn_kernel_ElecEwQSTab_VdwLJEwCombGeom_VF_prune_cuda,
nbnxn_kernel_ElecEwQSTab_VdwLJEwCombLB_VF_prune_cuda },
{ nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJ_VF_prune_cuda,
nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombGeom_VF_prune_cuda,
nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJPsw_VF_prune_cuda,
nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombGeom_VF_prune_cuda,
nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombLB_VF_prune_cuda },
- { nbnxn_kernel_ElecEw_VdwLJ_VF_prune_cuda, nbnxn_kernel_ElecEw_VdwLJCombGeom_VF_prune_cuda,
- nbnxn_kernel_ElecEw_VdwLJCombLB_VF_prune_cuda, nbnxn_kernel_ElecEw_VdwLJFsw_VF_prune_cuda,
- nbnxn_kernel_ElecEw_VdwLJPsw_VF_prune_cuda, nbnxn_kernel_ElecEw_VdwLJEwCombGeom_VF_prune_cuda,
+ { nbnxn_kernel_ElecEw_VdwLJ_VF_prune_cuda,
+ nbnxn_kernel_ElecEw_VdwLJCombGeom_VF_prune_cuda,
+ nbnxn_kernel_ElecEw_VdwLJCombLB_VF_prune_cuda,
+ nbnxn_kernel_ElecEw_VdwLJFsw_VF_prune_cuda,
+ nbnxn_kernel_ElecEw_VdwLJPsw_VF_prune_cuda,
+ nbnxn_kernel_ElecEw_VdwLJEwCombGeom_VF_prune_cuda,
nbnxn_kernel_ElecEw_VdwLJEwCombLB_VF_prune_cuda },
- { nbnxn_kernel_ElecEwTwinCut_VdwLJ_VF_prune_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJCombGeom_VF_prune_cuda,
+ { nbnxn_kernel_ElecEwTwinCut_VdwLJ_VF_prune_cuda,
+ nbnxn_kernel_ElecEwTwinCut_VdwLJCombGeom_VF_prune_cuda,
nbnxn_kernel_ElecEwTwinCut_VdwLJCombLB_VF_prune_cuda,
- nbnxn_kernel_ElecEwTwinCut_VdwLJFsw_VF_prune_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJPsw_VF_prune_cuda,
+ nbnxn_kernel_ElecEwTwinCut_VdwLJFsw_VF_prune_cuda,
+ nbnxn_kernel_ElecEwTwinCut_VdwLJPsw_VF_prune_cuda,
nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF_prune_cuda,
nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombLB_VF_prune_cuda }
};
/*! Return a pointer to the kernel version to be executed at the current step. */
-static inline nbnxn_cu_kfunc_ptr_t select_nbnxn_kernel(int eeltype,
- int evdwtype,
+static inline nbnxn_cu_kfunc_ptr_t select_nbnxn_kernel(enum ElecType elecType,
+ enum VdwType vdwType,
bool bDoEne,
bool bDoPrune,
const DeviceInformation gmx_unused* deviceInfo)
{
- nbnxn_cu_kfunc_ptr_t res;
+ const int elecTypeIdx = static_cast<int>(elecType);
+ const int vdwTypeIdx = static_cast<int>(vdwType);
- GMX_ASSERT(eeltype < eelTypeNR,
+ GMX_ASSERT(elecTypeIdx < c_numElecTypes,
"The electrostatics type requested is not implemented in the CUDA kernels.");
- GMX_ASSERT(evdwtype < evdwTypeNR,
+ GMX_ASSERT(vdwTypeIdx < c_numVdwTypes,
"The VdW type requested is not implemented in the CUDA kernels.");
/* assert assumptions made by the kernels */
{
if (bDoPrune)
{
- res = nb_kfunc_ener_prune_ptr[eeltype][evdwtype];
+ return nb_kfunc_ener_prune_ptr[elecTypeIdx][vdwTypeIdx];
}
else
{
- res = nb_kfunc_ener_noprune_ptr[eeltype][evdwtype];
+ return nb_kfunc_ener_noprune_ptr[elecTypeIdx][vdwTypeIdx];
}
}
else
{
if (bDoPrune)
{
- res = nb_kfunc_noener_prune_ptr[eeltype][evdwtype];
+ return nb_kfunc_noener_prune_ptr[elecTypeIdx][vdwTypeIdx];
}
else
{
- res = nb_kfunc_noener_noprune_ptr[eeltype][evdwtype];
+ return nb_kfunc_noener_noprune_ptr[elecTypeIdx][vdwTypeIdx];
}
}
-
- return res;
}
/*! \brief Calculates the amount of shared memory required by the nonbonded kernel in use. */
/* cj in shared memory, for each warp separately */
shmem += num_threads_z * c_nbnxnGpuClusterpairSplit * c_nbnxnGpuJgroupSize * sizeof(int);
- if (nbp->vdwtype == evdwTypeCUTCOMBGEOM || nbp->vdwtype == evdwTypeCUTCOMBLB)
+ if (nbp->vdwType == VdwType::CutCombGeom || nbp->vdwType == VdwType::CutCombLB)
{
/* i-atom LJ combination parameters in shared memory */
shmem += c_nbnxnGpuNumClusterPerSupercluster * c_clSize * sizeof(float2);
static_assert(sizeof(adat->xq[0]) == sizeof(float4),
"The size of the xyzq buffer element should be equal to the size of float4.");
- copyToDeviceBuffer(&adat->xq, reinterpret_cast<const float4*>(nbatom->x().data()) + adat_begin,
- adat_begin, adat_len, deviceStream, GpuApiCallBehavior::Async, nullptr);
+ copyToDeviceBuffer(&adat->xq,
+ reinterpret_cast<const float4*>(nbatom->x().data()) + adat_begin,
+ adat_begin,
+ adat_len,
+ deviceStream,
+ GpuApiCallBehavior::Async,
+ nullptr);
if (bDoTime)
{
"Non-bonded GPU launch configuration:\n\tThread block: %zux%zux%zu\n\t"
"\tGrid: %zux%zu\n\t#Super-clusters/clusters: %d/%d (%d)\n"
"\tShMem: %zu\n",
- config.blockSize[0], config.blockSize[1], config.blockSize[2], config.gridSize[0],
- config.gridSize[1], plist->nsci * c_nbnxnGpuNumClusterPerSupercluster,
- c_nbnxnGpuNumClusterPerSupercluster, plist->na_c, config.sharedMemorySize);
+ config.blockSize[0],
+ config.blockSize[1],
+ config.blockSize[2],
+ config.gridSize[0],
+ config.gridSize[1],
+ plist->nsci * c_nbnxnGpuNumClusterPerSupercluster,
+ c_nbnxnGpuNumClusterPerSupercluster,
+ plist->na_c,
+ config.sharedMemorySize);
}
auto* timingEvent = bDoTime ? t->interaction[iloc].nb_k.fetchNextEvent() : nullptr;
const auto kernel =
- select_nbnxn_kernel(nbp->eeltype, nbp->vdwtype, stepWork.computeEnergy,
+ select_nbnxn_kernel(nbp->elecType,
+ nbp->vdwType,
+ stepWork.computeEnergy,
(plist->haveFreshList && !nb->timers->interaction[iloc].didPrune),
&nb->deviceContext_->deviceInfo());
const auto kernelArgs =
"Pruning GPU kernel launch configuration:\n\tThread block: %zux%zux%zu\n\t"
"\tGrid: %zux%zu\n\t#Super-clusters/clusters: %d/%d (%d)\n"
"\tShMem: %zu\n",
- config.blockSize[0], config.blockSize[1], config.blockSize[2], config.gridSize[0],
- config.gridSize[1], numSciInPart * c_nbnxnGpuNumClusterPerSupercluster,
- c_nbnxnGpuNumClusterPerSupercluster, plist->na_c, config.sharedMemorySize);
+ config.blockSize[0],
+ config.blockSize[1],
+ config.blockSize[2],
+ config.gridSize[0],
+ config.gridSize[1],
+ numSciInPart * c_nbnxnGpuNumClusterPerSupercluster,
+ c_nbnxnGpuNumClusterPerSupercluster,
+ plist->na_c,
+ config.sharedMemorySize);
}
auto* timingEvent = bDoTime ? timer->fetchNextEvent() : nullptr;
static_assert(
sizeof(adat->f[0]) == sizeof(float3),
"The size of the force buffer element should be equal to the size of float3.");
- copyFromDeviceBuffer(reinterpret_cast<float3*>(nbatom->out[0].f.data()) + adat_begin, &adat->f,
- adat_begin, adat_len, deviceStream, GpuApiCallBehavior::Async, nullptr);
+ copyFromDeviceBuffer(reinterpret_cast<float3*>(nbatom->out[0].f.data()) + adat_begin,
+ &adat->f,
+ adat_begin,
+ adat_len,
+ deviceStream,
+ GpuApiCallBehavior::Async,
+ nullptr);
}
/* After the non-local D2H is launched the nonlocal_done event can be
{
static_assert(sizeof(nb->nbst.fshift[0]) == sizeof(adat->fshift[0]),
"Sizes of host- and device-side shift vectors should be the same.");
- copyFromDeviceBuffer(nb->nbst.fshift, &adat->fshift, 0, SHIFTS, deviceStream,
- GpuApiCallBehavior::Async, nullptr);
+ copyFromDeviceBuffer(
+ nb->nbst.fshift, &adat->fshift, 0, SHIFTS, deviceStream, GpuApiCallBehavior::Async, nullptr);
}
/* DtoH energies */
{
static_assert(sizeof(nb->nbst.e_lj[0]) == sizeof(adat->e_lj[0]),
"Sizes of host- and device-side LJ energy terms should be the same.");
- copyFromDeviceBuffer(nb->nbst.e_lj, &adat->e_lj, 0, 1, deviceStream,
- GpuApiCallBehavior::Async, nullptr);
+ copyFromDeviceBuffer(
+ nb->nbst.e_lj, &adat->e_lj, 0, 1, deviceStream, GpuApiCallBehavior::Async, nullptr);
static_assert(sizeof(nb->nbst.e_el[0]) == sizeof(adat->e_el[0]),
"Sizes of host- and device-side electrostatic energy terms should be the "
"same.");
- copyFromDeviceBuffer(nb->nbst.e_el, &adat->e_el, 0, 1, deviceStream,
- GpuApiCallBehavior::Async, nullptr);
+ copyFromDeviceBuffer(
+ nb->nbst.e_el, &adat->e_el, 0, 1, deviceStream, GpuApiCallBehavior::Async, nullptr);
}
}
{
cudaError_t stat;
- for (int i = 0; i < eelTypeNR; i++)
+ for (int i = 0; i < c_numElecTypes; i++)
{
- for (int j = 0; j < evdwTypeNR; j++)
+ for (int j = 0; j < c_numVdwTypes; j++)
{
/* Default kernel 32/32 kB Shared/L1 */
cudaFuncSetCacheConfig(nb_kfunc_ener_prune_ptr[i][j], cudaFuncCachePreferEqual);
const int* d_atomIndices = nb->atomIndices;
const int* d_cxy_na = &nb->cxy_na[numColumnsMax * gridId];
const int* d_cxy_ind = &nb->cxy_ind[numColumnsMax * gridId];
- const auto kernelArgs = prepareGpuKernelArguments(kernelFn, config, &numColumns, &d_xq,
- &d_xFloat3, &d_atomIndices, &d_cxy_na,
- &d_cxy_ind, &cellOffset, &numAtomsPerCell);
+ const auto kernelArgs = prepareGpuKernelArguments(kernelFn,
+ config,
+ &numColumns,
+ &d_xq,
+ &d_xFloat3,
+ &d_atomIndices,
+ &d_cxy_na,
+ &d_cxy_ind,
+ &cellOffset,
+ &numAtomsPerCell);
launchGpuKernel(kernelFn, config, deviceStream, nullptr, "XbufferOps", kernelArgs);
}
const nbnxn_atomdata_t::Params& nbatParams,
const DeviceContext& deviceContext)
{
- int ntypes;
-
- ntypes = nbatParams.numTypes;
+ const int ntypes = nbatParams.numTypes;
set_cutoff_parameters(nbp, ic, listParams);
* combination is rarely used. LJ force-switch with LB rule is more common,
* but gives only 1% speed-up.
*/
- if (ic->vdwtype == evdwCUT)
- {
- switch (ic->vdw_modifier)
- {
- case eintmodNONE:
- case eintmodPOTSHIFT:
- switch (nbatParams.comb_rule)
- {
- case ljcrNONE: nbp->vdwtype = evdwTypeCUT; break;
- case ljcrGEOM: nbp->vdwtype = evdwTypeCUTCOMBGEOM; break;
- case ljcrLB: nbp->vdwtype = evdwTypeCUTCOMBLB; break;
- default:
- gmx_incons(
- "The requested LJ combination rule is not implemented in the CUDA "
- "GPU accelerated kernels!");
- }
- break;
- case eintmodFORCESWITCH: nbp->vdwtype = evdwTypeFSWITCH; break;
- case eintmodPOTSWITCH: nbp->vdwtype = evdwTypePSWITCH; break;
- default:
- gmx_incons(
- "The requested VdW interaction modifier is not implemented in the CUDA GPU "
- "accelerated kernels!");
- }
- }
- else if (ic->vdwtype == evdwPME)
- {
- if (ic->ljpme_comb_rule == ljcrGEOM)
- {
- assert(nbatParams.comb_rule == ljcrGEOM);
- nbp->vdwtype = evdwTypeEWALDGEOM;
- }
- else
- {
- assert(nbatParams.comb_rule == ljcrLB);
- nbp->vdwtype = evdwTypeEWALDLB;
- }
- }
- else
- {
- gmx_incons(
- "The requested VdW type is not implemented in the CUDA GPU accelerated kernels!");
- }
-
- if (ic->eeltype == eelCUT)
- {
- nbp->eeltype = eelTypeCUT;
- }
- else if (EEL_RF(ic->eeltype))
- {
- nbp->eeltype = eelTypeRF;
- }
- else if ((EEL_PME(ic->eeltype) || ic->eeltype == eelEWALD))
- {
- nbp->eeltype = nbnxn_gpu_pick_ewald_kernel_type(*ic, deviceContext.deviceInfo());
- }
- else
- {
- /* Shouldn't happen, as this is checked when choosing Verlet-scheme */
- gmx_incons(
- "The requested electrostatics type is not implemented in the CUDA GPU accelerated "
- "kernels!");
- }
+ nbp->vdwType = nbnxmGpuPickVdwKernelType(ic, nbatParams.ljCombinationRule);
+ nbp->elecType = nbnxmGpuPickElectrostaticsKernelType(ic, deviceContext.deviceInfo());
/* generate table for PME */
nbp->coulomb_tab = nullptr;
- if (nbp->eeltype == eelTypeEWALD_TAB || nbp->eeltype == eelTypeEWALD_TAB_TWIN)
+ if (nbp->elecType == ElecType::EwaldTab || nbp->elecType == ElecType::EwaldTabTwin)
{
GMX_RELEASE_ASSERT(ic->coulombEwaldTables, "Need valid Coulomb Ewald correction tables");
init_ewald_coulomb_force_table(*ic->coulombEwaldTables, nbp, deviceContext);
}
/* set up LJ parameter lookup table */
- if (!useLjCombRule(nbp->vdwtype))
+ if (!useLjCombRule(nbp->vdwType))
{
- initParamLookupTable(&nbp->nbfp, &nbp->nbfp_texobj, nbatParams.nbfp.data(),
- 2 * ntypes * ntypes, deviceContext);
+ initParamLookupTable(
+ &nbp->nbfp, &nbp->nbfp_texobj, nbatParams.nbfp.data(), 2 * ntypes * ntypes, deviceContext);
}
/* set up LJ-PME parameter lookup table */
if (ic->vdwtype == evdwPME)
{
- initParamLookupTable(&nbp->nbfp_comb, &nbp->nbfp_comb_texobj, nbatParams.nbfp_comb.data(),
- 2 * ntypes, deviceContext);
+ initParamLookupTable(
+ &nbp->nbfp_comb, &nbp->nbfp_comb_texobj, nbatParams.nbfp_comb.data(), 2 * ntypes, deviceContext);
}
}
{
static_assert(sizeof(adat->shift_vec[0]) == sizeof(nbatom->shift_vec[0]),
"Sizes of host- and device-side shift vectors should be the same.");
- copyToDeviceBuffer(&adat->shift_vec, reinterpret_cast<const float3*>(nbatom->shift_vec.data()),
- 0, SHIFTS, localStream, GpuApiCallBehavior::Async, nullptr);
+ copyToDeviceBuffer(&adat->shift_vec,
+ reinterpret_cast<const float3*>(nbatom->shift_vec.data()),
+ 0,
+ SHIFTS,
+ localStream,
+ GpuApiCallBehavior::Async,
+ nullptr);
adat->bShiftVecUploaded = true;
}
}
allocateDeviceBuffer(&d_atdat->f, nalloc, deviceContext);
allocateDeviceBuffer(&d_atdat->xq, nalloc, deviceContext);
- if (useLjCombRule(nb->nbparam->vdwtype))
+ if (useLjCombRule(nb->nbparam->vdwType))
{
allocateDeviceBuffer(&d_atdat->lj_comb, nalloc, deviceContext);
}
nbnxn_cuda_clear_f(nb, nalloc);
}
- if (useLjCombRule(nb->nbparam->vdwtype))
+ if (useLjCombRule(nb->nbparam->vdwType))
{
static_assert(sizeof(d_atdat->lj_comb[0]) == sizeof(float2),
"Size of the LJ parameters element should be equal to the size of float2.");
copyToDeviceBuffer(&d_atdat->lj_comb,
- reinterpret_cast<const float2*>(nbat->params().lj_comb.data()), 0,
- natoms, localStream, GpuApiCallBehavior::Async, nullptr);
+ reinterpret_cast<const float2*>(nbat->params().lj_comb.data()),
+ 0,
+ natoms,
+ localStream,
+ GpuApiCallBehavior::Async,
+ nullptr);
}
else
{
static_assert(sizeof(d_atdat->atom_types[0]) == sizeof(nbat->params().type[0]),
"Sizes of host- and device-side atom types should be the same.");
- copyToDeviceBuffer(&d_atdat->atom_types, nbat->params().type.data(), 0, natoms, localStream,
- GpuApiCallBehavior::Async, nullptr);
+ copyToDeviceBuffer(&d_atdat->atom_types,
+ nbat->params().type.data(),
+ 0,
+ natoms,
+ localStream,
+ GpuApiCallBehavior::Async,
+ nullptr);
}
if (bDoTime)
nbparam = nb->nbparam;
if ((!nbparam->coulomb_tab)
- && (nbparam->eeltype == eelTypeEWALD_TAB || nbparam->eeltype == eelTypeEWALD_TAB_TWIN))
+ && (nbparam->elecType == ElecType::EwaldTab || nbparam->elecType == ElecType::EwaldTabTwin))
{
destroyParamLookupTable(&nbparam->coulomb_tab, nbparam->coulomb_tab_texobj);
}
delete nb->timers;
- if (!useLjCombRule(nb->nbparam->vdwtype))
+ if (!useLjCombRule(nb->nbparam->vdwType))
{
destroyParamLookupTable(&nbparam->nbfp, nbparam->nbfp_texobj);
}
- if (nbparam->vdwtype == evdwTypeEWALDGEOM || nbparam->vdwtype == evdwTypeEWALDLB)
+ if (nbparam->vdwType == VdwType::EwaldGeom || nbparam->vdwType == VdwType::EwaldLB)
{
destroyParamLookupTable(&nbparam->nbfp_comb, nbparam->nbfp_comb_texobj);
}
/* TODO Remove explicit pinning from host arrays from here and manage in a more natural way*/
void nbnxn_gpu_init_x_to_nbat_x(const Nbnxm::GridSet& gridSet, NbnxmGpu* gpu_nbv)
{
- const DeviceStream& deviceStream = *gpu_nbv->deviceStreams[InteractionLocality::Local];
+ const DeviceStream& localStream = *gpu_nbv->deviceStreams[InteractionLocality::Local];
bool bDoTime = gpu_nbv->bDoTime;
const int maxNumColumns = gridSet.numColumnsMax();
- reallocateDeviceBuffer(&gpu_nbv->cxy_na, maxNumColumns * gridSet.grids().size(),
- &gpu_nbv->ncxy_na, &gpu_nbv->ncxy_na_alloc, *gpu_nbv->deviceContext_);
- reallocateDeviceBuffer(&gpu_nbv->cxy_ind, maxNumColumns * gridSet.grids().size(),
- &gpu_nbv->ncxy_ind, &gpu_nbv->ncxy_ind_alloc, *gpu_nbv->deviceContext_);
+ reallocateDeviceBuffer(&gpu_nbv->cxy_na,
+ maxNumColumns * gridSet.grids().size(),
+ &gpu_nbv->ncxy_na,
+ &gpu_nbv->ncxy_na_alloc,
+ *gpu_nbv->deviceContext_);
+ reallocateDeviceBuffer(&gpu_nbv->cxy_ind,
+ maxNumColumns * gridSet.grids().size(),
+ &gpu_nbv->ncxy_ind,
+ &gpu_nbv->ncxy_ind_alloc,
+ *gpu_nbv->deviceContext_);
for (unsigned int g = 0; g < gridSet.grids().size(); g++)
{
const int* cxy_na = grid.cxy_na().data();
const int* cxy_ind = grid.cxy_ind().data();
- reallocateDeviceBuffer(&gpu_nbv->atomIndices, atomIndicesSize, &gpu_nbv->atomIndicesSize,
- &gpu_nbv->atomIndicesSize_alloc, *gpu_nbv->deviceContext_);
+ reallocateDeviceBuffer(&gpu_nbv->atomIndices,
+ atomIndicesSize,
+ &gpu_nbv->atomIndicesSize,
+ &gpu_nbv->atomIndicesSize_alloc,
+ *gpu_nbv->deviceContext_);
if (atomIndicesSize > 0)
{
if (bDoTime)
{
- gpu_nbv->timers->xf[AtomLocality::Local].nb_h2d.openTimingRegion(deviceStream);
+ gpu_nbv->timers->xf[AtomLocality::Local].nb_h2d.openTimingRegion(localStream);
}
- copyToDeviceBuffer(&gpu_nbv->atomIndices, atomIndices, 0, atomIndicesSize, deviceStream,
- GpuApiCallBehavior::Async, nullptr);
+ copyToDeviceBuffer(&gpu_nbv->atomIndices,
+ atomIndices,
+ 0,
+ atomIndicesSize,
+ localStream,
+ GpuApiCallBehavior::Async,
+ nullptr);
if (bDoTime)
{
- gpu_nbv->timers->xf[AtomLocality::Local].nb_h2d.closeTimingRegion(deviceStream);
+ gpu_nbv->timers->xf[AtomLocality::Local].nb_h2d.closeTimingRegion(localStream);
}
}
{
if (bDoTime)
{
- gpu_nbv->timers->xf[AtomLocality::Local].nb_h2d.openTimingRegion(deviceStream);
+ gpu_nbv->timers->xf[AtomLocality::Local].nb_h2d.openTimingRegion(localStream);
}
int* destPtr = &gpu_nbv->cxy_na[maxNumColumns * g];
- copyToDeviceBuffer(&destPtr, cxy_na, 0, numColumns, deviceStream,
- GpuApiCallBehavior::Async, nullptr);
+ copyToDeviceBuffer(
+ &destPtr, cxy_na, 0, numColumns, localStream, GpuApiCallBehavior::Async, nullptr);
if (bDoTime)
{
- gpu_nbv->timers->xf[AtomLocality::Local].nb_h2d.closeTimingRegion(deviceStream);
+ gpu_nbv->timers->xf[AtomLocality::Local].nb_h2d.closeTimingRegion(localStream);
}
if (bDoTime)
{
- gpu_nbv->timers->xf[AtomLocality::Local].nb_h2d.openTimingRegion(deviceStream);
+ gpu_nbv->timers->xf[AtomLocality::Local].nb_h2d.openTimingRegion(localStream);
}
destPtr = &gpu_nbv->cxy_ind[maxNumColumns * g];
- copyToDeviceBuffer(&destPtr, cxy_ind, 0, numColumns, deviceStream,
- GpuApiCallBehavior::Async, nullptr);
+ copyToDeviceBuffer(
+ &destPtr, cxy_ind, 0, numColumns, localStream, GpuApiCallBehavior::Async, nullptr);
if (bDoTime)
{
- gpu_nbv->timers->xf[AtomLocality::Local].nb_h2d.closeTimingRegion(deviceStream);
+ gpu_nbv->timers->xf[AtomLocality::Local].nb_h2d.closeTimingRegion(localStream);
}
}
}
# ifdef LJ_EWALD
# ifdef LJ_EWALD_COMB_GEOM
# ifdef CALC_ENERGIES
- calculate_lj_ewald_comb_geom_F_E(nbparam, typei, typej, r2, inv_r2,
- lje_coeff2, lje_coeff6_6, int_bit,
- &F_invr, &E_lj_p);
+ calculate_lj_ewald_comb_geom_F_E(
+ nbparam, typei, typej, r2, inv_r2, lje_coeff2, lje_coeff6_6, int_bit, &F_invr, &E_lj_p);
# else
- calculate_lj_ewald_comb_geom_F(nbparam, typei, typej, r2, inv_r2,
- lje_coeff2, lje_coeff6_6, &F_invr);
+ calculate_lj_ewald_comb_geom_F(
+ nbparam, typei, typej, r2, inv_r2, lje_coeff2, lje_coeff6_6, &F_invr);
# endif /* CALC_ENERGIES */
# elif defined LJ_EWALD_COMB_LB
- calculate_lj_ewald_comb_LB_F_E(nbparam, typei, typej, r2, inv_r2,
- lje_coeff2, lje_coeff6_6,
+ calculate_lj_ewald_comb_LB_F_E(nbparam,
+ typei,
+ typej,
+ r2,
+ inv_r2,
+ lje_coeff2,
+ lje_coeff6_6,
# ifdef CALC_ENERGIES
- int_bit, &F_invr, &E_lj_p
+ int_bit,
+ &F_invr,
+ &E_lj_p
# else
- 0, &F_invr, nullptr
+ 0,
+ &F_invr,
+ nullptr
# endif /* CALC_ENERGIES */
);
# endif /* LJ_EWALD_COMB_GEOM */
std::string str = gmx::formatString(
"Invalid atom locality passed (%d); valid here is only "
"local (%d) or nonlocal (%d)",
- static_cast<int>(atomLocality), static_cast<int>(AtomLocality::Local),
+ static_cast<int>(atomLocality),
+ static_cast<int>(AtomLocality::Local),
static_cast<int>(AtomLocality::NonLocal));
GMX_ASSERT(atomLocality == AtomLocality::Local || atomLocality == AtomLocality::NonLocal, str.c_str());
if (stepWork.computeEnergy || stepWork.computeVirial)
{
- gpu_reduce_staged_outputs(nb->nbst, iLocality, stepWork.computeEnergy, stepWork.computeVirial,
- e_lj, e_el, as_rvec_array(shiftForces.data()));
+ gpu_reduce_staged_outputs(nb->nbst,
+ iLocality,
+ stepWork.computeEnergy,
+ stepWork.computeVirial,
+ e_lj,
+ e_el,
+ as_rvec_array(shiftForces.data()));
}
}
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2014,2015,2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/gpu_utils/gpu_macros.h"
#include "gromacs/mdtypes/locality.h"
+#include "nbnxm.h"
+
struct NbnxmGpu;
struct DeviceInformation;
struct gmx_wallclock_gpu_nbnxn_t;
GPU_FUNC_QUALIFIER
bool gpu_is_kernel_ewald_analytical(const NbnxmGpu gmx_unused* nb) GPU_FUNC_TERM_WITH_RETURN(FALSE);
+/** Return the enum value of electrostatics kernel type for given interaction parameters \p ic. */
+GPU_FUNC_QUALIFIER
+enum ElecType nbnxmGpuPickElectrostaticsKernelType(const interaction_const_t gmx_unused* ic,
+ const DeviceInformation gmx_unused& deviceInfo)
+ GPU_FUNC_TERM_WITH_RETURN(ElecType::Count);
+
+/** Return the enum value of VdW kernel type for given \p ic and \p combRule. */
+GPU_FUNC_QUALIFIER
+enum VdwType nbnxmGpuPickVdwKernelType(const interaction_const_t gmx_unused* ic,
+ LJCombinationRule gmx_unused ljCombinationRule)
+ GPU_FUNC_TERM_WITH_RETURN(VdwType::Count);
+
/** Returns an opaque pointer to the GPU command stream
* Note: CUDA only.
*/
#include "gromacs/mdtypes/locality.h"
#include "gromacs/utility/enumerationhelpers.h"
+#include "nbnxm.h"
#include "pairlist.h"
#if GMX_GPU_OPENCL
struct NBParamGpu
{
- //! type of electrostatics, takes values from #eelType
- int eeltype;
- //! type of VdW impl., takes values from #evdwType
- int vdwtype;
+ //! type of electrostatics
+ enum Nbnxm::ElecType elecType;
+ //! type of VdW impl.
+ enum Nbnxm::VdwType vdwType;
//! charge multiplication factor
float epsfac;
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team.
- * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
return static_cast<real>(numAtoms) / (size[XX] * size[YY] * size[ZZ]);
}
+// Get approximate dimensions of each cell. Returns the length along X and Y.
+static std::array<real, DIM - 1> getTargetCellLength(const Grid::Geometry& geometry, const real atomDensity)
+{
+ if (geometry.isSimple)
+ {
+ /* To minimize the zero interactions, we should make
+ * the largest of the i/j cell cubic.
+ */
+ int numAtomsInCell = std::max(geometry.numAtomsICluster, geometry.numAtomsJCluster);
+
+ /* Approximately cubic cells */
+ real tlen = std::cbrt(numAtomsInCell / atomDensity);
+ return { tlen, tlen };
+ }
+ else
+ {
+ /* Approximately cubic sub cells */
+ real tlen = std::cbrt(geometry.numAtomsICluster / atomDensity);
+ return { tlen * c_gpuNumClusterPerCellX, tlen * c_gpuNumClusterPerCellY };
+ }
+}
+
+static int getMaxNumCells(const Grid::Geometry& geometry, const int numAtoms, const int numColumns)
+{
+ if (geometry.numAtomsJCluster <= geometry.numAtomsICluster)
+ {
+ return numAtoms / geometry.numAtomsPerCell + numColumns;
+ }
+ else
+ {
+ return numAtoms / geometry.numAtomsPerCell
+ + numColumns * geometry.numAtomsJCluster / geometry.numAtomsICluster;
+ }
+}
+
void Grid::setDimensions(const int ddZone,
const int numAtoms,
gmx::RVec lowerCorner,
GMX_ASSERT(atomDensity > 0, "With one or more atoms, the density should be positive");
/* target cell length */
- real tlen_x;
- real tlen_y;
- if (geometry_.isSimple)
- {
- /* To minimize the zero interactions, we should make
- * the largest of the i/j cell cubic.
- */
- int numAtomsInCell = std::max(geometry_.numAtomsICluster, geometry_.numAtomsJCluster);
+ const std::array<real, DIM - 1> tlen = getTargetCellLength(geometry_, atomDensity);
- /* Approximately cubic cells */
- real tlen = std::cbrt(numAtomsInCell / atomDensity);
- tlen_x = tlen;
- tlen_y = tlen;
- }
- else
- {
- /* Approximately cubic sub cells */
- real tlen = std::cbrt(geometry_.numAtomsICluster / atomDensity);
- tlen_x = tlen * c_gpuNumClusterPerCellX;
- tlen_y = tlen * c_gpuNumClusterPerCellY;
- }
/* We round ncx and ncy down, because we get less cell pairs
* in the pairlist when the fixed cell dimensions (x,y) are
* larger than the variable one (z) than the other way around.
*/
- dimensions_.numCells[XX] = std::max(1, static_cast<int>(size[XX] / tlen_x));
- dimensions_.numCells[YY] = std::max(1, static_cast<int>(size[YY] / tlen_y));
+ dimensions_.numCells[XX] = std::max(1, static_cast<int>(size[XX] / tlen[XX]));
+ dimensions_.numCells[YY] = std::max(1, static_cast<int>(size[YY] / tlen[YY]));
}
else
{
changePinningPolicy(&cxy_ind_, pinningPolicy);
/* Worst case scenario of 1 atom in each last cell */
- int maxNumCells;
- if (geometry_.numAtomsJCluster <= geometry_.numAtomsICluster)
- {
- maxNumCells = numAtoms / geometry_.numAtomsPerCell + numColumns();
- }
- else
- {
- maxNumCells = numAtoms / geometry_.numAtomsPerCell
- + numColumns() * geometry_.numAtomsJCluster / geometry_.numAtomsICluster;
- }
+ const int maxNumCells = getMaxNumCells(geometry_, numAtoms, numColumns());
if (!geometry_.isSimple)
{
/* As we can have rounding effect, we use > iso >= here */
if (relevantAtomsAreWithinGridBounds && (zi < 0 || (dd_zone == 0 && zi > n_per_h * c_sortGridRatio)))
{
- gmx_fatal(FARGS, "(int)((x[%d][%c]=%f - %f)*%f) = %d, not in 0 - %d*%d\n", a[i],
- 'x' + dim, x[a[i]][dim], h0, invh, zi, n_per_h, c_sortGridRatio);
+ gmx_fatal(FARGS,
+ "(int)((x[%d][%c]=%f - %f)*%f) = %d, not in 0 - %d*%d\n",
+ a[i],
+ 'x' + dim,
+ x[a[i]][dim],
+ h0,
+ invh,
+ zi,
+ n_per_h,
+ c_sortGridRatio);
}
#endif
if (zi < 0)
zi = 0;
}
- /* In a non-local domain, particles communcated for bonded interactions
+ /* In a non-local domain, particles communicated for bonded interactions
* can be far beyond the grid size, which is set by the non-bonded
* cut-off distance. We sort such particles into the last cell.
*/
//! Computes the bounding box for na coordinates in order x,y,z, bb order xyz0
static void calc_bounding_box(int na, int stride, const real* x, BoundingBox* bb)
{
- int i;
- real xl, xh, yl, yh, zl, zh;
-
- i = 0;
- xl = x[i + XX];
- xh = x[i + XX];
- yl = x[i + YY];
- yh = x[i + YY];
- zl = x[i + ZZ];
- zh = x[i + ZZ];
+ int i = 0;
+ real xl = x[i + XX];
+ real xh = x[i + XX];
+ real yl = x[i + YY];
+ real yh = x[i + YY];
+ real zl = x[i + ZZ];
+ real zh = x[i + ZZ];
i += stride;
for (int j = 1; j < na; j++)
{
/*! \brief Computes the bounding box for na packed coordinates, bb order xyz0 */
static void calc_bounding_box_x_x4(int na, const real* x, BoundingBox* bb)
{
- real xl, xh, yl, yh, zl, zh;
-
- xl = x[XX * c_packX4];
- xh = x[XX * c_packX4];
- yl = x[YY * c_packX4];
- yh = x[YY * c_packX4];
- zl = x[ZZ * c_packX4];
- zh = x[ZZ * c_packX4];
+ real xl = x[XX * c_packX4];
+ real xh = x[XX * c_packX4];
+ real yl = x[YY * c_packX4];
+ real yh = x[YY * c_packX4];
+ real zl = x[ZZ * c_packX4];
+ real zh = x[ZZ * c_packX4];
for (int j = 1; j < na; j++)
{
xl = std::min(xl, x[j + XX * c_packX4]);
/*! \brief Computes the bounding box for na coordinates, bb order xyz0 */
static void calc_bounding_box_x_x8(int na, const real* x, BoundingBox* bb)
{
- real xl, xh, yl, yh, zl, zh;
-
- xl = x[XX * c_packX8];
- xh = x[XX * c_packX8];
- yl = x[YY * c_packX8];
- yh = x[YY * c_packX8];
- zl = x[ZZ * c_packX8];
- zh = x[ZZ * c_packX8];
+ real xl = x[XX * c_packX8];
+ real xh = x[XX * c_packX8];
+ real yl = x[YY * c_packX8];
+ real yh = x[YY * c_packX8];
+ real zl = x[ZZ * c_packX8];
+ real zh = x[ZZ * c_packX8];
for (int j = 1; j < na; j++)
{
xl = std::min(xl, x[j + XX * c_packX8]);
/*! \brief Computes the bounding box for na coordinates in order xyz, bb order xxxxyyyyzzzz */
static void calc_bounding_box_xxxx(int na, int stride, const real* x, float* bb)
{
- int i;
- real xl, xh, yl, yh, zl, zh;
-
- i = 0;
- xl = x[i + XX];
- xh = x[i + XX];
- yl = x[i + YY];
- yh = x[i + YY];
- zl = x[i + ZZ];
- zh = x[i + ZZ];
+ int i = 0;
+ real xl = x[i + XX];
+ real xh = x[i + XX];
+ real yl = x[i + YY];
+ real yh = x[i + YY];
+ real zl = x[i + ZZ];
+ real zh = x[i + ZZ];
i += stride;
for (int j = 1; j < na; j++)
{
const int sc2 = grid.firstCellInColumn(i) >> 1;
/* For odd numbers skip the last bb here */
const int nc2 = (grid.numAtomsInColumn(i) + 3) >> (2 + 1);
- int c2;
- for (c2 = sc2; c2 < sc2 + nc2; c2++)
+ for (int c2 = sc2; c2 < sc2 + nc2; c2++)
{
#if NBNXN_SEARCH_BB_SIMD4
Simd4Float min_S, max_S;
if (((grid.numAtomsInColumn(i) + 3) >> 2) & 1)
{
/* The bb count in this column is odd: duplicate the last bb */
+ int c2 = sc2 + nc2;
bbj[c2].lower = bb[c2 * 2].lower;
bbj[c2].upper = bb[c2 * 2].upper;
}
/ (dims.atomDensity * dims.cellSize[XX] * dims.cellSize[YY])
: 0.0);
- fprintf(fp, "ns bb: grid %4.2f %4.2f %4.2f abs %4.2f %4.2f %4.2f rel %4.2f %4.2f %4.2f\n",
- dims.cellSize[XX], dims.cellSize[YY], avgCellSizeZ, ba[XX], ba[YY], ba[ZZ],
- ba[XX] * dims.invCellSize[XX], ba[YY] * dims.invCellSize[YY],
+ fprintf(fp,
+ "ns bb: grid %4.2f %4.2f %4.2f abs %4.2f %4.2f %4.2f rel %4.2f %4.2f %4.2f\n",
+ dims.cellSize[XX],
+ dims.cellSize[YY],
+ avgCellSizeZ,
+ ba[XX],
+ ba[YY],
+ ba[ZZ],
+ ba[XX] * dims.invCellSize[XX],
+ ba[YY] * dims.invCellSize[YY],
dims.atomDensity > 0 ? ba[ZZ] / avgCellSizeZ : 0.0);
}
/*! \brief Prints the average bb size, used for debug output */
static void print_bbsizes_supersub(FILE* fp, const Grid& grid)
{
- int ns;
dvec ba;
clear_dvec(ba);
- ns = 0;
+ int ns = 0;
for (int c = 0; c < grid.numCells(); c++)
{
#if NBNXN_BBXXXX
* dims.cellSize[YY] * c_gpuNumClusterPerCellZ)
: 0.0);
- fprintf(fp, "ns bb: grid %4.2f %4.2f %4.2f abs %4.2f %4.2f %4.2f rel %4.2f %4.2f %4.2f\n",
+ fprintf(fp,
+ "ns bb: grid %4.2f %4.2f %4.2f abs %4.2f %4.2f %4.2f rel %4.2f %4.2f %4.2f\n",
dims.cellSize[XX] / c_gpuNumClusterPerCellX,
- dims.cellSize[YY] / c_gpuNumClusterPerCellY, avgClusterSizeZ, ba[XX], ba[YY], ba[ZZ],
+ dims.cellSize[YY] / c_gpuNumClusterPerCellY,
+ avgClusterSizeZ,
+ ba[XX],
+ ba[YY],
+ ba[ZZ],
ba[XX] * c_gpuNumClusterPerCellX * dims.invCellSize[XX],
ba[YY] * c_gpuNumClusterPerCellY * dims.invCellSize[YY],
dims.atomDensity > 0 ? ba[ZZ] / avgClusterSizeZ : 0.0);
* Then sort_cluster_on_flag will only set the flags and the sorting
* will not affect the atom order.
*/
- sort_cluster_on_flag(geometry_.numAtomsICluster, atomStart, atomEnd, atinfo, atomIndices,
+ sort_cluster_on_flag(geometry_.numAtomsICluster,
+ atomStart,
+ atomEnd,
+ atinfo,
+ atomIndices,
flags_.data() + atomToCluster(atomStart) - cellOffset_);
}
cells[atomIndices[at]] = at;
}
- copy_rvec_to_nbat_real(atomIndices.data() + atomStart, numAtoms, geometry_.numAtomsICluster,
- as_rvec_array(x.data()), nbat->XFormat, nbat->x().data(), atomStart);
+ copy_rvec_to_nbat_real(atomIndices.data() + atomStart,
+ numAtoms,
+ geometry_.numAtomsICluster,
+ as_rvec_array(x.data()),
+ nbat->XFormat,
+ nbat->x().data(),
+ atomStart);
if (nbat->XFormat == nbatX4)
{
{
calc_bounding_box_x_x4_halves(numAtoms,
nbat->x().data() + atom_to_x_index<c_packX4>(atomStart),
- bb_ptr, bbj_.data() + offset * 2);
+ bb_ptr,
+ bbj_.data() + offset * 2);
}
else
#endif
if (nbat->XFormat == nbatXYZQ)
{
GMX_ASSERT(bb_work_aligned != nullptr, "Must have valid aligned work structure");
- calc_bounding_box_xxxx_simd4(numAtoms, nbat->x().data() + atomStart * nbat->xstride,
- bb_work_aligned, pbb_ptr);
+ calc_bounding_box_xxxx_simd4(
+ numAtoms, nbat->x().data() + atomStart * nbat->xstride, bb_work_aligned, pbb_ptr);
}
else
# endif
{
- calc_bounding_box_xxxx(numAtoms, nbat->xstride,
- nbat->x().data() + atomStart * nbat->xstride, pbb_ptr);
+ calc_bounding_box_xxxx(
+ numAtoms, nbat->xstride, nbat->x().data() + atomStart * nbat->xstride, pbb_ptr);
}
if (gmx_debug_at)
{
- fprintf(debug, "cell %4d bb %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f\n",
- atomToCluster(atomStart), pbb_ptr[0 * c_packedBoundingBoxesDimSize],
- pbb_ptr[3 * c_packedBoundingBoxesDimSize], pbb_ptr[1 * c_packedBoundingBoxesDimSize],
- pbb_ptr[4 * c_packedBoundingBoxesDimSize], pbb_ptr[2 * c_packedBoundingBoxesDimSize],
+ fprintf(debug,
+ "cell %4d bb %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f\n",
+ atomToCluster(atomStart),
+ pbb_ptr[0 * c_packedBoundingBoxesDimSize],
+ pbb_ptr[3 * c_packedBoundingBoxesDimSize],
+ pbb_ptr[1 * c_packedBoundingBoxesDimSize],
+ pbb_ptr[4 * c_packedBoundingBoxesDimSize],
+ pbb_ptr[2 * c_packedBoundingBoxesDimSize],
pbb_ptr[5 * c_packedBoundingBoxesDimSize]);
}
}
if (gmx_debug_at)
{
int bbo = atomToCluster(atomStart - cellOffset_ * geometry_.numAtomsPerCell);
- fprintf(debug, "cell %4d bb %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f\n",
- atomToCluster(atomStart), bb_[bbo].lower.x, bb_[bbo].lower.y, bb_[bbo].lower.z,
- bb_[bbo].upper.x, bb_[bbo].upper.y, bb_[bbo].upper.z);
+ fprintf(debug,
+ "cell %4d bb %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f\n",
+ atomToCluster(atomStart),
+ bb_[bbo].lower.x,
+ bb_[bbo].lower.y,
+ bb_[bbo].lower.z,
+ bb_[bbo].upper.x,
+ bb_[bbo].upper.y,
+ bb_[bbo].upper.z);
}
}
}
{
if (debug)
{
- fprintf(debug, "cell_offset %d sorting columns %d - %d\n", cellOffset_,
- *columnRange.begin(), *columnRange.end());
+ fprintf(debug,
+ "cell_offset %d sorting columns %d - %d\n",
+ cellOffset_,
+ *columnRange.begin(),
+ *columnRange.end());
}
const bool relevantAtomsAreWithinGridBounds = (dimensions_.maxAtomGroupRadius == 0);
const int atomOffset = firstAtomInColumn(cxy);
/* Sort the atoms within each x,y column on z coordinate */
- sort_atoms(ZZ, FALSE, dd_zone, relevantAtomsAreWithinGridBounds,
- gridSetData->atomIndices.data() + atomOffset, numAtoms, x, dimensions_.lowerCorner[ZZ],
- 1.0 / dimensions_.gridSize[ZZ], numCellsZ * numAtomsPerCell, sort_work);
+ sort_atoms(ZZ,
+ FALSE,
+ dd_zone,
+ relevantAtomsAreWithinGridBounds,
+ gridSetData->atomIndices.data() + atomOffset,
+ numAtoms,
+ x,
+ dimensions_.lowerCorner[ZZ],
+ 1.0 / dimensions_.gridSize[ZZ],
+ numCellsZ * numAtomsPerCell,
+ sort_work);
/* Fill the ncz cells in this column */
const int firstCell = firstCellInColumn(cxy);
{
const int cell = firstCell + cellZ;
- const int atomOffsetCell = atomOffset + cellZ * numAtomsPerCell;
- const int numAtomsCell = std::min(numAtomsPerCell, numAtoms - (atomOffsetCell - atomOffset));
+ const int atomOffsetCell = atomOffset + cellZ * numAtomsPerCell;
+ const int numAtomsLeftInColumn = std::max(numAtoms - (atomOffsetCell - atomOffset), 0);
+ const int numAtomsCell = std::min(numAtomsPerCell, numAtomsLeftInColumn);
fillCell(gridSetData, nbat, atomOffsetCell, atomOffsetCell + numAtomsCell, atinfo, x, nullptr);
const gmx::Range<int> columnRange,
gmx::ArrayRef<int> sort_work)
{
- BoundingBox bb_work_array[2];
- BoundingBox* bb_work_aligned = reinterpret_cast<BoundingBox*>(
+ BoundingBox bb_work_array[2];
+ auto* bb_work_aligned = reinterpret_cast<BoundingBox*>(
(reinterpret_cast<std::size_t>(bb_work_array + 1)) & (~(static_cast<std::size_t>(15))));
if (debug)
{
- fprintf(debug, "cell_offset %d sorting columns %d - %d\n", cellOffset_,
- *columnRange.begin(), *columnRange.end());
+ fprintf(debug,
+ "cell_offset %d sorting columns %d - %d\n",
+ cellOffset_,
+ *columnRange.begin(),
+ *columnRange.end());
}
const bool relevantAtomsAreWithinGridBounds = (dimensions_.maxAtomGroupRadius == 0);
const int atomOffset = firstAtomInColumn(cxy);
/* Sort the atoms within each x,y column on z coordinate */
- sort_atoms(ZZ, FALSE, dd_zone, relevantAtomsAreWithinGridBounds,
- atomIndices.data() + atomOffset, numAtomsInColumn, x, dimensions_.lowerCorner[ZZ],
- 1.0 / dimensions_.gridSize[ZZ], numCellsInColumn * numAtomsPerCell, sort_work);
+ sort_atoms(ZZ,
+ FALSE,
+ dd_zone,
+ relevantAtomsAreWithinGridBounds,
+ atomIndices.data() + atomOffset,
+ numAtomsInColumn,
+ x,
+ dimensions_.lowerCorner[ZZ],
+ 1.0 / dimensions_.gridSize[ZZ],
+ numCellsInColumn * numAtomsPerCell,
+ sort_work);
/* This loop goes over the cells and clusters along z at once */
for (int sub_z = 0; sub_z < numCellsInColumn * c_gpuNumClusterPerCellZ; sub_z++)
const int numAtoms =
std::min(numAtomsPerCell, numAtomsInColumn - (atomOffsetZ - atomOffset));
- numClusters_[cell] =
- std::min(c_gpuNumClusterPerCell, (numAtoms + geometry_.numAtomsICluster - 1)
- / geometry_.numAtomsICluster);
+ numClusters_[cell] = std::min(
+ c_gpuNumClusterPerCell,
+ (numAtoms + geometry_.numAtomsICluster - 1) / geometry_.numAtomsICluster);
/* Store the z-boundaries of the bounding box of the cell */
bbcz_[cell].lower = x[atomIndices[atomOffsetZ]][ZZ];
if (c_gpuNumClusterPerCellY > 1)
{
/* Sort the atoms along y */
- sort_atoms(YY, (sub_z & 1) != 0, dd_zone, relevantAtomsAreWithinGridBounds,
- atomIndices.data() + atomOffsetZ, numAtomsZ, x,
+ sort_atoms(YY,
+ (sub_z & 1) != 0,
+ dd_zone,
+ relevantAtomsAreWithinGridBounds,
+ atomIndices.data() + atomOffsetZ,
+ numAtomsZ,
+ x,
dimensions_.lowerCorner[YY] + gridY * dimensions_.cellSize[YY],
- dimensions_.invCellSize[YY], subdiv_z, sort_work);
+ dimensions_.invCellSize[YY],
+ subdiv_z,
+ sort_work);
}
for (int sub_y = 0; sub_y < c_gpuNumClusterPerCellY; sub_y++)
if (c_gpuNumClusterPerCellX > 1)
{
/* Sort the atoms along x */
- sort_atoms(XX, ((cz * c_gpuNumClusterPerCellY + sub_y) & 1) != 0, dd_zone,
- relevantAtomsAreWithinGridBounds, atomIndices.data() + atomOffsetY, numAtomsY,
- x, dimensions_.lowerCorner[XX] + gridX * dimensions_.cellSize[XX],
- dimensions_.invCellSize[XX], subdiv_y, sort_work);
+ sort_atoms(XX,
+ ((cz * c_gpuNumClusterPerCellY + sub_y) & 1) != 0,
+ dd_zone,
+ relevantAtomsAreWithinGridBounds,
+ atomIndices.data() + atomOffsetY,
+ numAtomsY,
+ x,
+ dimensions_.lowerCorner[XX] + gridX * dimensions_.cellSize[XX],
+ dimensions_.invCellSize[XX],
+ subdiv_y,
+ sort_work);
}
for (int sub_x = 0; sub_x < c_gpuNumClusterPerCellX; sub_x++)
const int numAtomsX =
std::min(subdiv_x, numAtomsInColumn - (atomOffsetX - atomOffset));
- fillCell(gridSetData, nbat, atomOffsetX, atomOffsetX + numAtomsX, atinfo, x,
- bb_work_aligned);
+ fillCell(gridSetData, nbat, atomOffsetX, atomOffsetX + numAtomsX, atinfo, x, bb_work_aligned);
}
}
}
gmx_fatal(FARGS,
"grid cell cx %d cy %d out of range (max %d %d)\n"
"atom %f %f %f, grid->c0 %f %f",
- cx, cy, gridDims.numCells[XX], gridDims.numCells[YY], x[i][XX],
- x[i][YY], x[i][ZZ], gridDims.lowerCorner[XX], gridDims.lowerCorner[YY]);
+ cx,
+ cy,
+ gridDims.numCells[XX],
+ gridDims.numCells[YY],
+ x[i][XX],
+ x[i][YY],
+ x[i][ZZ],
+ gridDims.lowerCorner[XX],
+ gridDims.lowerCorner[YY]);
}
#endif
- /* Take care of potential rouding issues */
+ /* Take care of potential rounding issues */
cx = std::min(cx, gridDims.numCells[XX] - 1);
cy = std::min(cy, gridDims.numCells[YY] - 1);
if (debug)
{
- fprintf(debug, "ns na_sc %d na_c %d super-cells: %d x %d y %d z %.1f maxz %d\n",
- numAtomsPerCell, geometry_.numAtomsICluster, numCellsTotal_, dimensions_.numCells[XX],
- dimensions_.numCells[YY], numCellsTotal_ / (static_cast<double>(numColumns())), ncz_max);
+ fprintf(debug,
+ "ns na_sc %d na_c %d super-cells: %d x %d y %d z %.1f maxz %d\n",
+ numAtomsPerCell,
+ geometry_.numAtomsICluster,
+ numCellsTotal_,
+ dimensions_.numCells[XX],
+ dimensions_.numCells[YY],
+ numCellsTotal_ / (static_cast<double>(numColumns())),
+ ncz_max);
if (gmx_debug_at)
{
int i = 0;
((thread + 1) * numColumns()) / nthread);
if (geometry_.isSimple)
{
- sortColumnsCpuGeometry(gridSetData, ddZone, atinfo, x, nbat, columnRange,
- gridWork[thread].sortBuffer);
+ sortColumnsCpuGeometry(
+ gridSetData, ddZone, atinfo, x, nbat, columnRange, gridWork[thread].sortBuffer);
}
else
{
- sortColumnsGpuGeometry(gridSetData, ddZone, atinfo, x, nbat, columnRange,
- gridWork[thread].sortBuffer);
+ sortColumnsGpuGeometry(
+ gridSetData, ddZone, atinfo, x, nbat, columnRange, gridWork[thread].sortBuffer);
}
}
GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
}
else
{
- fprintf(debug, "ns non-zero sub-cells: %d average atoms %.2f\n", numClustersTotal_,
+ fprintf(debug,
+ "ns non-zero sub-cells: %d average atoms %.2f\n",
+ numClustersTotal_,
atomRange.size() / static_cast<double>(numClustersTotal_));
print_bbsizes_supersub(debug, *this);
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
//! Returns the number of search grids
static int numGrids(const GridSet::DomainSetup& domainSetup)
{
- int numGrids;
+ // One grid for the test particle, one for the rest
+ static constexpr int sc_numGridsForTestParticleInsertion = 2;
if (domainSetup.doTestParticleInsertion)
{
- numGrids = 2;
+ return sc_numGridsForTestParticleInsertion;
}
else
{
- numGrids = 1;
+ int numGrids = 1;
for (auto haveDD : domainSetup.haveMultipleDomainsPerDim)
{
if (haveDD)
numGrids *= 2;
}
}
+ return numGrids;
}
-
- return numGrids;
}
GridSet::DomainSetup::DomainSetup(const PbcType pbcType,
}
}
+static int getGridOffset(gmx::ArrayRef<const Grid> grids, int gridIndex)
+{
+ if (gridIndex == 0)
+ {
+ return 0;
+ }
+ else
+ {
+ const Nbnxm::Grid& previousGrid = grids[gridIndex - 1];
+ return previousGrid.atomIndexEnd() / previousGrid.geometry().numAtomsPerCell;
+ }
+}
+
void GridSet::putOnGrid(const matrix box,
const int gridIndex,
const rvec lowerCorner,
const int* move,
nbnxn_atomdata_t* nbat)
{
- Nbnxm::Grid& grid = grids_[gridIndex];
-
- int cellOffset;
- if (gridIndex == 0)
- {
- cellOffset = 0;
- }
- else
- {
- const Nbnxm::Grid& previousGrid = grids_[gridIndex - 1];
- cellOffset = previousGrid.atomIndexEnd() / previousGrid.geometry().numAtomsPerCell;
- }
-
- const int n = atomRange.size();
+ Nbnxm::Grid& grid = grids_[gridIndex];
+ const int cellOffset = getGridOffset(grids_, gridIndex);
+ const int n = atomRange.size();
+ real maxAtomGroupRadius = NAN;
- real maxAtomGroupRadius;
if (gridIndex == 0)
{
copy_mat(box, box_);
const int ddZone = (domainSetup_.doTestParticleInsertion ? 0 : gridIndex);
// grid data used in GPU transfers inherits the gridset pinning policy
auto pinPolicy = gridSetData_.cells.get_allocator().pinningPolicy();
- grid.setDimensions(ddZone, n - numAtomsMoved, lowerCorner, upperCorner, atomDensity,
- maxAtomGroupRadius, haveFep_, pinPolicy);
+ grid.setDimensions(
+ ddZone, n - numAtomsMoved, lowerCorner, upperCorner, atomDensity, maxAtomGroupRadius, haveFep_, pinPolicy);
for (GridWork& work : gridWork_)
{
{
try
{
- Grid::calcColumnIndices(grid.dimensions(), updateGroupsCog, atomRange, x, ddZone, move, thread,
- nthread, gridSetData_.cells, gridWork_[thread].numAtomsPerColumn);
+ Grid::calcColumnIndices(grid.dimensions(),
+ updateGroupsCog,
+ atomRange,
+ x,
+ ddZone,
+ move,
+ thread,
+ nthread,
+ gridSetData_.cells,
+ gridWork_[thread].numAtomsPerColumn);
}
GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
}
/* Copy the already computed cell indices to the grid and sort, when needed */
- grid.setCellIndices(ddZone, cellOffset, &gridSetData_, gridWork_, atomRange, atomInfo.data(), x,
- numAtomsMoved, nbat);
+ grid.setCellIndices(
+ ddZone, cellOffset, &gridSetData_, gridWork_, atomRange, atomInfo.data(), x, numAtomsMoved, nbat);
if (gridIndex == 0)
{
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012,2013,2014,2015,2017 by the GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
static void clearBufferFlagged(const nbnxn_atomdata_t& nbat, int outputIndex, gmx::ArrayRef<real> buffer)
{
gmx::ArrayRef<const gmx_bitmask_t> flags = nbat.buffer_flags;
- gmx_bitmask_t our_flag;
+ gmx_bitmask_t our_flag; // NOLINT(cppcoreguidelines-init-variables)
bitmask_init_bit(&our_flag, outputIndex);
constexpr size_t numComponentsPerBlock = NBNXN_BUFFERFLAG_SIZE * numComponentsPerElement;
void clear_fshift(real* fshift)
{
- int i;
-
- for (i = 0; i < SHIFTS * DIM; i++)
+ for (int i = 0; i < SHIFTS * DIM; i++)
{
fshift[i] = 0;
}
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team.
- * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/nbnxm/nbnxm.h"
#include "gromacs/simd/simd.h"
#include "gromacs/timing/wallcycle.h"
+#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/real.h"
}
}
-/*! \brief Dispatches the non-bonded N versus M atom cluster CPU kernels.
- *
- * OpenMP parallelization is performed within this function.
- * Energy reduction, but not force and shift force reduction, is performed
- * within this function.
- *
- * \param[in] pairlistSet Pairlists with local or non-local interactions to compute
- * \param[in] kernelSetup The non-bonded kernel setup
- * \param[in,out] nbat The atomdata for the interactions
- * \param[in] ic Non-bonded interaction constants
- * \param[in] shiftVectors The PBC shift vectors
- * \param[in] stepWork Flags that tell what to compute
- * \param[in] clearF Enum that tells if to clear the force output buffer
- * \param[out] vCoulomb Output buffer for Coulomb energies
- * \param[out] vVdw Output buffer for Van der Waals energies
- * \param[in] wcycle Pointer to cycle counting data structure.
- */
-static void nbnxn_kernel_cpu(const PairlistSet& pairlistSet,
- const Nbnxm::KernelSetup& kernelSetup,
- nbnxn_atomdata_t* nbat,
- const interaction_const_t& ic,
- rvec* shiftVectors,
- const gmx::StepWorkload& stepWork,
- int clearF,
- real* vCoulomb,
- real* vVdw,
- gmx_wallcycle* wcycle)
+static int getCoulombKernelType(const Nbnxm::KernelSetup& kernelSetup, const interaction_const_t& ic)
{
- int coulkt;
if (EEL_RF(ic.eeltype) || ic.eeltype == eelCUT)
{
- coulkt = coulktRF;
+ return coulktRF;
}
else
{
{
if (ic.rcoulomb == ic.rvdw)
{
- coulkt = coulktTAB;
+ return coulktTAB;
}
else
{
- coulkt = coulktTAB_TWIN;
+ return coulktTAB_TWIN;
}
}
else
{
if (ic.rcoulomb == ic.rvdw)
{
- coulkt = coulktEWALD;
+ return coulktEWALD;
}
else
{
- coulkt = coulktEWALD_TWIN;
+ return coulktEWALD_TWIN;
}
}
}
+}
- const nbnxn_atomdata_t::Params& nbatParams = nbat->params();
-
- int vdwkt = 0;
+static int getVdwKernelType(const Nbnxm::KernelSetup& kernelSetup,
+ const nbnxn_atomdata_t::Params& nbatParams,
+ const interaction_const_t& ic)
+{
if (ic.vdwtype == evdwCUT)
{
switch (ic.vdw_modifier)
{
case eintmodNONE:
case eintmodPOTSHIFT:
- switch (nbatParams.comb_rule)
+ switch (nbatParams.ljCombinationRule)
{
- case ljcrGEOM: vdwkt = vdwktLJCUT_COMBGEOM; break;
- case ljcrLB: vdwkt = vdwktLJCUT_COMBLB; break;
- case ljcrNONE: vdwkt = vdwktLJCUT_COMBNONE; break;
- default: GMX_RELEASE_ASSERT(false, "Unknown combination rule");
+ case LJCombinationRule::Geometric: return vdwktLJCUT_COMBGEOM;
+ case LJCombinationRule::LorentzBerthelot: return vdwktLJCUT_COMBLB;
+ case LJCombinationRule::None: return vdwktLJCUT_COMBNONE;
+ default: gmx_incons("Unknown combination rule");
}
- break;
- case eintmodFORCESWITCH: vdwkt = vdwktLJFORCESWITCH; break;
- case eintmodPOTSWITCH: vdwkt = vdwktLJPOTSWITCH; break;
- default: GMX_RELEASE_ASSERT(false, "Unsupported VdW interaction modifier");
+ case eintmodFORCESWITCH: return vdwktLJFORCESWITCH;
+ case eintmodPOTSWITCH: return vdwktLJPOTSWITCH;
+ default:
+ std::string errorMsg =
+ gmx::formatString("Unsupported VdW interaction modifier %s (%d)",
+ INTMODIFIER(ic.vdw_modifier),
+ ic.vdw_modifier);
+ gmx_incons(errorMsg);
}
}
else if (ic.vdwtype == evdwPME)
{
if (ic.ljpme_comb_rule == eljpmeGEOM)
{
- vdwkt = vdwktLJEWALDCOMBGEOM;
+ return vdwktLJEWALDCOMBGEOM;
}
else
{
- vdwkt = vdwktLJEWALDCOMBLB;
/* At setup we (should have) selected the C reference kernel */
GMX_RELEASE_ASSERT(kernelSetup.kernelType == Nbnxm::KernelType::Cpu4x4_PlainC,
"Only the C reference nbnxn SIMD kernel supports LJ-PME with LB "
"combination rules");
+ return vdwktLJEWALDCOMBLB;
}
}
else
{
- GMX_RELEASE_ASSERT(false, "Unsupported VdW interaction type");
+ std::string errorMsg = gmx::formatString(
+ "Unsupported VdW interaction type %s (%d)", EVDWTYPE(ic.vdwtype), ic.vdwtype);
+ gmx_incons(errorMsg);
}
+}
+
+/*! \brief Dispatches the non-bonded N versus M atom cluster CPU kernels.
+ *
+ * OpenMP parallelization is performed within this function.
+ * Energy reduction, but not force and shift force reduction, is performed
+ * within this function.
+ *
+ * \param[in] pairlistSet Pairlists with local or non-local interactions to compute
+ * \param[in] kernelSetup The non-bonded kernel setup
+ * \param[in,out] nbat The atomdata for the interactions
+ * \param[in] ic Non-bonded interaction constants
+ * \param[in] shiftVectors The PBC shift vectors
+ * \param[in] stepWork Flags that tell what to compute
+ * \param[in] clearF Enum that tells if to clear the force output buffer
+ * \param[out] vCoulomb Output buffer for Coulomb energies
+ * \param[out] vVdw Output buffer for Van der Waals energies
+ * \param[in] wcycle Pointer to cycle counting data structure.
+ */
+static void nbnxn_kernel_cpu(const PairlistSet& pairlistSet,
+ const Nbnxm::KernelSetup& kernelSetup,
+ nbnxn_atomdata_t* nbat,
+ const interaction_const_t& ic,
+ rvec* shiftVectors,
+ const gmx::StepWorkload& stepWork,
+ int clearF,
+ real* vCoulomb,
+ real* vVdw,
+ gmx_wallcycle* wcycle)
+{
+
+ const nbnxn_atomdata_t::Params& nbatParams = nbat->params();
+
+ const int coulkt = getCoulombKernelType(kernelSetup, ic);
+ const int vdwkt = getVdwKernelType(kernelSetup, nbatParams, ic);
gmx::ArrayRef<const NbnxnPairlistCpu> pairlists = pairlistSet.cpuLists();
{
const bool usingGpuKernels = nbv.useGpu();
- int enr_nbnxn_kernel_ljc;
+ int enr_nbnxn_kernel_ljc = eNRNB;
if (EEL_RF(ic.eeltype) || ic.eeltype == eelCUT)
{
enr_nbnxn_kernel_ljc = eNR_NBNXN_LJ_RF;
if (ic.vdw_modifier == eintmodFORCESWITCH)
{
/* We add up the switch cost separately */
- inc_nrnb(nrnb, eNR_NBNXN_ADD_LJ_FSW + (stepWork.computeEnergy ? 1 : 0),
+ inc_nrnb(nrnb,
+ eNR_NBNXN_ADD_LJ_FSW + (stepWork.computeEnergy ? 1 : 0),
pairlistSet.natpair_ljq_ + pairlistSet.natpair_lj_);
}
if (ic.vdw_modifier == eintmodPOTSWITCH)
{
/* We add up the switch cost separately */
- inc_nrnb(nrnb, eNR_NBNXN_ADD_LJ_PSW + (stepWork.computeEnergy ? 1 : 0),
+ inc_nrnb(nrnb,
+ eNR_NBNXN_ADD_LJ_PSW + (stepWork.computeEnergy ? 1 : 0),
pairlistSet.natpair_ljq_ + pairlistSet.natpair_lj_);
}
if (ic.vdwtype == evdwPME)
{
/* We add up the LJ Ewald cost separately */
- inc_nrnb(nrnb, eNR_NBNXN_ADD_LJ_EWALD + (stepWork.computeEnergy ? 1 : 0),
+ inc_nrnb(nrnb,
+ eNR_NBNXN_ADD_LJ_EWALD + (stepWork.computeEnergy ? 1 : 0),
pairlistSet.natpair_ljq_ + pairlistSet.natpair_lj_);
}
}
case Nbnxm::KernelType::Cpu4x4_PlainC:
case Nbnxm::KernelType::Cpu4xN_Simd_4xN:
case Nbnxm::KernelType::Cpu4xN_Simd_2xNN:
- nbnxn_kernel_cpu(pairlistSet, kernelSetup(), nbat.get(), ic, fr.shift_vec, stepWork,
- clearF, enerd->grpp.ener[egCOULSR].data(),
+ nbnxn_kernel_cpu(pairlistSet,
+ kernelSetup(),
+ nbat.get(),
+ ic,
+ fr.shift_vec,
+ stepWork,
+ clearF,
+ enerd->grpp.ener[egCOULSR].data(),
fr.bBHAM ? enerd->grpp.ener[egBHAMSR].data() : enerd->grpp.ener[egLJSR].data(),
wcycle_);
break;
case Nbnxm::KernelType::Cpu8x8x8_PlainC:
nbnxn_kernel_gpu_ref(
- pairlistSet.gpuList(), nbat.get(), &ic, fr.shift_vec, stepWork, clearF,
- nbat->out[0].f, nbat->out[0].fshift.data(), enerd->grpp.ener[egCOULSR].data(),
+ pairlistSet.gpuList(),
+ nbat.get(),
+ &ic,
+ fr.shift_vec,
+ stepWork,
+ clearF,
+ nbat->out[0].f,
+ nbat->out[0].fshift.data(),
+ enerd->grpp.ener[egCOULSR].data(),
fr.bBHAM ? enerd->grpp.ener[egBHAMSR].data() : enerd->grpp.ener[egLJSR].data());
break;
{
try
{
- gmx_nb_free_energy_kernel(nbl_fep[th].get(), x, forceWithShiftForces, fr, &mdatoms,
- &kernel_data, nrnb);
+ gmx_nb_free_energy_kernel(
+ nbl_fep[th].get(), x, forceWithShiftForces, fr, &mdatoms, &kernel_data, nrnb);
}
GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
}
{
try
{
- gmx_nb_free_energy_kernel(nbl_fep[th].get(), x, forceWithShiftForces, fr,
- &mdatoms, &kernel_data, nrnb);
+ gmx_nb_free_energy_kernel(
+ nbl_fep[th].get(), x, forceWithShiftForces, fr, &mdatoms, &kernel_data, nrnb);
}
GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
}
sum_epot(enerd->foreign_grpp, enerd->foreign_term);
- enerd->foreignLambdaTerms.accumulate(i, enerd->foreign_term[F_EPOT],
- dvdl_nb[efptVDW] + dvdl_nb[efptCOUL]);
+ enerd->foreignLambdaTerms.accumulate(
+ i, enerd->foreign_term[F_EPOT], dvdl_nb[efptVDW] + dvdl_nb[efptCOUL]);
}
}
wallcycle_sub_stop(wcycle_, ewcsNONBONDED_FEP);
gmx_fatal(FARGS,
"The neighborlist cluster size in the GPU reference kernel is %d, expected it to "
"be %d",
- nbl->na_ci, c_clSize);
+ nbl->na_ci,
+ c_clSize);
}
if (clearF == enbvClearFYes)
if (debug)
{
- fprintf(debug, "number of half %dx%d atom pairs: %d after pruning: %d fraction %4.2f\n",
- nbl->na_ci, nbl->na_ci, nhwu, nhwu_pruned, nhwu_pruned / static_cast<double>(nhwu));
- fprintf(debug, "generic kernel pair interactions: %d\n",
- nhwu * nbl->na_ci / 2 * nbl->na_ci);
- fprintf(debug, "generic kernel post-prune pair interactions: %d\n",
+ fprintf(debug,
+ "number of half %dx%d atom pairs: %d after pruning: %d fraction %4.2f\n",
+ nbl->na_ci,
+ nbl->na_ci,
+ nhwu,
+ nhwu_pruned,
+ nhwu_pruned / static_cast<double>(nhwu));
+ fprintf(debug, "generic kernel pair interactions: %d\n", nhwu * nbl->na_ci / 2 * nbl->na_ci);
+ fprintf(debug,
+ "generic kernel post-prune pair interactions: %d\n",
nhwu_pruned * nbl->na_ci / 2 * nbl->na_ci);
fprintf(debug, "generic kernel non-zero pair interactions: %d\n", npair_tot);
- fprintf(debug, "ratio non-zero/post-prune pair interactions: %4.2f\n",
+ fprintf(debug,
+ "ratio non-zero/post-prune pair interactions: %4.2f\n",
npair_tot / static_cast<double>(nhwu_pruned * gmx::exactDiv(nbl->na_ci, 2) * nbl->na_ci));
}
}
*/
//! \{
static p_nbk_func_noener nbnxn_kernel_noener_ref[coulktNR][vdwktNR_ref] = {
- { nbnxn_kernel_ElecRF_VdwLJ_F_ref, nbnxn_kernel_ElecRF_VdwLJ_F_ref, nbnxn_kernel_ElecRF_VdwLJ_F_ref,
- nbnxn_kernel_ElecRF_VdwLJFsw_F_ref, nbnxn_kernel_ElecRF_VdwLJPsw_F_ref,
- nbnxn_kernel_ElecRF_VdwLJEwCombGeom_F_ref, nbnxn_kernel_ElecRF_VdwLJEwCombLB_F_ref },
- { nbnxn_kernel_ElecQSTab_VdwLJ_F_ref, nbnxn_kernel_ElecQSTab_VdwLJ_F_ref, nbnxn_kernel_ElecQSTab_VdwLJ_F_ref,
- nbnxn_kernel_ElecQSTab_VdwLJFsw_F_ref, nbnxn_kernel_ElecQSTab_VdwLJPsw_F_ref,
- nbnxn_kernel_ElecQSTab_VdwLJEwCombGeom_F_ref, nbnxn_kernel_ElecQSTab_VdwLJEwCombLB_F_ref },
- { nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_F_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_F_ref,
- nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_F_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_F_ref,
- nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_F_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F_ref,
+ { nbnxn_kernel_ElecRF_VdwLJ_F_ref,
+ nbnxn_kernel_ElecRF_VdwLJ_F_ref,
+ nbnxn_kernel_ElecRF_VdwLJ_F_ref,
+ nbnxn_kernel_ElecRF_VdwLJFsw_F_ref,
+ nbnxn_kernel_ElecRF_VdwLJPsw_F_ref,
+ nbnxn_kernel_ElecRF_VdwLJEwCombGeom_F_ref,
+ nbnxn_kernel_ElecRF_VdwLJEwCombLB_F_ref },
+ { nbnxn_kernel_ElecQSTab_VdwLJ_F_ref,
+ nbnxn_kernel_ElecQSTab_VdwLJ_F_ref,
+ nbnxn_kernel_ElecQSTab_VdwLJ_F_ref,
+ nbnxn_kernel_ElecQSTab_VdwLJFsw_F_ref,
+ nbnxn_kernel_ElecQSTab_VdwLJPsw_F_ref,
+ nbnxn_kernel_ElecQSTab_VdwLJEwCombGeom_F_ref,
+ nbnxn_kernel_ElecQSTab_VdwLJEwCombLB_F_ref },
+ { nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_F_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_F_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_F_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_F_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_F_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F_ref,
nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombLB_F_ref },
- { nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_F_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_F_ref,
- nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_F_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_F_ref,
- nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_F_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F_ref,
+ { nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_F_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_F_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_F_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_F_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_F_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F_ref,
nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombLB_F_ref },
- { nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_F_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_F_ref,
- nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_F_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_F_ref,
- nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_F_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F_ref,
+ { nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_F_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_F_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_F_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_F_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_F_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F_ref,
nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombLB_F_ref }
};
static p_nbk_func_ener nbnxn_kernel_ener_ref[coulktNR][vdwktNR_ref] = {
- { nbnxn_kernel_ElecRF_VdwLJ_VF_ref, nbnxn_kernel_ElecRF_VdwLJ_VF_ref, nbnxn_kernel_ElecRF_VdwLJ_VF_ref,
- nbnxn_kernel_ElecRF_VdwLJFsw_VF_ref, nbnxn_kernel_ElecRF_VdwLJPsw_VF_ref,
- nbnxn_kernel_ElecRF_VdwLJEwCombGeom_VF_ref, nbnxn_kernel_ElecRF_VdwLJEwCombLB_VF_ref },
- { nbnxn_kernel_ElecQSTab_VdwLJ_VF_ref, nbnxn_kernel_ElecQSTab_VdwLJ_VF_ref,
- nbnxn_kernel_ElecQSTab_VdwLJ_VF_ref, nbnxn_kernel_ElecQSTab_VdwLJFsw_VF_ref,
- nbnxn_kernel_ElecQSTab_VdwLJPsw_VF_ref, nbnxn_kernel_ElecQSTab_VdwLJEwCombGeom_VF_ref,
+ { nbnxn_kernel_ElecRF_VdwLJ_VF_ref,
+ nbnxn_kernel_ElecRF_VdwLJ_VF_ref,
+ nbnxn_kernel_ElecRF_VdwLJ_VF_ref,
+ nbnxn_kernel_ElecRF_VdwLJFsw_VF_ref,
+ nbnxn_kernel_ElecRF_VdwLJPsw_VF_ref,
+ nbnxn_kernel_ElecRF_VdwLJEwCombGeom_VF_ref,
+ nbnxn_kernel_ElecRF_VdwLJEwCombLB_VF_ref },
+ { nbnxn_kernel_ElecQSTab_VdwLJ_VF_ref,
+ nbnxn_kernel_ElecQSTab_VdwLJ_VF_ref,
+ nbnxn_kernel_ElecQSTab_VdwLJ_VF_ref,
+ nbnxn_kernel_ElecQSTab_VdwLJFsw_VF_ref,
+ nbnxn_kernel_ElecQSTab_VdwLJPsw_VF_ref,
+ nbnxn_kernel_ElecQSTab_VdwLJEwCombGeom_VF_ref,
nbnxn_kernel_ElecQSTab_VdwLJEwCombLB_VF_ref },
- { nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VF_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VF_ref,
- nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VF_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_VF_ref,
- nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_VF_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF_ref,
+ { nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VF_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VF_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VF_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_VF_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_VF_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF_ref,
nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombLB_VF_ref },
- { nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VF_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VF_ref,
- nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VF_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_VF_ref,
- nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_VF_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF_ref,
+ { nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VF_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VF_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VF_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_VF_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_VF_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF_ref,
nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombLB_VF_ref },
- { nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VF_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VF_ref,
- nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VF_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_VF_ref,
- nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_VF_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF_ref,
+ { nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VF_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VF_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VF_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_VF_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_VF_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF_ref,
nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombLB_VF_ref }
};
static p_nbk_func_ener nbnxn_kernel_energrp_ref[coulktNR][vdwktNR_ref] = {
- { nbnxn_kernel_ElecRF_VdwLJ_VgrpF_ref, nbnxn_kernel_ElecRF_VdwLJ_VgrpF_ref,
- nbnxn_kernel_ElecRF_VdwLJ_VgrpF_ref, nbnxn_kernel_ElecRF_VdwLJFsw_VgrpF_ref,
- nbnxn_kernel_ElecRF_VdwLJPsw_VgrpF_ref, nbnxn_kernel_ElecRF_VdwLJEwCombGeom_VgrpF_ref,
+ { nbnxn_kernel_ElecRF_VdwLJ_VgrpF_ref,
+ nbnxn_kernel_ElecRF_VdwLJ_VgrpF_ref,
+ nbnxn_kernel_ElecRF_VdwLJ_VgrpF_ref,
+ nbnxn_kernel_ElecRF_VdwLJFsw_VgrpF_ref,
+ nbnxn_kernel_ElecRF_VdwLJPsw_VgrpF_ref,
+ nbnxn_kernel_ElecRF_VdwLJEwCombGeom_VgrpF_ref,
nbnxn_kernel_ElecRF_VdwLJEwCombLB_VgrpF_ref },
- { nbnxn_kernel_ElecQSTab_VdwLJ_VgrpF_ref, nbnxn_kernel_ElecQSTab_VdwLJ_VgrpF_ref,
- nbnxn_kernel_ElecQSTab_VdwLJ_VgrpF_ref, nbnxn_kernel_ElecQSTab_VdwLJFsw_VgrpF_ref,
- nbnxn_kernel_ElecQSTab_VdwLJPsw_VgrpF_ref, nbnxn_kernel_ElecQSTab_VdwLJEwCombGeom_VgrpF_ref,
+ { nbnxn_kernel_ElecQSTab_VdwLJ_VgrpF_ref,
+ nbnxn_kernel_ElecQSTab_VdwLJ_VgrpF_ref,
+ nbnxn_kernel_ElecQSTab_VdwLJ_VgrpF_ref,
+ nbnxn_kernel_ElecQSTab_VdwLJFsw_VgrpF_ref,
+ nbnxn_kernel_ElecQSTab_VdwLJPsw_VgrpF_ref,
+ nbnxn_kernel_ElecQSTab_VdwLJEwCombGeom_VgrpF_ref,
nbnxn_kernel_ElecQSTab_VdwLJEwCombLB_VgrpF_ref },
- { nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_ref,
- nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_VgrpF_ref,
- nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_VgrpF_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF_ref,
+ { nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_VgrpF_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_VgrpF_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF_ref,
nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombLB_VgrpF_ref },
- { nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_ref,
- nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_VgrpF_ref,
- nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_VgrpF_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF_ref,
+ { nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_VgrpF_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_VgrpF_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF_ref,
nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombLB_VgrpF_ref },
- { nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_ref,
- nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_VgrpF_ref,
- nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_VgrpF_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF_ref,
+ { nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_VgrpF_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_VgrpF_ref,
+ nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF_ref,
nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombLB_VgrpF_ref }
};
//! \}
for (int jj = 0; jj < (UNROLLJ / 2); jj++)
{
incrDualHsimd(v0 + offset_jj[jj] + jj * GMX_SIMD_REAL_WIDTH / 2,
- v1 + offset_jj[jj] + jj * GMX_SIMD_REAL_WIDTH / 2, e_S);
+ v1 + offset_jj[jj] + jj * GMX_SIMD_REAL_WIDTH / 2,
+ e_S);
}
}
#endif
ajz = ajy + STRIDE;
#ifdef CHECK_EXCLS
- gmx_load_simd_2xnn_interactions(static_cast<int>(l_cj[cjind].excl), filter_S0, filter_S2,
- &interact_S0, &interact_S2);
+ gmx_load_simd_2xnn_interactions(
+ static_cast<int>(l_cj[cjind].excl), filter_S0, filter_S2, &interact_S0, &interact_S2);
#endif /* CHECK_EXCLS */
/* load j atom coordinates */
c6_S2 * fma(sixth_S, rinvsix_S2, v_fswitch_pr(rsw_S2, rsw2_S2, p6_6cpot_S, p6_vc3_S, p6_vc4_S));
# endif
SimdReal VLJ12_S0 = c12_S0
- * fma(twelveth_S, rinvsix_S0 * rinvsix_S0,
+ * fma(twelveth_S,
+ rinvsix_S0 * rinvsix_S0,
v_fswitch_pr(rsw_S0, rsw2_S0, p12_12cpot_S, p12_vc3_S, p12_vc4_S));
# ifndef HALF_LJ
SimdReal VLJ12_S2 = c12_S2
- * fma(twelveth_S, rinvsix_S2 * rinvsix_S2,
+ * fma(twelveth_S,
+ rinvsix_S2 * rinvsix_S2,
v_fswitch_pr(rsw_S2, rsw2_S2, p12_12cpot_S, p12_vc3_S, p12_vc4_S));
# endif
# undef v_fswitch_pr
* r^-6*cexp*(1 + cr2 + cr2^2/2 + cr2^3/6) = cexp*(r^-6*poly + c^6/6)
*/
frLJ_S0 = fma(c6grid_S0,
- fnma(expmcr2_S0, fma(rinvsix_nm_S0, poly_S0, lje_c6_6_S), rinvsix_nm_S0), frLJ_S0);
+ fnma(expmcr2_S0, fma(rinvsix_nm_S0, poly_S0, lje_c6_6_S), rinvsix_nm_S0),
+ frLJ_S0);
# ifndef HALF_LJ
frLJ_S2 = fma(c6grid_S2,
- fnma(expmcr2_S2, fma(rinvsix_nm_S2, poly_S2, lje_c6_6_S), rinvsix_nm_S2), frLJ_S2);
+ fnma(expmcr2_S2, fma(rinvsix_nm_S2, poly_S2, lje_c6_6_S), rinvsix_nm_S2),
+ frLJ_S2);
# endif
# ifdef CALC_ENERGIES
# endif
VLJ_S0 = fma(sixth_S * c6grid_S0,
- fma(rinvsix_nm_S0, fnma(expmcr2_S0, poly_S0, one_S), sh_mask_S0), VLJ_S0);
+ fma(rinvsix_nm_S0, fnma(expmcr2_S0, poly_S0, one_S), sh_mask_S0),
+ VLJ_S0);
# ifndef HALF_LJ
VLJ_S2 = fma(sixth_S * c6grid_S2,
- fma(rinvsix_nm_S2, fnma(expmcr2_S2, poly_S2, one_S), sh_mask_S2), VLJ_S2);
+ fma(rinvsix_nm_S2, fnma(expmcr2_S2, poly_S2, one_S), sh_mask_S2),
+ VLJ_S2);
# endif
# endif /* CALC_ENERGIES */
}
ajz = ajy + STRIDE;
# ifdef CHECK_EXCLS
- gmx_load_simd_4xn_interactions(static_cast<int>(l_cj[cjind].excl), filter_S0, filter_S1,
- filter_S2, filter_S3, nbat->simdMasks.interaction_array.data(),
- &interact_S0, &interact_S1, &interact_S2, &interact_S3);
+ gmx_load_simd_4xn_interactions(static_cast<int>(l_cj[cjind].excl),
+ filter_S0,
+ filter_S1,
+ filter_S2,
+ filter_S3,
+ nbat->simdMasks.interaction_array.data(),
+ &interact_S0,
+ &interact_S1,
+ &interact_S2,
+ &interact_S3);
# endif /* CHECK_EXCLS */
/* load j atom coordinates */
c6_S3 * fma(sixth_S, rinvsix_S3, v_fswitch_r(rsw_S3, rsw2_S3, p6_6cpot_S, p6_vc3_S, p6_vc4_S));
# endif
SimdReal VLJ12_S0 = c12_S0
- * fma(twelveth_S, rinvsix_S0 * rinvsix_S0,
+ * fma(twelveth_S,
+ rinvsix_S0 * rinvsix_S0,
v_fswitch_r(rsw_S0, rsw2_S0, p12_12cpot_S, p12_vc3_S, p12_vc4_S));
SimdReal VLJ12_S1 = c12_S1
- * fma(twelveth_S, rinvsix_S1 * rinvsix_S1,
+ * fma(twelveth_S,
+ rinvsix_S1 * rinvsix_S1,
v_fswitch_r(rsw_S1, rsw2_S1, p12_12cpot_S, p12_vc3_S, p12_vc4_S));
# ifndef HALF_LJ
SimdReal VLJ12_S2 = c12_S2
- * fma(twelveth_S, rinvsix_S2 * rinvsix_S2,
+ * fma(twelveth_S,
+ rinvsix_S2 * rinvsix_S2,
v_fswitch_r(rsw_S2, rsw2_S2, p12_12cpot_S, p12_vc3_S, p12_vc4_S));
SimdReal VLJ12_S3 = c12_S3
- * fma(twelveth_S, rinvsix_S3 * rinvsix_S3,
+ * fma(twelveth_S,
+ rinvsix_S3 * rinvsix_S3,
v_fswitch_r(rsw_S3, rsw2_S3, p12_12cpot_S, p12_vc3_S, p12_vc4_S));
# endif
# undef v_fswitch_r
* r^-6*cexp*(1 + cr2 + cr2^2/2 + cr2^3/6) = cexp*(r^-6*poly + c^6/6)
*/
frLJ_S0 = fma(c6grid_S0,
- fnma(expmcr2_S0, fma(rinvsix_nm_S0, poly_S0, lje_c6_6_S), rinvsix_nm_S0), frLJ_S0);
+ fnma(expmcr2_S0, fma(rinvsix_nm_S0, poly_S0, lje_c6_6_S), rinvsix_nm_S0),
+ frLJ_S0);
frLJ_S1 = fma(c6grid_S1,
- fnma(expmcr2_S1, fma(rinvsix_nm_S1, poly_S1, lje_c6_6_S), rinvsix_nm_S1), frLJ_S1);
+ fnma(expmcr2_S1, fma(rinvsix_nm_S1, poly_S1, lje_c6_6_S), rinvsix_nm_S1),
+ frLJ_S1);
# ifndef HALF_LJ
frLJ_S2 = fma(c6grid_S2,
- fnma(expmcr2_S2, fma(rinvsix_nm_S2, poly_S2, lje_c6_6_S), rinvsix_nm_S2), frLJ_S2);
+ fnma(expmcr2_S2, fma(rinvsix_nm_S2, poly_S2, lje_c6_6_S), rinvsix_nm_S2),
+ frLJ_S2);
frLJ_S3 = fma(c6grid_S3,
- fnma(expmcr2_S3, fma(rinvsix_nm_S3, poly_S3, lje_c6_6_S), rinvsix_nm_S3), frLJ_S3);
+ fnma(expmcr2_S3, fma(rinvsix_nm_S3, poly_S3, lje_c6_6_S), rinvsix_nm_S3),
+ frLJ_S3);
# endif
# ifdef CALC_ENERGIES
# endif
VLJ_S0 = fma(sixth_S * c6grid_S0,
- fma(rinvsix_nm_S0, fnma(expmcr2_S0, poly_S0, one_S), sh_mask_S0), VLJ_S0);
+ fma(rinvsix_nm_S0, fnma(expmcr2_S0, poly_S0, one_S), sh_mask_S0),
+ VLJ_S0);
VLJ_S1 = fma(sixth_S * c6grid_S1,
- fma(rinvsix_nm_S1, fnma(expmcr2_S1, poly_S1, one_S), sh_mask_S1), VLJ_S1);
+ fma(rinvsix_nm_S1, fnma(expmcr2_S1, poly_S1, one_S), sh_mask_S1),
+ VLJ_S1);
# ifndef HALF_LJ
VLJ_S2 = fma(sixth_S * c6grid_S2,
- fma(rinvsix_nm_S2, fnma(expmcr2_S2, poly_S2, one_S), sh_mask_S2), VLJ_S2);
+ fma(rinvsix_nm_S2, fnma(expmcr2_S2, poly_S2, one_S), sh_mask_S2),
+ VLJ_S2);
VLJ_S3 = fma(sixth_S * c6grid_S3,
- fma(rinvsix_nm_S3, fnma(expmcr2_S3, poly_S3, one_S), sh_mask_S3), VLJ_S3);
+ fma(rinvsix_nm_S3, fnma(expmcr2_S3, poly_S3, one_S), sh_mask_S3),
+ VLJ_S3);
# endif
# endif /* CALC_ENERGIES */
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
int numAtomsMoved,
const int* move)
{
- nb_verlet->pairSearch_->putOnGrid(box, gridIndex, lowerCorner, upperCorner, updateGroupsCog,
- atomRange, atomDensity, atomInfo, x, numAtomsMoved, move,
+ nb_verlet->pairSearch_->putOnGrid(box,
+ gridIndex,
+ lowerCorner,
+ upperCorner,
+ updateGroupsCog,
+ atomRange,
+ atomDensity,
+ atomInfo,
+ x,
+ numAtomsMoved,
+ move,
nb_verlet->nbat.get());
}
c1[d] = zones->size[zone].bb_x1[d];
}
- nbnxn_put_on_grid(nbv, nullptr, zone, c0, c1, nullptr,
- { zones->cg_range[zone], zones->cg_range[zone + 1] }, -1, atomInfo, x, 0,
+ nbnxn_put_on_grid(nbv,
+ nullptr,
+ zone,
+ c0,
+ c1,
+ nullptr,
+ { zones->cg_range[zone], zones->cg_range[zone + 1] },
+ -1,
+ atomInfo,
+ x,
+ 0,
nullptr);
}
}
return gmx::constArrayRefFromArray(pairSearch_->gridSet().atomIndices().data(), numIndices);
}
-void nonbonded_verlet_t::setLocalAtomOrder()
+void nonbonded_verlet_t::setLocalAtomOrder() const
{
pairSearch_->setLocalAtomOrder();
}
void nonbonded_verlet_t::setAtomProperties(gmx::ArrayRef<const int> atomTypes,
gmx::ArrayRef<const real> atomCharges,
- gmx::ArrayRef<const int> atomInfo)
+ gmx::ArrayRef<const int> atomInfo) const
{
nbnxn_atomdata_set(nbat.get(), pairSearch_->gridSet(), atomTypes, atomCharges, atomInfo);
}
wallcycle_start(wcycle_, ewcNB_XF_BUF_OPS);
wallcycle_sub_start(wcycle_, ewcsNB_X_BUF_OPS);
- nbnxn_atomdata_copy_x_to_nbat_x(pairSearch_->gridSet(), locality, fillLocal,
- as_rvec_array(coordinates.data()), nbat.get());
+ nbnxn_atomdata_copy_x_to_nbat_x(
+ pairSearch_->gridSet(), locality, fillLocal, as_rvec_array(coordinates.data()), nbat.get());
wallcycle_sub_stop(wcycle_, ewcsNB_X_BUF_OPS);
wallcycle_stop(wcycle_, ewcNB_XF_BUF_OPS);
wallcycle_stop(wcycle_, ewcNB_XF_BUF_OPS);
}
-int nonbonded_verlet_t::getNumAtoms(const gmx::AtomLocality locality)
+int nonbonded_verlet_t::getNumAtoms(const gmx::AtomLocality locality) const
{
int numAtoms = 0;
switch (locality)
return numAtoms;
}
-void* nonbonded_verlet_t::getGpuForces()
+void* nonbonded_verlet_t::getGpuForces() const
{
return Nbnxm::getGpuForces(gpu_nbv);
}
return pairlistSets_->params().rlistOuter;
}
-void nonbonded_verlet_t::changePairlistRadii(real rlistOuter, real rlistInner)
+void nonbonded_verlet_t::changePairlistRadii(real rlistOuter, real rlistInner) const
{
pairlistSets_->changePairlistRadii(rlistOuter, rlistInner);
}
void nonbonded_verlet_t::setupGpuShortRangeWork(const gmx::GpuBonded* gpuBonded,
- const gmx::InteractionLocality iLocality)
+ const gmx::InteractionLocality iLocality) const
{
if (useGpu() && !emulateGpu())
{
}
}
-void nonbonded_verlet_t::atomdata_init_copy_x_to_nbat_x_gpu()
+void nonbonded_verlet_t::atomdata_init_copy_x_to_nbat_x_gpu() const
{
Nbnxm::nbnxn_gpu_init_x_to_nbat_x(pairSearch_->gridSet(), gpu_nbv);
}
-void nonbonded_verlet_t::insertNonlocalGpuDependency(const gmx::InteractionLocality interactionLocality)
+void nonbonded_verlet_t::insertNonlocalGpuDependency(const gmx::InteractionLocality interactionLocality) const
{
Nbnxm::nbnxnInsertNonlocalGpuDependency(gpu_nbv, interactionLocality);
}
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012,2013,2014,2015,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
struct NbnxmGpu;
struct gmx_wallcycle;
struct interaction_const_t;
+enum class LJCombinationRule;
struct nbnxn_atomdata_t;
struct nonbonded_verlet_t;
class PairSearch;
class UpdateGroupsCog;
} // namespace gmx
+//! Namespace for non-bonded kernels
namespace Nbnxm
{
enum class KernelType;
-}
-namespace Nbnxm
+/*! \brief Nbnxm electrostatic GPU kernel flavors.
+ *
+ * Types of electrostatics implementations available in the GPU non-bonded
+ * force kernels. These represent both the electrostatics types implemented
+ * by the kernels (cut-off, RF, and Ewald - a subset of what's defined in
+ * enums.h) as well as encode implementation details analytical/tabulated
+ * and single or twin cut-off (for Ewald kernels).
+ * Note that the cut-off and RF kernels have only analytical flavor and unlike
+ * in the CPU kernels, the tabulated kernels are ATM Ewald-only.
+ *
+ * The row-order of pointers to different electrostatic kernels defined in
+ * nbnxn_cuda.cu by the nb_*_kfunc_ptr function pointer table
+ * should match the order of enumerated types below.
+ */
+enum class ElecType : int
{
+ Cut, //!< Plain cut-off
+ RF, //!< Reaction field
+ EwaldTab, //!< Tabulated Ewald with single cut-off
+ EwaldTabTwin, //!< Tabulated Ewald with twin cut-off
+ EwaldAna, //!< Analytical Ewald with single cut-off
+ EwaldAnaTwin, //!< Analytical Ewald with twin cut-off
+ Count //!< Number of valid values
+};
+
+//! Number of possible \ref ElecType values.
+constexpr int c_numElecTypes = static_cast<int>(ElecType::Count);
+
+/*! \brief Nbnxm VdW GPU kernel flavors.
+ *
+ * The enumerates values correspond to the LJ implementations in the GPU non-bonded
+ * kernels.
+ *
+ * The column-order of pointers to different electrostatic kernels defined in
+ * nbnxn_cuda_ocl.cpp/.cu by the nb_*_kfunc_ptr function pointer table
+ * should match the order of enumerated types below.
+ */
+enum class VdwType : int
+{
+ Cut, //!< Plain cut-off
+ CutCombGeom, //!< Cut-off with geometric combination rules
+ CutCombLB, //!< Cut-off with Lorentz-Berthelot combination rules
+ FSwitch, //!< Smooth force switch
+ PSwitch, //!< Smooth potential switch
+ EwaldGeom, //!< Ewald with geometric combination rules
+ EwaldLB, //!< Ewald with Lorentz-Berthelot combination rules
+ Count //!< Number of valid values
+};
+
+//! Number of possible \ref VdwType values.
+constexpr int c_numVdwTypes = static_cast<int>(VdwType::Count);
/*! \brief Nonbonded NxN kernel types: plain C, CPU SIMD, GPU, GPU emulation */
enum class KernelType : int
//! Return whether the pairlist is of simple, CPU type
bool pairlistIsSimple() const { return !useGpu() && !emulateGpu(); }
- //! Initialize the pair list sets, TODO this should be private
- void initPairlistSets(bool haveMultipleDomains);
//! Returns the order of the local atoms on the grid
gmx::ArrayRef<const int> getLocalAtomOrder() const;
//! Sets the order of the local atoms to the order grid atom ordering
- void setLocalAtomOrder();
+ void setLocalAtomOrder() const;
//! Returns the index position of the atoms on the search grid
gmx::ArrayRef<const int> getGridIndices() const;
void constructPairlist(gmx::InteractionLocality iLocality,
const gmx::ListOfLists<int>& exclusions,
int64_t step,
- t_nrnb* nrnb);
+ t_nrnb* nrnb) const;
//! Updates all the atom properties in Nbnxm
void setAtomProperties(gmx::ArrayRef<const int> atomTypes,
gmx::ArrayRef<const real> atomCharges,
- gmx::ArrayRef<const int> atomInfo);
+ gmx::ArrayRef<const int> atomInfo) const;
/*!\brief Convert the coordinates to NBNXM format for the given locality.
*
GpuEventSynchronizer* xReadyOnDevice);
//! Init for GPU version of setup coordinates in Nbnxm
- void atomdata_init_copy_x_to_nbat_x_gpu();
+ void atomdata_init_copy_x_to_nbat_x_gpu() const;
//! Sync the nonlocal GPU stream with dependent tasks in the local queue.
- void insertNonlocalGpuDependency(gmx::InteractionLocality interactionLocality);
+ void insertNonlocalGpuDependency(gmx::InteractionLocality interactionLocality) const;
//! Returns a reference to the pairlist sets
const PairlistSets& pairlistSets() const { return *pairlistSets_; }
bool isDynamicPruningStepGpu(int64_t step) const;
//! Dispatches the dynamic pruning kernel for the given locality, for CPU lists
- void dispatchPruneKernelCpu(gmx::InteractionLocality iLocality, const rvec* shift_vec);
+ void dispatchPruneKernelCpu(gmx::InteractionLocality iLocality, const rvec* shift_vec) const;
//! Dispatches the dynamic pruning kernel for GPU lists
void dispatchPruneKernelGpu(int64_t step);
*/
void atomdata_add_nbat_f_to_f(gmx::AtomLocality locality, gmx::ArrayRef<gmx::RVec> force);
- /*! \brief Add the forces stored in nbat to total force using GPU buffer opse
- *
- * \param [in] locality Local or non-local
- * \param [in,out] totalForcesDevice Force to be added to
- * \param [in] forcesPmeDevice Device buffer with PME forces
- * \param[in] dependencyList List of synchronizers that represent the dependencies the reduction task needs to sync on.
- * \param [in] useGpuFPmeReduction Whether PME forces should be added
- * \param [in] accumulateForce If the total force buffer already contains data
- */
- void atomdata_add_nbat_f_to_f_gpu(gmx::AtomLocality locality,
- DeviceBuffer<gmx::RVec> totalForcesDevice,
- void* forcesPmeDevice,
- gmx::ArrayRef<GpuEventSynchronizer* const> dependencyList,
- bool useGpuFPmeReduction,
- bool accumulateForce);
-
/*! \brief Get the number of atoms for a given locality
*
* \param [in] locality Local or non-local
* \returns The number of atoms for given locality
*/
- int getNumAtoms(gmx::AtomLocality locality);
+ int getNumAtoms(gmx::AtomLocality locality) const;
/*! \brief Get the pointer to the GPU nonbonded force buffer
*
* \returns A pointer to the force buffer in GPU memory
*/
- void* getGpuForces();
+ void* getGpuForces() const;
//! Return the kernel setup
const Nbnxm::KernelSetup& kernelSetup() const { return kernelSetup_; }
real pairlistOuterRadius() const;
//! Changes the pair-list outer and inner radius
- void changePairlistRadii(real rlistOuter, real rlistInner);
+ void changePairlistRadii(real rlistOuter, real rlistInner) const;
//! Set up internal flags that indicate what type of short-range work there is.
- void setupGpuShortRangeWork(const gmx::GpuBonded* gpuBonded, gmx::InteractionLocality iLocality);
+ void setupGpuShortRangeWork(const gmx::GpuBonded* gpuBonded, gmx::InteractionLocality iLocality) const;
// TODO: Make all data members private
-public:
//! All data related to the pair lists
std::unique_ptr<PairlistSets> pairlistSets_;
//! Working data for constructing the pairlists
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team.
- * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
*/
static inline int get_2log(int n)
{
- int log2;
-
- log2 = 0;
+ // TODO: Replace with gmx::Log2I?
+ int log2 = 0;
while ((1 << log2) < n)
{
log2++;
/*! \brief The nbnxn i-cluster size in atoms for each nbnxn kernel type */
static constexpr gmx::EnumerationArray<KernelType, int> IClusterSizePerKernelType = {
- { 0, c_nbnxnCpuIClusterSize, c_nbnxnCpuIClusterSize, c_nbnxnCpuIClusterSize,
- c_nbnxnGpuClusterSize, c_nbnxnGpuClusterSize }
+ { 0, c_nbnxnCpuIClusterSize, c_nbnxnCpuIClusterSize, c_nbnxnCpuIClusterSize, c_nbnxnGpuClusterSize, c_nbnxnGpuClusterSize }
};
/*! \brief The nbnxn j-cluster size in atoms for each nbnxn kernel type */
static constexpr gmx::EnumerationArray<KernelType, int> JClusterSizePerKernelType = {
- { 0, c_nbnxnCpuIClusterSize,
+ { 0,
+ c_nbnxnCpuIClusterSize,
#if GMX_SIMD
- GMX_SIMD_REAL_WIDTH, GMX_SIMD_REAL_WIDTH / 2,
+ GMX_SIMD_REAL_WIDTH,
+ GMX_SIMD_REAL_WIDTH / 2,
#else
- 0, 0,
+ 0,
+ 0,
#endif
- c_nbnxnGpuClusterSize, c_nbnxnGpuClusterSize / 2 }
+ c_nbnxnGpuClusterSize,
+ c_nbnxnGpuClusterSize / 2 }
};
/*! \brief Returns whether the pair-list corresponding to nb_kernel_type is simple */
#include "gromacs/utility/basedefinitions.h"
#include "gromacs/utility/real.h"
+#include "nbnxm.h"
+
struct interaction_const_t;
struct nbnxn_atomdata_t;
struct gmx_wallcycle;
class StepWorkload;
} // namespace gmx
-/*! \brief Nbnxm electrostatic GPU kernel flavors.
- *
- * Types of electrostatics implementations available in the GPU non-bonded
- * force kernels. These represent both the electrostatics types implemented
- * by the kernels (cut-off, RF, and Ewald - a subset of what's defined in
- * enums.h) as well as encode implementation details analytical/tabulated
- * and single or twin cut-off (for Ewald kernels).
- * Note that the cut-off and RF kernels have only analytical flavor and unlike
- * in the CPU kernels, the tabulated kernels are ATM Ewald-only.
- *
- * The row-order of pointers to different electrostatic kernels defined in
- * nbnxn_cuda.cu by the nb_*_kfunc_ptr function pointer table
- * should match the order of enumerated types below.
- */
-enum eelType : int
-{
- eelTypeCUT,
- eelTypeRF,
- eelTypeEWALD_TAB,
- eelTypeEWALD_TAB_TWIN,
- eelTypeEWALD_ANA,
- eelTypeEWALD_ANA_TWIN,
- eelTypeNR
-};
-
-/*! \brief Nbnxm VdW GPU kernel flavors.
- *
- * The enumerates values correspond to the LJ implementations in the GPU non-bonded
- * kernels.
- *
- * The column-order of pointers to different electrostatic kernels defined in
- * nbnxn_cuda_ocl.cpp/.cu by the nb_*_kfunc_ptr function pointer table
- * should match the order of enumerated types below.
- */
-enum evdwType : int
-{
- evdwTypeCUT,
- evdwTypeCUTCOMBGEOM,
- evdwTypeCUTCOMBLB,
- evdwTypeFSWITCH,
- evdwTypePSWITCH,
- evdwTypeEWALDGEOM,
- evdwTypeEWALDLB,
- evdwTypeNR
-};
-
namespace Nbnxm
{
/*! \brief Returns true if LJ combination rules are used in the non-bonded kernels.
*
- * \param[in] vdwType The VdW interaction/implementation type as defined by evdwType
+ * \param[in] vdwType The VdW interaction/implementation type as defined by VdwType
* enumeration.
*
* \returns Whether combination rules are used by the run.
*/
-static inline bool useLjCombRule(const int vdwType)
+static inline bool useLjCombRule(const enum VdwType vdwType)
{
- return (vdwType == evdwTypeCUTCOMBGEOM || vdwType == evdwTypeCUTCOMBLB);
+ return (vdwType == VdwType::CutCombGeom || vdwType == VdwType::CutCombLB);
}
/*! \brief
#include "nbnxm_gpu_data_mgmt.h"
#include "gromacs/hardware/device_information.h"
+#include "gromacs/mdtypes/interaction_const.h"
#include "gromacs/nbnxm/gpu_data_mgmt.h"
#include "gromacs/timing/gpu_timing.h"
#include "gromacs/utility/cstringutil.h"
}
nbp->coulomb_tab_scale = tables.scale;
- initParamLookupTable(&nbp->coulomb_tab, &nbp->coulomb_tab_texobj, tables.tableF.data(),
- tables.tableF.size(), deviceContext);
+ initParamLookupTable(
+ &nbp->coulomb_tab, &nbp->coulomb_tab_texobj, tables.tableF.data(), tables.tableF.size(), deviceContext);
}
-void inline printEnvironmentVariableDeprecationMessage(bool isEnvironmentVariableSet,
- const std::string& environmentVariableSuffix)
-{
- if (isEnvironmentVariableSet)
- {
- fprintf(stderr,
- "Environment variables GMX_CUDA_%s and GMX_OCL_%s are deprecated and will be\n"
- "removed in release 2022, please use GMX_GPU_%s instead.",
- environmentVariableSuffix.c_str(), environmentVariableSuffix.c_str(),
- environmentVariableSuffix.c_str());
- }
-}
-
-int nbnxn_gpu_pick_ewald_kernel_type(const interaction_const_t& ic,
- const DeviceInformation gmx_unused& deviceInfo)
+enum ElecType nbnxn_gpu_pick_ewald_kernel_type(const interaction_const_t& ic,
+ const DeviceInformation gmx_unused& deviceInfo)
{
bool bTwinCut = (ic.rcoulomb != ic.rvdw);
- int kernel_type;
/* Benchmarking/development environment variables to force the use of
analytical or tabulated Ewald kernel. */
-
- // Remove these when old environment variables are deprecated
- const bool forceAnalyticalEwaldLegacy = (getenv("GMX_CUDA_NB_ANA_EWALD") != nullptr)
- || (getenv("GMX_OCL_NB_ANA_EWALD") != nullptr);
- const bool forceTabulatedEwaldLegacy = (getenv("GMX_CUDA_NB_TAB_EWALD") != nullptr)
- || (getenv("GMX_OCL_NB_TAB_EWALD") != nullptr);
- const bool forceTwinCutoffEwaldLegacy = (getenv("GMX_CUDA_NB_EWALD_TWINCUT") != nullptr)
- || (getenv("GMX_OCL_NB_EWALD_TWINCUT") != nullptr);
-
- printEnvironmentVariableDeprecationMessage(forceAnalyticalEwaldLegacy, "NB_ANA_EWALD");
- printEnvironmentVariableDeprecationMessage(forceTabulatedEwaldLegacy, "NB_TAB_EWALD");
- printEnvironmentVariableDeprecationMessage(forceTwinCutoffEwaldLegacy, "NB_EWALD_TWINCUT");
-
- const bool forceAnalyticalEwald =
- (getenv("GMX_GPU_NB_ANA_EWALD") != nullptr) || forceAnalyticalEwaldLegacy;
- const bool forceTabulatedEwald =
- (getenv("GMX_GPU_NB_TAB_EWALD") != nullptr) || forceTabulatedEwaldLegacy;
- const bool forceTwinCutoffEwald =
- (getenv("GMX_GPU_NB_EWALD_TWINCUT") != nullptr) || forceTwinCutoffEwaldLegacy;
+ const bool forceAnalyticalEwald = (getenv("GMX_GPU_NB_ANA_EWALD") != nullptr);
+ const bool forceTabulatedEwald = (getenv("GMX_GPU_NB_TAB_EWALD") != nullptr);
+ const bool forceTwinCutoffEwald = (getenv("GMX_GPU_NB_EWALD_TWINCUT") != nullptr);
if (forceAnalyticalEwald && forceTabulatedEwald)
{
forces it (use it for debugging/benchmarking only). */
if (!bTwinCut && !forceTwinCutoffEwald)
{
- kernel_type = bUseAnalyticalEwald ? eelTypeEWALD_ANA : eelTypeEWALD_TAB;
+ return bUseAnalyticalEwald ? ElecType::EwaldAna : ElecType::EwaldTab;
}
else
{
- kernel_type = bUseAnalyticalEwald ? eelTypeEWALD_ANA_TWIN : eelTypeEWALD_TAB_TWIN;
+ return bUseAnalyticalEwald ? ElecType::EwaldAnaTwin : ElecType::EwaldTabTwin;
}
-
- return kernel_type;
}
void set_cutoff_parameters(NBParamGpu* nbp, const interaction_const_t* ic, const PairlistParams& listParams)
set_cutoff_parameters(nbp, ic, nbv->pairlistSets().params());
- nbp->eeltype = nbnxn_gpu_pick_ewald_kernel_type(*ic, nb->deviceContext_->deviceInfo());
+ nbp->elecType = nbnxn_gpu_pick_ewald_kernel_type(*ic, nb->deviceContext_->deviceInfo());
GMX_RELEASE_ASSERT(ic->coulombEwaldTables, "Need valid Coulomb Ewald correction tables");
init_ewald_coulomb_force_table(*ic->coulombEwaldTables, nbp, *nb->deviceContext_);
void init_timings(gmx_wallclock_gpu_nbnxn_t* t)
{
- int i, j;
-
t->nb_h2d_t = 0.0;
t->nb_d2h_t = 0.0;
t->nb_c = 0;
t->pl_h2d_t = 0.0;
t->pl_h2d_c = 0;
- for (i = 0; i < 2; i++)
+ for (int i = 0; i < 2; i++)
{
- for (j = 0; j < 2; j++)
+ for (int j = 0; j < 2; j++)
{
t->ktime[i][j].t = 0.0;
t->ktime[i][j].c = 0;
{
if (d_plist->na_c != h_plist->na_ci)
{
- sprintf(sbuf, "In init_plist: the #atoms per cell has changed (from %d to %d)",
- d_plist->na_c, h_plist->na_ci);
+ sprintf(sbuf,
+ "In init_plist: the #atoms per cell has changed (from %d to %d)",
+ d_plist->na_c,
+ h_plist->na_ci);
gmx_incons(sbuf);
}
}
// TODO most of this function is same in CUDA and OpenCL, move into the header
const DeviceContext& deviceContext = *nb->deviceContext_;
- reallocateDeviceBuffer(&d_plist->sci, h_plist->sci.size(), &d_plist->nsci, &d_plist->sci_nalloc,
- deviceContext);
- copyToDeviceBuffer(&d_plist->sci, h_plist->sci.data(), 0, h_plist->sci.size(), deviceStream,
- GpuApiCallBehavior::Async, bDoTime ? iTimers.pl_h2d.fetchNextEvent() : nullptr);
-
- reallocateDeviceBuffer(&d_plist->cj4, h_plist->cj4.size(), &d_plist->ncj4, &d_plist->cj4_nalloc,
+ reallocateDeviceBuffer(
+ &d_plist->sci, h_plist->sci.size(), &d_plist->nsci, &d_plist->sci_nalloc, deviceContext);
+ copyToDeviceBuffer(&d_plist->sci,
+ h_plist->sci.data(),
+ 0,
+ h_plist->sci.size(),
+ deviceStream,
+ GpuApiCallBehavior::Async,
+ bDoTime ? iTimers.pl_h2d.fetchNextEvent() : nullptr);
+
+ reallocateDeviceBuffer(
+ &d_plist->cj4, h_plist->cj4.size(), &d_plist->ncj4, &d_plist->cj4_nalloc, deviceContext);
+ copyToDeviceBuffer(&d_plist->cj4,
+ h_plist->cj4.data(),
+ 0,
+ h_plist->cj4.size(),
+ deviceStream,
+ GpuApiCallBehavior::Async,
+ bDoTime ? iTimers.pl_h2d.fetchNextEvent() : nullptr);
+
+ reallocateDeviceBuffer(&d_plist->imask,
+ h_plist->cj4.size() * c_nbnxnGpuClusterpairSplit,
+ &d_plist->nimask,
+ &d_plist->imask_nalloc,
deviceContext);
- copyToDeviceBuffer(&d_plist->cj4, h_plist->cj4.data(), 0, h_plist->cj4.size(), deviceStream,
- GpuApiCallBehavior::Async, bDoTime ? iTimers.pl_h2d.fetchNextEvent() : nullptr);
- reallocateDeviceBuffer(&d_plist->imask, h_plist->cj4.size() * c_nbnxnGpuClusterpairSplit,
- &d_plist->nimask, &d_plist->imask_nalloc, deviceContext);
-
- reallocateDeviceBuffer(&d_plist->excl, h_plist->excl.size(), &d_plist->nexcl,
- &d_plist->excl_nalloc, deviceContext);
- copyToDeviceBuffer(&d_plist->excl, h_plist->excl.data(), 0, h_plist->excl.size(), deviceStream,
- GpuApiCallBehavior::Async, bDoTime ? iTimers.pl_h2d.fetchNextEvent() : nullptr);
+ reallocateDeviceBuffer(
+ &d_plist->excl, h_plist->excl.size(), &d_plist->nexcl, &d_plist->excl_nalloc, deviceContext);
+ copyToDeviceBuffer(&d_plist->excl,
+ h_plist->excl.data(),
+ 0,
+ h_plist->excl.size(),
+ deviceStream,
+ GpuApiCallBehavior::Async,
+ bDoTime ? iTimers.pl_h2d.fetchNextEvent() : nullptr);
if (bDoTime)
{
bool gpu_is_kernel_ewald_analytical(const NbnxmGpu* nb)
{
- return ((nb->nbparam->eeltype == eelTypeEWALD_ANA) || (nb->nbparam->eeltype == eelTypeEWALD_ANA_TWIN));
+ return ((nb->nbparam->elecType == ElecType::EwaldAna)
+ || (nb->nbparam->elecType == ElecType::EwaldAnaTwin));
+}
+
+enum ElecType nbnxmGpuPickElectrostaticsKernelType(const interaction_const_t* ic,
+ const DeviceInformation& deviceInfo)
+{
+ if (ic->eeltype == eelCUT)
+ {
+ return ElecType::Cut;
+ }
+ else if (EEL_RF(ic->eeltype))
+ {
+ return ElecType::RF;
+ }
+ else if ((EEL_PME(ic->eeltype) || ic->eeltype == eelEWALD))
+ {
+ return nbnxn_gpu_pick_ewald_kernel_type(*ic, deviceInfo);
+ }
+ else
+ {
+ /* Shouldn't happen, as this is checked when choosing Verlet-scheme */
+ GMX_THROW(gmx::InconsistentInputError(
+ gmx::formatString("The requested electrostatics type %s (%d) is not implemented in "
+ "the GPU accelerated kernels!",
+ EELTYPE(ic->eeltype),
+ ic->eeltype)));
+ }
+}
+
+
+enum VdwType nbnxmGpuPickVdwKernelType(const interaction_const_t* ic, LJCombinationRule ljCombinationRule)
+{
+ if (ic->vdwtype == evdwCUT)
+ {
+ switch (ic->vdw_modifier)
+ {
+ case eintmodNONE:
+ case eintmodPOTSHIFT:
+ switch (ljCombinationRule)
+ {
+ case LJCombinationRule::None: return VdwType::Cut;
+ case LJCombinationRule::Geometric: return VdwType::CutCombGeom;
+ case LJCombinationRule::LorentzBerthelot: return VdwType::CutCombLB;
+ default:
+ GMX_THROW(gmx::InconsistentInputError(gmx::formatString(
+ "The requested LJ combination rule %s is not implemented in "
+ "the GPU accelerated kernels!",
+ enumValueToString(ljCombinationRule))));
+ }
+ case eintmodFORCESWITCH: return VdwType::FSwitch;
+ case eintmodPOTSWITCH: return VdwType::PSwitch;
+ default:
+ GMX_THROW(gmx::InconsistentInputError(
+ gmx::formatString("The requested VdW interaction modifier %s (%d) is not "
+ "implemented in the GPU accelerated kernels!",
+ INTMODIFIER(ic->vdw_modifier),
+ ic->vdw_modifier)));
+ }
+ }
+ else if (ic->vdwtype == evdwPME)
+ {
+ if (ic->ljpme_comb_rule == eljpmeGEOM)
+ {
+ assert(ljCombinationRule == LJCombinationRule::Geometric);
+ return VdwType::EwaldGeom;
+ }
+ else
+ {
+ assert(ljCombinationRule == LJCombinationRule::LorentzBerthelot);
+ return VdwType::EwaldLB;
+ }
+ }
+ else
+ {
+ GMX_THROW(gmx::InconsistentInputError(gmx::formatString(
+ "The requested VdW type %s (%d) is not implemented in the GPU accelerated kernels!",
+ EVDWTYPE(ic->vdwtype),
+ ic->vdwtype)));
+ }
}
} // namespace Nbnxm
const DeviceContext& deviceContext);
/*! \brief Selects the Ewald kernel type, analytical or tabulated, single or twin cut-off. */
-int nbnxn_gpu_pick_ewald_kernel_type(const interaction_const_t gmx_unused& ic,
- const DeviceInformation& deviceInfo);
+enum ElecType nbnxn_gpu_pick_ewald_kernel_type(const interaction_const_t gmx_unused& ic,
+ const DeviceInformation& deviceInfo);
/*! \brief Copies all parameters related to the cut-off from ic to nbp
*/
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
const char* lookup_kernel_name(const KernelType kernelType)
{
- const char* returnvalue = nullptr;
switch (kernelType)
{
- case KernelType::NotSet: returnvalue = "not set"; break;
- case KernelType::Cpu4x4_PlainC: returnvalue = "plain C"; break;
+ case KernelType::NotSet: return "not set";
+ case KernelType::Cpu4x4_PlainC: return "plain C";
case KernelType::Cpu4xN_Simd_4xN:
case KernelType::Cpu4xN_Simd_2xNN:
#if GMX_SIMD
- returnvalue = "SIMD";
+ return "SIMD";
#else // GMX_SIMD
- returnvalue = "not available";
+ return "not available";
#endif // GMX_SIMD
- break;
- case KernelType::Gpu8x8x8: returnvalue = "GPU"; break;
- case KernelType::Cpu8x8x8_PlainC: returnvalue = "plain C"; break;
+ case KernelType::Gpu8x8x8: return "GPU";
+ case KernelType::Cpu8x8x8_PlainC: return "plain C";
default: gmx_fatal(FARGS, "Illegal kernel type selected");
}
- return returnvalue;
};
/*! \brief Returns the most suitable kernel type and Ewald handling */
/*! \brief Gets and returns the minimum i-list count for balacing based on the GPU used or env.var. when set */
static int getMinimumIlistCountForGpuBalancing(NbnxmGpu* nbnxmGpu)
{
- int minimumIlistCount;
-
if (const char* env = getenv("GMX_NB_MIN_CI"))
{
- char* end;
+ char* end = nullptr;
- minimumIlistCount = strtol(env, &end, 10);
+ int minimumIlistCount = strtol(env, &end, 10);
if (!end || (*end != 0) || minimumIlistCount < 0)
{
- gmx_fatal(FARGS,
- "Invalid value passed in GMX_NB_MIN_CI=%s, non-negative integer required", env);
+ gmx_fatal(
+ FARGS, "Invalid value passed in GMX_NB_MIN_CI=%s, non-negative integer required", env);
}
if (debug)
{
- fprintf(debug, "Neighbor-list balancing parameter: %d (passed as env. var.)\n",
- minimumIlistCount);
+ fprintf(debug, "Neighbor-list balancing parameter: %d (passed as env. var.)\n", minimumIlistCount);
}
+ return minimumIlistCount;
}
else
{
- minimumIlistCount = gpu_min_ci_balanced(nbnxmGpu);
+ int minimumIlistCount = gpu_min_ci_balanced(nbnxmGpu);
if (debug)
{
fprintf(debug,
"multi-processors)\n",
minimumIlistCount);
}
+ return minimumIlistCount;
}
+}
- return minimumIlistCount;
+static int getENbnxnInitCombRule(const t_forcerec* fr)
+{
+ if (fr->ic->vdwtype == evdwCUT
+ && (fr->ic->vdw_modifier == eintmodNONE || fr->ic->vdw_modifier == eintmodPOTSHIFT)
+ && getenv("GMX_NO_LJ_COMB_RULE") == nullptr)
+ {
+ /* Plain LJ cut-off: we can optimize with combination rules */
+ return enbnxninitcombruleDETECT;
+ }
+ else if (fr->ic->vdwtype == evdwPME)
+ {
+ /* LJ-PME: we need to use a combination rule for the grid */
+ if (fr->ljpme_combination_rule == eljpmeGEOM)
+ {
+ return enbnxninitcombruleGEOM;
+ }
+ else
+ {
+ return enbnxninitcombruleLB;
+ }
+ }
+ else
+ {
+ /* We use a full combination matrix: no rule required */
+ return enbnxninitcombruleNONE;
+ }
}
std::unique_ptr<nonbonded_verlet_t> init_nb_verlet(const gmx::MDLogger& mdlog,
setupDynamicPairlistPruning(mdlog, ir, mtop, box, fr->ic, &pairlistParams);
- int enbnxninitcombrule;
- if (fr->ic->vdwtype == evdwCUT
- && (fr->ic->vdw_modifier == eintmodNONE || fr->ic->vdw_modifier == eintmodPOTSHIFT)
- && getenv("GMX_NO_LJ_COMB_RULE") == nullptr)
- {
- /* Plain LJ cut-off: we can optimize with combination rules */
- enbnxninitcombrule = enbnxninitcombruleDETECT;
- }
- else if (fr->ic->vdwtype == evdwPME)
- {
- /* LJ-PME: we need to use a combination rule for the grid */
- if (fr->ljpme_combination_rule == eljpmeGEOM)
- {
- enbnxninitcombrule = enbnxninitcombruleGEOM;
- }
- else
- {
- enbnxninitcombrule = enbnxninitcombruleLB;
- }
- }
- else
- {
- /* We use a full combination matrix: no rule required */
- enbnxninitcombrule = enbnxninitcombruleNONE;
- }
+ const int enbnxninitcombrule = getENbnxnInitCombRule(fr);
auto pinPolicy = (useGpuForNonbonded ? gmx::PinningPolicy::PinnedIfSupported
: gmx::PinningPolicy::CannotBePinned);
*/
mimimumNumEnergyGroupNonbonded = 1;
}
- nbnxn_atomdata_init(mdlog, nbat.get(), kernelSetup.kernelType, enbnxninitcombrule, fr->ntype,
- fr->nbfp, mimimumNumEnergyGroupNonbonded,
+ nbnxn_atomdata_init(mdlog,
+ nbat.get(),
+ kernelSetup.kernelType,
+ enbnxninitcombrule,
+ fr->ntype,
+ fr->nbfp,
+ mimimumNumEnergyGroupNonbonded,
(useGpuForNonbonded || emulateGpu) ? 1 : gmx_omp_nthreads_get(emntNonbonded));
NbnxmGpu* gpu_nbv = nullptr;
minimumIlistCountForGpuBalancing = getMinimumIlistCountForGpuBalancing(gpu_nbv);
}
- auto pairlistSets = std::make_unique<PairlistSets>(pairlistParams, haveMultipleDomains,
- minimumIlistCountForGpuBalancing);
+ auto pairlistSets = std::make_unique<PairlistSets>(
+ pairlistParams, haveMultipleDomains, minimumIlistCountForGpuBalancing);
- auto pairSearch = std::make_unique<PairSearch>(
- ir->pbcType, EI_TPI(ir->eI), DOMAINDECOMP(cr) ? &cr->dd->numCells : nullptr,
- DOMAINDECOMP(cr) ? domdec_zones(cr->dd) : nullptr, pairlistParams.pairlistType,
- bFEP_NonBonded, gmx_omp_nthreads_get(emntPairsearch), pinPolicy);
+ auto pairSearch = std::make_unique<PairSearch>(ir->pbcType,
+ EI_TPI(ir->eI),
+ DOMAINDECOMP(cr) ? &cr->dd->numCells : nullptr,
+ DOMAINDECOMP(cr) ? domdec_zones(cr->dd) : nullptr,
+ pairlistParams.pairlistType,
+ bFEP_NonBonded,
+ gmx_omp_nthreads_get(emntPairsearch),
+ pinPolicy);
- return std::make_unique<nonbonded_verlet_t>(std::move(pairlistSets), std::move(pairSearch),
- std::move(nbat), kernelSetup, gpu_nbv, wcycle);
+ return std::make_unique<nonbonded_verlet_t>(
+ std::move(pairlistSets), std::move(pairSearch), std::move(nbat), kernelSetup, gpu_nbv, wcycle);
}
} // namespace Nbnxm
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014,2015,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015,2019,2020,2021, 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.
/*! \brief The nbnxn SIMD 4xN and 2x(N+N) kernels can be added independently.
* Currently the 2xNN SIMD kernels only make sense with:
* 8-way SIMD: 4x4 setup, works with AVX-256 in single precision
- * 16-way SIMD: 4x8 setup, works with Intel MIC in single precision
+ * 16-way SIMD: 4x8 setup, not currently in use, but worked with Intel MIC
*/
# if GMX_SIMD_REAL_WIDTH == 2 || GMX_SIMD_REAL_WIDTH == 4 || GMX_SIMD_REAL_WIDTH == 8
# define GMX_NBNXN_SIMD_4XN
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team.
- * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
# include <limits>
#endif
-#include "thread_mpi/atomic.h"
-
#include "gromacs/gpu_utils/device_context.h"
#include "gromacs/gpu_utils/gputraits_ocl.h"
#include "gromacs/gpu_utils/oclutils.h"
"Watch out, the input system is too large to simulate!\n"
"The number of nonbonded work units (=number of super-clusters) exceeds the"
"device capabilities. Global work size limit exceeded (%zu > %zu)!",
- global_work_size[i], device_limit);
+ global_work_size[i],
+ device_limit);
}
}
}
*/
/*! \brief Force-only kernel function names. */
-static const char* nb_kfunc_noener_noprune_ptr[eelTypeNR][evdwTypeNR] = {
- { "nbnxn_kernel_ElecCut_VdwLJ_F_opencl", "nbnxn_kernel_ElecCut_VdwLJCombGeom_F_opencl",
- "nbnxn_kernel_ElecCut_VdwLJCombLB_F_opencl", "nbnxn_kernel_ElecCut_VdwLJFsw_F_opencl",
- "nbnxn_kernel_ElecCut_VdwLJPsw_F_opencl", "nbnxn_kernel_ElecCut_VdwLJEwCombGeom_F_opencl",
+static const char* nb_kfunc_noener_noprune_ptr[c_numElecTypes][c_numVdwTypes] = {
+ { "nbnxn_kernel_ElecCut_VdwLJ_F_opencl",
+ "nbnxn_kernel_ElecCut_VdwLJCombGeom_F_opencl",
+ "nbnxn_kernel_ElecCut_VdwLJCombLB_F_opencl",
+ "nbnxn_kernel_ElecCut_VdwLJFsw_F_opencl",
+ "nbnxn_kernel_ElecCut_VdwLJPsw_F_opencl",
+ "nbnxn_kernel_ElecCut_VdwLJEwCombGeom_F_opencl",
"nbnxn_kernel_ElecCut_VdwLJEwCombLB_F_opencl" },
- { "nbnxn_kernel_ElecRF_VdwLJ_F_opencl", "nbnxn_kernel_ElecRF_VdwLJCombGeom_F_opencl",
- "nbnxn_kernel_ElecRF_VdwLJCombLB_F_opencl", "nbnxn_kernel_ElecRF_VdwLJFsw_F_opencl",
- "nbnxn_kernel_ElecRF_VdwLJPsw_F_opencl", "nbnxn_kernel_ElecRF_VdwLJEwCombGeom_F_opencl",
+ { "nbnxn_kernel_ElecRF_VdwLJ_F_opencl",
+ "nbnxn_kernel_ElecRF_VdwLJCombGeom_F_opencl",
+ "nbnxn_kernel_ElecRF_VdwLJCombLB_F_opencl",
+ "nbnxn_kernel_ElecRF_VdwLJFsw_F_opencl",
+ "nbnxn_kernel_ElecRF_VdwLJPsw_F_opencl",
+ "nbnxn_kernel_ElecRF_VdwLJEwCombGeom_F_opencl",
"nbnxn_kernel_ElecRF_VdwLJEwCombLB_F_opencl" },
- { "nbnxn_kernel_ElecEwQSTab_VdwLJ_F_opencl", "nbnxn_kernel_ElecEwQSTab_VdwLJCombGeom_F_opencl",
- "nbnxn_kernel_ElecEwQSTab_VdwLJCombLB_F_opencl", "nbnxn_kernel_ElecEwQSTab_VdwLJFsw_F_opencl",
+ { "nbnxn_kernel_ElecEwQSTab_VdwLJ_F_opencl",
+ "nbnxn_kernel_ElecEwQSTab_VdwLJCombGeom_F_opencl",
+ "nbnxn_kernel_ElecEwQSTab_VdwLJCombLB_F_opencl",
+ "nbnxn_kernel_ElecEwQSTab_VdwLJFsw_F_opencl",
"nbnxn_kernel_ElecEwQSTab_VdwLJPsw_F_opencl",
"nbnxn_kernel_ElecEwQSTab_VdwLJEwCombGeom_F_opencl",
"nbnxn_kernel_ElecEwQSTab_VdwLJEwCombLB_F_opencl" },
"nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJPsw_F_opencl",
"nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombGeom_F_opencl",
"nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombLB_F_opencl" },
- { "nbnxn_kernel_ElecEw_VdwLJ_F_opencl", "nbnxn_kernel_ElecEw_VdwLJCombGeom_F_opencl",
- "nbnxn_kernel_ElecEw_VdwLJCombLB_F_opencl", "nbnxn_kernel_ElecEw_VdwLJFsw_F_opencl",
- "nbnxn_kernel_ElecEw_VdwLJPsw_F_opencl", "nbnxn_kernel_ElecEw_VdwLJEwCombGeom_F_opencl",
+ { "nbnxn_kernel_ElecEw_VdwLJ_F_opencl",
+ "nbnxn_kernel_ElecEw_VdwLJCombGeom_F_opencl",
+ "nbnxn_kernel_ElecEw_VdwLJCombLB_F_opencl",
+ "nbnxn_kernel_ElecEw_VdwLJFsw_F_opencl",
+ "nbnxn_kernel_ElecEw_VdwLJPsw_F_opencl",
+ "nbnxn_kernel_ElecEw_VdwLJEwCombGeom_F_opencl",
"nbnxn_kernel_ElecEw_VdwLJEwCombLB_F_opencl" },
{ "nbnxn_kernel_ElecEwTwinCut_VdwLJ_F_opencl",
"nbnxn_kernel_ElecEwTwinCut_VdwLJCombGeom_F_opencl",
"nbnxn_kernel_ElecEwTwinCut_VdwLJCombLB_F_opencl",
- "nbnxn_kernel_ElecEwTwinCut_VdwLJFsw_F_opencl", "nbnxn_kernel_ElecEwTwinCut_VdwLJPsw_F_opencl",
+ "nbnxn_kernel_ElecEwTwinCut_VdwLJFsw_F_opencl",
+ "nbnxn_kernel_ElecEwTwinCut_VdwLJPsw_F_opencl",
"nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombGeom_F_opencl",
"nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombLB_F_opencl" }
};
/*! \brief Force + energy kernel function pointers. */
-static const char* nb_kfunc_ener_noprune_ptr[eelTypeNR][evdwTypeNR] = {
- { "nbnxn_kernel_ElecCut_VdwLJ_VF_opencl", "nbnxn_kernel_ElecCut_VdwLJCombGeom_VF_opencl",
- "nbnxn_kernel_ElecCut_VdwLJCombLB_VF_opencl", "nbnxn_kernel_ElecCut_VdwLJFsw_VF_opencl",
- "nbnxn_kernel_ElecCut_VdwLJPsw_VF_opencl", "nbnxn_kernel_ElecCut_VdwLJEwCombGeom_VF_opencl",
+static const char* nb_kfunc_ener_noprune_ptr[c_numElecTypes][c_numVdwTypes] = {
+ { "nbnxn_kernel_ElecCut_VdwLJ_VF_opencl",
+ "nbnxn_kernel_ElecCut_VdwLJCombGeom_VF_opencl",
+ "nbnxn_kernel_ElecCut_VdwLJCombLB_VF_opencl",
+ "nbnxn_kernel_ElecCut_VdwLJFsw_VF_opencl",
+ "nbnxn_kernel_ElecCut_VdwLJPsw_VF_opencl",
+ "nbnxn_kernel_ElecCut_VdwLJEwCombGeom_VF_opencl",
"nbnxn_kernel_ElecCut_VdwLJEwCombLB_VF_opencl" },
- { "nbnxn_kernel_ElecRF_VdwLJ_VF_opencl", "nbnxn_kernel_ElecRF_VdwLJCombGeom_VF_opencl",
- "nbnxn_kernel_ElecRF_VdwLJCombLB_VF_opencl", "nbnxn_kernel_ElecRF_VdwLJFsw_VF_opencl",
- "nbnxn_kernel_ElecRF_VdwLJPsw_VF_opencl", "nbnxn_kernel_ElecRF_VdwLJEwCombGeom_VF_opencl",
+ { "nbnxn_kernel_ElecRF_VdwLJ_VF_opencl",
+ "nbnxn_kernel_ElecRF_VdwLJCombGeom_VF_opencl",
+ "nbnxn_kernel_ElecRF_VdwLJCombLB_VF_opencl",
+ "nbnxn_kernel_ElecRF_VdwLJFsw_VF_opencl",
+ "nbnxn_kernel_ElecRF_VdwLJPsw_VF_opencl",
+ "nbnxn_kernel_ElecRF_VdwLJEwCombGeom_VF_opencl",
"nbnxn_kernel_ElecRF_VdwLJEwCombLB_VF_opencl" },
- { "nbnxn_kernel_ElecEwQSTab_VdwLJ_VF_opencl", "nbnxn_kernel_ElecEwQSTab_VdwLJCombGeom_VF_opencl",
+ { "nbnxn_kernel_ElecEwQSTab_VdwLJ_VF_opencl",
+ "nbnxn_kernel_ElecEwQSTab_VdwLJCombGeom_VF_opencl",
"nbnxn_kernel_ElecEwQSTab_VdwLJCombLB_VF_opencl",
- "nbnxn_kernel_ElecEwQSTab_VdwLJFsw_VF_opencl", "nbnxn_kernel_ElecEwQSTab_VdwLJPsw_VF_opencl",
+ "nbnxn_kernel_ElecEwQSTab_VdwLJFsw_VF_opencl",
+ "nbnxn_kernel_ElecEwQSTab_VdwLJPsw_VF_opencl",
"nbnxn_kernel_ElecEwQSTab_VdwLJEwCombGeom_VF_opencl",
"nbnxn_kernel_ElecEwQSTab_VdwLJEwCombLB_VF_opencl" },
{ "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJ_VF_opencl",
"nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJPsw_VF_opencl",
"nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombGeom_VF_opencl",
"nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombLB_VF_opencl" },
- { "nbnxn_kernel_ElecEw_VdwLJ_VF_opencl", "nbnxn_kernel_ElecEw_VdwLJCombGeom_VF_opencl",
- "nbnxn_kernel_ElecEw_VdwLJCombLB_VF_opencl", "nbnxn_kernel_ElecEw_VdwLJFsw_VF_opencl",
- "nbnxn_kernel_ElecEw_VdwLJPsw_VF_opencl", "nbnxn_kernel_ElecEw_VdwLJEwCombGeom_VF_opencl",
+ { "nbnxn_kernel_ElecEw_VdwLJ_VF_opencl",
+ "nbnxn_kernel_ElecEw_VdwLJCombGeom_VF_opencl",
+ "nbnxn_kernel_ElecEw_VdwLJCombLB_VF_opencl",
+ "nbnxn_kernel_ElecEw_VdwLJFsw_VF_opencl",
+ "nbnxn_kernel_ElecEw_VdwLJPsw_VF_opencl",
+ "nbnxn_kernel_ElecEw_VdwLJEwCombGeom_VF_opencl",
"nbnxn_kernel_ElecEw_VdwLJEwCombLB_VF_opencl" },
{ "nbnxn_kernel_ElecEwTwinCut_VdwLJ_VF_opencl",
"nbnxn_kernel_ElecEwTwinCut_VdwLJCombGeom_VF_opencl",
};
/*! \brief Force + pruning kernel function pointers. */
-static const char* nb_kfunc_noener_prune_ptr[eelTypeNR][evdwTypeNR] = {
+static const char* nb_kfunc_noener_prune_ptr[c_numElecTypes][c_numVdwTypes] = {
{ "nbnxn_kernel_ElecCut_VdwLJ_F_prune_opencl",
"nbnxn_kernel_ElecCut_VdwLJCombGeom_F_prune_opencl",
"nbnxn_kernel_ElecCut_VdwLJCombLB_F_prune_opencl",
- "nbnxn_kernel_ElecCut_VdwLJFsw_F_prune_opencl", "nbnxn_kernel_ElecCut_VdwLJPsw_F_prune_opencl",
+ "nbnxn_kernel_ElecCut_VdwLJFsw_F_prune_opencl",
+ "nbnxn_kernel_ElecCut_VdwLJPsw_F_prune_opencl",
"nbnxn_kernel_ElecCut_VdwLJEwCombGeom_F_prune_opencl",
"nbnxn_kernel_ElecCut_VdwLJEwCombLB_F_prune_opencl" },
- { "nbnxn_kernel_ElecRF_VdwLJ_F_prune_opencl", "nbnxn_kernel_ElecRF_VdwLJCombGeom_F_prune_opencl",
+ { "nbnxn_kernel_ElecRF_VdwLJ_F_prune_opencl",
+ "nbnxn_kernel_ElecRF_VdwLJCombGeom_F_prune_opencl",
"nbnxn_kernel_ElecRF_VdwLJCombLB_F_prune_opencl",
- "nbnxn_kernel_ElecRF_VdwLJFsw_F_prune_opencl", "nbnxn_kernel_ElecRF_VdwLJPsw_F_prune_opencl",
+ "nbnxn_kernel_ElecRF_VdwLJFsw_F_prune_opencl",
+ "nbnxn_kernel_ElecRF_VdwLJPsw_F_prune_opencl",
"nbnxn_kernel_ElecRF_VdwLJEwCombGeom_F_prune_opencl",
"nbnxn_kernel_ElecRF_VdwLJEwCombLB_F_prune_opencl" },
{ "nbnxn_kernel_ElecEwQSTab_VdwLJ_F_prune_opencl",
"nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJPsw_F_prune_opencl",
"nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombGeom_F_prune_opencl",
"nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombLB_F_prune_opencl" },
- { "nbnxn_kernel_ElecEw_VdwLJ_F_prune_opencl", "nbnxn_kernel_ElecEw_VdwLJCombGeom_F_prune_opencl",
+ { "nbnxn_kernel_ElecEw_VdwLJ_F_prune_opencl",
+ "nbnxn_kernel_ElecEw_VdwLJCombGeom_F_prune_opencl",
"nbnxn_kernel_ElecEw_VdwLJCombLB_F_prune_opencl",
- "nbnxn_kernel_ElecEw_VdwLJFsw_F_prune_opencl", "nbnxn_kernel_ElecEw_VdwLJPsw_F_prune_opencl",
+ "nbnxn_kernel_ElecEw_VdwLJFsw_F_prune_opencl",
+ "nbnxn_kernel_ElecEw_VdwLJPsw_F_prune_opencl",
"nbnxn_kernel_ElecEw_VdwLJEwCombGeom_F_prune_opencl",
"nbnxn_kernel_ElecEw_VdwLJEwCombLB_F_prune_opencl" },
{ "nbnxn_kernel_ElecEwTwinCut_VdwLJ_F_prune_opencl",
};
/*! \brief Force + energy + pruning kernel function pointers. */
-static const char* nb_kfunc_ener_prune_ptr[eelTypeNR][evdwTypeNR] = {
+static const char* nb_kfunc_ener_prune_ptr[c_numElecTypes][c_numVdwTypes] = {
{ "nbnxn_kernel_ElecCut_VdwLJ_VF_prune_opencl",
"nbnxn_kernel_ElecCut_VdwLJCombGeom_VF_prune_opencl",
"nbnxn_kernel_ElecCut_VdwLJCombLB_VF_prune_opencl",
{ "nbnxn_kernel_ElecRF_VdwLJ_VF_prune_opencl",
"nbnxn_kernel_ElecRF_VdwLJCombGeom_VF_prune_opencl",
"nbnxn_kernel_ElecRF_VdwLJCombLB_VF_prune_opencl",
- "nbnxn_kernel_ElecRF_VdwLJFsw_VF_prune_opencl", "nbnxn_kernel_ElecRF_VdwLJPsw_VF_prune_opencl",
+ "nbnxn_kernel_ElecRF_VdwLJFsw_VF_prune_opencl",
+ "nbnxn_kernel_ElecRF_VdwLJPsw_VF_prune_opencl",
"nbnxn_kernel_ElecRF_VdwLJEwCombGeom_VF_prune_opencl",
"nbnxn_kernel_ElecRF_VdwLJEwCombLB_VF_prune_opencl" },
{ "nbnxn_kernel_ElecEwQSTab_VdwLJ_VF_prune_opencl",
{ "nbnxn_kernel_ElecEw_VdwLJ_VF_prune_opencl",
"nbnxn_kernel_ElecEw_VdwLJCombGeom_VF_prune_opencl",
"nbnxn_kernel_ElecEw_VdwLJCombLB_VF_prune_opencl",
- "nbnxn_kernel_ElecEw_VdwLJFsw_VF_prune_opencl", "nbnxn_kernel_ElecEw_VdwLJPsw_VF_prune_opencl",
+ "nbnxn_kernel_ElecEw_VdwLJFsw_VF_prune_opencl",
+ "nbnxn_kernel_ElecEw_VdwLJPsw_VF_prune_opencl",
"nbnxn_kernel_ElecEw_VdwLJEwCombGeom_VF_prune_opencl",
"nbnxn_kernel_ElecEw_VdwLJEwCombLB_VF_prune_opencl" },
{ "nbnxn_kernel_ElecEwTwinCut_VdwLJ_VF_prune_opencl",
* OpenCL kernel objects are cached in nb. If the requested kernel is not
* found in the cache, it will be created and the cache will be updated.
*/
-static inline cl_kernel select_nbnxn_kernel(NbnxmGpu* nb, int eeltype, int evdwtype, bool bDoEne, bool bDoPrune)
+static inline cl_kernel
+select_nbnxn_kernel(NbnxmGpu* nb, enum ElecType elecType, enum VdwType vdwType, bool bDoEne, bool bDoPrune)
{
const char* kernel_name_to_run;
cl_kernel* kernel_ptr;
cl_int cl_error;
- GMX_ASSERT(eeltype < eelTypeNR,
+ const int elecTypeIdx = static_cast<int>(elecType);
+ const int vdwTypeIdx = static_cast<int>(vdwType);
+
+ GMX_ASSERT(elecTypeIdx < c_numElecTypes,
"The electrostatics type requested is not implemented in the OpenCL kernels.");
- GMX_ASSERT(evdwtype < evdwTypeNR,
+ GMX_ASSERT(vdwTypeIdx < c_numVdwTypes,
"The VdW type requested is not implemented in the OpenCL kernels.");
if (bDoEne)
{
if (bDoPrune)
{
- kernel_name_to_run = nb_kfunc_ener_prune_ptr[eeltype][evdwtype];
- kernel_ptr = &(nb->kernel_ener_prune_ptr[eeltype][evdwtype]);
+ kernel_name_to_run = nb_kfunc_ener_prune_ptr[elecTypeIdx][vdwTypeIdx];
+ kernel_ptr = &(nb->kernel_ener_prune_ptr[elecTypeIdx][vdwTypeIdx]);
}
else
{
- kernel_name_to_run = nb_kfunc_ener_noprune_ptr[eeltype][evdwtype];
- kernel_ptr = &(nb->kernel_ener_noprune_ptr[eeltype][evdwtype]);
+ kernel_name_to_run = nb_kfunc_ener_noprune_ptr[elecTypeIdx][vdwTypeIdx];
+ kernel_ptr = &(nb->kernel_ener_noprune_ptr[elecTypeIdx][vdwTypeIdx]);
}
}
else
{
if (bDoPrune)
{
- kernel_name_to_run = nb_kfunc_noener_prune_ptr[eeltype][evdwtype];
- kernel_ptr = &(nb->kernel_noener_prune_ptr[eeltype][evdwtype]);
+ kernel_name_to_run = nb_kfunc_noener_prune_ptr[elecTypeIdx][vdwTypeIdx];
+ kernel_ptr = &(nb->kernel_noener_prune_ptr[elecTypeIdx][vdwTypeIdx]);
}
else
{
- kernel_name_to_run = nb_kfunc_noener_noprune_ptr[eeltype][evdwtype];
- kernel_ptr = &(nb->kernel_noener_noprune_ptr[eeltype][evdwtype]);
+ kernel_name_to_run = nb_kfunc_noener_noprune_ptr[elecTypeIdx][vdwTypeIdx];
+ kernel_ptr = &(nb->kernel_noener_noprune_ptr[elecTypeIdx][vdwTypeIdx]);
}
}
if (nullptr == kernel_ptr[0])
{
*kernel_ptr = clCreateKernel(nb->dev_rundata->program, kernel_name_to_run, &cl_error);
- GMX_ASSERT(cl_error == CL_SUCCESS, ("clCreateKernel failed: " + ocl_get_error_string(cl_error)
- + " for kernel named " + kernel_name_to_run)
- .c_str());
+ GMX_ASSERT(cl_error == CL_SUCCESS,
+ ("clCreateKernel failed: " + ocl_get_error_string(cl_error)
+ + " for kernel named " + kernel_name_to_run)
+ .c_str());
}
return *kernel_ptr;
/*! \brief Calculates the amount of shared memory required by the nonbonded kernel in use.
*/
-static inline int calc_shmem_required_nonbonded(int vdwType, bool bPrefetchLjParam)
+static inline int calc_shmem_required_nonbonded(enum VdwType vdwType, bool bPrefetchLjParam)
{
int shmem;
nbparams_params->coulomb_tab_scale = nbp->coulomb_tab_scale;
nbparams_params->c_rf = nbp->c_rf;
nbparams_params->dispersion_shift = nbp->dispersion_shift;
- nbparams_params->eeltype = nbp->eeltype;
+ nbparams_params->elecType = nbp->elecType;
nbparams_params->epsfac = nbp->epsfac;
nbparams_params->ewaldcoeff_lj = nbp->ewaldcoeff_lj;
nbparams_params->ewald_beta = nbp->ewald_beta;
nbparams_params->sh_ewald = nbp->sh_ewald;
nbparams_params->sh_lj_ewald = nbp->sh_lj_ewald;
nbparams_params->two_k_rf = nbp->two_k_rf;
- nbparams_params->vdwtype = nbp->vdwtype;
+ nbparams_params->vdwType = nbp->vdwType;
nbparams_params->vdw_switch = nbp->vdw_switch;
}
/* HtoD x, q */
GMX_ASSERT(sizeof(float) == sizeof(*nbatom->x().data()),
"The size of the xyzq buffer element should be equal to the size of float4.");
- copyToDeviceBuffer(&adat->xq, nbatom->x().data() + adat_begin * 4, adat_begin * 4, adat_len * 4,
- deviceStream, GpuApiCallBehavior::Async,
+ copyToDeviceBuffer(&adat->xq,
+ nbatom->x().data() + adat_begin * 4,
+ adat_begin * 4,
+ adat_len * 4,
+ deviceStream,
+ GpuApiCallBehavior::Async,
bDoTime ? t->xf[atomLocality].nb_h2d.fetchNextEvent() : nullptr);
if (bDoTime)
/* kernel launch config */
KernelLaunchConfig config;
- config.sharedMemorySize = calc_shmem_required_nonbonded(nbp->vdwtype, nb->bPrefetchLjParam);
+ config.sharedMemorySize = calc_shmem_required_nonbonded(nbp->vdwType, nb->bPrefetchLjParam);
config.blockSize[0] = c_clSize;
config.blockSize[1] = c_clSize;
config.gridSize[0] = plist->nsci;
fprintf(debug,
"Non-bonded GPU launch configuration:\n\tLocal work size: %zux%zux%zu\n\t"
"Global work size : %zux%zu\n\t#Super-clusters/clusters: %d/%d (%d)\n",
- config.blockSize[0], config.blockSize[1], config.blockSize[2],
- config.blockSize[0] * config.gridSize[0], config.blockSize[1] * config.gridSize[1],
+ config.blockSize[0],
+ config.blockSize[1],
+ config.blockSize[2],
+ config.blockSize[0] * config.gridSize[0],
+ config.blockSize[1] * config.gridSize[1],
plist->nsci * c_nbnxnGpuNumClusterPerSupercluster,
- c_nbnxnGpuNumClusterPerSupercluster, plist->na_c);
+ c_nbnxnGpuNumClusterPerSupercluster,
+ plist->na_c);
}
fillin_ocl_structures(nbp, &nbparams_params);
auto* timingEvent = bDoTime ? t->interaction[iloc].nb_k.fetchNextEvent() : nullptr;
constexpr char kernelName[] = "k_calc_nb";
const auto kernel =
- select_nbnxn_kernel(nb, nbp->eeltype, nbp->vdwtype, stepWork.computeEnergy,
+ select_nbnxn_kernel(nb,
+ nbp->elecType,
+ nbp->vdwType,
+ stepWork.computeEnergy,
(plist->haveFreshList && !nb->timers->interaction[iloc].didPrune));
// The OpenCL kernel takes int as second to last argument because bool is
// not supported as a kernel argument type (sizeof(bool) is implementation defined).
const int computeFshift = static_cast<int>(stepWork.computeVirial);
- if (useLjCombRule(nb->nbparam->vdwtype))
+ if (useLjCombRule(nb->nbparam->vdwType))
{
- const auto kernelArgs = prepareGpuKernelArguments(
- kernel, config, &nbparams_params, &adat->xq, &adat->f, &adat->e_lj, &adat->e_el,
- &adat->fshift, &adat->lj_comb, &adat->shift_vec, &nbp->nbfp, &nbp->nbfp_comb,
- &nbp->coulomb_tab, &plist->sci, &plist->cj4, &plist->excl, &computeFshift);
+ const auto kernelArgs = prepareGpuKernelArguments(kernel,
+ config,
+ &nbparams_params,
+ &adat->xq,
+ &adat->f,
+ &adat->e_lj,
+ &adat->e_el,
+ &adat->fshift,
+ &adat->lj_comb,
+ &adat->shift_vec,
+ &nbp->nbfp,
+ &nbp->nbfp_comb,
+ &nbp->coulomb_tab,
+ &plist->sci,
+ &plist->cj4,
+ &plist->excl,
+ &computeFshift);
launchGpuKernel(kernel, config, deviceStream, timingEvent, kernelName, kernelArgs);
}
else
{
- const auto kernelArgs = prepareGpuKernelArguments(
- kernel, config, &adat->ntypes, &nbparams_params, &adat->xq, &adat->f, &adat->e_lj,
- &adat->e_el, &adat->fshift, &adat->atom_types, &adat->shift_vec, &nbp->nbfp, &nbp->nbfp_comb,
- &nbp->coulomb_tab, &plist->sci, &plist->cj4, &plist->excl, &computeFshift);
+ const auto kernelArgs = prepareGpuKernelArguments(kernel,
+ config,
+ &adat->ntypes,
+ &nbparams_params,
+ &adat->xq,
+ &adat->f,
+ &adat->e_lj,
+ &adat->e_el,
+ &adat->fshift,
+ &adat->atom_types,
+ &adat->shift_vec,
+ &nbp->nbfp,
+ &nbp->nbfp_comb,
+ &nbp->coulomb_tab,
+ &plist->sci,
+ &plist->cj4,
+ &plist->excl,
+ &computeFshift);
launchGpuKernel(kernel, config, deviceStream, timingEvent, kernelName, kernelArgs);
}
"Pruning GPU kernel launch configuration:\n\tLocal work size: %zux%zux%zu\n\t"
"\tGlobal work size: %zux%zu\n\t#Super-clusters/clusters: %d/%d (%d)\n"
"\tShMem: %zu\n",
- config.blockSize[0], config.blockSize[1], config.blockSize[2],
- config.blockSize[0] * config.gridSize[0], config.blockSize[1] * config.gridSize[1],
+ config.blockSize[0],
+ config.blockSize[1],
+ config.blockSize[2],
+ config.blockSize[0] * config.gridSize[0],
+ config.blockSize[1] * config.gridSize[1],
plist->nsci * c_nbnxnGpuNumClusterPerSupercluster,
- c_nbnxnGpuNumClusterPerSupercluster, plist->na_c, config.sharedMemorySize);
+ c_nbnxnGpuNumClusterPerSupercluster,
+ plist->na_c,
+ config.sharedMemorySize);
}
cl_nbparam_params_t nbparams_params;
auto* timingEvent = bDoTime ? timer->fetchNextEvent() : nullptr;
constexpr char kernelName[] = "k_pruneonly";
const auto pruneKernel = selectPruneKernel(nb->kernel_pruneonly, plist->haveFreshList);
- const auto kernelArgs = prepareGpuKernelArguments(pruneKernel, config, &nbparams_params,
- &adat->xq, &adat->shift_vec, &plist->sci,
- &plist->cj4, &plist->imask, &numParts, &part);
+ const auto kernelArgs = prepareGpuKernelArguments(pruneKernel,
+ config,
+ &nbparams_params,
+ &adat->xq,
+ &adat->shift_vec,
+ &plist->sci,
+ &plist->cj4,
+ &plist->imask,
+ &numParts,
+ &part);
launchGpuKernel(pruneKernel, config, deviceStream, timingEvent, kernelName, kernelArgs);
if (plist->haveFreshList)
/* DtoH f */
GMX_ASSERT(sizeof(*nbatom->out[0].f.data()) == sizeof(float),
"The host force buffer should be in single precision to match device data size.");
- copyFromDeviceBuffer(&nbatom->out[0].f[adat_begin * DIM], &adat->f, adat_begin * DIM,
- adat_len * DIM, deviceStream, GpuApiCallBehavior::Async,
+ copyFromDeviceBuffer(&nbatom->out[0].f[adat_begin * DIM],
+ &adat->f,
+ adat_begin * DIM,
+ adat_len * DIM,
+ deviceStream,
+ GpuApiCallBehavior::Async,
bDoTime ? t->xf[aloc].nb_d2h.fetchNextEvent() : nullptr);
/* kick off work */
{
GMX_ASSERT(sizeof(*nb->nbst.fshift) == DIM * sizeof(float),
"Sizes of host- and device-side shift vector elements should be the same.");
- copyFromDeviceBuffer(reinterpret_cast<float*>(nb->nbst.fshift), &adat->fshift, 0,
- SHIFTS * DIM, deviceStream, GpuApiCallBehavior::Async,
+ copyFromDeviceBuffer(reinterpret_cast<float*>(nb->nbst.fshift),
+ &adat->fshift,
+ 0,
+ SHIFTS * DIM,
+ deviceStream,
+ GpuApiCallBehavior::Async,
bDoTime ? t->xf[aloc].nb_d2h.fetchNextEvent() : nullptr);
}
{
GMX_ASSERT(sizeof(*nb->nbst.e_lj) == sizeof(float),
"Sizes of host- and device-side LJ energy terms should be the same.");
- copyFromDeviceBuffer(nb->nbst.e_lj, &adat->e_lj, 0, 1, deviceStream, GpuApiCallBehavior::Async,
+ copyFromDeviceBuffer(nb->nbst.e_lj,
+ &adat->e_lj,
+ 0,
+ 1,
+ deviceStream,
+ GpuApiCallBehavior::Async,
bDoTime ? t->xf[aloc].nb_d2h.fetchNextEvent() : nullptr);
GMX_ASSERT(sizeof(*nb->nbst.e_el) == sizeof(float),
"Sizes of host- and device-side electrostatic energy terms should be the "
"same.");
- copyFromDeviceBuffer(nb->nbst.e_el, &adat->e_el, 0, 1, deviceStream, GpuApiCallBehavior::Async,
+ copyFromDeviceBuffer(nb->nbst.e_el,
+ &adat->e_el,
+ 0,
+ 1,
+ deviceStream,
+ GpuApiCallBehavior::Async,
bDoTime ? t->xf[aloc].nb_d2h.fetchNextEvent() : nullptr);
}
}
ad->nalloc = -1;
}
-/*! \brief Returns the kinds of electrostatics and Vdw OpenCL
- * kernels that will be used.
- *
- * Respectively, these values are from enum eelOcl and enum
- * evdwOcl. */
-static void map_interaction_types_to_gpu_kernel_flavors(const interaction_const_t* ic,
- int combRule,
- int* gpu_eeltype,
- int* gpu_vdwtype,
- const DeviceContext& deviceContext)
-{
- if (ic->vdwtype == evdwCUT)
- {
- switch (ic->vdw_modifier)
- {
- case eintmodNONE:
- case eintmodPOTSHIFT:
- switch (combRule)
- {
- case ljcrNONE: *gpu_vdwtype = evdwTypeCUT; break;
- case ljcrGEOM: *gpu_vdwtype = evdwTypeCUTCOMBGEOM; break;
- case ljcrLB: *gpu_vdwtype = evdwTypeCUTCOMBLB; break;
- default:
- gmx_incons(
- "The requested LJ combination rule is not implemented in the "
- "OpenCL GPU accelerated kernels!");
- }
- break;
- case eintmodFORCESWITCH: *gpu_vdwtype = evdwTypeFSWITCH; break;
- case eintmodPOTSWITCH: *gpu_vdwtype = evdwTypePSWITCH; break;
- default:
- gmx_incons(
- "The requested VdW interaction modifier is not implemented in the GPU "
- "accelerated kernels!");
- }
- }
- else if (ic->vdwtype == evdwPME)
- {
- if (ic->ljpme_comb_rule == ljcrGEOM)
- {
- *gpu_vdwtype = evdwTypeEWALDGEOM;
- }
- else
- {
- *gpu_vdwtype = evdwTypeEWALDLB;
- }
- }
- else
- {
- gmx_incons("The requested VdW type is not implemented in the GPU accelerated kernels!");
- }
-
- if (ic->eeltype == eelCUT)
- {
- *gpu_eeltype = eelTypeCUT;
- }
- else if (EEL_RF(ic->eeltype))
- {
- *gpu_eeltype = eelTypeRF;
- }
- else if ((EEL_PME(ic->eeltype) || ic->eeltype == eelEWALD))
- {
- *gpu_eeltype = nbnxn_gpu_pick_ewald_kernel_type(*ic, deviceContext.deviceInfo());
- }
- else
- {
- /* Shouldn't happen, as this is checked when choosing Verlet-scheme */
- gmx_incons(
- "The requested electrostatics type is not implemented in the GPU accelerated "
- "kernels!");
- }
-}
/*! \brief Initializes the nonbonded parameter data structure.
*/
{
set_cutoff_parameters(nbp, ic, listParams);
- map_interaction_types_to_gpu_kernel_flavors(ic, nbatParams.comb_rule, &(nbp->eeltype),
- &(nbp->vdwtype), deviceContext);
+ nbp->vdwType = nbnxmGpuPickVdwKernelType(ic, nbatParams.ljCombinationRule);
+ nbp->elecType = nbnxmGpuPickElectrostaticsKernelType(ic, deviceContext.deviceInfo());
if (ic->vdwtype == evdwPME)
{
- if (ic->ljpme_comb_rule == ljcrGEOM)
+ if (ic->ljpme_comb_rule == eljpmeGEOM)
{
- GMX_ASSERT(nbatParams.comb_rule == ljcrGEOM, "Combination rule mismatch!");
+ GMX_ASSERT(nbatParams.ljCombinationRule == LJCombinationRule::Geometric,
+ "Combination rule mismatch!");
}
else
{
- GMX_ASSERT(nbatParams.comb_rule == ljcrLB, "Combination rule mismatch!");
+ GMX_ASSERT(nbatParams.ljCombinationRule == LJCombinationRule::LorentzBerthelot,
+ "Combination rule mismatch!");
}
}
/* generate table for PME */
nbp->coulomb_tab = nullptr;
- if (nbp->eeltype == eelTypeEWALD_TAB || nbp->eeltype == eelTypeEWALD_TAB_TWIN)
+ if (nbp->elecType == ElecType::EwaldTab || nbp->elecType == ElecType::EwaldTabTwin)
{
GMX_RELEASE_ASSERT(ic->coulombEwaldTables, "Need valid Coulomb Ewald correction tables");
init_ewald_coulomb_force_table(*ic->coulombEwaldTables, nbp, deviceContext);
kernel = clCreateKernel(nb->dev_rundata->program, kernel_name, &cl_error);
if (CL_SUCCESS != cl_error)
{
- gmx_fatal(FARGS, "Failed to create kernel '%s' for GPU #%s: OpenCL error %d", kernel_name,
- nb->deviceContext_->deviceInfo().device_name, cl_error);
+ gmx_fatal(FARGS,
+ "Failed to create kernel '%s' for GPU #%s: OpenCL error %d",
+ kernel_name,
+ nb->deviceContext_->deviceInfo().device_name,
+ cl_error);
}
return kernel;
cl_error |= clSetKernelArg(zero_e_fshift, arg_no++, sizeof(cl_uint), &shifts);
GMX_ASSERT(cl_error == CL_SUCCESS, ocl_get_error_string(cl_error).c_str());
- cl_error = clEnqueueNDRangeKernel(ls, zero_e_fshift, 3, nullptr, global_work_size,
- local_work_size, 0, nullptr, nullptr);
+ cl_error = clEnqueueNDRangeKernel(
+ ls, zero_e_fshift, 3, nullptr, global_work_size, local_work_size, 0, nullptr, nullptr);
GMX_ASSERT(cl_error == CL_SUCCESS, ocl_get_error_string(cl_error).c_str());
}
//! This function is documented in the header file
void gpu_upload_shiftvec(NbnxmGpu* nb, const nbnxn_atomdata_t* nbatom)
{
- cl_atomdata_t* adat = nb->atdat;
- const DeviceStream& deviceStream = *nb->deviceStreams[InteractionLocality::Local];
+ cl_atomdata_t* adat = nb->atdat;
+ const DeviceStream& localStream = *nb->deviceStreams[InteractionLocality::Local];
/* only if we have a dynamic box */
if (nbatom->bDynamicBox || !adat->bShiftVecUploaded)
{
GMX_ASSERT(sizeof(float) * DIM == sizeof(*nbatom->shift_vec.data()),
"Sizes of host- and device-side shift vectors should be the same.");
- copyToDeviceBuffer(&adat->shift_vec, reinterpret_cast<const float*>(nbatom->shift_vec.data()),
- 0, SHIFTS * DIM, deviceStream, GpuApiCallBehavior::Async, nullptr);
+ copyToDeviceBuffer(&adat->shift_vec,
+ reinterpret_cast<const float*>(nbatom->shift_vec.data()),
+ 0,
+ SHIFTS * DIM,
+ localStream,
+ GpuApiCallBehavior::Async,
+ nullptr);
adat->bShiftVecUploaded = CL_TRUE;
}
}
cl_timers_t* timers = nb->timers;
cl_atomdata_t* d_atdat = nb->atdat;
const DeviceContext& deviceContext = *nb->deviceContext_;
- const DeviceStream& deviceStream = *nb->deviceStreams[InteractionLocality::Local];
+ const DeviceStream& localStream = *nb->deviceStreams[InteractionLocality::Local];
natoms = nbat->numAtoms();
realloced = false;
if (bDoTime)
{
/* time async copy */
- timers->atdat.openTimingRegion(deviceStream);
+ timers->atdat.openTimingRegion(localStream);
}
/* need to reallocate if we have to copy more atoms than the amount of space
allocateDeviceBuffer(&d_atdat->f, nalloc * DIM, deviceContext);
allocateDeviceBuffer(&d_atdat->xq, nalloc * (DIM + 1), deviceContext);
- if (useLjCombRule(nb->nbparam->vdwtype))
+ if (useLjCombRule(nb->nbparam->vdwType))
{
// Two Lennard-Jones parameters per atom
allocateDeviceBuffer(&d_atdat->lj_comb, nalloc * 2, deviceContext);
nbnxn_ocl_clear_f(nb, nalloc);
}
- if (useLjCombRule(nb->nbparam->vdwtype))
+ if (useLjCombRule(nb->nbparam->vdwType))
{
GMX_ASSERT(sizeof(float) == sizeof(*nbat->params().lj_comb.data()),
"Size of the LJ parameters element should be equal to the size of float2.");
- copyToDeviceBuffer(&d_atdat->lj_comb, nbat->params().lj_comb.data(), 0, 2 * natoms,
- deviceStream, GpuApiCallBehavior::Async,
+ copyToDeviceBuffer(&d_atdat->lj_comb,
+ nbat->params().lj_comb.data(),
+ 0,
+ 2 * natoms,
+ localStream,
+ GpuApiCallBehavior::Async,
bDoTime ? timers->atdat.fetchNextEvent() : nullptr);
}
else
{
GMX_ASSERT(sizeof(int) == sizeof(*nbat->params().type.data()),
"Sizes of host- and device-side atom types should be the same.");
- copyToDeviceBuffer(&d_atdat->atom_types, nbat->params().type.data(), 0, natoms, deviceStream,
- GpuApiCallBehavior::Async, bDoTime ? timers->atdat.fetchNextEvent() : nullptr);
+ copyToDeviceBuffer(&d_atdat->atom_types,
+ nbat->params().type.data(),
+ 0,
+ natoms,
+ localStream,
+ GpuApiCallBehavior::Async,
+ bDoTime ? timers->atdat.fetchNextEvent() : nullptr);
}
if (bDoTime)
{
- timers->atdat.closeTimingRegion(deviceStream);
+ timers->atdat.closeTimingRegion(localStream);
}
/* kick off the tasks enqueued above to ensure concurrency with the search */
- cl_error = clFlush(deviceStream.stream());
+ cl_error = clFlush(localStream.stream());
GMX_RELEASE_ASSERT(cl_error == CL_SUCCESS,
("clFlush failed: " + ocl_get_error_string(cl_error)).c_str());
}
/*! \brief Returns a string with the compiler defines required to avoid all flavour generation
*
- * For example if flavour eelTypeRF with evdwTypeFSWITCH, the output will be such that the corresponding
+ * For example if flavour ElecType::RF with VdwType::FSwitch, the output will be such that the corresponding
* kernel flavour is generated:
* -DGMX_OCL_FASTGEN (will replace flavour generator nbnxn_ocl_kernels.clh with nbnxn_ocl_kernels_fastgen.clh)
- * -DEL_RF (The eelTypeRF flavour)
+ * -DEL_RF (The ElecType::RF flavour)
* -DEELNAME=_ElecRF (The first part of the generated kernel name )
- * -DLJ_EWALD_COMB_GEOM (The evdwTypeFSWITCH flavour)
+ * -DLJ_EWALD_COMB_GEOM (The VdwType::FSwitch flavour)
* -DVDWNAME=_VdwLJEwCombGeom (The second part of the generated kernel name )
*
* prune/energy are still generated as originally. It is only the flavour-level that has changed, so that
* only the required flavour for the simulation is compiled.
*
- * If eeltype is single-range Ewald, then we need to add the
+ * If elecType is single-range Ewald, then we need to add the
* twin-cutoff flavour kernels to the JIT, because PME tuning might
* need it. This path sets -DGMX_OCL_FASTGEN_ADD_TWINCUT, which
* triggers the use of nbnxn_ocl_kernels_fastgen_add_twincut.clh. This
* JIT defaults to compiling all kernel flavours.
*
* \param[in] bFastGen Whether FastGen should be used
- * \param[in] eeltype Electrostatics kernel flavour for FastGen
- * \param[in] vdwtype VDW kernel flavour for FastGen
+ * \param[in] elecType Electrostatics kernel flavour for FastGen
+ * \param[in] vdwType VDW kernel flavour for FastGen
* \return String with the defines if FastGen is active
*
* \throws std::bad_alloc if out of memory
*/
-static std::string makeDefinesForKernelTypes(bool bFastGen, int eeltype, int vdwtype)
+static std::string makeDefinesForKernelTypes(bool bFastGen,
+ enum Nbnxm::ElecType elecType,
+ enum Nbnxm::VdwType vdwType)
{
+ using Nbnxm::ElecType;
std::string defines_for_kernel_types;
if (bFastGen)
{
- bool bIsEwaldSingleCutoff = (eeltype == eelTypeEWALD_TAB || eeltype == eelTypeEWALD_ANA);
+ bool bIsEwaldSingleCutoff = (elecType == ElecType::EwaldTab || elecType == ElecType::EwaldAna);
if (bIsEwaldSingleCutoff)
{
nbnxn_ocl_kernels_fastgen.clh. */
defines_for_kernel_types += "-DGMX_OCL_FASTGEN";
}
- defines_for_kernel_types += kernel_electrostatic_family_definitions[eeltype];
- defines_for_kernel_types += kernel_VdW_family_definitions[vdwtype];
+ defines_for_kernel_types += kernel_electrostatic_family_definitions[static_cast<int>(elecType)];
+ defines_for_kernel_types += kernel_VdW_family_definitions[static_cast<int>(vdwType)];
}
return defines_for_kernel_types;
try
{
std::string extraDefines =
- makeDefinesForKernelTypes(bFastGen, nb->nbparam->eeltype, nb->nbparam->vdwtype);
+ makeDefinesForKernelTypes(bFastGen, nb->nbparam->elecType, nb->nbparam->vdwType);
/* Here we pass macros and static const/constexpr int variables defined
* in include files outside the opencl as macros, to avoid
" -Dc_nbnxnGpuNumClusterPerSupercluster=%d"
" -Dc_nbnxnGpuJgroupSize=%d"
"%s",
- c_nbnxnGpuClusterSize, c_nbnxnMinDistanceSquared, c_nbnxnGpuNumClusterPerSupercluster,
- c_nbnxnGpuJgroupSize, (nb->bPrefetchLjParam) ? " -DIATYPE_SHMEM" : "");
+ c_nbnxnGpuClusterSize,
+ c_nbnxnMinDistanceSquared,
+ c_nbnxnGpuNumClusterPerSupercluster,
+ c_nbnxnGpuJgroupSize,
+ (nb->bPrefetchLjParam) ? " -DIATYPE_SHMEM" : "");
try
{
/* TODO when we have a proper MPI-aware logging module,
the log output here should be written there */
- program = gmx::ocl::compileProgram(
- stderr, "gromacs/nbnxm/opencl", "nbnxm_ocl_kernels.cl", extraDefines,
- nb->deviceContext_->context(), nb->deviceContext_->deviceInfo().oclDeviceId,
- nb->deviceContext_->deviceInfo().deviceVendor);
+ program = gmx::ocl::compileProgram(stderr,
+ "gromacs/nbnxm/opencl",
+ "nbnxm_ocl_kernels.cl",
+ extraDefines,
+ nb->deviceContext_->context(),
+ nb->deviceContext_->deviceInfo().oclDeviceId,
+ nb->deviceContext_->deviceInfo().deviceVendor);
}
catch (gmx::GromacsException& e)
{
- e.prependContext(gmx::formatString(
- "Failed to compile/load nbnxm kernels for GPU #%d %s\n",
- nb->deviceContext_->deviceInfo().id, nb->deviceContext_->deviceInfo().device_name));
+ e.prependContext(
+ gmx::formatString("Failed to compile/load nbnxm kernels for GPU #%d %s\n",
+ nb->deviceContext_->deviceInfo().id,
+ nb->deviceContext_->deviceInfo().device_name));
throw;
}
}
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012-2018, The GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
#else
const __global int* restrict atom_types, /* IN */
#endif
- const __global float* restrict shift_vec, /* IN stores float3 values */
- __constant const float* gmx_unused nbfp_climg2d, /* IN */
- __constant const float* gmx_unused nbfp_comb_climg2d, /* IN */
- __constant const float* gmx_unused coulomb_tab_climg2d, /* IN */
- const __global nbnxn_sci_t* pl_sci, /* IN */
+ const __global float* restrict shift_vec, /* IN stores float3 values */
+ __constant const float* gmx_unused nbfp, /* IN */
+ __constant const float* gmx_unused nbfp_comb, /* IN */
+ __constant const float* gmx_unused coulomb_tab, /* IN */
+ const __global nbnxn_sci_t* pl_sci, /* IN */
#ifndef PRUNE_NBL
const
#endif
const int ai = ci * CL_SIZE + tidxi;
float4 xqbuf = xq[ai]
- + (float4)(shift_vec[3 * nb_sci.shift], shift_vec[3 * nb_sci.shift + 1],
- shift_vec[3 * nb_sci.shift + 2], 0.0F);
+ + (float4)(shift_vec[3 * nb_sci.shift],
+ shift_vec[3 * nb_sci.shift + 1],
+ shift_vec[3 * nb_sci.shift + 2],
+ 0.0F);
xqbuf.w *= nbparam->epsfac;
xqib[(tidxj + i) * CL_SIZE + tidxi] = xqbuf;
#ifdef IATYPE_SHMEM
E_el += qi * qi;
# endif
# if defined LJ_EWALD
- E_lj += nbfp_climg2d[atom_types[(sci * c_nbnxnGpuNumClusterPerSupercluster + i) * CL_SIZE + tidxi]
- * (ntypes + 1) * 2];
+ E_lj += nbfp[atom_types[(sci * c_nbnxnGpuNumClusterPerSupercluster + i) * CL_SIZE + tidxi]
+ * (ntypes + 1) * 2];
# endif /* LJ_EWALD */
}
#endif /* IATYPE_SHMEM */
/* LJ 6*C6 and 12*C12 */
#ifndef LJ_COMB
- const float c6 = nbfp_climg2d[2 * (ntypes * typei + typej)];
- const float c12 = nbfp_climg2d[2 * (ntypes * typei + typej) + 1];
+ const float c6 = nbfp[2 * (ntypes * typei + typej)];
+ const float c12 = nbfp[2 * (ntypes * typei + typej) + 1];
#else /* LJ_COMB */
# ifdef LJ_COMB_GEOM
const float c6 = ljcp_i.x * ljcp_j.x;
#ifdef LJ_EWALD
# ifdef LJ_EWALD_COMB_GEOM
# ifdef CALC_ENERGIES
- calculate_lj_ewald_comb_geom_F_E(
- nbfp_comb_climg2d, nbparam, typei, typej, r2, inv_r2,
- lje_coeff2, lje_coeff6_6, int_bit, &F_invr, &E_lj_p);
+ calculate_lj_ewald_comb_geom_F_E(nbfp_comb,
+ nbparam,
+ typei,
+ typej,
+ r2,
+ inv_r2,
+ lje_coeff2,
+ lje_coeff6_6,
+ int_bit,
+ &F_invr,
+ &E_lj_p);
# else
- calculate_lj_ewald_comb_geom_F(nbfp_comb_climg2d, typei, typej, r2, inv_r2,
- lje_coeff2, lje_coeff6_6, &F_invr);
+ calculate_lj_ewald_comb_geom_F(
+ nbfp_comb, typei, typej, r2, inv_r2, lje_coeff2, lje_coeff6_6, &F_invr);
# endif /* CALC_ENERGIES */
# elif defined LJ_EWALD_COMB_LB
- calculate_lj_ewald_comb_LB_F_E(nbfp_comb_climg2d, nbparam, typei, typej,
- r2, inv_r2, lje_coeff2, lje_coeff6_6,
+ calculate_lj_ewald_comb_LB_F_E(nbfp_comb,
+ nbparam,
+ typei,
+ typej,
+ r2,
+ inv_r2,
+ lje_coeff2,
+ lje_coeff6_6,
# ifdef CALC_ENERGIES
- int_bit, true, &F_invr, &E_lj_p
+ int_bit,
+ true,
+ &F_invr,
+ &E_lj_p
# else
- 0, false, &F_invr, 0
+ 0,
+ false,
+ &F_invr,
+ 0
# endif /* CALC_ENERGIES */
);
# endif /* LJ_EWALD_COMB_GEOM */
#elif defined EL_EWALD_TAB
F_invr += qi * qj_f
* (int_bit * inv_r2
- - interpolate_coulomb_force_r(coulomb_tab_climg2d, r2 * inv_r,
- coulomb_tab_scale))
+ - interpolate_coulomb_force_r(
+ coulomb_tab, r2 * inv_r, coulomb_tab_scale))
* inv_r;
#endif /* EL_EWALD_ANA/TAB */
/* We don't need q, but using float4 in shmem avoids bank conflicts */
const float4 tmp = xq[ai];
const float4 xi = tmp
- + (float4)(shift_vec[3 * nb_sci.shift], shift_vec[3 * nb_sci.shift + 1],
- shift_vec[3 * nb_sci.shift + 2], 0.0F);
+ + (float4)(shift_vec[3 * nb_sci.shift],
+ shift_vec[3 * nb_sci.shift + 1],
+ shift_vec[3 * nb_sci.shift + 2],
+ 0.0F);
xib[(tidxj + i) * c_clSize + tidxi] = xi;
}
}
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012,2013,2014,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
# ifdef __GNUC__
-/* GCC, clang, and some ICC pretending to be GCC */
+/* GCC, clang */
# define gmx_unused __attribute__((unused))
# else
# define gmx_unused
typedef struct cl_nbparam_params
{
- //! type of electrostatics, takes values from #eelCu
- int eeltype;
- //! type of VdW impl., takes values from #evdwCu
- int vdwtype;
+ //! type of electrostatics, takes values from #ElecType
+ int elecType;
+ //! type of VdW impl., takes values from #VdwType
+ int vdwType;
//! charge multiplication factor
float epsfac;
} nbnxn_excl_t;
/*! i-cluster interaction mask for a super-cluster with all c_nbnxnGpuNumClusterPerSupercluster bits set */
-__constant unsigned supercl_interaction_mask = ((1U << c_nbnxnGpuNumClusterPerSupercluster) - 1U);
+__constant const unsigned supercl_interaction_mask = ((1U << c_nbnxnGpuNumClusterPerSupercluster) - 1U);
/*! Minimum single precision threshold for r^2 to avoid r^-12 overflow. */
-__constant float c_nbnxnMinDistanceSquared = NBNXM_MIN_DISTANCE_SQUARED_VALUE_FLOAT;
+__constant const float c_nbnxnMinDistanceSquared = NBNXM_MIN_DISTANCE_SQUARED_VALUE_FLOAT;
gmx_opencl_inline void preloadCj4Generic(__local int* sm_cjPreload,
const __global int* gm_cj,
/*! Calculate LJ-PME grid force contribution with
* geometric combination rule.
*/
-gmx_opencl_inline void calculate_lj_ewald_comb_geom_F(__constant const float* nbfp_comb_climg2d,
+gmx_opencl_inline void calculate_lj_ewald_comb_geom_F(__constant const float* nbfp_comb,
int typei,
int typej,
float r2,
float lje_coeff6_6,
float* F_invr)
{
- const float c6grid = nbfp_comb_climg2d[2 * typei] * nbfp_comb_climg2d[2 * typej];
+ const float c6grid = nbfp_comb[2 * typei] * nbfp_comb[2 * typej];
/* Recalculate inv_r6 without exclusion mask */
const float inv_r6_nm = inv_r2 * inv_r2 * inv_r2;
/*! Calculate LJ-PME grid force + energy contribution with
* geometric combination rule.
*/
-gmx_opencl_inline void calculate_lj_ewald_comb_geom_F_E(__constant const float* nbfp_comb_climg2d,
+gmx_opencl_inline void calculate_lj_ewald_comb_geom_F_E(__constant const float* nbfp_comb,
const cl_nbparam_params_t* nbparam,
int typei,
int typej,
float* F_invr,
float* E_lj)
{
- const float c6grid = nbfp_comb_climg2d[2 * typei] * nbfp_comb_climg2d[2 * typej];
+ const float c6grid = nbfp_comb[2 * typei] * nbfp_comb[2 * typej];
/* Recalculate inv_r6 without exclusion mask */
const float inv_r6_nm = inv_r2 * inv_r2 * inv_r2;
* We use a single F+E kernel with conditional because the performance impact
* of this is pretty small and LB on the CPU is anyway very slow.
*/
-gmx_opencl_inline void calculate_lj_ewald_comb_LB_F_E(__constant const float* nbfp_comb_climg2d,
+gmx_opencl_inline void calculate_lj_ewald_comb_LB_F_E(__constant const float* nbfp_comb,
const cl_nbparam_params_t* nbparam,
int typei,
int typej,
float* E_lj)
{
/* sigma and epsilon are scaled to give 6*C6 */
- const float sigma = nbfp_comb_climg2d[2 * typei] + nbfp_comb_climg2d[2 * typej];
+ const float sigma = nbfp_comb[2 * typei] + nbfp_comb[2 * typej];
- const float epsilon = nbfp_comb_climg2d[2 * typei + 1] * nbfp_comb_climg2d[2 * typej + 1];
+ const float epsilon = nbfp_comb[2 * typei + 1] * nbfp_comb[2 * typej + 1];
const float sigma2 = sigma * sigma;
const float c6grid = epsilon * sigma2 * sigma2 * sigma2;
/*! Interpolate Ewald coulomb force using the table through the tex_nbfp texture.
* Original idea: from the OpenMM project
*/
-gmx_opencl_inline float interpolate_coulomb_force_r(__constant const float* coulomb_tab_climg2d,
- float r,
- float scale)
+gmx_opencl_inline float interpolate_coulomb_force_r(__constant const float* coulomb_tab, float r, float scale)
{
float normalized = scale * r;
int index = (int)normalized;
float fract2 = normalized - (float)index;
float fract1 = 1.0F - fract2;
- return fract1 * coulomb_tab_climg2d[index] + fract2 * coulomb_tab_climg2d[index + 1];
+ return fract1 * coulomb_tab[index] + fract2 * coulomb_tab[index + 1];
}
/*! Calculate analytical Ewald correction term. */
typedef struct cl_nbparam_params
{
- //! type of electrostatics, takes values from #eelType
- int eeltype;
- //! type of VdW impl., takes values from #evdwType
- int vdwtype;
+ //! type of electrostatics
+ enum Nbnxm::ElecType elecType;
+ //! type of VdW impl.
+ enum Nbnxm::VdwType vdwType;
//! charge multiplication factor
float epsfac;
float two_k_rf;
//! Ewald/PME parameter
float ewald_beta;
- //! Ewald/PME correction term substracted from the direct-space potential
+ //! Ewald/PME correction term subtracted from the direct-space potential
float sh_ewald;
//! LJ-Ewald/PME correction term added to the correction potential
float sh_lj_ewald;
/**< Pointers to non-bonded kernel functions
* organized similar with nb_kfunc_xxx arrays in nbnxn_ocl.cpp */
///@{
- cl_kernel kernel_noener_noprune_ptr[eelTypeNR][evdwTypeNR] = { { nullptr } };
- cl_kernel kernel_ener_noprune_ptr[eelTypeNR][evdwTypeNR] = { { nullptr } };
- cl_kernel kernel_noener_prune_ptr[eelTypeNR][evdwTypeNR] = { { nullptr } };
- cl_kernel kernel_ener_prune_ptr[eelTypeNR][evdwTypeNR] = { { nullptr } };
+ cl_kernel kernel_noener_noprune_ptr[Nbnxm::c_numElecTypes][Nbnxm::c_numVdwTypes] = { { nullptr } };
+ cl_kernel kernel_ener_noprune_ptr[Nbnxm::c_numElecTypes][Nbnxm::c_numVdwTypes] = { { nullptr } };
+ cl_kernel kernel_noener_prune_ptr[Nbnxm::c_numElecTypes][Nbnxm::c_numVdwTypes] = { { nullptr } };
+ cl_kernel kernel_ener_prune_ptr[Nbnxm::c_numElecTypes][Nbnxm::c_numVdwTypes] = { { nullptr } };
///@}
//! prune kernels, ePruneKind defined the kernel kinds
cl_kernel kernel_pruneonly[ePruneNR] = { nullptr };
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team.
- * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2020,2021, 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.
using Grid = Nbnxm::Grid; // TODO: Remove when refactoring this file
-// Convience alias for partial Nbnxn namespace usage
+// Convenience alias for partial Nbnxn namespace usage
using InteractionLocality = gmx::InteractionLocality;
/* We shift the i-particles backward for PBC.
{
nl->type = GMX_NBLIST_INTERACTION_FREE_ENERGY;
nl->igeometry = GMX_NBLIST_GEOMETRY_PARTICLE_PARTICLE;
- /* The interaction functions are set in the free energy kernel fuction */
+ /* The interaction functions are set in the free energy kernel function */
nl->ivdw = -1;
nl->ivdwmod = -1;
nl->ielec = -1;
static_assert(c_nbnxnGpuClusterSize == 8 || c_nbnxnGpuClusterSize == 4,
"A cluster is hard-coded to 4/8 atoms.");
- Simd4Real rc2_S = Simd4Real(rlist2);
+ Simd4Real rc2_S{ rlist2 };
const real* x_i = work.iSuperClusterData.xSimd.data();
// TODO: Move to pairlistset.cpp
PairlistSet::PairlistSet(const InteractionLocality locality, const PairlistParams& pairlistParams) :
locality_(locality),
- params_(pairlistParams)
+ params_(pairlistParams),
+ combineLists_(sc_isGpuPairListType[pairlistParams.pairlistType]), // Currently GPU lists are always combined
+ isCpuType_(!sc_isGpuPairListType[pairlistParams.pairlistType])
{
- isCpuType_ = (params_.pairlistType == PairlistType::Simple4x2
- || params_.pairlistType == PairlistType::Simple4x4
- || params_.pairlistType == PairlistType::Simple4x8);
- // Currently GPU lists are always combined
- combineLists_ = !isCpuType_;
const int numLists = gmx_omp_nthreads_get(emntNonbonded);
"%d OpenMP threads were requested. Since the non-bonded force buffer reduction "
"is prohibitively slow with more than %d threads, we do not allow this. Use %d "
"or less OpenMP threads.",
- numLists, NBNXN_BUFFERFLAG_MAX_THREADS, NBNXN_BUFFERFLAG_MAX_THREADS);
+ numLists,
+ NBNXN_BUFFERFLAG_MAX_THREADS,
+ NBNXN_BUFFERFLAG_MAX_THREADS);
}
if (isCpuType_)
fprintf(fp, "nbl nci %zu ncj %d\n", nbl.ci.size(), nbl.ncjInUse);
const int numAtomsJCluster = grid.geometry().numAtomsJCluster;
const double numAtomsPerCell = nbl.ncjInUse / static_cast<double>(grid.numCells()) * numAtomsJCluster;
- fprintf(fp, "nbl na_cj %d rl %g ncp %d per cell %.1f atoms %.1f ratio %.2f\n", nbl.na_cj, rl,
- nbl.ncjInUse, nbl.ncjInUse / static_cast<double>(grid.numCells()), numAtomsPerCell,
+ fprintf(fp,
+ "nbl na_cj %d rl %g ncp %d per cell %.1f atoms %.1f ratio %.2f\n",
+ nbl.na_cj,
+ rl,
+ nbl.ncjInUse,
+ nbl.ncjInUse / static_cast<double>(grid.numCells()),
+ numAtomsPerCell,
numAtomsPerCell
/ (0.5 * 4.0 / 3.0 * M_PI * rl * rl * rl * grid.numCells() * numAtomsJCluster
/ (dims.gridSize[XX] * dims.gridSize[YY] * dims.gridSize[ZZ])));
- fprintf(fp, "nbl average j cell list length %.1f\n",
+ fprintf(fp,
+ "nbl average j cell list length %.1f\n",
0.25 * nbl.ncjInUse / std::max(static_cast<double>(nbl.ci.size()), 1.0));
int cs[SHIFTS] = { 0 };
j++;
}
}
- fprintf(fp, "nbl cell pairs, total: %zu excl: %d %.1f%%\n", nbl.cj.size(), npexcl,
+ fprintf(fp,
+ "nbl cell pairs, total: %zu excl: %d %.1f%%\n",
+ nbl.cj.size(),
+ npexcl,
100 * npexcl / std::max(static_cast<double>(nbl.cj.size()), 1.0));
for (int s = 0; s < SHIFTS; s++)
{
const Grid& grid = gridSet.grids()[0];
const Grid::Dimensions& dims = grid.dimensions();
- fprintf(fp, "nbl nsci %zu ncj4 %zu nsi %d excl4 %zu\n", nbl.sci.size(), nbl.cj4.size(),
- nbl.nci_tot, nbl.excl.size());
+ fprintf(fp,
+ "nbl nsci %zu ncj4 %zu nsi %d excl4 %zu\n",
+ nbl.sci.size(),
+ nbl.cj4.size(),
+ nbl.nci_tot,
+ nbl.excl.size());
const int numAtomsCluster = grid.geometry().numAtomsICluster;
const double numAtomsPerCell = nbl.nci_tot / static_cast<double>(grid.numClusters()) * numAtomsCluster;
- fprintf(fp, "nbl na_c %d rl %g ncp %d per cell %.1f atoms %.1f ratio %.2f\n", nbl.na_ci, rl,
- nbl.nci_tot, nbl.nci_tot / static_cast<double>(grid.numClusters()), numAtomsPerCell,
+ fprintf(fp,
+ "nbl na_c %d rl %g ncp %d per cell %.1f atoms %.1f ratio %.2f\n",
+ nbl.na_ci,
+ rl,
+ nbl.nci_tot,
+ nbl.nci_tot / static_cast<double>(grid.numClusters()),
+ numAtomsPerCell,
numAtomsPerCell
/ (0.5 * 4.0 / 3.0 * M_PI * rl * rl * rl * grid.numClusters() * numAtomsCluster
/ (dims.gridSize[XX] * dims.gridSize[YY] * dims.gridSize[ZZ])));
sum_nsp /= nbl.sci.size();
sum_nsp2 /= nbl.sci.size();
}
- fprintf(fp, "nbl #cluster-pairs: av %.1f stddev %.1f max %d\n", sum_nsp,
- std::sqrt(sum_nsp2 - sum_nsp * sum_nsp), nsp_max);
+ fprintf(fp,
+ "nbl #cluster-pairs: av %.1f stddev %.1f max %d\n",
+ sum_nsp,
+ std::sqrt(sum_nsp2 - sum_nsp * sum_nsp),
+ nsp_max);
if (!nbl.cj4.empty())
{
for (int b = 0; b <= c_gpuNumClusterPerCell; b++)
{
- fprintf(fp, "nbl j-list #i-subcell %d %7d %4.1f\n", b, c[b],
+ fprintf(fp,
+ "nbl j-list #i-subcell %d %7d %4.1f\n",
+ b,
+ c[b],
100.0 * c[b] / size_t{ nbl.cj4.size() * c_nbnxnGpuJgroupSize });
}
}
const BoundingBox* gmx_restrict bb_ci = nbl->work->iClusterData.bb.data();
const real* gmx_restrict x_ci = nbl->work->iClusterData.x.data();
- gmx_bool InRange;
-
- InRange = FALSE;
+ bool InRange = false;
while (!InRange && jclusterFirst <= jclusterLast)
{
real d2 = clusterBoundingBoxDistance2(bb_ci[0], jGrid.jBoundingBoxes()[jclusterFirst]);
*/
if (d2 < rbb2)
{
- InRange = TRUE;
+ InRange = true;
}
else if (d2 < rlist2)
{
return;
}
- InRange = FALSE;
+ InRange = false;
while (!InRange && jclusterLast > jclusterFirst)
{
real d2 = clusterBoundingBoxDistance2(bb_ci[0], jGrid.jBoundingBoxes()[jclusterLast]);
*/
if (d2 < rbb2)
{
- InRange = TRUE;
+ InRange = true;
}
else if (d2 < rlist2)
{
const int cj_gl = jGrid.cellOffset() * c_gpuNumClusterPerCell + cj;
- int ci1;
- if (excludeSubDiagonal && sci == scj)
- {
- ci1 = subc + 1;
- }
- else
- {
- ci1 = iGrid.numClustersPerCell()[sci];
- }
+ int ci1 = (excludeSubDiagonal && sci == scj) ? subc + 1 : iGrid.numClustersPerCell()[sci];
+
#if NBNXN_BBXXXX
/* Determine all ci1 bb distances in one call with SIMD4 */
const int offset = packedBoundingBoxesIndex(cj) + (cj & (c_packedBoundingBoxesDimSize - 1));
- clusterBoundingBoxDistance2_xxxx_simd4(jGrid.packedBoundingBoxes().data() + offset, ci1,
- pbb_ci, d2l);
+ clusterBoundingBoxDistance2_xxxx_simd4(
+ jGrid.packedBoundingBoxes().data() + offset, ci1, pbb_ci, d2l);
*numDistanceChecks += c_nbnxnGpuClusterSize * 2;
#endif
const JListRanges& ranges,
gmx::ArrayRef<const CjListType> cjList)
{
- int index;
-
if (jCluster < ranges.cjFirst + ranges.numDirect)
{
/* We can calculate the index directly using the offset */
- index = ranges.cjIndexStart + jCluster - ranges.cjFirst;
+ return ranges.cjIndexStart + jCluster - ranges.cjFirst;
}
else
{
/* Search for jCluster using bisection */
- index = -1;
+ int index = -1;
int rangeStart = ranges.cjIndexStart + ranges.numDirect;
int rangeEnd = ranges.cjIndexEnd;
- int rangeMiddle;
while (index == -1 && rangeStart < rangeEnd)
{
- rangeMiddle = (rangeStart + rangeEnd) >> 1;
+ int rangeMiddle = (rangeStart + rangeEnd) >> 1;
const int clusterMiddle = nblCj(cjList, rangeMiddle);
rangeStart = rangeMiddle + 1;
}
}
+ return index;
}
-
- return index;
}
// TODO: Get rid of the two functions below by renaming sci to ci (or something better)
{
fprintf(debug,
"reallocating neigborlist (ielec=%d, ivdw=%d, igeometry=%d, type=%d), maxnri=%d\n",
- nl->ielec, nl->ivdw, nl->igeometry, nl->type, nl->maxnri);
+ nl->ielec,
+ nl->ivdw,
+ nl->igeometry,
+ nl->type,
+ nl->maxnri);
}
srenew(nl->iinr, nl->maxnri);
srenew(nl->gid, nl->maxnri);
const Grid& jGrid,
t_nblist* nlist)
{
- int ci, cj_ind_start, cj_ind_end, cja, cjr;
- int nri_max;
- int gid_i = 0, gid_j, gid;
- int egp_shift, egp_mask;
- int gid_cj = 0;
- int ind_i, ind_j, ai, aj;
- int nri;
- gmx_bool bFEP_i, bFEP_i_all;
+ int gid_i = 0;
+ int gid_cj = 0;
if (nbl_ci->cj_ind_end == nbl_ci->cj_ind_start)
{
return;
}
- ci = nbl_ci->ci;
+ const int ci = nbl_ci->ci;
- cj_ind_start = nbl_ci->cj_ind_start;
- cj_ind_end = nbl_ci->cj_ind_end;
+ const int cj_ind_start = nbl_ci->cj_ind_start;
+ const int cj_ind_end = nbl_ci->cj_ind_end;
/* In worst case we have alternating energy groups
* and create #atom-pair lists, which means we need the size
* of a cluster pair (na_ci*na_cj) times the number of cj's.
*/
- nri_max = nbl->na_ci * nbl->na_cj * (cj_ind_end - cj_ind_start);
+ const int nri_max = nbl->na_ci * nbl->na_cj * (cj_ind_end - cj_ind_start);
if (nlist->nri + nri_max > nlist->maxnri)
{
nlist->maxnri = over_alloc_large(nlist->nri + nri_max);
gmx_fatal(FARGS,
"The Verlet scheme with %dx%d kernels and free-energy only supports up to %zu "
"energy groups",
- iGrid.geometry().numAtomsICluster, numAtomsJCluster,
+ iGrid.geometry().numAtomsICluster,
+ numAtomsJCluster,
(sizeof(gid_cj) * 8) / numAtomsJCluster);
}
- egp_shift = nbatParams.neg_2log;
- egp_mask = (1 << egp_shift) - 1;
+ const int egp_shift = nbatParams.neg_2log;
+ const int egp_mask = (1 << egp_shift) - 1;
/* Loop over the atoms in the i sub-cell */
- bFEP_i_all = TRUE;
+ bool bFEP_i_all = true;
for (int i = 0; i < nbl->na_ci; i++)
{
- ind_i = ci * nbl->na_ci + i;
- ai = atomIndices[ind_i];
+ const int ind_i = ci * nbl->na_ci + i;
+ const int ai = atomIndices[ind_i];
if (ai >= 0)
{
- nri = nlist->nri;
+ int nri = nlist->nri;
nlist->jindex[nri + 1] = nlist->jindex[nri];
nlist->iinr[nri] = ai;
/* The actual energy group pair index is set later */
nlist->gid[nri] = 0;
nlist->shift[nri] = nbl_ci->shift & NBNXN_CI_SHIFT;
- bFEP_i = iGrid.atomIsPerturbed(ci - iGrid.cellOffset(), i);
+ bool bFEP_i = iGrid.atomIsPerturbed(ci - iGrid.cellOffset(), i);
bFEP_i_all = bFEP_i_all && bFEP_i;
for (int cj_ind = cj_ind_start; cj_ind < cj_ind_end; cj_ind++)
{
- unsigned int fep_cj;
+ unsigned int fep_cj = 0U;
+ gid_cj = 0;
- cja = nbl->cj[cj_ind].cj;
+ const int cja = nbl->cj[cj_ind].cj;
if (numAtomsJCluster == jGrid.geometry().numAtomsICluster)
{
- cjr = cja - jGrid.cellOffset();
- fep_cj = jGrid.fepBits(cjr);
+ const int cjr = cja - jGrid.cellOffset();
+ fep_cj = jGrid.fepBits(cjr);
if (ngid > 1)
{
gid_cj = nbatParams.energrp[cja];
}
else if (2 * numAtomsJCluster == jGrid.geometry().numAtomsICluster)
{
- cjr = cja - jGrid.cellOffset() * 2;
+ const int cjr = cja - jGrid.cellOffset() * 2;
/* Extract half of the ci fep/energrp mask */
fep_cj = (jGrid.fepBits(cjr >> 1) >> ((cjr & 1) * numAtomsJCluster))
& ((1 << numAtomsJCluster) - 1);
}
else
{
- cjr = cja - (jGrid.cellOffset() >> 1);
+ const int cjr = cja - (jGrid.cellOffset() >> 1);
/* Combine two ci fep masks/energrp */
fep_cj = jGrid.fepBits(cjr * 2)
+ (jGrid.fepBits(cjr * 2 + 1) << jGrid.geometry().numAtomsICluster);
for (int j = 0; j < nbl->na_cj; j++)
{
/* Is this interaction perturbed and not excluded? */
- ind_j = cja * nbl->na_cj + j;
- aj = atomIndices[ind_j];
+ const int ind_j = cja * nbl->na_cj + j;
+ const int aj = atomIndices[ind_j];
if (aj >= 0 && (bFEP_i || (fep_cj & (1 << j))) && (!bDiagRemoved || ind_j >= ind_i))
{
if (ngid > 1)
{
- gid_j = (gid_cj >> (j * egp_shift)) & egp_mask;
- gid = GID(gid_i, gid_j, ngid);
+ const int gid_j = (gid_cj >> (j * egp_shift)) & egp_mask;
+ const int gid = GID(gid_i, gid_j, ngid);
if (nlist->nrj > nlist->jindex[nri] && nlist->gid[nri] != gid)
{
const Grid& jGrid,
t_nblist* nlist)
{
- int nri_max;
- int c_abs;
- int ind_i, ind_j, ai, aj;
- int nri;
- gmx_bool bFEP_i;
- real xi, yi, zi;
- const nbnxn_cj4_t* cj4;
-
const int numJClusterGroups = nbl_sci->numJClusterGroups();
if (numJClusterGroups == 0)
{
* So for each of the na_sc i-atoms, we need max one FEP list
* for each max_nrj_fep j-atoms.
*/
- nri_max = nbl->na_sc * nbl->na_cj * (1 + (numJClusterGroups * c_nbnxnGpuJgroupSize) / max_nrj_fep);
+ const int nri_max =
+ nbl->na_sc * nbl->na_cj * (1 + (numJClusterGroups * c_nbnxnGpuJgroupSize) / max_nrj_fep);
if (nlist->nri + nri_max > nlist->maxnri)
{
nlist->maxnri = over_alloc_large(nlist->nri + nri_max);
/* Loop over the atoms in the i super-cluster */
for (int c = 0; c < c_gpuNumClusterPerCell; c++)
{
- c_abs = sci * c_gpuNumClusterPerCell + c;
+ const int c_abs = sci * c_gpuNumClusterPerCell + c;
for (int i = 0; i < nbl->na_ci; i++)
{
- ind_i = c_abs * nbl->na_ci + i;
- ai = atomIndices[ind_i];
+ const int ind_i = c_abs * nbl->na_ci + i;
+ const int ai = atomIndices[ind_i];
if (ai >= 0)
{
- nri = nlist->nri;
+ int nri = nlist->nri;
nlist->jindex[nri + 1] = nlist->jindex[nri];
nlist->iinr[nri] = ai;
/* With GPUs, energy groups are not supported */
nlist->gid[nri] = 0;
nlist->shift[nri] = nbl_sci->shift & NBNXN_CI_SHIFT;
- bFEP_i = iGrid.atomIsPerturbed(c_abs - iGrid.cellOffset() * c_gpuNumClusterPerCell, i);
+ const bool bFEP_i =
+ iGrid.atomIsPerturbed(c_abs - iGrid.cellOffset() * c_gpuNumClusterPerCell, i);
- xi = nbat->x()[ind_i * nbat->xstride + XX] + shx;
- yi = nbat->x()[ind_i * nbat->xstride + YY] + shy;
- zi = nbat->x()[ind_i * nbat->xstride + ZZ] + shz;
+ real xi = nbat->x()[ind_i * nbat->xstride + XX] + shx;
+ real yi = nbat->x()[ind_i * nbat->xstride + YY] + shy;
+ real zi = nbat->x()[ind_i * nbat->xstride + ZZ] + shz;
const int nrjMax = nlist->nrj + numJClusterGroups * c_nbnxnGpuJgroupSize * nbl->na_cj;
if (nrjMax > nlist->maxnrj)
for (int cj4_ind = cj4_ind_start; cj4_ind < cj4_ind_end; cj4_ind++)
{
- cj4 = &nbl->cj4[cj4_ind];
+ const nbnxn_cj4_t* cj4 = &nbl->cj4[cj4_ind];
for (int gcj = 0; gcj < c_nbnxnGpuJgroupSize; gcj++)
{
for (int j = 0; j < nbl->na_cj; j++)
{
/* Is this interaction perturbed and not excluded? */
- ind_j = (jGrid.cellOffset() * c_gpuNumClusterPerCell + cjr) * nbl->na_cj + j;
- aj = atomIndices[ind_j];
+ const int ind_j =
+ (jGrid.cellOffset() * c_gpuNumClusterPerCell + cjr) * nbl->na_cj + j;
+ const int aj = atomIndices[ind_j];
if (aj >= 0 && (bFEP_i || jGrid.atomIsPerturbed(cjr, j))
&& (!bDiagRemoved || ind_j >= ind_i))
{
- int excl_pair;
- unsigned int excl_bit;
- real dx, dy, dz;
-
const int jHalf =
j / (c_nbnxnGpuClusterSize / c_nbnxnGpuClusterpairSplit);
nbnxn_excl_t& excl = get_exclusion_mask(nbl, cj4_ind, jHalf);
- excl_pair = a_mod_wj(j) * nbl->na_ci + i;
- excl_bit = (1U << (gcj * c_gpuNumClusterPerCell + c));
+ int excl_pair = a_mod_wj(j) * nbl->na_ci + i;
+ unsigned int excl_bit = (1U << (gcj * c_gpuNumClusterPerCell + c));
- dx = nbat->x()[ind_j * nbat->xstride + XX] - xi;
- dy = nbat->x()[ind_j * nbat->xstride + YY] - yi;
- dz = nbat->x()[ind_j * nbat->xstride + ZZ] - zi;
+ real dx = nbat->x()[ind_j * nbat->xstride + XX] - xi;
+ real dy = nbat->x()[ind_j * nbat->xstride + YY] - yi;
+ real dz = nbat->x()[ind_j * nbat->xstride + ZZ] - zi;
/* The unpruned GPU list has more than 2/3
* of the atom pairs beyond rlist. Using
* Note that here we can not use cj4_ind_end, since the last cj4
* can be only partially filled, so we use cj_ind.
*/
- const JListRanges ranges(iEntry.cj4_ind_start * c_nbnxnGpuJgroupSize, nbl->work->cj_ind,
+ const JListRanges ranges(iEntry.cj4_ind_start * c_nbnxnGpuJgroupSize,
+ nbl->work->cj_ind,
gmx::makeConstArrayRef(nbl->cj4));
GMX_ASSERT(nbl->na_ci == c_nbnxnGpuClusterSize, "na_ci should match the GPU cluster size");
int thread,
int nthread)
{
- int nsp_max;
+
+ int nsp_max = nsp_target_av;
if (progBal)
{
- float nsp_est;
-
/* Estimate the total numbers of ci's of the nblist combined
* over all threads using the target number of ci's.
*/
- nsp_est = (nsp_tot_est * thread) / nthread + nbl->nci_tot;
+ float nsp_est = (nsp_tot_est * thread) / nthread + nbl->nci_tot;
/* The first ci blocks should be larger, to avoid overhead.
* The last ci blocks should be smaller, to improve load balancing.
*/
nsp_max = static_cast<int>(nsp_target_av * (nsp_tot_est * 1.5 / (nsp_est + nsp_tot_est)));
}
- else
- {
- nsp_max = nsp_target_av;
- }
const int cj4_start = nbl->sci.back().cj4_ind_start;
const int cj4_end = nbl->sci.back().cj4_ind_end;
gmx_unused static void set_icell_bb(const Grid& iGrid, int ci, real shx, real shy, real shz, NbnxnPairlistGpuWork* work)
{
#if NBNXN_BBXXXX
- set_icell_bbxxxx_supersub(iGrid.packedBoundingBoxes(), ci, shx, shy, shz,
- work->iSuperClusterData.bbPacked.data());
+ set_icell_bbxxxx_supersub(
+ iGrid.packedBoundingBoxes(), ci, shx, shy, shz, work->iSuperClusterData.bbPacked.data());
#else
set_icell_bb_supersub(iGrid.iBoundingBoxes(), ci, shx, shy, shz, work->iSuperClusterData.bb.data());
#endif
/* Estimates the interaction volume^2 for non-local interactions */
static real nonlocal_vol2(const struct gmx_domdec_zones_t* zones, const rvec ls, real r)
{
- real cl, ca, za;
- real vold_est;
- real vol2_est_tot;
-
- vol2_est_tot = 0;
+ real vol2_est_tot = 0;
/* Here we simply add up the volumes of 1, 2 or 3 1D decomposition
* not home interaction volume^2. As these volumes are not additive,
{
if (zones->shift[z][XX] + zones->shift[z][YY] + zones->shift[z][ZZ] == 1)
{
- cl = 0;
- ca = 1;
- za = 1;
+ real cl = 0;
+ real ca = 1;
+ real za = 1;
for (int d = 0; d < DIM; d++)
{
if (zones->shift[z][d] == 0)
}
/* 4 octants of a sphere */
- vold_est = 0.25 * M_PI * r * r * r * r;
+ real vold_est = 0.25 * M_PI * r * r * r * r;
/* 4 quarter pie slices on the edges */
vold_est += 4 * cl * M_PI / 6.0 * r * r * r;
/* One rectangular volume on a face */
* Maxwell is less sensitive to the exact value.
*/
const int nsubpair_target_min = 36;
- real r_eff_sup, vol_est, nsp_est, nsp_est_nl;
const Grid& grid = gridSet.grids()[0];
ls[ZZ] = numAtomsCluster / (dims.atomDensity * ls[XX] * ls[YY]);
/* The formulas below are a heuristic estimate of the average nsj per si*/
- r_eff_sup = rlist + nbnxn_get_rlist_effective_inc(numAtomsCluster, ls);
+ const real r_eff_sup = rlist + nbnxn_get_rlist_effective_inc(numAtomsCluster, ls);
- if (!gridSet.domainSetup().haveMultipleDomains || gridSet.domainSetup().zones->n == 1)
- {
- nsp_est_nl = 0;
- }
- else
+ real nsp_est_nl = 0;
+ if (gridSet.domainSetup().haveMultipleDomains && gridSet.domainSetup().zones->n != 1)
{
nsp_est_nl = gmx::square(dims.atomDensity / numAtomsCluster)
* nonlocal_vol2(gridSet.domainSetup().zones, ls, r_eff_sup);
}
+ real nsp_est = nsp_est_nl;
if (iloc == InteractionLocality::Local)
{
/* Sub-cell interacts with itself */
- vol_est = ls[XX] * ls[YY] * ls[ZZ];
+ real vol_est = ls[XX] * ls[YY] * ls[ZZ];
/* 6/2 rectangular volume on the faces */
vol_est += (ls[XX] * ls[YY] + ls[XX] * ls[ZZ] + ls[YY] * ls[ZZ]) * r_eff_sup;
/* 12/2 quarter pie slices on the edges */
/* Subtract the non-local pair count */
nsp_est -= nsp_est_nl;
- /* For small cut-offs nsp_est will be an underesimate.
+ /* For small cut-offs nsp_est will be an underestimate.
* With DD nsp_est_nl is an overestimate so nsp_est can get negative.
* So to avoid too small or negative nsp_est we set a minimum of
* all cells interacting with all 3^3 direct neighbors (3^3-1)/2+1=14.
fprintf(debug, "nsp_est local %5.1f non-local %5.1f\n", nsp_est, nsp_est_nl);
}
}
- else
- {
- nsp_est = nsp_est_nl;
- }
/* Thus the (average) maximum j-list size should be as follows.
* Since there is overhead, we shouldn't make the lists too small
{
for (const nbnxn_ci_t& ciEntry : nbl.ci)
{
- fprintf(fp, "ci %4d shift %2d ncj %3d\n", ciEntry.ci, ciEntry.shift,
- ciEntry.cj_ind_end - ciEntry.cj_ind_start);
+ fprintf(fp, "ci %4d shift %2d ncj %3d\n", ciEntry.ci, ciEntry.shift, ciEntry.cj_ind_end - ciEntry.cj_ind_start);
for (int j = ciEntry.cj_ind_start; j < ciEntry.cj_ind_end; j++)
{
}
}
}
- fprintf(fp, "ci %4d shift %2d ncj4 %2d ncp %3d\n", sci.sci, sci.shift,
- sci.numJClusterGroups(), ncp);
+ fprintf(fp, "ci %4d shift %2d ncj4 %2d ncp %3d\n", sci.sci, sci.shift, sci.numJClusterGroups(), ncp);
}
}
int nsci = nblc->sci.size();
int ncj4 = nblc->cj4.size();
int nexcl = nblc->excl.size();
- for (auto& nbl : nbls)
+ for (const auto& nbl : nbls)
{
nsci += nbl.sci.size();
ncj4 += nbl.cj4.size();
GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
}
- for (auto& nbl : nbls)
+ for (const auto& nbl : nbls)
{
nblc->nci_tot += nbl.nci_tot;
}
for (int i = 0; i < nbls->nri; i++)
{
- int nrj;
-
/* The number of pairs in this i-entry */
- nrj = nbls->jindex[i + 1] - nbls->jindex[i];
+ const int nrj = nbls->jindex[i + 1] - nbls->jindex[i];
/* Decide if list th_dest is too large and we should procede
* to the next destination list.
* is only performed when only 1 out of 8 sub-cells in within range,
* this is because the GPU is much faster than the cpu.
*/
- real bbx, bby;
- real rbb2;
- bbx = 0.5 * (iGridDims.cellSize[XX] + jGridDims.cellSize[XX]);
- bby = 0.5 * (iGridDims.cellSize[YY] + jGridDims.cellSize[YY]);
+ real bbx = 0.5 * (iGridDims.cellSize[XX] + jGridDims.cellSize[XX]);
+ real bby = 0.5 * (iGridDims.cellSize[YY] + jGridDims.cellSize[YY]);
if (!simple)
{
bbx /= c_gpuNumClusterPerCellX;
bby /= c_gpuNumClusterPerCellY;
}
- rbb2 = std::max(0.0, rlist - 0.5 * std::sqrt(bbx * bbx + bby * bby));
- rbb2 = rbb2 * rbb2;
+ real rbb2 = std::max(0.0, rlist - 0.5 * std::sqrt(bbx * bbx + bby * bby));
+ rbb2 = rbb2 * rbb2;
#if !GMX_DOUBLE
return rbb2;
const int ci_block_enum = 5;
const int ci_block_denom = 11;
const int ci_block_min_atoms = 16;
- int ci_block;
/* Here we decide how to distribute the blocks over the threads.
* We use prime numbers to try to avoid that the grid size becomes
*/
GMX_ASSERT(iGrid.dimensions().numCells[XX] > 0, "Grid can't be empty");
GMX_ASSERT(numLists > 0, "We need at least one list");
- ci_block = (iGrid.numCells() * ci_block_enum)
- / (ci_block_denom * iGrid.dimensions().numCells[XX] * numLists);
+ int ci_block = (iGrid.numCells() * ci_block_enum)
+ / (ci_block_denom * iGrid.dimensions().numCells[XX] * numLists);
const int numAtomsPerCell = iGrid.geometry().numAtomsPerCell;
switch (kernelType)
{
case ClusterDistanceKernelType::CpuPlainC:
- makeClusterListSimple(jGrid, nbl, ci, firstCell, lastCell, excludeSubDiagonal,
- nbat->x().data(), rlist2, rbb2, numDistanceChecks);
+ makeClusterListSimple(
+ jGrid, nbl, ci, firstCell, lastCell, excludeSubDiagonal, nbat->x().data(), rlist2, rbb2, numDistanceChecks);
break;
#ifdef GMX_NBNXN_SIMD_4XN
case ClusterDistanceKernelType::CpuSimd_4xM:
- makeClusterListSimd4xn(jGrid, nbl, ci, firstCell, lastCell, excludeSubDiagonal,
- nbat->x().data(), rlist2, rbb2, numDistanceChecks);
+ makeClusterListSimd4xn(
+ jGrid, nbl, ci, firstCell, lastCell, excludeSubDiagonal, nbat->x().data(), rlist2, rbb2, numDistanceChecks);
break;
#endif
#ifdef GMX_NBNXN_SIMD_2XNN
case ClusterDistanceKernelType::CpuSimd_2xMM:
- makeClusterListSimd2xnn(jGrid, nbl, ci, firstCell, lastCell, excludeSubDiagonal,
- nbat->x().data(), rlist2, rbb2, numDistanceChecks);
+ makeClusterListSimd2xnn(
+ jGrid, nbl, ci, firstCell, lastCell, excludeSubDiagonal, nbat->x().data(), rlist2, rbb2, numDistanceChecks);
break;
#endif
default: GMX_ASSERT(false, "Unhandled kernel type");
{
for (int cj = firstCell; cj <= lastCell; cj++)
{
- make_cluster_list_supersub(iGrid, jGrid, nbl, ci, cj, excludeSubDiagonal, nbat->xstride,
- nbat->x().data(), rlist2, rbb2, numDistanceChecks);
+ make_cluster_list_supersub(
+ iGrid, jGrid, nbl, ci, cj, excludeSubDiagonal, nbat->xstride, nbat->x().data(), rlist2, rbb2, numDistanceChecks);
}
}
T* nbl,
t_nblist* nbl_fep)
{
- int na_cj_2log;
matrix box;
real rl_fep2 = 0;
- float rbb2;
- int ci_b, ci, ci_x, ci_y, ci_xy;
ivec shp;
- real bx0, bx1, by0, by1, bz0, bz1;
- real bz1_frac;
- real d2cx, d2z, d2z_cx, d2z_cy, d2zx, d2zxy, d2xy;
- int cxf, cxl, cyf, cyf_x, cyl;
- int numDistanceChecks;
int gridi_flag_shift = 0, gridj_flag_shift = 0;
gmx_bitmask_t* gridj_flag = nullptr;
- int ncj_old_i, ncj_old_j;
if (jGrid.geometry().isSimple != pairlistIsSimple(*nbl)
|| iGrid.geometry().isSimple != pairlistIsSimple(*nbl))
sync_work(nbl);
GMX_ASSERT(nbl->na_ci == jGrid.geometry().numAtomsICluster,
"The cluster sizes in the list and grid should match");
- nbl->na_cj = JClusterSizePerListType[pairlistType];
- na_cj_2log = get_2log(nbl->na_cj);
+ nbl->na_cj = JClusterSizePerListType[pairlistType];
+ const int na_cj_2log = get_2log(nbl->na_cj);
nbl->rlist = rlist;
* We should not simply use rlist, since then we would not have
* the small, effective buffering of the NxN lists.
* The buffer is on overestimate, but the resulting cost for pairs
- * beyond rlist is neglible compared to the FEP pairs within rlist.
+ * beyond rlist is negligible compared to the FEP pairs within rlist.
*/
rl_fep2 = nbl->rlist + effective_buffer_1x1_vs_MxN(iGrid, jGrid);
const Grid::Dimensions& iGridDims = iGrid.dimensions();
const Grid::Dimensions& jGridDims = jGrid.dimensions();
- rbb2 = boundingbox_only_distance2(iGridDims, jGridDims, nbl->rlist, pairlistIsSimple(*nbl));
+ const float rbb2 =
+ boundingbox_only_distance2(iGridDims, jGridDims, nbl->rlist, pairlistIsSimple(*nbl));
if (debug)
{
if (debug)
{
- fprintf(debug, "nbl nc_i %d col.av. %.1f ci_block %d\n", iGrid.numCells(),
- iGrid.numCells() / static_cast<double>(iGrid.numColumns()), ci_block);
+ fprintf(debug,
+ "nbl nc_i %d col.av. %.1f ci_block %d\n",
+ iGrid.numCells(),
+ iGrid.numCells() / static_cast<double>(iGrid.numColumns()),
+ ci_block);
}
- numDistanceChecks = 0;
+ int numDistanceChecks = 0;
const real listRangeBBToJCell2 =
gmx::square(listRangeForBoundingBoxToGridCell(rlist, jGrid.dimensions()));
/* Initially ci_b and ci to 1 before where we want them to start,
* as they will both be incremented in next_ci.
*/
- ci_b = -1;
- ci = th * ci_block - 1;
- ci_x = 0;
- ci_y = 0;
+ int ci_b = -1;
+ int ci = th * ci_block - 1;
+ int ci_x = 0;
+ int ci_y = 0;
while (next_ci(iGrid, nth, ci_block, &ci_x, &ci_y, &ci_b, &ci))
{
if (bSimple && flags_i[ci] == 0)
{
continue;
}
- ncj_old_i = getNumSimpleJClustersInList(*nbl);
+ const int ncj_old_i = getNumSimpleJClustersInList(*nbl);
- d2cx = 0;
+ real d2cx = 0;
if (!isIntraGridList && shp[XX] == 0)
{
- if (bSimple)
- {
- bx1 = bb_i[ci].upper.x;
- }
- else
- {
- bx1 = iGridDims.lowerCorner[XX] + (real(ci_x) + 1) * iGridDims.cellSize[XX];
- }
+ const real bx1 =
+ bSimple ? bb_i[ci].upper.x
+ : iGridDims.lowerCorner[XX] + (real(ci_x) + 1) * iGridDims.cellSize[XX];
if (bx1 < jGridDims.lowerCorner[XX])
{
d2cx = gmx::square(jGridDims.lowerCorner[XX] - bx1);
}
}
- ci_xy = ci_x * iGridDims.numCells[YY] + ci_y;
+ int ci_xy = ci_x * iGridDims.numCells[YY] + ci_y;
/* Loop over shift vectors in three dimensions */
for (int tz = -shp[ZZ]; tz <= shp[ZZ]; tz++)
{
const real shz = real(tz) * box[ZZ][ZZ];
- bz0 = bbcz_i[ci].lower + shz;
- bz1 = bbcz_i[ci].upper + shz;
+ real bz0 = bbcz_i[ci].lower + shz;
+ real bz1 = bbcz_i[ci].upper + shz;
- if (tz == 0)
- {
- d2z = 0;
- }
- else if (tz < 0)
+ real d2z = 0;
+ if (tz < 0)
{
d2z = gmx::square(bz1);
}
- else
+ else if (tz > 0)
{
d2z = gmx::square(bz0 - box[ZZ][ZZ]);
}
- d2z_cx = d2z + d2cx;
+ const real d2z_cx = d2z + d2cx;
if (d2z_cx >= rlist2)
{
continue;
}
- bz1_frac = bz1 / real(iGrid.numCellsInColumn(ci_xy));
+ real bz1_frac = bz1 / real(iGrid.numCellsInColumn(ci_xy));
if (bz1_frac < 0)
{
bz1_frac = 0;
{
const real shy = real(ty) * box[YY][YY] + real(tz) * box[ZZ][YY];
- if (bSimple)
- {
- by0 = bb_i[ci].lower.y + shy;
- by1 = bb_i[ci].upper.y + shy;
- }
- else
- {
- by0 = iGridDims.lowerCorner[YY] + (real(ci_y)) * iGridDims.cellSize[YY] + shy;
- by1 = iGridDims.lowerCorner[YY] + (real(ci_y) + 1) * iGridDims.cellSize[YY] + shy;
- }
+ const real by0 = bSimple ? bb_i[ci].lower.y + shy
+ : iGridDims.lowerCorner[YY]
+ + (real(ci_y)) * iGridDims.cellSize[YY] + shy;
+ const real by1 = bSimple ? bb_i[ci].upper.y + shy
+ : iGridDims.lowerCorner[YY]
+ + (real(ci_y) + 1) * iGridDims.cellSize[YY] + shy;
+ int cyf, cyl; //NOLINT(cppcoreguidelines-init-variables)
get_cell_range<YY>(by0, by1, jGridDims, d2z_cx, rlist, &cyf, &cyl);
if (cyf > cyl)
continue;
}
- d2z_cy = d2z;
+ real d2z_cy = d2z;
if (by1 < jGridDims.lowerCorner[YY])
{
d2z_cy += gmx::square(jGridDims.lowerCorner[YY] - by1);
const real shx =
real(tx) * box[XX][XX] + real(ty) * box[YY][XX] + real(tz) * box[ZZ][XX];
- if (bSimple)
- {
- bx0 = bb_i[ci].lower.x + shx;
- bx1 = bb_i[ci].upper.x + shx;
- }
- else
- {
- bx0 = iGridDims.lowerCorner[XX] + (real(ci_x)) * iGridDims.cellSize[XX] + shx;
- bx1 = iGridDims.lowerCorner[XX] + (real(ci_x) + 1) * iGridDims.cellSize[XX] + shx;
- }
+ const real bx0 = bSimple ? bb_i[ci].lower.x + shx
+ : iGridDims.lowerCorner[XX]
+ + (real(ci_x)) * iGridDims.cellSize[XX] + shx;
+ const real bx1 = bSimple ? bb_i[ci].upper.x + shx
+ : iGridDims.lowerCorner[XX]
+ + (real(ci_x) + 1) * iGridDims.cellSize[XX] + shx;
+ int cxf, cxl; //NOLINT(cppcoreguidelines-init-variables)
get_cell_range<XX>(bx0, bx1, jGridDims, d2z_cy, rlist, &cxf, &cxl);
if (cxf > cxl)
set_icell_bb(iGrid, ci, shx, shy, shz, nbl->work.get());
- icell_set_x(cell0_i + ci, shx, shy, shz, nbat->xstride, nbat->x().data(),
- kernelType, nbl->work.get());
+ icell_set_x(cell0_i + ci,
+ shx,
+ shy,
+ shz,
+ nbat->xstride,
+ nbat->x().data(),
+ kernelType,
+ nbl->work.get());
for (int cx = cxf; cx <= cxl; cx++)
{
const real cx_real = cx;
- d2zx = d2z;
+ real d2zx = d2z;
if (jGridDims.lowerCorner[XX] + cx_real * jGridDims.cellSize[XX] > bx1)
{
d2zx += gmx::square(jGridDims.lowerCorner[XX]
+ (cx_real + 1) * jGridDims.cellSize[XX] - bx0);
}
- if (isIntraGridList && cx == 0 && (!c_pbcShiftBackward || shift == CENTRAL)
- && cyf < ci_y)
- {
- /* Leave the pairs with i > j.
- * Skip half of y when i and j have the same x.
- */
- cyf_x = ci_y;
- }
- else
- {
- cyf_x = cyf;
- }
+ /* When true, leave the pairs with i > j.
+ * Skip half of y when i and j have the same x.
+ */
+ const bool skipHalfY =
+ (isIntraGridList && cx == 0
+ && (!c_pbcShiftBackward || shift == CENTRAL) && cyf < ci_y);
+ const int cyf_x = skipHalfY ? ci_y : cyf;
for (int cy = cyf_x; cy <= cyl; cy++)
{
jGrid.firstCellInColumn(cx * jGridDims.numCells[YY] + cy + 1);
const real cy_real = cy;
- d2zxy = d2zx;
+ real d2zxy = d2zx;
if (jGridDims.lowerCorner[YY] + cy_real * jGridDims.cellSize[YY] > by1)
{
d2zxy += gmx::square(jGridDims.lowerCorner[YY]
midCell = columnEnd - 1;
}
- d2xy = d2zxy - d2z;
+ const real d2xy = d2zxy - d2z;
/* Find the lowest cell that can possibly
* be within range.
"column");
/* For f buffer flags with simple lists */
- ncj_old_j = getNumSimpleJClustersInList(*nbl);
-
- makeClusterListWrapper(nbl, iGrid, ci, jGrid, firstCell, lastCell,
- excludeSubDiagonal, nbat, rlist2, rbb2,
- kernelType, &numDistanceChecks);
+ const int ncj_old_j = getNumSimpleJClustersInList(*nbl);
+
+ makeClusterListWrapper(nbl,
+ iGrid,
+ ci,
+ jGrid,
+ firstCell,
+ lastCell,
+ excludeSubDiagonal,
+ nbat,
+ rlist2,
+ rbb2,
+ kernelType,
+ &numDistanceChecks);
if (bFBufferFlag)
{
if (!exclusions.empty())
{
/* Set the exclusions for this ci list */
- setExclusionsForIEntry(gridSet, nbl, excludeSubDiagonal, na_cj_2log,
- *getOpenIEntry(nbl), exclusions);
+ setExclusionsForIEntry(
+ gridSet, nbl, excludeSubDiagonal, na_cj_2log, *getOpenIEntry(nbl), exclusions);
}
if (haveFep)
{
- make_fep_list(gridSet.atomIndices(), nbat, nbl, excludeSubDiagonal,
- getOpenIEntry(nbl), shx, shy, shz, rl_fep2, iGrid, jGrid, nbl_fep);
+ make_fep_list(gridSet.atomIndices(),
+ nbat,
+ nbl,
+ excludeSubDiagonal,
+ getOpenIEntry(nbl),
+ shx,
+ shy,
+ shz,
+ rl_fep2,
+ iGrid,
+ jGrid,
+ nbl_fep);
}
/* Close this ci list */
static void print_reduction_cost(gmx::ArrayRef<const gmx_bitmask_t> flags, int nout)
{
- int nelem, nkeep, ncopy, nred, out;
- gmx_bitmask_t mask_0;
+ int nelem = 0;
+ int nkeep = 0;
+ int ncopy = 0;
+ int nred = 0;
- nelem = 0;
- nkeep = 0;
- ncopy = 0;
- nred = 0;
+ gmx_bitmask_t mask_0; // NOLINT(cppcoreguidelines-init-variables)
bitmask_init_bit(&mask_0, 0);
for (const gmx_bitmask_t& flag_mask : flags)
{
else if (!bitmask_is_zero(flag_mask))
{
int c = 0;
- for (out = 0; out < nout; out++)
+ for (int out = 0; out < nout; out++)
{
if (bitmask_is_set(flag_mask, out))
{
const auto numFlags = static_cast<double>(flags.size());
fprintf(debug,
"nbnxn reduction: #flag %zu #list %d elem %4.2f, keep %4.2f copy %4.2f red %4.2f\n",
- flags.size(), nout, nelem / numFlags, nkeep / numFlags, ncopy / numFlags, nred / numFlags);
+ flags.size(),
+ nout,
+ nelem / numFlags,
+ nkeep / numFlags,
+ ncopy / numFlags,
+ nred / numFlags);
}
/* Copies the list entries from src to dest when cjStart <= *cjGlobal < cjEnd.
}
}
-#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && __GNUC__ == 7
+#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ == 7
/* Avoid gcc 7 avx512 loop vectorization bug (actually only needed with -mavx512f) */
# pragma GCC push_options
# pragma GCC optimize("no-tree-vectorize")
return ncjTotal;
}
-#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && __GNUC__ == 7
+#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ == 7
# pragma GCC pop_options
#endif
}
else
{
- copySelectedListRange<false>(srcCi, src, &dest, flag, iFlagShift,
- jFlagShift, t);
+ copySelectedListRange<false>(
+ srcCi, src, &dest, flag, iFlagShift, jFlagShift, t);
}
}
cjGlobal += ncj;
{
const real rlist = params_.rlistOuter;
- int nsubpair_target;
- float nsubpair_tot_est;
- int ci_block;
- gmx_bool progBal;
- int np_tot, np_noq, np_hlj, nap;
-
const int numLists = (isCpuType_ ? cpuLists_.size() : gpuLists_.size());
if (debug)
resizeAndZeroBufferFlags(&nbat->buffer_flags, nbat->numAtoms());
}
+ int nsubpair_target = 0;
+ float nsubpair_tot_est = 0.0F;
if (!isCpuType_ && minimumIlistCountForGpuBalancing > 0)
{
- get_nsubpair_target(gridSet, locality_, rlist, minimumIlistCountForGpuBalancing,
- &nsubpair_target, &nsubpair_tot_est);
- }
- else
- {
- nsubpair_target = 0;
- nsubpair_tot_est = 0;
+ get_nsubpair_target(
+ gridSet, locality_, rlist, minimumIlistCountForGpuBalancing, &nsubpair_target, &nsubpair_tot_est);
}
/* Clear all pair-lists */
searchCycleCounting->start(enbsCCsearch);
- ci_block = get_ci_block_size(iGrid, gridSet.domainSetup().haveMultipleDomains, numLists);
+ const int ci_block =
+ get_ci_block_size(iGrid, gridSet.domainSetup().haveMultipleDomains, numLists);
/* With GPU: generate progressively smaller lists for
* load balancing for local only or non-local with 2 zones.
*/
- progBal = (locality_ == InteractionLocality::Local || ddZones->n <= 2);
+ const bool progBal = (locality_ == InteractionLocality::Local || ddZones->n <= 2);
#pragma omp parallel for num_threads(numLists) schedule(static)
for (int th = 0; th < numLists; th++)
/* Divide the i cells equally over the pairlists */
if (isCpuType_)
{
- nbnxn_make_pairlist_part(gridSet, iGrid, jGrid, &work, nbat, exclusions, rlist,
- params_.pairlistType, ci_block, nbat->bUseBufferFlags,
- nsubpair_target, progBal, nsubpair_tot_est, th,
- numLists, &cpuLists_[th], fepListPtr);
+ nbnxn_make_pairlist_part(gridSet,
+ iGrid,
+ jGrid,
+ &work,
+ nbat,
+ exclusions,
+ rlist,
+ params_.pairlistType,
+ ci_block,
+ nbat->bUseBufferFlags,
+ nsubpair_target,
+ progBal,
+ nsubpair_tot_est,
+ th,
+ numLists,
+ &cpuLists_[th],
+ fepListPtr);
}
else
{
- nbnxn_make_pairlist_part(gridSet, iGrid, jGrid, &work, nbat, exclusions, rlist,
- params_.pairlistType, ci_block, nbat->bUseBufferFlags,
- nsubpair_target, progBal, nsubpair_tot_est, th,
- numLists, &gpuLists_[th], fepListPtr);
+ nbnxn_make_pairlist_part(gridSet,
+ iGrid,
+ jGrid,
+ &work,
+ nbat,
+ exclusions,
+ rlist,
+ params_.pairlistType,
+ ci_block,
+ nbat->bUseBufferFlags,
+ nsubpair_target,
+ progBal,
+ nsubpair_tot_est,
+ th,
+ numLists,
+ &gpuLists_[th],
+ fepListPtr);
}
work.cycleCounter.stop();
}
searchCycleCounting->stop(enbsCCsearch);
- np_tot = 0;
- np_noq = 0;
- np_hlj = 0;
+ int np_tot = 0;
+ int np_noq = 0;
+ int np_hlj = 0;
for (int th = 0; th < numLists; th++)
{
inc_nrnb(nrnb, eNR_NBNXN_DIST2, searchWork[th].ndistc);
np_tot += nbl.nci_tot;
}
}
- if (isCpuType_)
- {
- nap = cpuLists_[0].na_ci * cpuLists_[0].na_cj;
- }
- else
- {
- nap = gmx::square(gpuLists_[0].na_ci);
- }
+ const int nap = isCpuType_ ? cpuLists_[0].na_ci * cpuLists_[0].na_cj
+ : gmx::square(gpuLists_[0].na_ci);
+
natpair_ljq_ = (np_tot - np_noq) * nap - np_hlj * nap / 2;
natpair_lj_ = np_noq * nap;
natpair_q_ = np_hlj * nap / 2;
"exclusions should either be empty or the number of lists should match the number of "
"local i-atoms");
- pairlistSet(iLocality).constructPairlists(gridSet, pairSearch->work(), nbat, exclusions,
- minimumIlistCountForGpuBalancing_, nrnb,
+ pairlistSet(iLocality).constructPairlists(gridSet,
+ pairSearch->work(),
+ nbat,
+ exclusions,
+ minimumIlistCountForGpuBalancing_,
+ nrnb,
&pairSearch->cycleCounting_);
if (iLocality == InteractionLocality::Local)
void nonbonded_verlet_t::constructPairlist(const InteractionLocality iLocality,
const ListOfLists<int>& exclusions,
int64_t step,
- t_nrnb* nrnb)
+ t_nrnb* nrnb) const
{
pairlistSets_->construct(iLocality, pairSearch_.get(), nbat.get(), exclusions, step, nrnb);
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team.
- * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
const real* x,
NbnxnPairlistCpuWork* work)
{
- int ia;
real* x_ci_simd = work->iClusterData.xSimd.data();
- ia = xIndexFromCi<NbnxnLayout::Simd2xNN>(ci);
+ const int ia = xIndexFromCi<NbnxnLayout::Simd2xNN>(ci);
store(x_ci_simd + 0 * GMX_SIMD_REAL_WIDTH,
loadU1DualHsimd(x + ia + 0 * c_xStride2xNN + 0) + SimdReal(shx));
/*! \brief SIMD code for checking and adding cluster-pairs to the list using coordinates in packed format.
*
- * Checks bouding box distances and possibly atom pair distances.
+ * Checks bounding box distances and possibly atom pair distances.
* This is an accelerated version of make_cluster_list_simple.
*
* \param[in] jGrid The j-grid
SimdReal rc2_S;
- gmx_bool InRange;
- float d2;
- int xind_f, xind_l;
-
int jclusterFirst = cjFromCi<NbnxnLayout::Simd2xNN, 0>(firstCell);
int jclusterLast = cjFromCi<NbnxnLayout::Simd2xNN, 1>(lastCell);
GMX_ASSERT(jclusterLast >= jclusterFirst,
rc2_S = SimdReal(rlist2);
- InRange = FALSE;
+ bool InRange = false;
while (!InRange && jclusterFirst <= jclusterLast)
{
- d2 = clusterBoundingBoxDistance2(bb_ci[0], jGrid.jBoundingBoxes()[jclusterFirst]);
+ const float d2 = clusterBoundingBoxDistance2(bb_ci[0], jGrid.jBoundingBoxes()[jclusterFirst]);
*numDistanceChecks += 2;
/* Check if the distance is within the distance where
*/
if (d2 < rbb2)
{
- InRange = TRUE;
+ InRange = true;
}
else if (d2 < rlist2)
{
- xind_f = xIndexFromCj<NbnxnLayout::Simd2xNN>(
+ const int xind_f = xIndexFromCj<NbnxnLayout::Simd2xNN>(
cjFromCi<NbnxnLayout::Simd2xNN, 0>(jGrid.cellOffset()) + jclusterFirst);
jx_S = loadDuplicateHsimd(x_j + xind_f + 0 * c_xStride2xNN);
return;
}
- InRange = FALSE;
+ InRange = false;
while (!InRange && jclusterLast > jclusterFirst)
{
- d2 = clusterBoundingBoxDistance2(bb_ci[0], jGrid.jBoundingBoxes()[jclusterLast]);
+ const float d2 = clusterBoundingBoxDistance2(bb_ci[0], jGrid.jBoundingBoxes()[jclusterLast]);
*numDistanceChecks += 2;
/* Check if the distance is within the distance where
*/
if (d2 < rbb2)
{
- InRange = TRUE;
+ InRange = true;
}
else if (d2 < rlist2)
{
- xind_l = xIndexFromCj<NbnxnLayout::Simd2xNN>(
+ const int xind_l = xIndexFromCj<NbnxnLayout::Simd2xNN>(
cjFromCi<NbnxnLayout::Simd2xNN, 0>(jGrid.cellOffset()) + jclusterLast);
jx_S = loadDuplicateHsimd(x_j + xind_l + 0 * c_xStride2xNN);
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team.
- * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
const real* x,
NbnxnPairlistCpuWork* work)
{
- int ia;
real* x_ci_simd = work->iClusterData.xSimd.data();
- ia = xIndexFromCi<NbnxnLayout::Simd4xN>(ci);
+ const int ia = xIndexFromCi<NbnxnLayout::Simd4xN>(ci);
store(x_ci_simd + 0 * GMX_SIMD_REAL_WIDTH, SimdReal(x[ia + 0 * c_xStride4xN] + shx));
store(x_ci_simd + 1 * GMX_SIMD_REAL_WIDTH, SimdReal(x[ia + 1 * c_xStride4xN] + shy));
/*! \brief SIMD code for checking and adding cluster-pairs to the list using coordinates in packed format.
*
- * Checks bouding box distances and possibly atom pair distances.
+ * Checks bounding box distances and possibly atom pair distances.
* This is an accelerated version of make_cluster_list_simple.
*
* \param[in] jGrid The j-grid
SimdReal rc2_S;
- gmx_bool InRange;
- float d2;
- int xind_f, xind_l;
-
/* Convert the j-range from i-cluster size indexing to j-cluster indexing */
int jclusterFirst = cjFromCi<NbnxnLayout::Simd4xN, 0>(firstCell);
int jclusterLast = cjFromCi<NbnxnLayout::Simd4xN, 1>(lastCell);
rc2_S = SimdReal(rlist2);
- InRange = FALSE;
+ bool InRange = false;
while (!InRange && jclusterFirst <= jclusterLast)
{
- d2 = clusterBoundingBoxDistance2(bb_ci[0], jGrid.jBoundingBoxes()[jclusterFirst]);
+ const float d2 = clusterBoundingBoxDistance2(bb_ci[0], jGrid.jBoundingBoxes()[jclusterFirst]);
*numDistanceChecks += 2;
/* Check if the distance is within the distance where
*/
if (d2 < rbb2)
{
- InRange = TRUE;
+ InRange = true;
}
else if (d2 < rlist2)
{
- xind_f = xIndexFromCj<NbnxnLayout::Simd4xN>(
+ const int xind_f = xIndexFromCj<NbnxnLayout::Simd4xN>(
cjFromCi<NbnxnLayout::Simd4xN, 0>(jGrid.cellOffset()) + jclusterFirst);
jx_S = load<SimdReal>(x_j + xind_f + 0 * c_xStride4xN);
return;
}
- InRange = FALSE;
+ InRange = false;
while (!InRange && jclusterLast > jclusterFirst)
{
- d2 = clusterBoundingBoxDistance2(bb_ci[0], jGrid.jBoundingBoxes()[jclusterLast]);
+ const float d2 = clusterBoundingBoxDistance2(bb_ci[0], jGrid.jBoundingBoxes()[jclusterLast]);
*numDistanceChecks += 2;
/* Check if the distance is within the distance where
*/
if (d2 < rbb2)
{
- InRange = TRUE;
+ InRange = true;
}
else if (d2 < rlist2)
{
- xind_l = xIndexFromCj<NbnxnLayout::Simd4xN>(
+ const int xind_l = xIndexFromCj<NbnxnLayout::Simd4xN>(
cjFromCi<NbnxnLayout::Simd4xN, 0>(jGrid.cellOffset()) + jclusterLast);
jx_S = load<SimdReal>(x_j + xind_l + 0 * c_xStride4xN);
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
static bool supportsDynamicPairlistGenerationInterval(const t_inputrec& ir)
{
return ir.cutoff_scheme == ecutsVERLET && EI_DYNAMICS(ir.eI)
- && !(EI_MD(ir.eI) && ir.etc == etcNO) && ir.verletbuf_tol > 0;
+ && !(EI_MD(ir.eI) && ir.etc == TemperatureCoupling::No) && ir.verletbuf_tol > 0;
}
/*! \brief Cost of non-bonded kernels
return;
}
- float listfac_ok, listfac_max;
- int nstlist_orig, nstlist_prev;
- real rlist_inc, rlist_ok, rlist_max;
- real rlist_new, rlist_prev;
size_t nstlist_ind = 0;
- gmx_bool bBox, bDD, bCont;
const char* nstl_gpu =
"\nFor optimal performance with a GPU nstlist (now %d) should be larger.\nThe "
"optimum depends on your CPU and GPU resources.\nYou might want to try several "
}
}
- if (EI_MD(ir->eI) && ir->etc == etcNO)
+ if (EI_MD(ir->eI) && ir->etc == TemperatureCoupling::No)
{
if (MASTER(cr))
{
"In all cases that do not support dynamic nstlist, we should have returned "
"with an appropriate message above");
- if (useOrEmulateGpuForNonbondeds)
- {
- listfac_ok = c_nbnxnListSizeFactorGPU;
- }
- else if (cpuinfo.brandString().find("Xeon Phi") != std::string::npos)
- {
- listfac_ok = c_nbnxnListSizeFactorIntelXeonPhi;
- }
- else
- {
- listfac_ok = c_nbnxnListSizeFactorCpu;
- }
- listfac_max = listfac_ok + c_nbnxnListSizeFactorMargin;
+ const bool runningOnXeonPhi = (cpuinfo.brandString().find("Xeon Phi") != std::string::npos);
+ const float listfac_ok = useOrEmulateGpuForNonbondeds
+ ? c_nbnxnListSizeFactorGPU
+ : runningOnXeonPhi ? c_nbnxnListSizeFactorIntelXeonPhi
+ : c_nbnxnListSizeFactorCpu;
+ float listfac_max = listfac_ok + c_nbnxnListSizeFactorMargin;
- nstlist_orig = ir->nstlist;
+ const int nstlist_orig = ir->nstlist;
if (nstlist_cmdline > 0)
{
if (fp)
/* Allow rlist to make the list a given factor larger than the list
* would be with the reference value for nstlist (10*mtsFactor).
*/
- nstlist_prev = ir->nstlist;
- ir->nstlist = nbnxnReferenceNstlist * mtsFactor;
+ int nstlist_prev = ir->nstlist;
+ ir->nstlist = nbnxnReferenceNstlist * mtsFactor;
const real rlistWithReferenceNstlist =
calcVerletBufferSize(*mtop, det(box), *ir, ir->nstlist, ir->nstlist - 1, -1, listSetup);
ir->nstlist = nstlist_prev;
/* Determine the pair list size increase due to zero interactions */
- rlist_inc = nbnxn_get_rlist_effective_inc(listSetup.cluster_size_j, mtop->natoms / det(box));
- rlist_ok = (rlistWithReferenceNstlist + rlist_inc) * std::cbrt(listfac_ok) - rlist_inc;
- rlist_max = (rlistWithReferenceNstlist + rlist_inc) * std::cbrt(listfac_max) - rlist_inc;
+ real rlist_inc = nbnxn_get_rlist_effective_inc(listSetup.cluster_size_j, mtop->natoms / det(box));
+ real rlist_ok = (rlistWithReferenceNstlist + rlist_inc) * std::cbrt(listfac_ok) - rlist_inc;
+ real rlist_max = (rlistWithReferenceNstlist + rlist_inc) * std::cbrt(listfac_max) - rlist_inc;
if (debug)
{
- fprintf(debug, "nstlist tuning: rlist_inc %.3f rlist_ok %.3f rlist_max %.3f\n", rlist_inc,
- rlist_ok, rlist_max);
+ fprintf(debug, "nstlist tuning: rlist_inc %.3f rlist_ok %.3f rlist_max %.3f\n", rlist_inc, rlist_ok, rlist_max);
}
- nstlist_prev = nstlist_orig;
- rlist_prev = ir->rlist;
+ nstlist_prev = nstlist_orig;
+ real rlist_prev = ir->rlist;
+ real rlist_new = 0;
+ bool bBox = false, bDD = false, bCont = false;
do
{
if (nstlist_cmdline <= 0)
}
/* Set the pair-list buffer size in ir */
- rlist_new = calcVerletBufferSize(*mtop, det(box), *ir, ir->nstlist, ir->nstlist - mtsFactor,
- -1, listSetup);
+ rlist_new = calcVerletBufferSize(
+ *mtop, det(box), *ir, ir->nstlist, ir->nstlist - mtsFactor, -1, listSetup);
/* Does rlist fit in the box? */
bBox = (gmx::square(rlist_new) < max_cutoff2(ir->pbcType, box));
- bDD = TRUE;
+ bDD = true;
if (bBox && DOMAINDECOMP(cr))
{
/* Currently (as of July 2020), the code in this if clause is never executed.
if (debug)
{
- fprintf(debug, "nstlist %d rlist %.3f bBox %s bDD %s\n", ir->nstlist, rlist_new,
- gmx::boolToString(bBox), gmx::boolToString(bDD));
+ fprintf(debug,
+ "nstlist %d rlist %.3f bBox %s bDD %s\n",
+ ir->nstlist,
+ rlist_new,
+ gmx::boolToString(bBox),
+ gmx::boolToString(bDD));
}
- bCont = FALSE;
+ bCont = false;
if (nstlist_cmdline <= 0)
{
/* Stick with the previous nstlist */
ir->nstlist = nstlist_prev;
rlist_new = rlist_prev;
- bBox = TRUE;
- bDD = TRUE;
+ bBox = true;
+ bDD = true;
}
}
}
else if (ir->nstlist != nstlist_orig || rlist_new != ir->rlist)
{
- sprintf(buf, "Changing nstlist from %d to %d, rlist from %g to %g", nstlist_orig,
- ir->nstlist, ir->rlist, rlist_new);
+ sprintf(buf,
+ "Changing nstlist from %d to %d, rlist from %g to %g",
+ nstlist_orig,
+ ir->nstlist,
+ ir->rlist,
+ rlist_new);
if (MASTER(cr))
{
fprintf(stderr, "%s\n\n", buf);
*/
int listLifetime = tunedNstlistPrune - (useGpuList ? 0 : mtsFactor);
listParams->nstlistPrune = tunedNstlistPrune;
- listParams->rlistInner = calcVerletBufferSize(*mtop, det(box), *ir, tunedNstlistPrune,
- listLifetime, -1, listSetup);
+ listParams->rlistInner = calcVerletBufferSize(
+ *mtop, det(box), *ir, tunedNstlistPrune, listLifetime, -1, listSetup);
/* On the GPU we apply the dynamic pruning in a rolling fashion
* every c_nbnxnGpuRollingListPruningInterval steps,
std::string nstListFormat =
"%" + gmx::formatString("%zu", gmx::formatString("%d", nstListForSpacing).size()) + "d";
listSetup += gmx::formatString(nstListFormat.c_str(), nstList);
- listSetup += gmx::formatString(" steps, buffer %.3f nm, rlist %.3f nm\n",
- rList - interactionCutoff, rList);
+ listSetup += gmx::formatString(
+ " steps, buffer %.3f nm, rlist %.3f nm\n", rList - interactionCutoff, rList);
return listSetup;
}
JClusterSizePerListType[listParams->pairlistType] };
/* Currently emulation mode does not support dual pair-lists */
- const bool useGpuList = (listParams->pairlistType == PairlistType::HierarchicalNxN);
+ const bool useGpuList = sc_isGpuPairListType[listParams->pairlistType];
if (supportsDynamicPairlistGenerationInterval(*ir) && getenv("GMX_DISABLE_DYNAMICPRUNING") == nullptr)
{
if (userSetNstlistPrune)
{
- char* end;
+ char* end = nullptr;
listParams->nstlistPrune = strtol(env, &end, 10);
if (!end || (*end != 0)
|| !(listParams->nstlistPrune > 0 && listParams->nstlistPrune < ir->nstlist))
listParams->nstlistPrune = c_nbnxnDynamicListPruningMinLifetime;
}
- setDynamicPairlistPruningParameters(ir, mtop, box, useGpuList, ls, userSetNstlistPrune, ic,
- listParams);
+ setDynamicPairlistPruningParameters(
+ ir, mtop, box, useGpuList, ls, userSetNstlistPrune, ic, listParams);
if (listParams->useDynamicPruning && useGpuList)
{
* rolling pruning interval slightly shorter than nstlistTune,
* thus giving correct results, but a slightly lower efficiency.
*/
- GMX_RELEASE_ASSERT(listParams->nstlistPrune >= c_nbnxnGpuRollingListPruningInterval, ("With dynamic list pruning on GPUs pruning frequency must be at least as large as the rolling pruning interval ("
- + std::to_string(c_nbnxnGpuRollingListPruningInterval)
- + ").")
- .c_str());
+ GMX_RELEASE_ASSERT(listParams->nstlistPrune >= c_nbnxnGpuRollingListPruningInterval,
+ ("With dynamic list pruning on GPUs pruning frequency must be at "
+ "least as large as the rolling pruning interval ("
+ + std::to_string(c_nbnxnGpuRollingListPruningInterval) + ").")
+ .c_str());
listParams->numRollingPruningParts =
listParams->nstlistPrune / c_nbnxnGpuRollingListPruningInterval;
}
if (listParams->useDynamicPruning)
{
mesg += gmx::formatString(
- "Using a dual %dx%d pair-list setup updated with dynamic%s pruning:\n", ls.cluster_size_i,
- ls.cluster_size_j, listParams->numRollingPruningParts > 1 ? ", rolling" : "");
+ "Using a dual %dx%d pair-list setup updated with dynamic%s pruning:\n",
+ ls.cluster_size_i,
+ ls.cluster_size_j,
+ listParams->numRollingPruningParts > 1 ? ", rolling" : "");
mesg += formatListSetup("outer", ir->nstlist, ir->nstlist, listParams->rlistOuter, interactionCutoff);
- mesg += formatListSetup("inner", listParams->nstlistPrune, ir->nstlist,
- listParams->rlistInner, interactionCutoff);
+ mesg += formatListSetup(
+ "inner", listParams->nstlistPrune, ir->nstlist, listParams->rlistInner, interactionCutoff);
}
else
{
if (supportsDynamicPairlistGenerationInterval(*ir))
{
const VerletbufListSetup listSetup1x1 = { 1, 1 };
- const real rlistOuter = calcVerletBufferSize(*mtop, det(box), *ir, ir->nstlist,
- ir->nstlist - 1, -1, listSetup1x1);
- real rlistInner = rlistOuter;
+ const real rlistOuter = calcVerletBufferSize(
+ *mtop, det(box), *ir, ir->nstlist, ir->nstlist - 1, -1, listSetup1x1);
+ real rlistInner = rlistOuter;
if (listParams->useDynamicPruning)
{
int listLifeTime = listParams->nstlistPrune - (useGpuList ? 0 : 1);
- rlistInner = calcVerletBufferSize(*mtop, det(box), *ir, listParams->nstlistPrune,
- listLifeTime, -1, listSetup1x1);
+ rlistInner = calcVerletBufferSize(
+ *mtop, det(box), *ir, listParams->nstlistPrune, listLifeTime, -1, listSetup1x1);
}
mesg += gmx::formatString(
if (listParams->useDynamicPruning)
{
mesg += formatListSetup("outer", ir->nstlist, ir->nstlist, rlistOuter, interactionCutoff);
- mesg += formatListSetup("inner", listParams->nstlistPrune, ir->nstlist, rlistInner,
- interactionCutoff);
+ mesg += formatListSetup(
+ "inner", listParams->nstlistPrune, ir->nstlist, rlistInner, interactionCutoff);
}
else
{
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
static constexpr gmx::EnumerationArray<PairlistType, int> JClusterSizePerListType = {
{ 2, 4, 8, c_nbnxnGpuClusterSize }
};
+//! True if given pairlist type is used on GPU, false if on CPU.
+static constexpr gmx::EnumerationArray<PairlistType, bool> sc_isGpuPairListType = {
+ { false, false, false, true }
+};
/*! \internal
* \brief The setup for generating and pruning the nbnxn pair list.
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
//! Working data for the actual i-supercell during pair search \internal
struct NbnxnPairlistCpuWork
{
- //! Struct for storing coordinats and bounding box for an i-entry during search \internal
+ //! Struct for storing coordinates and bounding box for an i-entry during search \internal
struct IClusterData
{
IClusterData() :
void SearchCycleCounting::printCycles(FILE* fp, gmx::ArrayRef<const PairsearchWork> work) const
{
fprintf(fp, "\n");
- fprintf(fp, "ns %4d grid %4.1f search %4.1f", cc_[enbsCCgrid].count(),
- cc_[enbsCCgrid].averageMCycles(), cc_[enbsCCsearch].averageMCycles());
+ fprintf(fp,
+ "ns %4d grid %4.1f search %4.1f",
+ cc_[enbsCCgrid].count(),
+ cc_[enbsCCgrid].averageMCycles(),
+ cc_[enbsCCsearch].averageMCycles());
if (work.size() > 1)
{
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team.
- * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2020,2021, 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.
*
* The PairSearch class holds the domain setup, the search grids
* and helper object for the pair search. It manages the search work.
- * The actual gridding and pairlist generation is performeed by the
+ * The actual gridding and pairlist generation is performed by the
* GridSet/Grid and PairlistSet/Pairlist classes, respectively.
*
* \author Berk Hess <hess@kth.se>
~PairsearchWork();
- //! Buffer to avoid cache polution
+ //! Buffer to avoid cache pollution
gmx_cache_protect_t cp0;
//! Temporary buffer for sorting atoms within a grid column
{
cycleCounting_.start(enbsCCgrid);
- gridSet_.putOnGrid(box, ddZone, lowerCorner, upperCorner, updateGroupsCog, atomRange,
- atomDensity, atomInfo, x, numAtomsMoved, move, nbat);
+ gridSet_.putOnGrid(box,
+ ddZone,
+ lowerCorner,
+ upperCorner,
+ updateGroupsCog,
+ atomRange,
+ atomDensity,
+ atomInfo,
+ x,
+ numAtomsMoved,
+ move,
+ nbat);
cycleCounting_.stop(enbsCCgrid);
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2016,2017,2018,2019,2020 by the GROMACS development team.
+ * Copyright (c) 2021, 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.
}
}
-void nonbonded_verlet_t::dispatchPruneKernelCpu(const gmx::InteractionLocality iLocality, const rvec* shift_vec)
+void nonbonded_verlet_t::dispatchPruneKernelCpu(const gmx::InteractionLocality iLocality,
+ const rvec* shift_vec) const
{
pairlistSets_->dispatchPruneKernel(iLocality, nbat.get(), shift_vec);
}
(pairlistSets().numStepsWithPairlist(step) % (2 * pairlistSets().params().mtsFactor) == 0);
Nbnxm::gpu_launch_kernel_pruneonly(
- gpu_nbv, stepIsEven ? gmx::InteractionLocality::Local : gmx::InteractionLocality::NonLocal,
+ gpu_nbv,
+ stepIsEven ? gmx::InteractionLocality::Local : gmx::InteractionLocality::NonLocal,
pairlistSets().params().numRollingPruningParts);
wallcycle_sub_stop(wcycle_, ewcsLAUNCH_GPU_NONBONDED);
#
# 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.
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+# Set up the module library
+add_library(onlinehelp INTERFACE)
file(GLOB ONLINEHELP_SOURCES *.cpp)
set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${ONLINEHELP_SOURCES} PARENT_SCOPE)
+# Source files have the following dependencies on library infrastructure.
+#target_link_libraries(onlinehelp PRIVATE
+# common
+# legacy_modules
+#)
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(onlinehelp PUBLIC
+target_include_directories(onlinehelp INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(onlinehelp PUBLIC
+target_link_libraries(onlinehelp INTERFACE
+ legacy_api
+ )
+
+# TODO: when onlinehelp is an OBJECT target
+#target_link_libraries(onlinehelp PUBLIC legacy_api)
+#target_link_libraries(onlinehelp PRIVATE common)
+
+# Module dependencies
+# onlinehelp interfaces convey transitive dependence on these modules.
+#target_link_libraries(onlinehelp PUBLIC
+target_link_libraries(onlinehelp INTERFACE
+ utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(onlinehelp PRIVATE NOTHING)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(onlinehelp PRIVATE legacy_modules)
+
if (BUILD_TESTING)
add_subdirectory(tests)
endif()
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2013,2014,2015,2019, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015,2019,2021, 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.
#ifndef GMX_ONLINEHELP_HELPFORMAT_H
#define GMX_ONLINEHELP_HELPFORMAT_H
+#include <memory>
#include <string>
-#include "gromacs/utility/classhelpers.h"
-
namespace gmx
{
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2014,2015,2017,2019, by the GROMACS development team, led by
+ * Copyright (c) 2012,2014,2015,2017,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.
}
else
{
- GMX_THROW(InvalidInputError(formatString("Help topic '%s' has no subtopic '%s'",
- impl_->currentTopicAsString().c_str(), name)));
+ GMX_THROW(InvalidInputError(formatString(
+ "Help topic '%s' has no subtopic '%s'", impl_->currentTopicAsString().c_str(), name)));
}
}
impl_->topicStack_.push_back(newTopic);
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2014,2015,2019, by the GROMACS development team, led by
+ * Copyright (c) 2012,2014,2015,2019,2021, 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.
#ifndef GMX_ONLINEHELP_HELPMANAGER_H
#define GMX_ONLINEHELP_HELPMANAGER_H
+#include <memory>
#include <string>
-#include "gromacs/utility/classhelpers.h"
-
namespace gmx
{
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2014,2015,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2012,2014,2015,2018,2019,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <memory>
#include "gromacs/onlinehelp/ihelptopic.h"
-#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/stringutil.h"
namespace gmx
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
/*! \cond libapi */
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team.
- * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <vector>
#include "gromacs/onlinehelp/helpformat.h"
+#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/programcontext.h"
if (state_->links_ != nullptr)
{
HelpLinks::Impl::LinkList::const_iterator link;
- for (link = state_->links_->impl_->links_.begin();
- link != state_->links_->impl_->links_.end(); ++link)
+ for (link = state_->links_->impl_->links_.begin(); link != state_->links_->impl_->links_.end(); ++link)
{
result = replaceAllWords(result, link->linkName, link->replacement);
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2013,2014,2015,2019, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015,2019,2021, 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.
#ifndef GMX_ONLINEHELP_HELPWRITERCONTEXT_H
#define GMX_ONLINEHELP_HELPWRITERCONTEXT_H
+#include <memory>
#include <string>
#include <vector>
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
//! Allows the context to use the links.
friend class HelpWriterContext;
*/
explicit HelpWriterContext(Impl* impl);
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
GMX_DISALLOW_ASSIGN(HelpWriterContext);
};
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2015,2018,2019,2021, 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.
#ifndef GMX_ONLINEHELP_RSTPARSER_H
#define GMX_ONLINEHELP_RSTPARSER_H
+#include <memory>
#include <string>
#include "gromacs/utility/classhelpers.h"
gmx_add_unit_test_library(onlinehelp-test-shared
mock_helptopic.cpp)
+target_link_libraries(onlinehelp-test-shared PUBLIC common)
gmx_add_unit_test(OnlineHelpUnitTests onlinehelp-test
CPP_SOURCE_FILES
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+# Set up the module library
+add_library(options INTERFACE)
+
gmx_add_libgromacs_sources(
abstractoption.cpp
abstractsection.cpp
DESTINATION include/gromacs/options)
endif()
+# Source files have the following private module dependencies.
+target_link_libraries(options PRIVATE
+ )
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(options PUBLIC
+target_include_directories(options INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(options PUBLIC
+target_link_libraries(options INTERFACE
+ legacy_api
+ )
+
+# TODO: when options is an OBJECT target
+#target_link_libraries(options PUBLIC legacy_api)
+#target_link_libraries(options PRIVATE common)
+
+# Module dependencies
+# options interfaces convey transitive dependence on these modules.
+#target_link_libraries(options PUBLIC
+target_link_libraries(options INTERFACE
+ utility
+ )
+
if (BUILD_TESTING)
add_subdirectory(tests)
endif()
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2010-2017, The GROMACS development team.
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 2019,2021, 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.
#ifndef GMX_OPTIONS_ABSTRACTOPTION_H
#define GMX_OPTIONS_ABSTRACTOPTION_H
+#include <memory>
#include <string>
#include <vector>
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2010,2011,2012,2014,2015 by the GROMACS development team.
- * Copyright (c) 2016,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2016,2019,2020,2021, 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.
#ifndef GMX_OPTIONS_ABSTRACTOPTIONSTORAGE_H
#define GMX_OPTIONS_ABSTRACTOPTIONSTORAGE_H
+#include <memory>
#include <string>
#include <vector>
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2016,2018,2019,2021, 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.
#ifndef GMX_OPTIONS_ABSTRACTSECTION_H
#define GMX_OPTIONS_ABSTRACTSECTION_H
+#include <memory>
+
#include "gromacs/options/ioptionscontainerwithsections.h"
#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/gmxassert.h"
AbstractOptionStorage* createStorage(const OptionManagerContainer& /*managers*/) const override
{
// TODO: Implement storeCount() if necessary.
- return internal::createEnumOptionStorage(*this, enumValues_, enumValuesCount_,
+ return internal::createEnumOptionStorage(*this,
+ enumValues_,
+ enumValuesCount_,
convertToInt(MyBase::defaultValue()),
convertToInt(MyBase::defaultValueIfSet()),
std::make_unique<internal::EnumIndexStore<EnumType>>(
AbstractOptionStorage* createStorage(const OptionManagerContainer& /*managers*/) const override
{
// TODO: Implement storeCount() if necessary.
- return internal::createEnumOptionStorage(*this, enumValues_, enumValuesCount_,
+ return internal::createEnumOptionStorage(*this,
+ enumValues_,
+ enumValuesCount_,
convertToInt(MyBase::defaultValue()),
convertToInt(MyBase::defaultValueIfSet()),
std::make_unique<internal::EnumIndexStore<EnumType>>(
"File '%s' cannot be used by GROMACS because it "
"does not have a recognizable extension.\n"
"The following extensions are possible for this option:\n %s",
- value.c_str(), joinStrings(extensions(), ", ").c_str());
+ value.c_str(),
+ joinStrings(extensions(), ", ").c_str());
GMX_THROW(InvalidInputError(message));
}
else if (!isValidType(fileType))
std::string message = formatString(
"File name '%s' cannot be used for this option.\n"
"Only the following extensions are possible:\n %s",
- value.c_str(), joinStrings(extensions(), ", ").c_str());
+ value.c_str(),
+ joinStrings(extensions(), ", ").c_str());
GMX_THROW(InvalidInputError(message));
}
return value;
std::string message = formatString(
"File '%s' does not exist or is not accessible.\n"
"The following extensions were tried to complete the file name:\n %s",
- value.c_str(), joinStrings(option.extensions(), ", ").c_str());
+ value.c_str(),
+ joinStrings(option.extensions(), ", ").c_str());
GMX_THROW(InvalidInputError(message));
}
}
"No file name was provided, and the default file "
"'%s' does not exist or is not accessible.\n"
"The following extensions were tried to complete the file name:\n %s",
- prefix.c_str(), joinStrings(option.extensions(), ", ").c_str());
+ prefix.c_str(),
+ joinStrings(option.extensions(), ", ").c_str());
GMX_THROW(InvalidInputError(message));
}
else if (option.isRequired())
"Required option was not provided, and the default file "
"'%s' does not exist or is not accessible.\n"
"The following extensions were tried to complete the file name:\n %s",
- prefix.c_str(), joinStrings(option.extensions(), ", ").c_str());
+ prefix.c_str(),
+ joinStrings(option.extensions(), ", ").c_str());
GMX_THROW(InvalidInputError(message));
}
// We get here with the legacy optional behavior.
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014,2015,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015,2018,2019,2021, 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.
#ifndef GMX_OPTIONS_FILENAMEOPTIONMANAGER_H
#define GMX_OPTIONS_FILENAMEOPTIONMANAGER_H
+#include <memory>
#include <string>
#include "gromacs/options/options.h"
-#include "gromacs/utility/classhelpers.h"
namespace gmx
{
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014,2015,2017,2019, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015,2017,2019,2021, 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.
#ifndef GMX_OPTIONS_OPTIONMANAGERCONTAINER_H
#define GMX_OPTIONS_OPTIONMANAGERCONTAINER_H
+#include <memory>
#include <vector>
#include "gromacs/utility/classhelpers.h"
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2010,2011,2012,2014,2015 by the GROMACS development team.
- * Copyright (c) 2016,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2016,2018,2019,2020,2021, 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.
#ifndef GMX_OPTIONS_OPTIONS_H
#define GMX_OPTIONS_OPTIONS_H
+#include <memory>
#include <string>
#include "gromacs/options/ioptionscontainerwithsections.h"
-#include "gromacs/utility/classhelpers.h"
namespace gmx
{
// From IOptionsContainer
OptionInfo* addOptionImpl(const AbstractOption& settings) override;
- PrivateImplPointer<internal::OptionsImpl> impl_;
+ std::unique_ptr<internal::OptionsImpl> impl_;
//! Needed to be able to extend the interface of this object.
friend class OptionsAssigner;
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2010-2018, The GROMACS development team.
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 2019,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/options/optionmanagercontainer.h"
#include "gromacs/options/options.h"
#include "gromacs/options/optionsection.h"
+#include "gromacs/utility/classhelpers.h"
#include "isectionstorage.h"
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2010,2011,2012,2013,2014 by the GROMACS development team.
- * Copyright (c) 2015,2016,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,2019,2020,2021, 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.
#ifndef GMX_OPTIONS_OPTIONSASSIGNER_H
#define GMX_OPTIONS_OPTIONSASSIGNER_H
+#include <memory>
#include <string>
-#include "gromacs/utility/classhelpers.h"
-
namespace gmx
{
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2016,2018,2019,2021, 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.
#ifndef GMX_OPTIONS_OPTIONSECTION_H
#define GMX_OPTIONS_OPTIONSECTION_H
-#include "gromacs/utility/classhelpers.h"
+#include <memory>
#include "abstractsection.h"
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2010,2011,2012,2014,2016 by the GROMACS development team.
- * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <cstddef>
+#include <memory>
#include <string>
#include "gromacs/options/abstractoption.h"
*
* These must correspond to the TimeUnit enum in the header!
*/
-const EnumerationArray<TimeUnit, const char*> c_timeUnitNames = { { "fs", "ps", "ns", "us", "ms",
- "s" } };
+const EnumerationArray<TimeUnit, const char*> c_timeUnitNames = {
+ { "fs", "ps", "ns", "us", "ms", "s" }
+};
/*! \brief
* Scaling factors from each time unit to internal units (=picoseconds).
*
"Time unit provided with environment variable GMXTIMEUNIT=%s "
"is not recognized as a valid time unit.\n"
"Possible values are: %s",
- value, joinStrings(c_timeUnitNames, ", ").c_str());
+ value,
+ joinStrings(c_timeUnitNames, ", ").c_str());
GMX_THROW(InvalidInputError(message));
}
setTimeUnit(result);
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2014,2015,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2012,2014,2015,2018,2019,2020,2021, 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.
#ifndef GMX_OPTIONS_TIMEUNITMANAGER_H
#define GMX_OPTIONS_TIMEUNITMANAGER_H
+#include <memory>
+
#include "gromacs/fileio/oenv.h"
#include "gromacs/options/ioptionsbehavior.h"
#include "gromacs/utility/classhelpers.h"
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2016,2017,2018,2019,2020, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
helper.processOptionSection(options.rootSection());
if (helper.hasUnknownPaths())
{
- std::string paths(formatAndJoin(helper.unknownPaths(), "\n ",
- [](const KeyValueTreePath& path) { return path.toString(); }));
+ std::string paths(formatAndJoin(helper.unknownPaths(), "\n ", [](const KeyValueTreePath& path) {
+ return path.toString();
+ }));
std::string message("Unknown input values:\n " + paths);
GMX_THROW(InvalidInputError(message));
}
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+# Set up the module library
+add_library(pbcutil INTERFACE)
file(GLOB PBCUTIL_SOURCES *.cpp)
set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${PBCUTIL_SOURCES} PARENT_SCOPE)
+# Source files have the following dependencies on library infrastructure.
+#target_link_libraries(pbcutil PRIVATE
+# common
+# legacy_modules
+#)
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(pbcutil PUBLIC
+target_include_directories(pbcutil INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(pbcutil PUBLIC
+target_link_libraries(pbcutil INTERFACE
+ legacy_api
+ )
+
+# TODO: when pbcutil is an OBJECT target
+#target_link_libraries(pbcutil PUBLIC legacy_api)
+#target_link_libraries(pbcutil PRIVATE common)
+
+# Module dependencies
+# pbcutil interfaces convey transitive dependence on these modules.
+#target_link_libraries(pbcutil PUBLIC
+target_link_libraries(pbcutil INTERFACE
+ utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(pbcutil PRIVATE NOTHING)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(pbcutil PRIVATE legacy_modules)
+
if(GMX_INSTALL_LEGACY_API)
install(FILES
pbc.h
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#define GMX_PBCUTIL_COM_H
#include <algorithm>
+#include <memory>
#include "gromacs/math/vec.h"
#include "gromacs/utility/arrayref.h"
-#include "gromacs/utility/classhelpers.h"
#include "pbcenums.h"
"You are probably trying to use a trajectory which does "
"not match the first %d atoms of the run input file.\n"
"You can make a matching run input file with gmx convert-tpr.",
- at_end, at_end);
+ at_end,
+ at_end);
}
if (ftype == F_SETTLE)
{
{
if (!g->edges[i].empty())
{
- fprintf(log, "%5d%7d%7d%7d %1s%5zu", g->edgeAtomBegin + i + 1,
- g->ishift[g->edgeAtomBegin + i][XX], g->ishift[g->edgeAtomBegin + i][YY],
+ fprintf(log,
+ "%5d%7d%7d%7d %1s%5zu",
+ g->edgeAtomBegin + i + 1,
+ g->ishift[g->edgeAtomBegin + i][XX],
+ g->ishift[g->edgeAtomBegin + i][YY],
g->ishift[g->edgeAtomBegin + i][ZZ],
- (!g->edgeColor.empty()) ? cc[g->edgeColor[i]] : " ", g->edges[i].size());
+ (!g->edgeColor.empty()) ? cc[g->edgeColor[i]] : " ",
+ g->edges[i].size());
for (const int edge : g->edges[i])
{
fprintf(log, " %5d", edge + 1);
}
if (debug)
{
- fprintf(debug, "graph partNr[] numAtomsChanged=%d, bMultiPart=%s\n", numAtomsChanged,
+ fprintf(debug,
+ "graph partNr[] numAtomsChanged=%d, bMultiPart=%s\n",
+ numAtomsChanged,
gmx::boolToString(haveMultipleParts));
}
} while (numAtomsChanged > 0);
"mk_grey: shifts for atom %d due to atom %d\n"
"are (%d,%d,%d), should be (%d,%d,%d)\n"
"dx = (%g,%g,%g)\n",
- aj + 1, ai + 1, is_aj[XX], is_aj[YY], is_aj[ZZ], g->ishift[aj][XX],
- g->ishift[aj][YY], g->ishift[aj][ZZ], dx[XX], dx[YY], dx[ZZ]);
+ aj + 1,
+ ai + 1,
+ is_aj[XX],
+ is_aj[YY],
+ is_aj[ZZ],
+ g->ishift[aj][XX],
+ g->ishift[aj][YY],
+ g->ishift[aj][ZZ],
+ dx[XX],
+ dx[YY],
+ dx[ZZ]);
}
(*nerror)++;
}
"There are inconsistent shifts over periodic boundaries in a molecule type "
"consisting of %d atoms. The longest distance involved in such interactions is "
"%.3f nm which is %s half the box length.",
- g->shiftAtomEnd, maxDistance, maxDistance >= 0.5 * minBoxSize ? "above" : "close to");
+ g->shiftAtomEnd,
+ maxDistance,
+ maxDistance >= 0.5 * minBoxSize ? "above" : "close to");
switch (g->parts)
{
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/smalloc.h"
-const gmx::EnumerationArray<PbcType, std::string> c_pbcTypeNames = { { "xyz", "no", "xy", "screw",
- "unset" } };
+const gmx::EnumerationArray<PbcType, std::string> c_pbcTypeNames = {
+ { "xyz", "no", "xy", "screw", "unset" }
+};
/* Skip 0 so we have more chance of detecting if we forgot to call set_pbc. */
enum
fprintf(stderr,
"WARNING: Unsupported box diagonal %f %f %f, "
"will not use periodic boundary conditions\n\n",
- box[XX][XX], box[YY][YY], box[ZZ][ZZ]);
+ box[XX][XX],
+ box[YY][YY],
+ box[ZZ][ZZ]);
bWarnedGuess = TRUE;
}
pbcType = PbcType::No;
fprintf(debug,
" tricvec %2d = %2d %2d %2d %5.2f %5.2f "
"%5.2f %5.2f %5.2f %5.2f %5.2f %5.2f\n",
- pbc->ntric_vec, i, j, k, sqrt(d2old),
- sqrt(d2new), trial[XX], trial[YY], trial[ZZ],
- pos[XX], pos[YY], pos[ZZ]);
+ pbc->ntric_vec,
+ i,
+ j,
+ k,
+ sqrt(d2old),
+ sqrt(d2new),
+ trial[XX],
+ trial[YY],
+ trial[ZZ],
+ pos[XX],
+ pos[YY],
+ pos[ZZ]);
}
}
}
gmx_fatal(FARGS,
"Molecule %d marked for clustering but not atom %d in it - check your "
"index!",
- i + 1, j + 1);
+ i + 1,
+ j + 1);
}
else if (!bMol[i] && bTmp[j])
{
gmx_fatal(FARGS,
"Atom %d marked for clustering but not molecule %d - this is an internal "
"error...",
- j + 1, i + 1);
+ j + 1,
+ i + 1);
}
else if (bMol[i])
{
fprintf(debug,
"\nShifting position of molecule %d "
"by %8.3f %8.3f %8.3f\n",
- i + 1, shift[XX], shift[YY], shift[ZZ]);
+ i + 1,
+ shift[XX],
+ shift[YY],
+ shift[ZZ]);
}
for (j = mols->index[i]; (j < mols->index[i + 1] && j < natoms); j++)
{
fprintf(debug,
"\nShifting position of residue %d (atoms %d-%d) "
"by %g,%g,%g\n",
- atom[res_start].resind + 1, res_start + 1, res_end + 1, shift[XX],
- shift[YY], shift[ZZ]);
+ atom[res_start].resind + 1,
+ res_start + 1,
+ res_end + 1,
+ shift[XX],
+ shift[YY],
+ shift[ZZ]);
}
for (j = res_start; j < res_end; j++)
{
{
gmx_fatal(FARGS,
"Structure or trajectory file has more atoms (%d) than the topology (%d)",
- natoms, gpbc->natoms_init);
+ natoms,
+ gpbc->natoms_init);
}
gpbc->ngraph++;
srenew(gpbc->graph, gpbc->ngraph);
auto unitcell = std::get<0>(params);
auto center = std::get<1>(params);
auto pbcType = std::get<2>(params);
- placeCoordinatesWithCOMInBox(pbcType, unitcell, center, box, testCoordinates_, testTopology_,
- COMShiftType::Molecule);
+ placeCoordinatesWithCOMInBox(
+ pbcType, unitcell, center, box, testCoordinates_, testTopology_, COMShiftType::Molecule);
std::string testString = "Molecule " + std::string(unitCellTypeNames(unitcell))
+ std::string(centerTypeNames(center)) + c_pbcTypeNames[pbcType]
+ c_pbcTypeNames[guessPbcType(box)];
auto unitcell = std::get<0>(params);
auto center = std::get<1>(params);
auto pbcType = std::get<2>(params);
- placeCoordinatesWithCOMInBox(pbcType, unitcell, center, box, testCoordinates_, testTopology_,
- COMShiftType::Residue);
+ placeCoordinatesWithCOMInBox(
+ pbcType, unitcell, center, box, testCoordinates_, testTopology_, COMShiftType::Residue);
std::string testString = "Residue " + std::string(unitCellTypeNames(unitcell))
+ std::string(centerTypeNames(center)) + c_pbcTypeNames[pbcType]
+ c_pbcTypeNames[guessPbcType(box)];
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2014,2015,2016, by the GROMACS development team, led by
+# Copyright (c) 2014,2015,2016,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.
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+# Set up the module library
+add_library(pulling INTERFACE)
file(GLOB PULLING_SOURCES *.cpp)
set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${PULLING_SOURCES} PARENT_SCOPE)
+# Source files have the following dependencies on library infrastructure.
+#target_link_libraries(pulling PRIVATE
+# common
+# legacy_modules
+#)
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(pulling PUBLIC
+target_include_directories(pulling INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(pulling PUBLIC
+target_link_libraries(pulling INTERFACE
+ legacy_api
+ )
+
+# TODO: when pulling is an OBJECT target
+#target_link_libraries(pulling PUBLIC legacy_api)
+#target_link_libraries(pulling PRIVATE common)
+
+# Module dependencies
+# pulling interfaces convey transitive dependence on these modules.
+#target_link_libraries(pulling PUBLIC
+target_link_libraries(pulling INTERFACE
+ utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(pulling PRIVATE NOTHING)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(pulling PRIVATE legacy_modules)
+
if (BUILD_TESTING)
add_subdirectory(tests)
endif()
pcrdHistory = &pull->coordForceHistory->pullCoordinateSums[c];
numValuesInSum = pull->coordForceHistory->numValuesInXSum;
- pull_print_coord_dr(out, pull->params, pcrd.params, *pcrdHistory, pcrdHistory->valueRef,
- numValuesInSum);
+ pull_print_coord_dr(
+ out, pull->params, pcrd.params, *pcrdHistory, pcrdHistory->valueRef, numValuesInSum);
}
else
{
- pull_print_coord_dr(out, pull->params, pcrd.params, pcrd.spatialData, pcrd.value_ref,
- numValuesInSum);
+ pull_print_coord_dr(
+ out, pull->params, pcrd.params, pcrd.spatialData, pcrd.value_ref, numValuesInSum);
}
if (pull->params.bPrintCOM)
{
if (pull->bXOutAverage)
{
- fprintf(out, "\t%g",
+ fprintf(out,
+ "\t%g",
pull->coordForceHistory->pullGroupSums[pcrd.params.group[0]].x[m]
/ numValuesInSum);
}
{
if (pull->bXOutAverage)
{
- fprintf(out, "\t%g",
+ fprintf(out,
+ "\t%g",
pull->coordForceHistory->pullGroupSums[pcrd.params.group[g]].x[m]
/ numValuesInSum);
}
{
for (size_t c = 0; c < pull->coord.size(); c++)
{
- fprintf(out, "\t%g",
+ fprintf(out,
+ "\t%g",
pull->coordForceHistory->pullCoordinateSums[c].scalarForce
/ pull->coordForceHistory->numValuesInFSum);
}
* the group COMs for all the groups (+ ngroups_max*DIM)
* and the components of the distance vectors can be printed (+ (ngroups_max/2)*DIM).
*/
- snew(setname, pull->coord.size()
- * (1 + 1 + c_pullCoordNgroupMax * DIM + c_pullCoordNgroupMax / 2 * DIM));
+ snew(setname,
+ pull->coord.size() * (1 + 1 + c_pullCoordNgroupMax * DIM + c_pullCoordNgroupMax / 2 * DIM));
nsets = 0;
for (size_t c = 0; c < pull->coord.size(); c++)
#include <algorithm>
#include <memory>
+#include <mutex>
#include "gromacs/commandline/filenm.h"
#include "gromacs/domdec/domdec_struct.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/gmxassert.h"
-#include "gromacs/utility/mutex.h"
#include "gromacs/utility/pleasecite.h"
#include "gromacs/utility/real.h"
#include "gromacs/utility/smalloc.h"
if (pcrd.params.eGeom == epullgCYL)
{
- apply_forces_cyl_grp(&pull->dyna[coord], pcrd.spatialData.cyl_dev, masses, forces.force01,
- pcrd.scalarForce, -1, f, pull->nthreads);
+ apply_forces_cyl_grp(&pull->dyna[coord],
+ pcrd.spatialData.cyl_dev,
+ masses,
+ forces.force01,
+ pcrd.scalarForce,
+ -1,
+ f,
+ pull->nthreads);
/* Sum the force along the vector and the radial force */
dvec f_tot;
if (!pull->group[pcrd.params.group[0]].params.ind.empty())
{
- apply_forces_grp(&pull->group[pcrd.params.group[0]], masses, forces.force01, -1, f,
- pull->nthreads);
+ apply_forces_grp(
+ &pull->group[pcrd.params.group[0]], masses, forces.force01, -1, f, pull->nthreads);
}
apply_forces_grp(&pull->group[pcrd.params.group[1]], masses, forces.force01, 1, f, pull->nthreads);
if (pcrd.params.ngroup >= 4)
{
- apply_forces_grp(&pull->group[pcrd.params.group[2]], masses, forces.force23, -1, f,
- pull->nthreads);
- apply_forces_grp(&pull->group[pcrd.params.group[3]], masses, forces.force23, 1, f,
- pull->nthreads);
+ apply_forces_grp(
+ &pull->group[pcrd.params.group[2]], masses, forces.force23, -1, f, pull->nthreads);
+ apply_forces_grp(&pull->group[pcrd.params.group[3]], masses, forces.force23, 1, f, pull->nthreads);
}
if (pcrd.params.ngroup >= 6)
{
- apply_forces_grp(&pull->group[pcrd.params.group[4]], masses, forces.force45, -1, f,
- pull->nthreads);
- apply_forces_grp(&pull->group[pcrd.params.group[5]], masses, forces.force45, 1, f,
- pull->nthreads);
+ apply_forces_grp(
+ &pull->group[pcrd.params.group[4]], masses, forces.force45, -1, f, pull->nthreads);
+ apply_forces_grp(&pull->group[pcrd.params.group[5]], masses, forces.force45, 1, f, pull->nthreads);
}
}
}
gmx_fatal(FARGS,
"Distance between pull groups %d and %d (%f nm) is larger than 0.49 times the "
"box size (%f).\n%s",
- pcrd->params.group[groupIndex0], pcrd->params.group[groupIndex1], sqrt(dr2),
- sqrt(0.98 * 0.98 * max_dist2), pcrd->params.eGeom == epullgDIR ? "You might want to consider using \"pull-geometry = direction-periodic\" instead.\n" : "");
+ pcrd->params.group[groupIndex0],
+ pcrd->params.group[groupIndex1],
+ sqrt(dr2),
+ sqrt(0.98 * 0.98 * max_dist2),
+ pcrd->params.eGeom == epullgDIR
+ ? "You might want to consider using \"pull-geometry = "
+ "direction-periodic\" instead.\n"
+ : "");
}
if (pcrd->params.eGeom == epullgDIRPBC)
}
if (debug)
{
- fprintf(debug, "pull coord %d vector: %6.3f %6.3f %6.3f normalized: %6.3f %6.3f %6.3f\n",
- coord_ind, vec[XX], vec[YY], vec[ZZ], spatialData.vec[XX], spatialData.vec[YY],
+ fprintf(debug,
+ "pull coord %d vector: %6.3f %6.3f %6.3f normalized: %6.3f %6.3f %6.3f\n",
+ coord_ind,
+ vec[XX],
+ vec[YY],
+ vec[ZZ],
+ spatialData.vec[XX],
+ spatialData.vec[YY],
spatialData.vec[ZZ]);
}
}
pull_group_work_t* pgrp0 = &pull->group[pcrd->params.group[0]];
pull_group_work_t* pgrp1 = &pull->group[pcrd->params.group[1]];
- low_get_pull_coord_dr(pull, pcrd, pbc, pgrp1->x,
- pcrd->params.eGeom == epullgCYL ? pull->dyna[coord_ind].x : pgrp0->x, 0,
- 1, md2, spatialData.dr01);
+ low_get_pull_coord_dr(pull,
+ pcrd,
+ pbc,
+ pgrp1->x,
+ pcrd->params.eGeom == epullgCYL ? pull->dyna[coord_ind].x : pgrp0->x,
+ 0,
+ 1,
+ md2,
+ spatialData.dr01);
if (pcrd->params.ngroup >= 4)
{
{
gmx_fatal(FARGS,
"Pull reference distance for coordinate %d (%f) needs to be non-negative",
- coord_ind + 1, value_ref);
+ coord_ind + 1,
+ value_ref);
}
}
else if (pcrd->params.eGeom == epullgANGLE || pcrd->params.eGeom == epullgANGLEAXIS)
const PullCoordSpatialData& spatialData = pcrd->spatialData;
if (debug)
{
- fprintf(debug, "Pull coord %zu dr %f %f %f\n", c, spatialData.dr01[XX],
- spatialData.dr01[YY], spatialData.dr01[ZZ]);
+ fprintf(debug,
+ "Pull coord %zu dr %f %f %f\n",
+ c,
+ spatialData.dr01[XX],
+ spatialData.dr01[YY],
+ spatialData.dr01[ZZ]);
}
if (pcrd->params.eGeom == epullgDIR || pcrd->params.eGeom == epullgDIRPBC)
pgrp1 = &pull->group[pcrd->params.group[1]];
/* Get the current difference vector */
- low_get_pull_coord_dr(pull, pcrd, pbc, rnew[pcrd->params.group[1]],
- rnew[pcrd->params.group[0]], 0, 1, -1, unc_ij);
+ low_get_pull_coord_dr(
+ pull, pcrd, pbc, rnew[pcrd->params.group[1]], rnew[pcrd->params.group[0]], 0, 1, -1, unc_ij);
if (debug)
{
gmx_fatal(
FARGS,
"The pull constraint reference distance for group %zu is <= 0 (%f)",
- c, pcrd->value_ref);
+ c,
+ pcrd->value_ref);
}
{
if (debug)
{
- fprintf(debug, "Pull ax^2+bx+c=0: a=%e b=%e c=%e lambda=%e\n", c_a, c_b,
- c_c, lambda);
+ fprintf(debug, "Pull ax^2+bx+c=0: a=%e b=%e c=%e lambda=%e\n", c_a, c_b, c_c, lambda);
}
}
g1 = pcrd->params.group[1];
low_get_pull_coord_dr(pull, pcrd, pbc, rnew[g1], rnew[g0], 0, 1, -1, tmp);
low_get_pull_coord_dr(pull, pcrd, pbc, dr1, dr0, 0, 1, -1, tmp3);
- fprintf(debug, "Pull cur %8.5f %8.5f %8.5f j:%8.5f %8.5f %8.5f d: %8.5f\n", rnew[g0][0],
- rnew[g0][1], rnew[g0][2], rnew[g1][0], rnew[g1][1], rnew[g1][2], dnorm(tmp));
- fprintf(debug, "Pull ref %8s %8s %8s %8s %8s %8s d: %8.5f\n", "", "", "", "", "",
- "", pcrd->value_ref);
- fprintf(debug, "Pull cor %8.5f %8.5f %8.5f j:%8.5f %8.5f %8.5f d: %8.5f\n", dr0[0],
- dr0[1], dr0[2], dr1[0], dr1[1], dr1[2], dnorm(tmp3));
+ fprintf(debug,
+ "Pull cur %8.5f %8.5f %8.5f j:%8.5f %8.5f %8.5f d: %8.5f\n",
+ rnew[g0][0],
+ rnew[g0][1],
+ rnew[g0][2],
+ rnew[g1][0],
+ rnew[g1][1],
+ rnew[g1][2],
+ dnorm(tmp));
+ fprintf(debug,
+ "Pull ref %8s %8s %8s %8s %8s %8s d: %8.5f\n",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ pcrd->value_ref);
+ fprintf(debug,
+ "Pull cor %8.5f %8.5f %8.5f j:%8.5f %8.5f %8.5f d: %8.5f\n",
+ dr0[0],
+ dr0[1],
+ dr0[2],
+ dr1[0],
+ dr1[1],
+ dr1[2],
+ dnorm(tmp3));
} /* END DEBUG */
/* Update the COMs with dr */
continue;
}
- low_get_pull_coord_dr(pull, &coord, pbc, rnew[coord.params.group[1]],
- rnew[coord.params.group[0]], 0, 1, -1, unc_ij);
+ low_get_pull_coord_dr(
+ pull, &coord, pbc, rnew[coord.params.group[1]], rnew[coord.params.group[0]], 0, 1, -1, unc_ij);
switch (coord.params.eGeom)
{
"Pull constraint not converged: "
"groups %d %d,"
"d_ref = %f, current d = %f\n",
- coord.params.group[0], coord.params.group[1], coord.value_ref, dnorm(unc_ij));
+ coord.params.group[0],
+ coord.params.group[1],
+ coord.value_ref,
+ dnorm(unc_ij));
}
bConverged_all = FALSE;
dist_32 = sqrdist_32 * inv_dist_32;
/* Forces on groups 0, 1 */
- a_01 = pcrd.scalarForce * dist_32 / m2; /* scalarForce is -dV/dphi */
- dsvmul(-a_01, spatialData.planevec_m,
- forces.force01); /* added sign to get force on group 1, not 0 */
+ a_01 = pcrd.scalarForce * dist_32 / m2; /* scalarForce is -dV/dphi */
+ dsvmul(-a_01, spatialData.planevec_m, forces.force01); /* added sign to get force on group 1, not 0 */
/* Forces on groups 4, 5 */
a_45 = -pcrd.scalarForce * dist_32 / n2;
* We could use a different, local mutex for each pull object, but the overhead
* is extremely small here and registration is only done during initialization.
*/
-static gmx::Mutex registrationMutex;
+static std::mutex registrationMutex;
-using Lock = gmx::lock_guard<gmx::Mutex>;
+using Lock = std::lock_guard<std::mutex>;
void register_external_pull_potential(struct pull_t* pull, int coord_index, const char* provider)
{
gmx_fatal(FARGS,
"Module '%s' attempted to register an external potential for pull coordinate %d "
"which is out of the pull coordinate range %d - %zu\n",
- provider, coord_index + 1, 1, pull->coord.size());
+ provider,
+ coord_index + 1,
+ 1,
+ pull->coord.size());
}
pull_coord_work_t* pcrd = &pull->coord[coord_index];
FARGS,
"Module '%s' attempted to register an external potential for pull coordinate %d "
"which of type '%s', whereas external potentials are only supported with type '%s'",
- provider, coord_index + 1, epull_names[pcrd->params.eType], epull_names[epullEXTERNAL]);
+ provider,
+ coord_index + 1,
+ epull_names[pcrd->params.eType],
+ epull_names[epullEXTERNAL]);
}
GMX_RELEASE_ASSERT(!pcrd->params.externalPotentialProvider.empty(),
gmx_fatal(FARGS,
"Module '%s' attempted to register an external potential for pull coordinate %d "
"which expects the external potential to be provided by a module named '%s'",
- provider, coord_index + 1, pcrd->params.externalPotentialProvider.c_str());
+ provider,
+ coord_index + 1,
+ pcrd->params.externalPotentialProvider.c_str());
}
/* Lock to avoid (extremely unlikely) simultaneous reading and writing of
gmx_fatal(FARGS,
"Module '%s' attempted to register an external potential for pull coordinate %d "
"more than once",
- provider, coord_index + 1);
+ provider,
+ coord_index + 1);
}
pcrd->bExternalPotentialProviderHasBeenRegistered = true;
"No external provider for external pull potentials have been provided for %d "
"pull coordinates. The first coordinate without provider is number %zu, which "
"expects a module named '%s' to provide the external potential.",
- pull->numUnregisteredExternalPotentials, c + 1,
+ pull->numUnregisteredExternalPotentials,
+ c + 1,
pull->coord[c].params.externalPotentialProvider.c_str());
}
}
forceWithVirial->addVirialContribution(virial);
}
- apply_forces_coord(pull, coord_index, pullCoordForces, masses,
- as_rvec_array(forceWithVirial->force_.data()));
+ apply_forces_coord(
+ pull, coord_index, pullCoordForces, masses, as_rvec_array(forceWithVirial->force_.data()));
}
pull->numExternalPotentialsStillToBeAppliedThisStep--;
if (debug && dd != nullptr)
{
- fprintf(debug, "Our DD rank (%3d) pull #atoms>0 or master: %s, will be part %s\n", dd->rank,
- gmx::boolToString(bMustParticipate), gmx::boolToString(bWillParticipate));
+ fprintf(debug,
+ "Our DD rank (%3d) pull #atoms>0 or master: %s, will be part %s\n",
+ dd->rank,
+ gmx::boolToString(bMustParticipate),
+ gmx::boolToString(bWillParticipate));
}
if (bWillParticipate)
}
else
{
- gmx_fatal(FARGS, "The total%s mass of pull group %d is zero",
- !pg->params.weight.empty() ? " weighted" : "", g);
+ gmx_fatal(FARGS,
+ "The total%s mass of pull group %d is zero",
+ !pg->params.weight.empty() ? " weighted" : "",
+ g);
}
}
if (fplog)
for (int i = 0; i < pull_params->ngroup; ++i)
{
- pull->group.emplace_back(pull_params->group[i], atomSets->add(pull_params->group[i].ind),
+ pull->group.emplace_back(pull_params->group[i],
+ atomSets->add(pull_params->group[i].ind),
pull_params->bSetPbcRefToPrevStepCOM);
}
"%d in the input is larger than that supported by the code (up to %d). "
"You are probably reading a tpr file generated with a newer version of "
"Gromacs with an binary from an older version of Gromacs.",
- c + 1, pcrd->params.eGeom, epullgNR - 1);
+ c + 1,
+ pcrd->params.eGeom,
+ epullgNR - 1);
}
if (pcrd->params.eType == epullCONSTRAINT)
gmx_fatal(FARGS,
"Pulling of type %s can not be combined with geometry %s. Consider using "
"pull type %s.",
- epull_names[pcrd->params.eType], epullg_names[pcrd->params.eGeom],
+ epull_names[pcrd->params.eType],
+ epullg_names[pcrd->params.eGeom],
epull_names[epullUMBRELLA]);
}
if (pcrd->params.eType != epullEXTERNAL)
{
low_set_pull_coord_reference_value(
- pcrd, c,
- pcrd->params.init * pull_conversion_factor_userinput2internal(&pcrd->params));
+ pcrd, c, pcrd->params.init * pull_conversion_factor_userinput2internal(&pcrd->params));
}
else
{
int numRealGroups = pull->group.size() - 1;
GMX_RELEASE_ASSERT(numRealGroups > 0,
"The reference absolute position pull group should always be present");
- fprintf(fplog, "with %zu pull coordinate%s and %d group%s\n", pull->coord.size(),
- pull->coord.size() == 1 ? "" : "s", numRealGroups, numRealGroups == 1 ? "" : "s");
+ fprintf(fplog,
+ "with %zu pull coordinate%s and %d group%s\n",
+ pull->coord.size(),
+ pull->coord.size() == 1 ? "" : "s",
+ numRealGroups,
+ numRealGroups == 1 ? "" : "s");
if (bAbs)
{
fprintf(fplog, "with an absolute reference\n");
}
}
const auto& referenceGroup = pull->group[coord.params.group[0]];
- pull->dyna.emplace_back(referenceGroup.params, referenceGroup.atomSet,
- pull->params.bSetPbcRefToPrevStepCOM);
+ pull->dyna.emplace_back(
+ referenceGroup.params, referenceGroup.atomSet, pull->params.bSetPbcRefToPrevStepCOM);
}
}
{
/* Only the master rank has the checkpointed COM from the previous step */
gmx_bcast(sizeof(double) * state->pull_com_prev_step.size(),
- &state->pull_com_prev_step[0], cr->mpi_comm_mygroup);
+ &state->pull_com_prev_step[0],
+ cr->mpi_comm_mygroup);
}
setPrevStepPullComFromState(pull_work, state);
}
/* Activate output of forces for correctness checks */
/* #define PRINT_FORCES */
#ifdef PRINT_FORCES
-# define PRINT_FORCE_J \
- fprintf(stderr, "f%d = %15.8f %15.8f %15.8f\n", erg->xc_ref_ind[j], erg->f_rot_loc[j][XX], \
- erg->f_rot_loc[j][YY], erg->f_rot_loc[j][ZZ]);
+# define PRINT_FORCE_J \
+ fprintf(stderr, \
+ "f%d = %15.8f %15.8f %15.8f\n", \
+ erg->xc_ref_ind[j], \
+ erg->f_rot_loc[j][XX], \
+ erg->f_rot_loc[j][YY], \
+ erg->f_rot_loc[j][ZZ]);
# define PRINT_POT_TAU \
if (MASTER(cr)) \
{ \
fprintf(stderr, \
"potential = %15.8f\n" \
"torque = %15.8f\n", \
- erg->V, erg->torque_v); \
+ erg->V, \
+ erg->torque_v); \
}
#else
# define PRINT_FORCE_J
}
#if GMX_MPI
- MPI_Reduce(er->mpi_inbuf, er->mpi_outbuf, count, GMX_MPI_REAL, MPI_SUM, MASTERRANK(cr),
- cr->mpi_comm_mygroup);
+ MPI_Reduce(er->mpi_inbuf, er->mpi_outbuf, count, GMX_MPI_REAL, MPI_SUM, MASTERRANK(cr), cr->mpi_comm_mygroup);
#endif
/* Copy back the reduced data from the buffer on the master */
/* We can do the calculations ONLY if there is weight in the slab! */
if (erg->slab_weights[slabIndex] > WEIGHT_MIN)
{
- svmul(1.0 / erg->slab_weights[slabIndex], erg->slab_center[slabIndex],
- erg->slab_center[slabIndex]);
+ svmul(1.0 / erg->slab_weights[slabIndex], erg->slab_center[slabIndex], erg->slab_center[slabIndex]);
}
else
{
for (int j = erg->slab_first; j <= erg->slab_last; j++)
{
int slabIndex = j - erg->slab_first;
- fprintf(out_slabs, "%6d%12.3e%12.3e%12.3e", j, erg->slab_center[slabIndex][XX],
- erg->slab_center[slabIndex][YY], erg->slab_center[slabIndex][ZZ]);
+ fprintf(out_slabs,
+ "%6d%12.3e%12.3e%12.3e",
+ j,
+ erg->slab_center[slabIndex][XX],
+ erg->slab_center[slabIndex][YY],
+ erg->slab_center[slabIndex][ZZ]);
}
fprintf(out_slabs, "\n");
}
fp = gmx_ffopen(fn, "w");
- fprintf(fp, "# Output of %s is written in intervals of %d time step%s.\n#\n", what, steps,
- steps > 1 ? "s" : "");
+ fprintf(fp, "# Output of %s is written in intervals of %d time step%s.\n#\n", what, steps, steps > 1 ? "s" : "");
return fp;
}
gmx_enfrotgrp* erg = &ergRef;
if (ISFLEX(erg->rotg))
{
- fprintf(fp, "# Rotation group %d (%s), slab distance %f nm, %s.\n", erg->groupIndex,
- erotg_names[erg->rotg->eType], erg->rotg->slab_dist,
+ fprintf(fp,
+ "# Rotation group %d (%s), slab distance %f nm, %s.\n",
+ erg->groupIndex,
+ erotg_names[erg->rotg->eType],
+ erg->rotg->slab_dist,
erg->rotg->bMassW ? "centers of mass" : "geometrical centers");
}
}
}
else
{
- fp = xvgropen(fn, "Rotation angles and energy", "Time (ps)",
- "angles (degrees) and energies (kJ/mol)", oenv);
+ fp = xvgropen(fn,
+ "Rotation angles and energy",
+ "Time (ps)",
+ "angles (degrees) and energies (kJ/mol)",
+ oenv);
fprintf(fp,
"# Output of enforced rotation data is written in intervals of %d time "
"step%s.\n#\n",
- er->nstrout, er->nstrout > 1 ? "s" : "");
+ er->nstrout,
+ er->nstrout > 1 ? "s" : "");
fprintf(fp,
"# The scalar tau is the torque (kJ/mol) in the direction of the rotation vector "
"v.\n");
fprintf(fp, "#\n");
fprintf(fp, "# ROTATION GROUP %d, potential type '%s':\n", g, erotg_names[rotg->eType]);
fprintf(fp, "# rot-massw%d %s\n", g, yesno_names[rotg->bMassW]);
- fprintf(fp, "# rot-vec%d %12.5e %12.5e %12.5e\n", g, erg->vec[XX],
- erg->vec[YY], erg->vec[ZZ]);
+ fprintf(fp,
+ "# rot-vec%d %12.5e %12.5e %12.5e\n",
+ g,
+ erg->vec[XX],
+ erg->vec[YY],
+ erg->vec[ZZ]);
fprintf(fp, "# rot-rate%d %12.5e degrees/ps\n", g, rotg->rate);
fprintf(fp, "# rot-k%d %12.5e kJ/(mol*nm^2)\n", g, rotg->k);
if (rotg->eType == erotgISO || rotg->eType == erotgPM || rotg->eType == erotgRM
|| rotg->eType == erotgRM2)
{
- fprintf(fp, "# rot-pivot%d %12.5e %12.5e %12.5e nm\n", g, rotg->pivot[XX],
- rotg->pivot[YY], rotg->pivot[ZZ]);
+ fprintf(fp,
+ "# rot-pivot%d %12.5e %12.5e %12.5e nm\n",
+ g,
+ rotg->pivot[XX],
+ rotg->pivot[YY],
+ rotg->pivot[ZZ]);
}
if (bFlex)
if ((rotg->eType == erotgISOPF) || (rotg->eType == erotgPMPF) || (rotg->eType == erotgRMPF)
|| (rotg->eType == erotgRM2PF || (rotg->eType == erotgFLEXT) || (rotg->eType == erotgFLEX2T)))
{
- fprintf(fp, "# ref. grp. %d center %12.5e %12.5e %12.5e\n", g,
- erg->xc_ref_center[XX], erg->xc_ref_center[YY], erg->xc_ref_center[ZZ]);
+ fprintf(fp,
+ "# ref. grp. %d center %12.5e %12.5e %12.5e\n",
+ g,
+ erg->xc_ref_center[XX],
+ erg->xc_ref_center[YY],
+ erg->xc_ref_center[ZZ]);
- fprintf(fp, "# grp. %d init.center %12.5e %12.5e %12.5e\n", g, erg->xc_center[XX],
- erg->xc_center[YY], erg->xc_center[ZZ]);
+ fprintf(fp,
+ "# grp. %d init.center %12.5e %12.5e %12.5e\n",
+ g,
+ erg->xc_center[XX],
+ erg->xc_center[YY],
+ erg->xc_center[ZZ]);
}
if ((rotg->eType == erotgRM2) || (rotg->eType == erotgFLEX2) || (rotg->eType == erotgFLEX2T))
fprintf(fp,
"# theta_fit%d is determined by first evaluating the potential for %d "
"angles around theta_ref%d.\n",
- g, rotg->PotAngle_nstep, g);
+ g,
+ rotg->PotAngle_nstep,
+ g);
fprintf(fp,
"# The fit angle is the one with the smallest potential. It is given as "
"the deviation\n");
buf[0] = '\0';
}
- fprintf(fp, "#\n# ROTATION GROUP %d '%s',%s fit type '%s'.\n", g,
- erotg_names[rotg->eType], buf, erotg_fitnames[rotg->eFittype]);
+ fprintf(fp,
+ "#\n# ROTATION GROUP %d '%s',%s fit type '%s'.\n",
+ g,
+ erotg_names[rotg->eType],
+ buf,
+ erotg_fitnames[rotg->eFittype]);
/* Special type of fitting using the potential minimum. This is
* done for the whole group only, not for the individual slabs. */
fprintf(fp,
"# To obtain theta_fit%d, the potential is evaluated for %d angles "
"around theta_ref%d\n",
- g, rotg->PotAngle_nstep, g);
+ g,
+ rotg->PotAngle_nstep,
+ g);
fprintf(fp,
"# The fit angle in the rotation standard outfile is the one with "
"minimal energy E(theta_fit) [kJ/mol].\n");
const gmx_enfrotgrp* erg = &er->enfrotgrp[g];
if (ISFLEX(rotg))
{
- fprintf(fp, "# Rotation group %d (%s), slab distance %f nm.\n", g,
- erotg_names[rotg->eType], rotg->slab_dist);
+ fprintf(fp,
+ "# Rotation group %d (%s), slab distance %f nm.\n",
+ g,
+ erotg_names[rotg->eType],
+ rotg->slab_dist);
fprintf(fp,
"# The scalar tau is the torque (kJ/mol) in the direction of the rotation "
"vector.\n");
fprintf(fp, "# To obtain the vectorial torque, multiply tau with\n");
- fprintf(fp, "# rot-vec%d %10.3e %10.3e %10.3e\n", g, erg->vec[XX],
- erg->vec[YY], erg->vec[ZZ]);
+ fprintf(fp,
+ "# rot-vec%d %10.3e %10.3e %10.3e\n",
+ g,
+ erg->vec[XX],
+ erg->vec[YY],
+ erg->vec[ZZ]);
fprintf(fp, "#\n");
}
}
/* From the point of view of the current positions, the reference has rotated
* backwards. Since we output the angle relative to the fixed reference,
* we need the minus sign. */
- fitangle = -opt_angle_analytic(erg->xc_ref_sorted, fitcoords, erg->mc_sorted, erg->rotg->nat,
- erg->xc_ref_center, center, erg->vec);
+ fitangle = -opt_angle_analytic(
+ erg->xc_ref_sorted, fitcoords, erg->mc_sorted, erg->rotg->nat, erg->xc_ref_center, center, erg->vec);
return fitangle;
}
clear_rvec(ref_center);
clear_rvec(act_center);
}
- fitangle = -opt_angle_analytic(sd->ref, sd->x, sd->weight, sd->nat, ref_center,
- act_center, erg->vec);
+ fitangle = -opt_angle_analytic(
+ sd->ref, sd->x, sd->weight, sd->nat, ref_center, act_center, erg->vec);
fprintf(fp, "%6d%6d%12.3f", n, sd->nat, fitangle);
}
}
}
#ifdef SUM_PARTS
- fprintf(stderr, "sum1: %15.8f %15.8f %15.8f\n", -erg->rotg->k * sum1vec[XX],
- -erg->rotg->k * sum1vec[YY], -erg->rotg->k * sum1vec[ZZ]);
- fprintf(stderr, "sum2: %15.8f %15.8f %15.8f\n", erg->rotg->k * sum2vec[XX],
- erg->rotg->k * sum2vec[YY], erg->rotg->k * sum2vec[ZZ]);
- fprintf(stderr, "sum3: %15.8f %15.8f %15.8f\n", -erg->rotg->k * sum3vec[XX],
- -erg->rotg->k * sum3vec[YY], -erg->rotg->k * sum3vec[ZZ]);
- fprintf(stderr, "sum4: %15.8f %15.8f %15.8f\n", 0.5 * erg->rotg->k * sum4vec[XX],
- 0.5 * erg->rotg->k * sum4vec[YY], 0.5 * erg->rotg->k * sum4vec[ZZ]);
+ fprintf(stderr,
+ "sum1: %15.8f %15.8f %15.8f\n",
+ -erg->rotg->k * sum1vec[XX],
+ -erg->rotg->k * sum1vec[YY],
+ -erg->rotg->k * sum1vec[ZZ]);
+ fprintf(stderr,
+ "sum2: %15.8f %15.8f %15.8f\n",
+ erg->rotg->k * sum2vec[XX],
+ erg->rotg->k * sum2vec[YY],
+ erg->rotg->k * sum2vec[ZZ]);
+ fprintf(stderr,
+ "sum3: %15.8f %15.8f %15.8f\n",
+ -erg->rotg->k * sum3vec[XX],
+ -erg->rotg->k * sum3vec[YY],
+ -erg->rotg->k * sum3vec[ZZ]);
+ fprintf(stderr,
+ "sum4: %15.8f %15.8f %15.8f\n",
+ 0.5 * erg->rotg->k * sum4vec[XX],
+ 0.5 * erg->rotg->k * sum4vec[YY],
+ 0.5 * erg->rotg->k * sum4vec[ZZ]);
#endif
PRINT_FORCE_J
/* Check whether we have reference data to compare against */
if (erg->slab_first < erg->slab_first_ref)
{
- gmx_fatal(FARGS, "%s No reference data for first slab (n=%d), unable to proceed.", RotStr,
- erg->slab_first);
+ gmx_fatal(FARGS, "%s No reference data for first slab (n=%d), unable to proceed.", RotStr, erg->slab_first);
}
/* Check whether we have reference data to compare against */
if (erg->slab_last > erg->slab_last_ref)
{
- gmx_fatal(FARGS, "%s No reference data for last slab (n=%d), unable to proceed.", RotStr,
- erg->slab_last);
+ gmx_fatal(FARGS, "%s No reference data for last slab (n=%d), unable to proceed.", RotStr, erg->slab_last);
}
}
/* Rotate with the alternative angle. Like rotate_local_reference(),
* just for a single local atom */
- mvmul(erg->PotAngleFit->rotmat[ifit], erg->rotg->x_ref[jj],
- fit_xr_loc); /* fit_xr_loc = Omega*(y_i-y_c) */
+ mvmul(erg->PotAngleFit->rotmat[ifit], erg->rotg->x_ref[jj], fit_xr_loc); /* fit_xr_loc = Omega*(y_i-y_c) */
/* Calculate Omega*(y_i-y_c)-(x_i-x_c) */
rvec_sub(fit_xr_loc, xi_xc, dr);
/* Rotate with the alternative angle. Like rotate_local_reference(),
* just for a single local atom */
- mvmul(erg->PotAngleFit->rotmat[ifit], erg->rotg->x_ref[jj],
- fit_tmpvec); /* fit_tmpvec = Omega*(yj0-u) */
+ mvmul(erg->PotAngleFit->rotmat[ifit], erg->rotg->x_ref[jj], fit_tmpvec); /* fit_tmpvec = Omega*(yj0-u) */
/* Calculate Omega.(yj0-u) */
cprod(erg->vec, fit_tmpvec, tmpvec); /* tmpvec = v x Omega.(yj0-u) */
int iigrp = collectiveRotationGroupIndex[j];
/* Rotate with the alternative angle. Like rotate_local_reference(),
* just for a single local atom */
- mvmul(erg->PotAngleFit->rotmat[ifit], erg->rotg->x_ref[iigrp],
- fit_rj); /* fit_rj = Omega*(yj0-u) */
+ mvmul(erg->PotAngleFit->rotmat[ifit], erg->rotg->x_ref[iigrp], fit_rj); /* fit_rj = Omega*(yj0-u) */
}
fit_fac = iprod(v_xj_u, fit_rj); /* fac = (v x (xj-u)).fit_rj */
/* Add to the rotation potential for this angle: */
if ((nullptr != fplog) && bVerbose)
{
- fprintf(fplog, "%s allocating memory to store data for %d slabs (rotation group %d).\n",
- RotStr, nslabs, erg->groupIndex);
+ fprintf(fplog,
+ "%s allocating memory to store data for %d slabs (rotation group %d).\n",
+ RotStr,
+ nslabs,
+ erg->groupIndex);
}
snew(erg->slab_center, nslabs);
snew(erg->slab_center_ref, nslabs);
{
nat_max = std::max(nat_max, erg->rotg->nat);
- init_rot_group(fplog, cr, erg, x_pbc, mtop, mdrunOptions.verbose, er->out_slabs,
- MASTER(cr) ? globalState->box : nullptr, ir,
+ init_rot_group(fplog,
+ cr,
+ erg,
+ x_pbc,
+ mtop,
+ mdrunOptions.verbose,
+ er->out_slabs,
+ MASTER(cr) ? globalState->box : nullptr,
+ ir,
!er->restartWithAppending); /* Do not output the reference centers
* again if we are appending */
}
/* Transfer the rotation group's positions such that every node has
* all of them. Every node contributes its local positions x and stores
* it in the collective erg->xc array. */
- communicate_group_positions(cr, erg->xc, erg->xc_shifts, erg->xc_eshifts, bNS, x,
- rotg->nat, erg->atomSet->numAtomsLocal(),
+ communicate_group_positions(cr,
+ erg->xc,
+ erg->xc_shifts,
+ erg->xc_eshifts,
+ bNS,
+ x,
+ rotg->nat,
+ erg->atomSet->numAtomsLocal(),
erg->atomSet->localIndex().data(),
- erg->atomSet->collectiveIndex().data(), erg->xc_old, box);
+ erg->atomSet->collectiveIndex().data(),
+ erg->xc_old,
+ box);
}
else
{
/* Get the center of the rotation group */
if ((rotg->eType == erotgISOPF) || (rotg->eType == erotgPMPF))
{
- get_center_comm(cr, erg->x_loc_pbc, erg->m_loc, erg->atomSet->numAtomsLocal(),
- rotg->nat, erg->xc_center);
+ get_center_comm(
+ cr, erg->x_loc_pbc, erg->m_loc, erg->atomSet->numAtomsLocal(), rotg->nat, erg->xc_center);
}
}
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2008, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/math/vectypes.h"
#include "gromacs/utility/basedefinitions.h"
-#include "gromacs/utility/classhelpers.h"
struct gmx_domdec_t;
struct gmx_enfrot;
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
{
/* Separate branch because gmx_sum uses cr->mpi_comm_mygroup */
#if GMX_MPI
-# if MPI_IN_PLACE_EXISTS
MPI_Allreduce(MPI_IN_PLACE, data, n, mpiDatatype(data), MPI_SUM, comm->mpi_comm_com);
-# else
- std::vector<T> buf(n);
-
- MPI_Allreduce(data, buf.data(), n, mpiDatatype(data), MPI_SUM, comm->mpi_comm_com);
-
- /* Copy the result from the buffer to the input/output data */
- for (int i = 0; i < n; i++)
- {
- data[i] = buf[i];
- }
-# endif
#else
gmx_incons("comm->bParticipateAll=FALSE without GMX_MPI");
#endif
if (debug)
{
- fprintf(debug, "Pull cylinder group %zu:%8.3f%8.3f%8.3f m:%8.3f\n", c, pdyna->x[0],
- pdyna->x[1], pdyna->x[2], 1.0 / pdyna->invtm);
- fprintf(debug, "ffrad %8.3f %8.3f %8.3f\n", spatialData.ffrad[XX],
- spatialData.ffrad[YY], spatialData.ffrad[ZZ]);
+ fprintf(debug,
+ "Pull cylinder group %zu:%8.3f%8.3f%8.3f m:%8.3f\n",
+ c,
+ pdyna->x[0],
+ pdyna->x[1],
+ pdyna->x[2],
+ 1.0 / pdyna->invtm);
+ fprintf(debug,
+ "ffrad %8.3f %8.3f %8.3f\n",
+ spatialData.ffrad[XX],
+ spatialData.ffrad[YY],
+ spatialData.ffrad[ZZ]);
}
}
}
}
/* calculates center of mass of selection index from all coordinates x */
-// Compiler segfault with 2019_update_5 and 2020_initial
-#if defined(__INTEL_COMPILER) \
- && ((__INTEL_COMPILER == 1900 && __INTEL_COMPILER_UPDATE >= 5) || __INTEL_COMPILER >= 1910)
-# pragma intel optimization_level 2
-#endif
void pull_calc_coms(const t_commrec* cr, pull_t* pull, const real* masses, t_pbc* pbc, double t, const rvec x[], rvec* xp)
{
real twopi_box = 0;
}
else if (pgrp->atomSet.numAtomsLocal() <= c_pullMaxNumLocalAtomsSingleThreaded)
{
- sum_com_part(pgrp, 0, pgrp->atomSet.numAtomsLocal(), x, xp, masses, pbc, x_pbc,
- &comSumsTotal);
+ sum_com_part(pgrp, 0, pgrp->atomSet.numAtomsLocal(), x, xp, masses, pbc, x_pbc, &comSumsTotal);
}
else
{
{
int ind_start = (pgrp->atomSet.numAtomsLocal() * (t + 0)) / pull->nthreads;
int ind_end = (pgrp->atomSet.numAtomsLocal() * (t + 1)) / pull->nthreads;
- sum_com_part(pgrp, ind_start, ind_end, x, xp, masses, pbc, x_pbc,
- &pull->comSums[t]);
+ sum_com_part(
+ pgrp, ind_start, ind_end, x, xp, masses, pbc, x_pbc, &pull->comSums[t]);
}
/* Reduce the thread contributions to sum_com[0] */
{
int ind_start = (pgrp->atomSet.numAtomsLocal() * (t + 0)) / pull->nthreads;
int ind_end = (pgrp->atomSet.numAtomsLocal() * (t + 1)) / pull->nthreads;
- sum_com_part_cosweight(pgrp, ind_start, ind_end, pull->cosdim, twopi_box, x, xp,
- masses, &pull->comSums[t]);
+ sum_com_part_cosweight(
+ pgrp, ind_start, ind_end, pull->cosdim, twopi_box, x, xp, masses, &pull->comSums[t]);
}
/* Reduce the thread contributions to comSums[0] */
}
}
- pullAllReduce(cr, comm, pull->group.size() * c_comBufferStride * DIM,
+ pullAllReduce(cr,
+ comm,
+ pull->group.size() * c_comBufferStride * DIM,
static_cast<double*>(comm->comBuffer[0]));
for (size_t g = 0; g < pull->group.size(); g++)
}
}
- return (pullGroupObeysPbcRestrictions(group, dimUsed, as_rvec_array(x.data()), pbc,
- pull.comm.pbcAtomBuffer[groupNr], pbcMargin));
+ return (pullGroupObeysPbcRestrictions(
+ group, dimUsed, as_rvec_array(x.data()), pbc, pull.comm.pbcAtomBuffer[groupNr], pbcMargin));
}
void setPrevStepPullComFromState(struct pull_t* pull, const t_state* state)
if (pgrp->atomSet.numAtomsLocal() <= c_pullMaxNumLocalAtomsSingleThreaded)
{
- sum_com_part(pgrp, 0, pgrp->atomSet.numAtomsLocal(), x, nullptr, masses, pbc, x_pbc,
- &comSumsTotal);
+ sum_com_part(pgrp, 0, pgrp->atomSet.numAtomsLocal(), x, nullptr, masses, pbc, x_pbc, &comSumsTotal);
}
else
{
{
int ind_start = (pgrp->atomSet.numAtomsLocal() * (t + 0)) / pull->nthreads;
int ind_end = (pgrp->atomSet.numAtomsLocal() * (t + 1)) / pull->nthreads;
- sum_com_part(pgrp, ind_start, ind_end, x, nullptr, masses, pbc, x_pbc,
- &pull->comSums[t]);
+ sum_com_part(
+ pgrp, ind_start, ind_end, x, nullptr, masses, pbc, x_pbc, &pull->comSums[t]);
}
/* Reduce the thread contributions to sum_com[0] */
}
if (debug)
{
- fprintf(debug, "Pull group %zu wmass %f invtm %f\n", g, 1.0 / pgrp->mwscale,
- pgrp->invtm);
+ fprintf(debug, "Pull group %zu wmass %f invtm %f\n", g, 1.0 / pgrp->mwscale, pgrp->invtm);
fprintf(debug, "Initialising prev step COM of pull group %zu to", g);
for (int m = 0; m < DIM; m++)
{
{
minBoxSize2 = std::min(minBoxSize2, norm2(box[d]));
}
- EXPECT_REAL_EQ_TOL(0.25 * minBoxSize2, max_pull_distance2(&pcrd, &pbc),
- defaultRealTolerance());
+ EXPECT_REAL_EQ_TOL(
+ 0.25 * minBoxSize2, max_pull_distance2(&pcrd, &pbc), defaultRealTolerance());
}
{
params.dim[ZZ] = 1;
pull_coord_work_t pcrd(params);
clear_dvec(pcrd.spatialData.vec);
- EXPECT_REAL_EQ_TOL(0.25 * boxSizeZSquared, max_pull_distance2(&pcrd, &pbc),
- defaultRealTolerance());
+ EXPECT_REAL_EQ_TOL(
+ 0.25 * boxSizeZSquared, max_pull_distance2(&pcrd, &pbc), defaultRealTolerance());
}
{
pull_coord_work_t pcrd(params);
clear_dvec(pcrd.spatialData.vec);
pcrd.spatialData.vec[ZZ] = 1;
- EXPECT_REAL_EQ_TOL(0.25 * boxSizeZSquared, max_pull_distance2(&pcrd, &pbc),
- defaultRealTolerance());
+ EXPECT_REAL_EQ_TOL(
+ 0.25 * boxSizeZSquared, max_pull_distance2(&pcrd, &pbc), defaultRealTolerance());
}
{
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2015,2016,2019, by the GROMACS development team, led by
+# Copyright (c) 2015,2016,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.
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+# Set up the module library
+add_library(random INTERFACE)
file(GLOB RANDOM_SOURCES *.cpp)
set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${RANDOM_SOURCES} PARENT_SCOPE)
+# Source files have the following dependencies on library infrastructure.
+#target_link_libraries(random PRIVATE
+# common
+# legacy_modules
+#)
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(random PUBLIC
+target_include_directories(random INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(random PUBLIC
+target_link_libraries(random INTERFACE
+ legacy_api
+ )
+
+# TODO: when random is an OBJECT target
+#target_link_libraries(random PUBLIC legacy_api)
+#target_link_libraries(random PRIVATE common)
+
+# Module dependencies
+# random interfaces convey transitive dependence on these modules.
+#target_link_libraries(random PUBLIC
+target_link_libraries(random INTERFACE
+ utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(random PRIVATE NOTHING)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(random PRIVATE legacy_modules)
+
if (BUILD_TESTING)
add_subdirectory(tests)
endif()
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2016,2019, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,2019,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <cmath>
#include <limits>
+#include <memory>
#include "gromacs/random/uniformrealdistribution.h"
#include "gromacs/utility/classhelpers.h"
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2016,2019, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,2019,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <cmath>
#include <limits>
+#include <memory>
#include "gromacs/random/exponentialdistribution.h"
#include "gromacs/random/uniformrealdistribution.h"
/*! \brief Gamma distribution
*
* The C++ standard library does provide a gamma distribution, but when
- * using libstdc++-4.4.7 with at least gcc-4.6 or icc-14.0 the headers
+ * using libstdc++-4.4.7 with at least gcc-4.6 the headers
* produce errors. Even for newer compilers, libstdc++ and libc++ appear to
* use different algorithms to generate it, which means their values differ
* in contrast to the uniform and normal distributions where they are
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2016,2019, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,2019,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <cmath>
#include <limits>
+#include <memory>
#include "gromacs/random/uniformrealdistribution.h"
#include "gromacs/utility/classhelpers.h"
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2016,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,2018,2019,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <array>
#include <limits>
+#include <memory>
#include "gromacs/math/functions.h"
#include "gromacs/math/utilities.h"
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2016,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2015,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.
* The 2x64 flavors of ThreeFry64 will use the first four values, while
* the 4x64 version uses all eight.
*/
-const std::vector<uint64_t> bitsOne{ { 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
- 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL } };
+const std::vector<uint64_t> bitsOne{
+ { 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL }
+};
/*! \brief Constant array of integers with bitpattern from Pi.
*
* The 2x64 flavors of ThreeFry64 will use the first four values, while
* the 4x64 version uses all eight.
*/
-const std::vector<uint64_t> bitsPi{ { 0x243f6a8885a308d3ULL, 0x13198a2e03707344ULL,
- 0xa4093822299f31d0ULL, 0x082efa98ec4e6c89ULL } };
+const std::vector<uint64_t> bitsPi{
+ { 0x243f6a8885a308d3ULL, 0x13198a2e03707344ULL, 0xa4093822299f31d0ULL, 0x082efa98ec4e6c89ULL }
+};
// Test the known ansers for the ThreeFry random function when the argument
// is (1) all zero, (2) all ones, (3) the bits of pi, for a bunch of different flavors of ThreeFry.
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2016,2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,2017,2018,2019,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <array>
#include <limits>
+#include <memory>
#include "gromacs/math/functions.h"
#include "gromacs/random/seed.h"
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2016,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,2018,2019,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#define GMX_RANDOM_UNIFORMINTDISTRIBUTION_H
#include <limits>
+#include <memory>
#include "gromacs/math/functions.h"
#include "gromacs/utility/basedefinitions.h"
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2016,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <algorithm>
#include <limits>
+#include <memory>
#include <type_traits>
#include "gromacs/math/functions.h"
+
#include "gromacs/utility/basedefinitions.h"
#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/gmxassert.h"
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2017,2018,2019, by the GROMACS development team, led by
+# Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
# and including many others, as listed in the AUTHORS file in the
# top-level source directory and at http://www.gromacs.org.
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+# Set up the module library
+add_library(restraint INTERFACE)
+file(GLOB RESTRAINT_SOURCES *.cpp)
+set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${RESTRAINT_SOURCES} PARENT_SCOPE)
-gmx_add_libgromacs_sources(
- manager.cpp
- restraintmdmodule.cpp
- )
-# TODO this is a hacky way to expose things for the API and needs to be changed to something proper
-install(FILES restraintpotential.h DESTINATION include/gromacs/restraint)
+# Source files have the following dependencies on library infrastructure.
+#target_link_libraries(restraint PRIVATE
+# common
+# legacy_modules
+#)
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(restraint PUBLIC
+target_include_directories(restraint INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(restraint PUBLIC
+target_link_libraries(restraint INTERFACE
+ legacy_api
+ )
+
+# TODO: when restraint is an OBJECT target
+#target_link_libraries(restraint PUBLIC legacy_api)
+#target_link_libraries(restraint PRIVATE common)
+
+# Module dependencies
+# restraint interfaces convey transitive dependence on these modules.
+#target_link_libraries(restraint PUBLIC
+target_link_libraries(restraint INTERFACE
+ utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(restraint PRIVATE NOTHING)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(restraint PRIVATE legacy_modules)
if (BUILD_TESTING)
add_subdirectory(tests)
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+# Set up the module library
+add_library(selection INTERFACE)
+
file(GLOB SELECTION_SOURCES *.cpp)
file(GLOB SCANNER_SOURCES scanner.cpp parser.cpp)
list(REMOVE_ITEM SELECTION_SOURCES ${SCANNER_SOURCES})
gmx_target_warning_suppression(scanner -Wno-missing-declarations HAS_NO_MISSING_DECLARATIONS)
gmx_target_warning_suppression(scanner -Wno-null-conversion HAS_NO_NULL_CONVERSIONS)
endif()
+target_link_libraries(scanner PRIVATE legacy_api)
+# TODO: Use explicit module dependencies.
+target_link_libraries(scanner PRIVATE legacy_modules)
+
list(APPEND libgromacs_object_library_dependencies scanner)
set(libgromacs_object_library_dependencies ${libgromacs_object_library_dependencies} PARENT_SCOPE)
+# Source files have the following dependencies on library infrastructure.
+#target_link_libraries(selection PRIVATE
+# common
+# legacy_modules
+#)
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(selection PUBLIC
+target_include_directories(selection INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(selection PUBLIC
+target_link_libraries(selection INTERFACE
+ legacy_api
+ )
+
+# TODO: when selection is an OBJECT target
+#target_link_libraries(selection PUBLIC legacy_api)
+#target_link_libraries(selection PRIVATE common)
+
+# Module dependencies
+# selection interfaces convey transitive dependence on these modules.
+#target_link_libraries(selection PUBLIC
+target_link_libraries(selection INTERFACE
+ utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(selection PRIVATE NOTHING)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(selection PRIVATE legacy_modules)
+
if(GMX_INSTALL_LEGACY_API)
install(FILES
indexutil.h
if (sel->u.expr.method->init && (bAtomVal || !(sel->flags & SEL_METHODINIT)))
{
sel->flags |= SEL_METHODINIT;
- sel->u.expr.method->init(top, sel->u.expr.method->nparams, sel->u.expr.method->param,
- sel->u.expr.mdata);
+ sel->u.expr.method->init(
+ top, sel->u.expr.method->nparams, sel->u.expr.method->param, sel->u.expr.mdata);
}
if (bAtomVal || !(sel->flags & SEL_OUTINIT))
{
for (i = 0; i < sc->sel.size(); ++i)
{
gmx::internal::SelectionData& sel = *sc->sel[i];
- init_pos_keyword_defaults(&sel.rootElement(), coll->impl_->spost_.c_str(),
- coll->impl_->rpost_.c_str(), &sel);
+ init_pos_keyword_defaults(
+ &sel.rootElement(), coll->impl_->spost_.c_str(), coll->impl_->rpost_.c_str(), &sel);
}
/* Remove any unused variables. */
expandValueForPositions(sel->v.u.r, &sel->v.nr, sel->u.expr.pos);
break;
default:
- GMX_RELEASE_ASSERT(false,
- "Unimplemented value type for position update method");
+ GMX_RELEASE_ASSERT(false, "Unimplemented value type for position update method");
}
}
}
bool IndexGroupsAndNames::containsGroupName(const std::string& groupName) const
{
- return std::any_of(
- std::begin(groupNames_), std::end(groupNames_),
- [&groupName](const std::string& name) { return equalCaseInsensitive(groupName, name); });
+ return std::any_of(std::begin(groupNames_), std::end(groupNames_), [&groupName](const std::string& name) {
+ return equalCaseInsensitive(groupName, name);
+ });
}
std::vector<index> IndexGroupsAndNames::indices(const std::string& groupName) const
"of grompp."));
}
const auto groupNamePosition = std::find_if(
- std::begin(groupNames_), std::end(groupNames_),
- [&groupName](const std::string& name) { return equalCaseInsensitive(groupName, name); });
+ std::begin(groupNames_), std::end(groupNames_), [&groupName](const std::string& name) {
+ return equalCaseInsensitive(groupName, name);
+ });
const auto groupIndex = std::distance(std::begin(groupNames_), groupNamePosition);
const auto groupSize = indexGroup_.index[groupIndex + 1] - indexGroup_.index[groupIndex];
std::vector<index> groupIndices(groupSize);
const auto startingIndex = indexGroup_.index[groupIndex];
std::iota(std::begin(groupIndices), std::end(groupIndices), startingIndex);
- std::transform(std::begin(groupIndices), std::end(groupIndices), std::begin(groupIndices),
+ std::transform(std::begin(groupIndices),
+ std::end(groupIndices),
+ std::begin(groupIndices),
[blockLookup = indexGroup_.a](auto i) { return blockLookup[i]; });
return groupIndices;
}
*
* Copyright (c) 2009,2010,2011,2012,2013 by the GROMACS development team.
* Copyright (c) 2014,2015,2016,2017,2018 by the GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <cstring>
#include <algorithm>
+#include <mutex>
#include <vector>
#include "gromacs/math/functions.h"
#include "gromacs/math/vec.h"
#include "gromacs/pbcutil/pbc.h"
#include "gromacs/utility/arrayref.h"
+#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/listoflists.h"
-#include "gromacs/utility/mutex.h"
#include "gromacs/utility/stringutil.h"
#include "position.h"
//! Data structure to hold the grid cell contents.
CellList cells_;
- Mutex createPairSearchMutex_;
+ std::mutex createPairSearchMutex_;
PairSearchList pairSearchList_;
friend class AnalysisNeighborhoodPairSearchImpl;
AnalysisNeighborhoodSearchImpl::PairSearchImplPointer AnalysisNeighborhoodSearchImpl::getPairSearch()
{
- lock_guard<Mutex> lock(createPairSearchMutex_);
+ std::lock_guard<std::mutex> lock(createPairSearchMutex_);
// TODO: Consider whether this needs to/can be faster, e.g., by keeping a
// separate pool of unused search objects.
PairSearchList::const_iterator i;
}
else if (bTryGrid_)
{
- bGrid_ = initGrid(pbc_, positions.count_, positions.x_,
- mode == AnalysisNeighborhood::eSearchMode_Grid);
+ bGrid_ = initGrid(
+ pbc_, positions.count_, positions.x_, mode == AnalysisNeighborhood::eSearchMode_Grid);
}
refIndices_ = positions.indices_;
if (bGrid_)
SearchImplPointer getSearch();
- Mutex createSearchMutex_;
+ std::mutex createSearchMutex_;
SearchList searchList_;
real cutoff_;
const ListOfLists<int>* excls_;
AnalysisNeighborhood::Impl::SearchImplPointer AnalysisNeighborhood::Impl::getSearch()
{
- lock_guard<Mutex> lock(createSearchMutex_);
+ std::lock_guard<std::mutex> lock(createSearchMutex_);
// TODO: Consider whether this needs to/can be faster, e.g., by keeping a
// separate pool of unused search objects.
SearchList::const_iterator i;
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2009-2018, The GROMACS development team.
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 2019,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/math/vec.h"
#include "gromacs/math/vectypes.h"
#include "gromacs/utility/arrayref.h"
-#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/real.h"
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
/*! \brief
/* Integers to floating point are easy */
if (value->type == INT_VALUE && type == REAL_VALUE)
{
- *value = SelectionParserValue::createRealRange(value->u.i.i1, value->u.i.i2,
- value->location());
+ *value = SelectionParserValue::createRealRange(
+ value->u.i.i1, value->u.i.i2, value->location());
return;
}
/* Reals that are integer-valued can also be converted */
GMX_RELEASE_ASSERT(false, "Variable-count value type not implemented");
}
}
- GMX_RELEASE_ASSERT(i == valueCount,
- "Inconsistent value count wrt. the actual value population");
+ GMX_RELEASE_ASSERT(i == valueCount, "Inconsistent value count wrt. the actual value population");
if (param->nvalptr)
{
*param->nvalptr = param->val.nr;
SelectionParserParameterList params;
params.push_back(SelectionParserParameter::createFromExpression(nullptr, child));
params.push_back(SelectionParserParameter::create(nullptr, std::move(args), location));
- _gmx_sel_parse_params(params, root->u.expr.method->nparams, root->u.expr.method->param,
- root, scanner);
+ _gmx_sel_parse_params(
+ params, root->u.expr.method->nparams, root->u.expr.method->param, root, scanner);
}
set_refpos_type(&sc->pcc, child, rpost);
root = modifier;
}
/* Process the parameters */
- _gmx_sel_parse_params(*params, modifier->u.expr.method->nparams, modifier->u.expr.method->param,
- modifier, scanner);
+ _gmx_sel_parse_params(
+ *params, modifier->u.expr.method->nparams, modifier->u.expr.method->param, modifier, scanner);
return root;
}
break;
default:
// TODO: It would probably be better to do this without the type casts.
- gmx_calc_comg_block(top, fr->x, reinterpret_cast<t_block*>(&pc->b), index.data(),
- bMass, p->x);
+ gmx_calc_comg_block(
+ top, fr->x, reinterpret_cast<t_block*>(&pc->b), index.data(), bMass, p->x);
if (p->v && fr->bV)
{
- gmx_calc_comg_block(top, fr->v, reinterpret_cast<t_block*>(&pc->b),
- index.data(), bMass, p->v);
+ gmx_calc_comg_block(
+ top, fr->v, reinterpret_cast<t_block*>(&pc->b), index.data(), bMass, p->v);
}
if (p->f && fr->bF)
{
- gmx_calc_comg_f_block(top, fr->f, reinterpret_cast<t_block*>(&pc->b),
- index.data(), bMass, p->f);
+ gmx_calc_comg_f_block(
+ top, fr->f, reinterpret_cast<t_block*>(&pc->b), index.data(), bMass, p->f);
}
break;
}
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2009-2016, The GROMACS development team.
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 2019,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <cstdio>
-#include "gromacs/utility/classhelpers.h"
+#include <memory>
/*! \name Flags for position calculation.
* \anchor poscalc_flags
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
/*! \brief
* Needed to access the implementation class from the C code.
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
- * if you want the limit (max/min) macros for int types.
- */
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS 1
-#endif
-
#include <inttypes.h>
typedef int8_t flex_int8_t;
typedef uint8_t flex_uint8_t;
// manually.
#define YY_BREAK
-#ifdef __INTEL_COMPILER
-// Ignore unused variables in generated code.
-#pragma warning(disable:593)
-#endif
#define YY_NO_UNISTD_H 1
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2009,2010,2011,2012,2013 by the GROMACS development team.
- * Copyright (c) 2014,2015,2016,2020, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015,2016,2020,2021, 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.
// manually.
#define YY_BREAK
-#ifdef __INTEL_COMPILER
-// Ignore unused variables in generated code.
-#pragma warning(disable:593)
-#endif
%}
INTEGER [[:digit:]]+
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
- * if you want the limit (max/min) macros for int types.
- */
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS 1
-#endif
-
#include <inttypes.h>
typedef int8_t flex_int8_t;
typedef uint8_t flex_uint8_t;
std::string message = formatString(
"Cannot group selection '%s' into %s, because some "
"positions have atoms from more than one such group.",
- name(), type == INDEX_MOL ? "molecules" : "residues");
+ name(),
+ type == INDEX_MOL ? "molecules" : "residues");
GMX_THROW(InconsistentInputError(message));
}
}
void Selection::printInfo(FILE* fp) const
{
- fprintf(fp, "\"%s\" (%d position%s, %d atom%s%s)", name(), posCount(), posCount() == 1 ? "" : "s",
- atomCount(), atomCount() == 1 ? "" : "s", isDynamic() ? ", dynamic" : "");
+ fprintf(fp,
+ "\"%s\" (%d position%s, %d atom%s%s)",
+ name(),
+ posCount(),
+ posCount() == 1 ? "" : "s",
+ atomCount(),
+ atomCount() == 1 ? "" : "s",
+ isDynamic() ? ", dynamic" : "");
fprintf(fp, "\n");
}
*
* Copyright (c) 2009,2010,2011,2012,2013 by the GROMACS development team.
* Copyright (c) 2014,2015,2016,2017,2018 by the GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
#ifndef GMX_SELECTION_SELECTION_H
#define GMX_SELECTION_SELECTION_H
+#include <memory>
#include <string>
#include <vector>
}
for (size_t i = firstSelection; i < sc->sel.size(); ++i)
{
- writer->writeString(formatString(" %2d. %s\n", static_cast<int>(i - firstSelection + 1),
- sc->sel[i]->selectionText()));
+ writer->writeString(formatString(
+ " %2d. %s\n", static_cast<int>(i - firstSelection + 1), sc->sel[i]->selectionText()));
}
if (maxCount > 0)
{
const int remaining = maxCount - static_cast<int>(sc->sel.size() - firstSelection);
- writer->writeString(formatString("(%d more selection%s required)\n", remaining,
- remaining > 1 ? "s" : ""));
+ writer->writeString(formatString(
+ "(%d more selection%s required)\n", remaining, remaining > 1 ? "s" : ""));
}
}
}
SelectionList SelectionCollection::parseFromStdin(int count, bool bInteractive, const std::string& context)
{
StandardInputStream inputStream;
- return parseInteractive(count, &inputStream,
- bInteractive ? &TextOutputFile::standardError() : nullptr, context);
+ return parseInteractive(
+ count, &inputStream, bInteractive ? &TextOutputFile::standardError() : nullptr, context);
}
namespace
yyscan_t scanner;
const std::unique_ptr<TextWriter> statusWriter(initStatusWriter(statusStream));
- _gmx_sel_init_lexer(&scanner, &impl_->sc_, statusWriter.get(), count,
- impl_->bExternalGroupsSet_, impl_->grps_);
+ _gmx_sel_init_lexer(
+ &scanner, &impl_->sc_, statusWriter.get(), count, impl_->bExternalGroupsSet_, impl_->grps_);
return runParser(scanner, inputStream, true, count, context);
}
"Trajectory has less atoms (%d) than what is required for "
"evaluating the provided selections (atoms up to index %d "
"are required).",
- fr->natoms, maxAtomIndex + 1);
+ fr->natoms,
+ maxAtomIndex + 1);
GMX_THROW(InconsistentInputError(message));
}
}
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2010,2011,2012,2013,2014 by the GROMACS development team.
- * Copyright (c) 2015,2016,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <cstdio>
+#include <memory>
#include <string>
#include <vector>
#include "gromacs/selection/selection.h" // For gmx::SelectionList
-#include "gromacs/utility/classhelpers.h"
struct gmx_ana_indexgrps_t;
struct gmx_mtop_t;
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
// Needed for the compiler to freely modify the collection.
friend void compileSelection(SelectionCollection* coll);
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2016,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,2018,2019,2021, 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.
#ifndef GMX_SELECTION_SELECTIONOPTIONBEHAVIOR_H
#define GMX_SELECTION_SELECTIONOPTIONBEHAVIOR_H
+#include <memory>
#include <string>
#include "gromacs/options/ioptionsbehavior.h"
-#include "gromacs/utility/classhelpers.h"
struct gmx_mtop_t;
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
formatString("Too few selections provided for '%s': "
"Expected %d selections, but only %d left "
"after assigning the first %d to other selections.",
- request.name().c_str(), request.count(), remaining, assigned)));
+ request.name().c_str(),
+ request.count(),
+ remaining,
+ assigned)));
}
last = first + request.count();
}
"selections to be assigned to '%s'. "
"Resolution for such cases is not implemented, "
"and may be impossible.",
- name, conflictName, name, conflictName)));
+ name,
+ conflictName,
+ name,
+ conflictName)));
}
last = selections.end();
}
formatString("Too many selections provided: "
"Expected %d selections, but %d provided. "
"Last %d selections could not be assigned to any option.",
- assigned, count, remaining)));
+ assigned,
+ count,
+ remaining)));
}
}
for (i = impl_->requests_.begin(); i != impl_->requests_.end(); ++i)
{
const Impl::SelectionRequest& request = *i;
- std::string context = formatString("for option '%s'\n(%s)", request.name().c_str(),
- request.description().c_str());
+ std::string context = formatString(
+ "for option '%s'\n(%s)", request.name().c_str(), request.description().c_str());
SelectionList selections =
impl_->collection_.parseFromStdin(request.count(), bInteractive, context);
request.storage_->addSelections(selections, true);
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012,2013,2014,2015,2018 by the GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
#ifndef GMX_SELECTION_SELECTIONOPTIONMANAGER_H
#define GMX_SELECTION_SELECTIONOPTIONMANAGER_H
+#include <memory>
#include <string>
#include "gromacs/options/options.h"
-#include "gromacs/utility/classhelpers.h"
namespace gmx
{
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
/*! \brief
* Needed for handling delayed selection parsing requests.
"Group '%s' cannot be used in selections, because it "
"contains negative atom indices and/or references atoms "
"not present (largest allowed atom index is %d).",
- name().c_str(), natoms);
+ name().c_str(),
+ natoms);
GMX_THROW(InconsistentInputError(message));
}
}
{
int i;
- fprintf(fp, "%*c %s %s", level * 2 + 1, '*', _gmx_selelem_type_str(sel),
- _gmx_sel_value_type_str(&sel.v));
+ fprintf(fp, "%*c %s %s", level * 2 + 1, '*', _gmx_selelem_type_str(sel), _gmx_sel_value_type_str(&sel.v));
if (!sel.name().empty())
{
fprintf(fp, " \"%s\"", sel.name().c_str());
* segfaults when printing the selection tree. */
if (sel.v.u.p->x)
{
- fprintf(fp, "(%f, %f, %f)", sel.v.u.p->x[0][XX], sel.v.u.p->x[0][YY],
- sel.v.u.p->x[0][ZZ]);
+ fprintf(fp, "(%f, %f, %f)", sel.v.u.p->x[0][XX], sel.v.u.p->x[0][YY], sel.v.u.p->x[0][ZZ]);
}
else
{
*
* Copyright (c) 2009,2010,2011,2012,2013 by the GROMACS development team.
* Copyright (c) 2014,2015,2016,2017,2018 by the GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/onlinehelp/helptopic.h"
#include "gromacs/onlinehelp/helpwritercontext.h"
+#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/stringutil.h"
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2009-2018, The GROMACS development team.
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
{
if (param[i].val.type != INT_VALUE && param[i].val.type != REAL_VALUE)
{
- report_param_error(fp, name, param[i].name,
+ report_param_error(fp,
+ name,
+ param[i].name,
"error: SPAR_RANGES cannot be set for a non-numeric parameter");
bOk = false;
}
if (param[i].flags & SPAR_DYNAMIC)
{
- report_param_error(fp, name, param[i].name,
+ report_param_error(fp,
+ name,
+ param[i].name,
"warning: SPAR_DYNAMIC does not have effect with SPAR_RANGES");
param[i].flags &= ~SPAR_DYNAMIC;
}
if (!(param[i].flags & SPAR_VARNUM) && param[i].val.nr != 1)
{
report_param_error(
- fp, name, param[i].name,
+ fp,
+ name,
+ param[i].name,
"error: range should take either one or an arbitrary number of values");
bOk = false;
}
if (param[i].flags & SPAR_ATOMVAL)
{
- report_param_error(fp, name, param[i].name,
- "error: SPAR_RANGES and SPAR_ATOMVAL both set");
+ report_param_error(
+ fp, name, param[i].name, "error: SPAR_RANGES and SPAR_ATOMVAL both set");
bOk = false;
}
}
if ((param[i].flags & SPAR_VARNUM) && (param[i].flags & SPAR_ATOMVAL))
{
- report_param_error(fp, name, param[i].name,
- "error: SPAR_VARNUM and SPAR_ATOMVAL both set");
+ report_param_error(
+ fp, name, param[i].name, "error: SPAR_VARNUM and SPAR_ATOMVAL both set");
bOk = false;
}
if (param[i].flags & SPAR_ENUMVAL)
{
if (param[i].val.type != STR_VALUE)
{
- report_param_error(fp, name, param[i].name,
+ report_param_error(fp,
+ name,
+ param[i].name,
"error: SPAR_ENUMVAL can only be set for string parameters");
bOk = false;
}
if (param[i].val.nr != 1)
{
- report_param_error(fp, name, param[i].name,
+ report_param_error(fp,
+ name,
+ param[i].name,
"error: SPAR_ENUMVAL parameters should take exactly one value");
bOk = false;
}
if (param[i].flags & (SPAR_DYNAMIC | SPAR_VARNUM | SPAR_ATOMVAL))
{
- report_param_error(fp, name, param[i].name,
+ report_param_error(fp,
+ name,
+ param[i].name,
"error: only SPAR_OPTIONAL supported with SPAR_ENUMVAL");
bOk = false;
}
{
if (param[i].val.nr != 0)
{
- report_param_error(fp, name, param[i].name,
+ report_param_error(fp,
+ name,
+ param[i].name,
"error: number of values should be zero for boolean parameters");
bOk = false;
}
/* Any other flags should not be specified */
if (param[i].flags & ~SPAR_OPTIONAL)
{
- report_param_error(fp, name, param[i].name,
+ report_param_error(fp,
+ name,
+ param[i].name,
"error: boolean parameter should not have any flags set");
bOk = false;
}
if (param[i].val.nr != -1)
{
report_param_error(
- fp, name, param[i].name,
+ fp,
+ name,
+ param[i].name,
"warning: val.nr is not -1 although SPAR_VARNUM/SPAR_ATOMVAL is set");
}
param[i].val.nr = -1;
{
if (param[i].name[j] != '_' && !isalnum(param[i].name[j]))
{
- report_param_error(fp, name, param[i].name,
- "error: name contains non-alphanumeric characters");
+ report_param_error(
+ fp, name, param[i].name, "error: name contains non-alphanumeric characters");
bOk = false;
break;
}
/* Check that the name does not conflict with a method */
if (symtab.findSymbol(param[i].name) != nullptr)
{
- report_param_error(fp, name, param[i].name,
+ report_param_error(fp,
+ name,
+ param[i].name,
"error: name conflicts with another method or a keyword");
bOk = false;
}
gmx_ana_selparam_t* param = gmx_ana_selmethod_find_param(name, method);
if (param)
{
- report_param_error(fp, method->name, param->name,
+ report_param_error(fp,
+ method->name,
+ param->name,
"error: name conflicts with another method or a keyword");
bOk = false;
}
/* Make some checks on init_data and free */
if (method->nparams > 0 && !method->init_data)
{
- report_error(fp, method->name,
+ report_error(fp,
+ method->name,
"error: init_data should be provided because the method has parameters");
bOk = false;
}
/* Check presence of outinit for position-valued methods */
if (method->type == POS_VALUE && !method->outinit)
{
- report_error(fp, method->name,
+ report_error(fp,
+ method->name,
"error: outinit should be provided because the method has POS_VALUE");
bOk = false;
}
/* Check presence of outinit for variable output count methods */
if ((method->flags & SMETH_VARNUMVAL) && !method->outinit)
{
- report_error(fp, method->name,
+ report_error(fp,
+ method->name,
"error: outinit should be provided because the method has SMETH_VARNUMVAL");
bOk = false;
}
/* Check that conflicting flags are not present. */
if (method->flags & SMETH_VARNUMVAL)
{
- report_error(fp, method->name,
+ report_error(fp,
+ method->name,
"error: SMETH_VARNUMVAL cannot be set for group-valued methods");
bOk = false;
}
}
if ((method->flags & SMETH_CHARVAL) && method->type != STR_VALUE)
{
- report_error(fp, method->name,
+ report_error(fp,
+ method->name,
"error: SMETH_CHARVAL can only be specified for STR_VALUE methods");
bOk = false;
}
/* Check flags */
if (method->flags & (SMETH_SINGLEVAL | SMETH_VARNUMVAL))
{
- report_error(fp, method->name,
+ report_error(fp,
+ method->name,
"error: modifier should not have SMETH_SINGLEVAL or SMETH_VARNUMVAL set");
bOk = false;
}
&init_frame_insolidangle,
nullptr,
&evaluate_insolidangle,
- { "insolidangle center POS span POS_EXPR [cutoff REAL]", "Selecting atoms in a solid angle",
- asize(help_insolidangle), help_insolidangle },
+ { "insolidangle center POS span POS_EXPR [cutoff REAL]",
+ "Selecting atoms in a solid angle",
+ asize(help_insolidangle),
+ help_insolidangle },
};
static void* init_data_insolidangle(int /* npar */, gmx_ana_selparam_t* param)
{
out->u.p->m.type = d->p1.m.type;
}
- gmx_ana_pos_reserve_for_append(out->u.p, d->p1.count() + d->p2.count(),
- d->p1.m.b.nra + d->p2.m.b.nra, d->p1.v != nullptr, d->p1.f != nullptr);
+ gmx_ana_pos_reserve_for_append(out->u.p,
+ d->p1.count() + d->p2.count(),
+ d->p1.m.b.nra + d->p2.m.b.nra,
+ d->p1.v != nullptr,
+ d->p1.f != nullptr);
gmx_ana_pos_empty_init(out->u.p);
}
int i, j, b;
out->u.p->m.type = d->p.m.type;
- gmx_ana_pos_reserve_for_append(out->u.p, d->p.count(), d->p.m.b.nra, d->p.v != nullptr,
- d->p.f != nullptr);
+ gmx_ana_pos_reserve_for_append(
+ out->u.p, d->p.count(), d->p.m.b.nra, d->p.v != nullptr, d->p.f != nullptr);
gmx_ana_pos_empty_init(out->u.p);
for (i = 0; i < d->p.count(); i += d->n)
{
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2009-2017, The GROMACS development team.
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 2019,2021, 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.
SelectionParserSymbolIterator& SelectionParserSymbolIterator::operator=(const SelectionParserSymbolIterator& other)
{
- impl_.reset(new Impl(*other.impl_));
+ impl_ = std::make_unique<Impl>(*other.impl_);
return *this;
}
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2009,2010,2011,2012,2013 by the GROMACS development team.
- * Copyright (c) 2014,2015,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#define GMX_SELECTION_SYMREC_H
#include <iterator>
+#include <memory>
#include <string>
#include <boost/stl_interfaces/iterator_interface.hpp>
-#include "gromacs/utility/classhelpers.h"
-
#include "selelem.h"
struct gmx_ana_selmethod_t;
*/
explicit SelectionParserSymbol(Impl* impl);
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
/*! \brief
* Needed to call the constructor and for other initialization.
*/
explicit SelectionParserSymbolIterator(Impl* impl);
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
/*! \brief
* Needed to access the constructor.
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
/*! \brief
* Needed to access implementation types.
for (int i = 0; i < blocka_.nr; ++i)
{
gmx::test::TestReferenceChecker blockCompound(compound.checkCompound("Block", nullptr));
- blockCompound.checkSequence(&blocka_.a[blocka_.index[i]], &blocka_.a[blocka_.index[i + 1]],
- "Atoms");
+ blockCompound.checkSequence(
+ &blocka_.a[blocka_.index[i]], &blocka_.a[blocka_.index[i + 1]], "Atoms");
}
}
for (int i = 0; i < map_.mapb.nr; ++i)
{
gmx::test::TestReferenceChecker blockCompound(compound.checkCompound("Block", nullptr));
- blockCompound.checkSequence(&atoms[map_.mapb.index[i]], &atoms[map_.mapb.index[i + 1]],
- "Atoms");
+ blockCompound.checkSequence(
+ &atoms[map_.mapb.index[i]], &atoms[map_.mapb.index[i + 1]], "Atoms");
blockCompound.checkInteger(map_.refid[i], "RefId");
blockCompound.checkInteger(map_.mapid[i], "MapId");
int originalIdIndex = (map_.refid[i] != -1 ? map_.refid[i] : i);
addGroupToBlocka_(indicesGroupSecondA_);
addGroupToBlocka_(indicesGroupC_);
- const char* const namesAsConstCharArray[4] = { groupNames[0].c_str(), groupNames[1].c_str(),
- groupNames[2].c_str(), groupNames[3].c_str() };
+ const char* const namesAsConstCharArray[4] = {
+ groupNames[0].c_str(), groupNames[1].c_str(), groupNames[2].c_str(), groupNames[3].c_str()
+ };
indexGroupAndNames_ = std::make_unique<gmx::IndexGroupsAndNames>(blockA_, namesAsConstCharArray);
}
~IndexGroupsAndNamesTest() override { done_blocka(&blockA_); }
if (selfPairs)
{
searchPair = NeighborhoodSearchTestData::RefPair(testIndex, 0.0);
- const auto otherRefPair = std::lower_bound(refPairs[refIndex].begin(),
- refPairs[refIndex].end(), searchPair);
+ const auto otherRefPair = std::lower_bound(
+ refPairs[refIndex].begin(), refPairs[refIndex].end(), searchPair);
GMX_RELEASE_ASSERT(otherRefPair != refPairs[refIndex].end(),
"Precomputed reference data is not symmetric");
otherRefPair->bFound = true;
nb_.initSearch(&data.pbc_, data.refPositions().exclusionIds(helper.refPosIds()));
ASSERT_EQ(gmx::AnalysisNeighborhood::eSearchMode_Simple, search.mode());
- testPairSearchFull(&search, data, data.testPositions().exclusionIds(helper.testPosIds()),
- helper.exclusions(), {}, {}, false);
+ testPairSearchFull(&search,
+ data,
+ data.testPositions().exclusionIds(helper.testPosIds()),
+ helper.exclusions(),
+ {},
+ {},
+ false);
}
TEST_F(NeighborhoodSearchTest, GridSearchExclusions)
nb_.initSearch(&data.pbc_, data.refPositions().exclusionIds(helper.refPosIds()));
ASSERT_EQ(gmx::AnalysisNeighborhood::eSearchMode_Grid, search.mode());
- testPairSearchFull(&search, data, data.testPositions().exclusionIds(helper.testPosIds()),
- helper.exclusions(), {}, {}, false);
+ testPairSearchFull(&search,
+ data,
+ data.testPositions().exclusionIds(helper.testPosIds()),
+ helper.exclusions(),
+ {},
+ {},
+ false);
}
} // namespace
for (int i = 0; i < p->count(); ++i)
{
gmx::test::TestReferenceChecker posCompound(compound.checkCompound("Position", nullptr));
- posCompound.checkSequence(&p->m.mapb.a[p->m.mapb.index[i]],
- &p->m.mapb.a[p->m.mapb.index[i + 1]], "Atoms");
+ posCompound.checkSequence(
+ &p->m.mapb.a[p->m.mapb.index[i]], &p->m.mapb.a[p->m.mapb.index[i + 1]], "Atoms");
posCompound.checkInteger(p->m.refid[i], "RefId");
if (bCoordinates)
{
{
helper_.setInputLines(inputLines);
// TODO: Check something about the returned selections as well.
- ASSERT_NO_THROW_GMX(sc_.parseInteractive(count, &helper_.inputStream(),
+ ASSERT_NO_THROW_GMX(sc_.parseInteractive(count,
+ &helper_.inputStream(),
bInteractive ? &helper_.outputStream() : nullptr,
"for test context"));
helper_.checkSession();
TEST_F(SelectionCollectionDataTest, HandlesAtomnr)
{
- static const char* const selections[] = { "atomnr 1 to 3 6 to 8", "atomnr 4 2 5 to 7",
+ static const char* const selections[] = { "atomnr 1 to 3 6 to 8",
+ "atomnr 4 2 5 to 7",
"atomnr <= 5" };
runTest(10, selections);
}
TEST_F(SelectionCollectionDataTest, HandlesPdbAtomname)
{
- static const char* const selections[] = { "name HG21", "name 1HG2", "pdbname HG21 CB",
- "pdbatomname 1HG2" };
+ static const char* const selections[] = {
+ "name HG21", "name 1HG2", "pdbname HG21 CB", "pdbatomname 1HG2"
+ };
runTest("simple.pdb", selections);
}
TEST_F(SelectionCollectionDataTest, HandlesPositionKeywords)
{
- static const char* const selections[] = { "cog of resnr 1 3", "res_cog of name CB and resnr 1 3",
+ static const char* const selections[] = { "cog of resnr 1 3",
+ "res_cog of name CB and resnr 1 3",
"whole_res_cog of name CB and resnr 1 3",
- "part_res_cog of x < 3", "dyn_res_cog of x < 3" };
+ "part_res_cog of x < 3",
+ "dyn_res_cog of x < 3" };
setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates | efTestPositionAtoms);
runTest("simple.gro", selections);
}
TEST_F(SelectionCollectionDataTest, HandlesPlusModifier)
{
static const char* const selections[] = {
- "name S2 plus name S1", "res_cog of resnr 2 plus res_cog of resnr 1 plus res_cog of resnr 3",
+ "name S2 plus name S1",
+ "res_cog of resnr 2 plus res_cog of resnr 1 plus res_cog of resnr 3",
"name S1 and y < 3 plus res_cog of x < 2.5"
};
setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates | efTestPositionAtoms
TEST_F(SelectionCollectionDataTest, HandlesFramesWithAtomSubsets)
{
const int index[] = { 0, 1, 2, 3, 4, 5, 9, 10, 11 };
- const char* const selections[] = { "resnr 1 4", "atomnr 1 2 5 11 and y > 2",
+ const char* const selections[] = { "resnr 1 4",
+ "atomnr 1 2 5 11 and y > 2",
"res_cog of atomnr 2 5 11" };
setFlags(TestFlags() | efTestEvaluation | efTestPositionAtoms);
ASSERT_NO_FATAL_FAILURE(runParser(selections));
TEST_F(SelectionCollectionDataTest, HandlesSelectionNames)
{
static const char* const selections[] = { "\"GroupSelection\" group \"GrpA\"",
- "\"DynamicSelection\" x < 5", "y < 3" };
+ "\"DynamicSelection\" x < 5",
+ "y < 3" };
setFlags(TestFlags() | efTestSelectionNames);
ASSERT_NO_THROW_GMX(loadIndexGroups("simple.ndx"));
runTest(10, selections);
TEST_F(SelectionCollectionDataTest, HandlesIndexGroupsInSelections)
{
- static const char* const selections[] = { "group \"GrpA\"", "GrpB", "1",
+ static const char* const selections[] = { "group \"GrpA\"",
+ "GrpB",
+ "1",
// These test that the name of the group is not too
// eagerly promoted to the name of the selection.
"group \"GrpB\" and resname RB",
TEST_F(SelectionCollectionDataTest, HandlesIndexGroupsInSelectionsDelayed)
{
- static const char* const selections[] = { "group \"GrpA\"", "GrpB", "1",
- "group \"GrpB\" and resname RB" };
+ static const char* const selections[] = {
+ "group \"GrpA\"", "GrpB", "1", "group \"GrpB\" and resname RB"
+ };
setFlags(TestFlags() | efTestSelectionNames);
ASSERT_NO_FATAL_FAILURE(runParser(selections));
ASSERT_NO_FATAL_FAILURE(loadTopology("simple.gro"));
TEST_F(SelectionCollectionDataTest, HandlesBasicBoolean)
{
static const char* const selections[] = {
- "atomnr 1 to 5 and atomnr 2 to 7", "atomnr 1 to 5 or not atomnr 3 to 8",
+ "atomnr 1 to 5 and atomnr 2 to 7",
+ "atomnr 1 to 5 or not atomnr 3 to 8",
"not not atomnr 1 to 5 and atomnr 2 to 6 and not not atomnr 3 to 7",
"atomnr 1 to 5 and (atomnr 2 to 7 and atomnr 3 to 6)",
"x < 5 and atomnr 1 to 5 and y < 3 and atomnr 2 to 4"
TEST_F(SelectionCollectionDataTest, HandlesEmptySelectionWithUnevaluatedExpressions)
{
- static const char* const selections[] = { "none and x > 2",
- "none and same resname as resnr 2" };
+ static const char* const selections[] = { "none and x > 2", "none and same resname as resnr 2" };
runTest("simple.gro", selections);
}
TEST_F(SelectionCollectionDataTest, HandlesNumericComparisons)
{
- static const char* const selections[] = { "x > 2", "2 < x", "y > resnr", "resnr < 2.5",
- "2.5 > resnr" };
+ static const char* const selections[] = {
+ "x > 2", "2 < x", "y > resnr", "resnr < 2.5", "2.5 > resnr"
+ };
setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates);
runTest("simple.gro", selections);
}
TEST_F(SelectionCollectionDataTest, HandlesNumericVariables)
{
- static const char* const selections[] = { "value = x + y", "value <= 4", "index = resnr",
- "index < 3" };
+ static const char* const selections[] = {
+ "value = x + y", "value <= 4", "index = resnr", "index < 3"
+ };
setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates);
runTest("simple.gro", selections);
}
TEST_F(SelectionCollectionDataTest, HandlesPositionVariableInModifier)
{
- static const char* const selections[] = { "foo = cog of resnr 1", "cog of resnr 2 plus foo",
+ static const char* const selections[] = { "foo = cog of resnr 1",
+ "cog of resnr 2 plus foo",
"cog of resnr 3 plus foo" };
setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates);
runTest("simple.gro", selections);
TEST_F(SelectionCollectionDataTest, HandlesConstantPositionInVariable)
{
- static const char* const selections[] = { "constpos = [1.0, 2.5, 0.5]", "constpos",
+ static const char* const selections[] = { "constpos = [1.0, 2.5, 0.5]",
+ "constpos",
"within 2 of constpos" };
setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates | efTestPositionAtoms);
runTest("simple.gro", selections);
TEST_F(SelectionCollectionDataTest, HandlesNumericConstantsInVariables)
{
- static const char* const selections[] = { "constint = 4", "constreal1 = 0.5", "constreal2 = 2.7",
- "resnr < constint", "x + constreal1 < constreal2" };
+ static const char* const selections[] = { "constint = 4",
+ "constreal1 = 0.5",
+ "constreal2 = 2.7",
+ "resnr < constint",
+ "x + constreal1 < constreal2" };
setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates);
runTest("simple.gro", selections);
}
TEST_F(SelectionCollectionDataTest, HandlesBooleanStaticAnalysis)
{
static const char* const selections[] = {
- "atomnr 1 to 5 and atomnr 2 to 7 and x < 2", "atomnr 1 to 5 and (atomnr 4 to 7 or x < 2)",
+ "atomnr 1 to 5 and atomnr 2 to 7 and x < 2",
+ "atomnr 1 to 5 and (atomnr 4 to 7 or x < 2)",
"atomnr 1 to 5 and y < 3 and (atomnr 4 to 7 or x < 2)",
"atomnr 1 to 5 and not (atomnr 4 to 7 or x < 2)",
"atomnr 1 to 5 or (atomnr 4 to 6 and (atomnr 5 to 7 or x < 2))"
TEST_F(SelectionCollectionDataTest, HandlesUnusedVariables)
{
- static const char* const selections[] = { "unused1 = atomnr 1 to 3", "foo = atomnr 4 to 7",
- "atomnr 1 to 6 and foo", "unused2 = atomnr 3 to 5" };
+ static const char* const selections[] = { "unused1 = atomnr 1 to 3",
+ "foo = atomnr 4 to 7",
+ "atomnr 1 to 6 and foo",
+ "unused2 = atomnr 3 to 5" };
runTest(10, selections);
}
TEST_F(SelectionCollectionDataTest, HandlesVariablesWithStaticEvaluationGroups)
{
static const char* const selections[] = { "foo = atomnr 4 to 7 and x < 2",
- "atomnr 1 to 5 and foo", "atomnr 3 to 7 and foo" };
+ "atomnr 1 to 5 and foo",
+ "atomnr 3 to 7 and foo" };
runTest(10, selections);
}
TEST_F(SelectionCollectionDataTest, HandlesVariablesWithMixedEvaluationGroups)
{
- static const char* const selections[] = { "foo = atomnr 4 to 7 and x < 2",
- "atomnr 1 to 6 and foo", "within 1 of foo", "foo" };
+ static const char* const selections[] = {
+ "foo = atomnr 4 to 7 and x < 2", "atomnr 1 to 6 and foo", "within 1 of foo", "foo"
+ };
runTest(10, selections);
}
TEST_F(SelectionCollectionDataTest, HandlesVariablesWithMixedEvaluationGroups2)
{
static const char* const selections[] = { "foo = atomnr 1 to 8 and x < 10",
- "atomnr 1 to 5 and y < 10 and foo", "foo" };
+ "atomnr 1 to 5 and y < 10 and foo",
+ "foo" };
setFlags(TestFlags() | efTestEvaluation);
runTest("simple.gro", selections);
}
GMX_RELEASE_ASSERT(mtop_ == nullptr, "Topology initialized more than once");
mtop_ = std::make_unique<gmx_mtop_t>();
- readConfAndTopology(gmx::test::TestFileManager::getInputFilePath(filename).c_str(), &fullTopology,
- mtop_.get(), &pbcType, frame_ != nullptr ? &xtop : nullptr, nullptr, box);
+ readConfAndTopology(gmx::test::TestFileManager::getInputFilePath(filename).c_str(),
+ &fullTopology,
+ mtop_.get(),
+ &pbcType,
+ frame_ != nullptr ? &xtop : nullptr,
+ nullptr,
+ box);
if (frame_ != nullptr)
{
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2014,2015, by the GROMACS development team, led by
+# Copyright (c) 2014,2015,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.
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+add_library(simd INTERFACE)
file(GLOB SIMD_SOURCES *.cpp)
set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${SIMD_SOURCES} PARENT_SCOPE)
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(simd PUBLIC
+target_include_directories(simd INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(simd PUBLIC
+target_link_libraries(simd INTERFACE
+ legacy_api
+ )
+
+# TODO: when simd is an OBJECT target
+#target_link_libraries(simd PUBLIC legacy_api)
+#target_link_libraries(simd PRIVATE common)
+
+# Module dependencies
+# simd interfaces convey transitive dependence on these modules.
+#target_link_libraries(simd PUBLIC
+target_link_libraries(simd INTERFACE
+ utility
+ )
+
if (BUILD_TESTING)
add_subdirectory(tests)
endif()
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 2014,2015, 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.
- */
-
-#ifndef GMX_SIMD_IMPL_ARM_NEON_H
-#define GMX_SIMD_IMPL_ARM_NEON_H
-
-#include "impl_arm_neon_definitions.h"
-#include "impl_arm_neon_general.h"
-// Arm/Neon cannot do double precision SIMD4
-#include "impl_arm_neon_simd4_float.h"
-// Arm/Neon cannot do double precision SIMD
-#include "impl_arm_neon_simd_float.h"
-// Arm/Neon cannot do double precision SIMD utilities
-#include "impl_arm_neon_util_float.h"
-
-#endif // GMX_SIMD_IMPL_ARM_NEON_H
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 2014,2015,2017,2018,2019,2020, by the GROMACS development team, led by
- * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
- * and including many others, as listed in the AUTHORS file in the
- * top-level source directory and at http://www.gromacs.org.
- *
- * 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.
- */
-
-#ifndef GMX_SIMD_IMPL_ARM_NEON_DEFINITIONS_H
-#define GMX_SIMD_IMPL_ARM_NEON_DEFINITIONS_H
-
-#define GMX_SIMD 1
-#define GMX_SIMD_HAVE_FLOAT 1
-#define GMX_SIMD_HAVE_DOUBLE 0
-#define GMX_SIMD_HAVE_LOADU 1
-#define GMX_SIMD_HAVE_STOREU 1
-#define GMX_SIMD_HAVE_LOGICAL 1
-#define GMX_SIMD_HAVE_FMA 1
-#define GMX_SIMD_HAVE_FINT32_EXTRACT 1
-#define GMX_SIMD_HAVE_FINT32_LOGICAL 1
-#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 1
-#define GMX_SIMD_HAVE_DINT32_EXTRACT 0
-#define GMX_SIMD_HAVE_DINT32_LOGICAL 0
-#define GMX_SIMD_HAVE_DINT32_ARITHMETICS 0
-#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_FLOAT 0
-#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT \
- 0 // Although there is support, it is disabled in GROMACS, because rsqrtIter does not work correctly for inputs near MAX_FLOAT
-#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_FLOAT 1
-#define GMX_SIMD_HAVE_NATIVE_LOG_FLOAT 0
-#define GMX_SIMD_HAVE_NATIVE_EXP2_FLOAT 0
-#define GMX_SIMD_HAVE_NATIVE_EXP_FLOAT 0
-#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_DOUBLE 0
-#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_DOUBLE 0
-#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_DOUBLE 0
-#define GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE 0
-#define GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE 0
-#define GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE 0
-#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT 1
-#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE 0
-#define GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT 0 // No need for half-simd, width is 4
-#define GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE 0
-
-#define GMX_SIMD4_HAVE_FLOAT 1
-#define GMX_SIMD4_HAVE_DOUBLE 0
-
-// Implementation details
-#define GMX_SIMD_FLOAT_WIDTH 4
-#undef GMX_SIMD_DOUBLE_WIDTH
-#define GMX_SIMD_FINT32_WIDTH 4
-#undef GMX_SIMD_DINT32_WIDTH
-#define GMX_SIMD4_WIDTH 4
-#define GMX_SIMD_ALIGNMENT 16 // Bytes (4*single)
-#define GMX_SIMD_RSQRT_BITS 8
-#define GMX_SIMD_RCP_BITS 8
-
-#endif // GMX_SIMD_IMPL_ARM_NEON_DEFINITIONS_H
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by
- * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
- * and including many others, as listed in the AUTHORS file in the
- * top-level source directory and at http://www.gromacs.org.
- *
- * GROMACS is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * GROMACS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with GROMACS; if not, see
- * http://www.gnu.org/licenses, or write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * If you want to redistribute modifications to GROMACS, please
- * consider that scientific software is very special. Version
- * control is crucial - bugs must be traceable. We will be happy to
- * consider code for inclusion in the official distribution, but
- * derived work must not be called official GROMACS. Details are found
- * in the README & COPYING files - if they are missing, get the
- * official version at http://www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org.
- */
-#ifndef GMX_SIMD_IMPL_ARM_NEON_GENERAL_H
-#define GMX_SIMD_IMPL_ARM_NEON_GENERAL_H
-
-namespace gmx
-{
-
-static inline void simdPrefetch(void* m)
-{
-#ifdef __GNUC__
- __builtin_prefetch(m);
-#endif
-}
-
-} // namespace gmx
-
-#endif // GMX_SIMD_IMPL_ARM_NEON_GENERAL_H
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by
- * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
- * and including many others, as listed in the AUTHORS file in the
- * top-level source directory and at http://www.gromacs.org.
- *
- * GROMACS is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * GROMACS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with GROMACS; if not, see
- * http://www.gnu.org/licenses, or write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * If you want to redistribute modifications to GROMACS, please
- * consider that scientific software is very special. Version
- * control is crucial - bugs must be traceable. We will be happy to
- * consider code for inclusion in the official distribution, but
- * derived work must not be called official GROMACS. Details are found
- * in the README & COPYING files - if they are missing, get the
- * official version at http://www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org.
- */
-#ifndef GMX_SIMD_IMPL_ARM_NEON_SIMD4_FLOAT_H
-#define GMX_SIMD_IMPL_ARM_NEON_SIMD4_FLOAT_H
-
-#include "config.h"
-
-#include <cassert>
-#include <cstddef>
-
-#include <arm_neon.h>
-
-namespace gmx
-{
-
-class Simd4Float
-{
-public:
- Simd4Float() {}
-
- Simd4Float(float f) : simdInternal_(vdupq_n_f32(f)) {}
-
- // Internal utility constructor to simplify return statements
- Simd4Float(float32x4_t simd) : simdInternal_(simd) {}
-
- float32x4_t simdInternal_;
-};
-
-class Simd4FBool
-{
-public:
- Simd4FBool() {}
-
- //! \brief Construct from scalar bool
- Simd4FBool(bool b) : simdInternal_(vdupq_n_u32(b ? 0xFFFFFFFF : 0)) {}
-
- // Internal utility constructor to simplify return statements
- Simd4FBool(uint32x4_t simd) : simdInternal_(simd) {}
-
- uint32x4_t simdInternal_;
-};
-
-static inline Simd4Float gmx_simdcall load4(const float* m)
-{
- assert(size_t(m) % 16 == 0);
- return { vld1q_f32(m) };
-}
-
-static inline void gmx_simdcall store4(float* m, Simd4Float a)
-{
- assert(size_t(m) % 16 == 0);
- vst1q_f32(m, a.simdInternal_);
-}
-
-static inline Simd4Float gmx_simdcall load4U(const float* m)
-{
- return { vld1q_f32(m) };
-}
-
-static inline void gmx_simdcall store4U(float* m, Simd4Float a)
-{
- vst1q_f32(m, a.simdInternal_);
-}
-
-static inline Simd4Float gmx_simdcall simd4SetZeroF()
-{
- return { vdupq_n_f32(0.0F) };
-}
-
-static inline Simd4Float gmx_simdcall operator&(Simd4Float a, Simd4Float b)
-{
- return { vreinterpretq_f32_s32(vandq_s32(vreinterpretq_s32_f32(a.simdInternal_),
- vreinterpretq_s32_f32(b.simdInternal_))) };
-}
-
-static inline Simd4Float gmx_simdcall andNot(Simd4Float a, Simd4Float b)
-{
- return { vreinterpretq_f32_s32(vbicq_s32(vreinterpretq_s32_f32(b.simdInternal_),
- vreinterpretq_s32_f32(a.simdInternal_))) };
-}
-
-static inline Simd4Float gmx_simdcall operator|(Simd4Float a, Simd4Float b)
-{
- return { vreinterpretq_f32_s32(vorrq_s32(vreinterpretq_s32_f32(a.simdInternal_),
- vreinterpretq_s32_f32(b.simdInternal_))) };
-}
-
-static inline Simd4Float gmx_simdcall operator^(Simd4Float a, Simd4Float b)
-{
- return { vreinterpretq_f32_s32(veorq_s32(vreinterpretq_s32_f32(a.simdInternal_),
- vreinterpretq_s32_f32(b.simdInternal_))) };
-}
-
-static inline Simd4Float gmx_simdcall operator+(Simd4Float a, Simd4Float b)
-{
- return { vaddq_f32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline Simd4Float gmx_simdcall operator-(Simd4Float a, Simd4Float b)
-{
- return { vsubq_f32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline Simd4Float gmx_simdcall operator-(Simd4Float x)
-{
- return { vnegq_f32(x.simdInternal_) };
-}
-
-static inline Simd4Float gmx_simdcall operator*(Simd4Float a, Simd4Float b)
-{
- return { vmulq_f32(a.simdInternal_, b.simdInternal_) };
-}
-
-// Override for Neon-Asimd
-#if GMX_SIMD_ARM_NEON
-static inline Simd4Float gmx_simdcall fma(Simd4Float a, Simd4Float b, Simd4Float c)
-{
- return {
-# ifdef __ARM_FEATURE_FMA
- vfmaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_)
-# else
- vmlaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_)
-# endif
- };
-}
-
-static inline Simd4Float gmx_simdcall fms(Simd4Float a, Simd4Float b, Simd4Float c)
-{
- return {
-# ifdef __ARM_FEATURE_FMA
- vnegq_f32(vfmsq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_))
-# else
- vnegq_f32(vmlsq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_))
-# endif
- };
-}
-
-static inline Simd4Float gmx_simdcall fnma(Simd4Float a, Simd4Float b, Simd4Float c)
-{
- return {
-# ifdef __ARM_FEATURE_FMA
- vfmsq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_)
-# else
- vmlsq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_)
-# endif
- };
-}
-
-static inline Simd4Float gmx_simdcall fnms(Simd4Float a, Simd4Float b, Simd4Float c)
-{
- return {
-# ifdef __ARM_FEATURE_FMA
- vnegq_f32(vfmaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_))
-# else
- vnegq_f32(vmlaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_))
-# endif
- };
-}
-#endif
-
-static inline Simd4Float gmx_simdcall rsqrt(Simd4Float x)
-{
- return { vrsqrteq_f32(x.simdInternal_) };
-}
-
-static inline Simd4Float gmx_simdcall abs(Simd4Float x)
-{
- return { vabsq_f32(x.simdInternal_) };
-}
-
-static inline Simd4Float gmx_simdcall max(Simd4Float a, Simd4Float b)
-{
- return { vmaxq_f32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline Simd4Float gmx_simdcall min(Simd4Float a, Simd4Float b)
-{
- return { vminq_f32(a.simdInternal_, b.simdInternal_) };
-}
-
-// Override for Neon-Asimd
-#if GMX_SIMD_ARM_NEON
-static inline Simd4Float gmx_simdcall round(Simd4Float x)
-{
- // Convert x to nearest integer
- float32x4_t signBitOfX = vreinterpretq_f32_u32(
- vandq_u32(vdupq_n_u32(0x80000000), vreinterpretq_u32_f32(x.simdInternal_)));
- float32x4_t half = vdupq_n_f32(0.5F);
- float32x4_t corr = vreinterpretq_f32_u32(
- vorrq_u32(vreinterpretq_u32_f32(half), vreinterpretq_u32_f32(signBitOfX)));
-
- int32x4_t integerX = vcvtq_s32_f32(vaddq_f32(x.simdInternal_, corr));
-
- // Convert back to float
-
- return { vcvtq_f32_s32(integerX) };
-}
-
-static inline Simd4Float gmx_simdcall trunc(Simd4Float x)
-{
- return { vcvtq_f32_s32(vcvtq_s32_f32(x.simdInternal_)) };
-}
-#endif
-
-static inline void gmx_simdcall transpose(Simd4Float* v0, Simd4Float* v1, Simd4Float* v2, Simd4Float* v3)
-{
- float32x4x2_t t0 = vuzpq_f32(v0->simdInternal_, v2->simdInternal_);
- float32x4x2_t t1 = vuzpq_f32(v1->simdInternal_, v3->simdInternal_);
- float32x4x2_t t2 = vtrnq_f32(t0.val[0], t1.val[0]);
- float32x4x2_t t3 = vtrnq_f32(t0.val[1], t1.val[1]);
- v0->simdInternal_ = t2.val[0];
- v1->simdInternal_ = t3.val[0];
- v2->simdInternal_ = t2.val[1];
- v3->simdInternal_ = t3.val[1];
-}
-
-static inline Simd4FBool gmx_simdcall operator==(Simd4Float a, Simd4Float b)
-{
- return { vceqq_f32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline Simd4FBool gmx_simdcall operator!=(Simd4Float a, Simd4Float b)
-{
- return { vmvnq_u32(vceqq_f32(a.simdInternal_, b.simdInternal_)) };
-}
-
-static inline Simd4FBool gmx_simdcall operator<(Simd4Float a, Simd4Float b)
-{
- return { vcltq_f32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline Simd4FBool gmx_simdcall operator<=(Simd4Float a, Simd4Float b)
-{
- return { vcleq_f32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline Simd4FBool gmx_simdcall operator&&(Simd4FBool a, Simd4FBool b)
-{
- return { vandq_u32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline Simd4FBool gmx_simdcall operator||(Simd4FBool a, Simd4FBool b)
-{
- return { vorrq_u32(a.simdInternal_, b.simdInternal_) };
-}
-
-// Override for Neon-Asimd
-#if GMX_SIMD_ARM_NEON
-static inline bool gmx_simdcall anyTrue(Simd4FBool a)
-{
- uint32x4_t x = a.simdInternal_;
- uint32x4_t y = vextq_u32(x, x, 2);
-
- x = vorrq_u32(x, y);
- y = vextq_u32(x, x, 1);
- x = vorrq_u32(x, y);
- return (vgetq_lane_u32(x, 0) != 0);
-}
-#endif
-
-static inline Simd4Float gmx_simdcall selectByMask(Simd4Float a, Simd4FBool m)
-{
- return { vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(a.simdInternal_), m.simdInternal_)) };
-}
-
-static inline Simd4Float gmx_simdcall selectByNotMask(Simd4Float a, Simd4FBool m)
-{
- return { vreinterpretq_f32_u32(vbicq_u32(vreinterpretq_u32_f32(a.simdInternal_), m.simdInternal_)) };
-}
-
-static inline Simd4Float gmx_simdcall blend(Simd4Float a, Simd4Float b, Simd4FBool sel)
-{
- return { vbslq_f32(sel.simdInternal_, b.simdInternal_, a.simdInternal_) };
-}
-
-// Override for Neon-Asimd
-#if GMX_SIMD_ARM_NEON
-static inline float gmx_simdcall reduce(Simd4Float a)
-{
- float32x4_t x = a.simdInternal_;
- float32x4_t y = vextq_f32(x, x, 2);
-
- x = vaddq_f32(x, y);
- y = vextq_f32(x, x, 1);
- x = vaddq_f32(x, y);
- return vgetq_lane_f32(x, 0);
-}
-
-static inline float gmx_simdcall dotProduct(Simd4Float a, Simd4Float b)
-{
- Simd4Float c;
-
- c = a * b;
- /* set 4th element to 0, then add all of them */
- c.simdInternal_ = vsetq_lane_f32(0.0F, c.simdInternal_, 3);
- return reduce(c);
-}
-#endif
-
-} // namespace gmx
-
-#endif // GMX_SIMD_IMPL_ARM_NEON_SIMD4_FLOAT_H
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 2014,2015,2016,2017,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.
- *
- * 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.
- */
-#ifndef GMX_SIMD_IMPL_ARM_NEON_SIMD_FLOAT_H
-#define GMX_SIMD_IMPL_ARM_NEON_SIMD_FLOAT_H
-
-#include "config.h"
-
-#include <cassert>
-#include <cstddef>
-#include <cstdint>
-
-#include <arm_neon.h>
-
-#include "gromacs/math/utilities.h"
-
-namespace gmx
-{
-
-class SimdFloat
-{
-public:
- SimdFloat() {}
-
- SimdFloat(float f) : simdInternal_(vdupq_n_f32(f)) {}
-
- // Internal utility constructor to simplify return statements
- SimdFloat(float32x4_t simd) : simdInternal_(simd) {}
-
- float32x4_t simdInternal_;
-};
-
-class SimdFInt32
-{
-public:
- SimdFInt32() {}
-
- SimdFInt32(std::int32_t i) : simdInternal_(vdupq_n_s32(i)) {}
-
- // Internal utility constructor to simplify return statements
- SimdFInt32(int32x4_t simd) : simdInternal_(simd) {}
-
- int32x4_t simdInternal_;
-};
-
-class SimdFBool
-{
-public:
- SimdFBool() {}
-
- SimdFBool(bool b) : simdInternal_(vdupq_n_u32(b ? 0xFFFFFFFF : 0)) {}
-
- // Internal utility constructor to simplify return statements
- SimdFBool(uint32x4_t simd) : simdInternal_(simd) {}
-
- uint32x4_t simdInternal_;
-};
-
-class SimdFIBool
-{
-public:
- SimdFIBool() {}
-
- SimdFIBool(bool b) : simdInternal_(vdupq_n_u32(b ? 0xFFFFFFFF : 0)) {}
-
- // Internal utility constructor to simplify return statements
- SimdFIBool(uint32x4_t simd) : simdInternal_(simd) {}
-
- uint32x4_t simdInternal_;
-};
-
-static inline SimdFloat gmx_simdcall simdLoad(const float* m, SimdFloatTag = {})
-{
- assert(std::size_t(m) % 16 == 0);
- return { vld1q_f32(m) };
-}
-
-static inline void gmx_simdcall store(float* m, SimdFloat a)
-{
- assert(std::size_t(m) % 16 == 0);
- vst1q_f32(m, a.simdInternal_);
-}
-
-static inline SimdFloat gmx_simdcall simdLoadU(const float* m, SimdFloatTag = {})
-{
- return { vld1q_f32(m) };
-}
-
-static inline void gmx_simdcall storeU(float* m, SimdFloat a)
-{
- vst1q_f32(m, a.simdInternal_);
-}
-
-static inline SimdFloat gmx_simdcall setZeroF()
-{
- return { vdupq_n_f32(0.0F) };
-}
-
-static inline SimdFInt32 gmx_simdcall simdLoad(const std::int32_t* m, SimdFInt32Tag)
-{
- assert(std::size_t(m) % 16 == 0);
- return { vld1q_s32(m) };
-}
-
-static inline void gmx_simdcall store(std::int32_t* m, SimdFInt32 a)
-{
- assert(std::size_t(m) % 16 == 0);
- vst1q_s32(m, a.simdInternal_);
-}
-
-static inline SimdFInt32 gmx_simdcall simdLoadU(const std::int32_t* m, SimdFInt32Tag)
-{
- return { vld1q_s32(m) };
-}
-
-static inline void gmx_simdcall storeU(std::int32_t* m, SimdFInt32 a)
-{
- vst1q_s32(m, a.simdInternal_);
-}
-
-static inline SimdFInt32 gmx_simdcall setZeroFI()
-{
- return { vdupq_n_s32(0) };
-}
-
-template<int index>
-gmx_simdcall static inline std::int32_t extract(SimdFInt32 a)
-{
- return vgetq_lane_s32(a.simdInternal_, index);
-}
-
-static inline SimdFloat gmx_simdcall operator&(SimdFloat a, SimdFloat b)
-{
- return { vreinterpretq_f32_s32(vandq_s32(vreinterpretq_s32_f32(a.simdInternal_),
- vreinterpretq_s32_f32(b.simdInternal_))) };
-}
-
-static inline SimdFloat gmx_simdcall andNot(SimdFloat a, SimdFloat b)
-{
- return { vreinterpretq_f32_s32(vbicq_s32(vreinterpretq_s32_f32(b.simdInternal_),
- vreinterpretq_s32_f32(a.simdInternal_))) };
-}
-
-static inline SimdFloat gmx_simdcall operator|(SimdFloat a, SimdFloat b)
-{
- return { vreinterpretq_f32_s32(vorrq_s32(vreinterpretq_s32_f32(a.simdInternal_),
- vreinterpretq_s32_f32(b.simdInternal_))) };
-}
-
-static inline SimdFloat gmx_simdcall operator^(SimdFloat a, SimdFloat b)
-{
- return { vreinterpretq_f32_s32(veorq_s32(vreinterpretq_s32_f32(a.simdInternal_),
- vreinterpretq_s32_f32(b.simdInternal_))) };
-}
-
-static inline SimdFloat gmx_simdcall operator+(SimdFloat a, SimdFloat b)
-{
- return { vaddq_f32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall operator-(SimdFloat a, SimdFloat b)
-{
- return { vsubq_f32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall operator-(SimdFloat x)
-{
- return { vnegq_f32(x.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall operator*(SimdFloat a, SimdFloat b)
-{
- return { vmulq_f32(a.simdInternal_, b.simdInternal_) };
-}
-
-// Override for Neon-Asimd
-#if GMX_SIMD_ARM_NEON
-static inline SimdFloat gmx_simdcall fma(SimdFloat a, SimdFloat b, SimdFloat c)
-{
- return {
-# ifdef __ARM_FEATURE_FMA
- vfmaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_)
-# else
- vmlaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_)
-# endif
- };
-}
-
-static inline SimdFloat gmx_simdcall fms(SimdFloat a, SimdFloat b, SimdFloat c)
-{
- return {
-# ifdef __ARM_FEATURE_FMA
- vnegq_f32(vfmsq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_))
-# else
- vnegq_f32(vmlsq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_))
-# endif
- };
-}
-
-static inline SimdFloat gmx_simdcall fnma(SimdFloat a, SimdFloat b, SimdFloat c)
-{
- return {
-# ifdef __ARM_FEATURE_FMA
- vfmsq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_)
-# else
- vmlsq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_)
-# endif
- };
-}
-
-static inline SimdFloat gmx_simdcall fnms(SimdFloat a, SimdFloat b, SimdFloat c)
-{
- return {
-# ifdef __ARM_FEATURE_FMA
- vnegq_f32(vfmaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_))
-# else
- vnegq_f32(vmlaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_))
-# endif
- };
-}
-#endif
-
-static inline SimdFloat gmx_simdcall rsqrt(SimdFloat x)
-{
- return { vrsqrteq_f32(x.simdInternal_) };
-}
-
-// The SIMD implementation seems to overflow when we square lu for
-// values close to FLOAT_MAX, so we fall back on the version in
-// simd_math.h, which is probably slightly slower.
-#if GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT
-static inline SimdFloat gmx_simdcall rsqrtIter(SimdFloat lu, SimdFloat x)
-{
- return { vmulq_f32(lu.simdInternal_,
- vrsqrtsq_f32(vmulq_f32(lu.simdInternal_, lu.simdInternal_), x.simdInternal_)) };
-}
-#endif
-
-static inline SimdFloat gmx_simdcall rcp(SimdFloat x)
-{
- return { vrecpeq_f32(x.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall rcpIter(SimdFloat lu, SimdFloat x)
-{
- return { vmulq_f32(lu.simdInternal_, vrecpsq_f32(lu.simdInternal_, x.simdInternal_)) };
-}
-
-static inline SimdFloat gmx_simdcall maskAdd(SimdFloat a, SimdFloat b, SimdFBool m)
-{
- b.simdInternal_ =
- vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(b.simdInternal_), m.simdInternal_));
-
- return { vaddq_f32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall maskzMul(SimdFloat a, SimdFloat b, SimdFBool m)
-{
- SimdFloat tmp = a * b;
-
- return { vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(tmp.simdInternal_), m.simdInternal_)) };
-}
-
-static inline SimdFloat gmx_simdcall maskzFma(SimdFloat a, SimdFloat b, SimdFloat c, SimdFBool m)
-{
-#ifdef __ARM_FEATURE_FMA
- float32x4_t tmp = vfmaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_);
-#else
- float32x4_t tmp = vmlaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_);
-#endif
-
- return { vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(tmp), m.simdInternal_)) };
-}
-
-static inline SimdFloat gmx_simdcall maskzRsqrt(SimdFloat x, SimdFBool m)
-{
- // The result will always be correct since we mask the result with m, but
- // for debug builds we also want to make sure not to generate FP exceptions
-#ifndef NDEBUG
- x.simdInternal_ = vbslq_f32(m.simdInternal_, x.simdInternal_, vdupq_n_f32(1.0F));
-#endif
- return { vreinterpretq_f32_u32(
- vandq_u32(vreinterpretq_u32_f32(vrsqrteq_f32(x.simdInternal_)), m.simdInternal_)) };
-}
-
-static inline SimdFloat gmx_simdcall maskzRcp(SimdFloat x, SimdFBool m)
-{
- // The result will always be correct since we mask the result with m, but
- // for debug builds we also want to make sure not to generate FP exceptions
-#ifndef NDEBUG
- x.simdInternal_ = vbslq_f32(m.simdInternal_, x.simdInternal_, vdupq_n_f32(1.0F));
-#endif
- return { vreinterpretq_f32_u32(
- vandq_u32(vreinterpretq_u32_f32(vrecpeq_f32(x.simdInternal_)), m.simdInternal_)) };
-}
-
-static inline SimdFloat gmx_simdcall abs(SimdFloat x)
-{
- return { vabsq_f32(x.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall max(SimdFloat a, SimdFloat b)
-{
- return { vmaxq_f32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall min(SimdFloat a, SimdFloat b)
-{
- return { vminq_f32(a.simdInternal_, b.simdInternal_) };
-}
-
-// Round and trunc operations are defined at the end of this file, since they
-// need to use float-to-integer and integer-to-float conversions.
-
-template<MathOptimization opt = MathOptimization::Safe>
-static inline SimdFloat gmx_simdcall frexp(SimdFloat value, SimdFInt32* exponent)
-{
- const int32x4_t exponentMask = vdupq_n_s32(0x7F800000);
- const int32x4_t mantissaMask = vdupq_n_s32(0x807FFFFF);
- const int32x4_t exponentBias = vdupq_n_s32(126); // add 1 to make our definition identical to frexp()
- 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);
-
- float32x4_t result = 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>
-static inline SimdFloat gmx_simdcall ldexp(SimdFloat value, SimdFInt32 exponent)
-{
- const int32x4_t exponentBias = vdupq_n_s32(127);
- int32x4_t iExponent = vaddq_s32(exponent.simdInternal_, exponentBias);
-
- if (opt == MathOptimization::Safe)
- {
- // Make sure biased argument is not negative
- iExponent = vmaxq_s32(iExponent, vdupq_n_s32(0));
- }
-
- iExponent = vshlq_n_s32(iExponent, 23);
-
- return { vmulq_f32(value.simdInternal_, vreinterpretq_f32_s32(iExponent)) };
-}
-
-// Override for Neon-Asimd
-#if GMX_SIMD_ARM_NEON
-static inline float gmx_simdcall reduce(SimdFloat a)
-{
- float32x4_t x = a.simdInternal_;
- float32x4_t y = vextq_f32(x, x, 2);
-
- x = vaddq_f32(x, y);
- y = vextq_f32(x, x, 1);
- x = vaddq_f32(x, y);
- return vgetq_lane_f32(x, 0);
-}
-#endif
-
-static inline SimdFBool gmx_simdcall operator==(SimdFloat a, SimdFloat b)
-{
- return { vceqq_f32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFBool gmx_simdcall operator!=(SimdFloat a, SimdFloat b)
-{
- return { vmvnq_u32(vceqq_f32(a.simdInternal_, b.simdInternal_)) };
-}
-
-static inline SimdFBool gmx_simdcall operator<(SimdFloat a, SimdFloat b)
-{
- return { vcltq_f32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFBool gmx_simdcall operator<=(SimdFloat a, SimdFloat b)
-{
- return { vcleq_f32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFBool gmx_simdcall testBits(SimdFloat a)
-{
- uint32x4_t tmp = vreinterpretq_u32_f32(a.simdInternal_);
-
- return { vtstq_u32(tmp, tmp) };
-}
-
-static inline SimdFBool gmx_simdcall operator&&(SimdFBool a, SimdFBool b)
-{
-
- return { vandq_u32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFBool gmx_simdcall operator||(SimdFBool a, SimdFBool b)
-{
- return { vorrq_u32(a.simdInternal_, b.simdInternal_) };
-}
-
-// Override for Neon-Asimd
-#if GMX_SIMD_ARM_NEON
-static inline bool gmx_simdcall anyTrue(SimdFBool a)
-{
- uint32x4_t x = a.simdInternal_;
- uint32x4_t y = vextq_u32(x, x, 2);
-
- x = vorrq_u32(x, y);
- y = vextq_u32(x, x, 1);
- x = vorrq_u32(x, y);
- return (vgetq_lane_u32(x, 0) != 0);
-}
-#endif
-
-static inline SimdFloat gmx_simdcall selectByMask(SimdFloat a, SimdFBool m)
-{
- return { vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(a.simdInternal_), m.simdInternal_)) };
-}
-
-static inline SimdFloat gmx_simdcall selectByNotMask(SimdFloat a, SimdFBool m)
-{
- return { vreinterpretq_f32_u32(vbicq_u32(vreinterpretq_u32_f32(a.simdInternal_), m.simdInternal_)) };
-}
-
-static inline SimdFloat gmx_simdcall blend(SimdFloat a, SimdFloat b, SimdFBool sel)
-{
- return { vbslq_f32(sel.simdInternal_, b.simdInternal_, a.simdInternal_) };
-}
-
-static inline SimdFInt32 gmx_simdcall operator&(SimdFInt32 a, SimdFInt32 b)
-{
- return { vandq_s32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFInt32 gmx_simdcall andNot(SimdFInt32 a, SimdFInt32 b)
-{
- return { vbicq_s32(b.simdInternal_, a.simdInternal_) };
-}
-
-static inline SimdFInt32 gmx_simdcall operator|(SimdFInt32 a, SimdFInt32 b)
-{
- return { vorrq_s32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFInt32 gmx_simdcall operator^(SimdFInt32 a, SimdFInt32 b)
-{
- return { veorq_s32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFInt32 gmx_simdcall operator+(SimdFInt32 a, SimdFInt32 b)
-{
- return { vaddq_s32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFInt32 gmx_simdcall operator-(SimdFInt32 a, SimdFInt32 b)
-{
- return { vsubq_s32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFInt32 gmx_simdcall operator*(SimdFInt32 a, SimdFInt32 b)
-{
- return { vmulq_s32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFIBool gmx_simdcall operator==(SimdFInt32 a, SimdFInt32 b)
-{
- return { vceqq_s32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFIBool gmx_simdcall testBits(SimdFInt32 a)
-{
- return { vtstq_s32(a.simdInternal_, a.simdInternal_) };
-}
-
-static inline SimdFIBool gmx_simdcall operator<(SimdFInt32 a, SimdFInt32 b)
-{
- return { vcltq_s32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFIBool gmx_simdcall operator&&(SimdFIBool a, SimdFIBool b)
-{
- return { vandq_u32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFIBool gmx_simdcall operator||(SimdFIBool a, SimdFIBool b)
-{
- return { vorrq_u32(a.simdInternal_, b.simdInternal_) };
-}
-
-// Override for Neon-Asimd
-#if GMX_SIMD_ARM_NEON
-static inline bool gmx_simdcall anyTrue(SimdFIBool a)
-{
- uint32x4_t x = a.simdInternal_;
- uint32x4_t y = vextq_u32(x, x, 2);
-
- x = vorrq_u32(x, y);
- y = vextq_u32(x, x, 1);
- x = vorrq_u32(x, y);
- return (vgetq_lane_u32(x, 0) != 0);
-}
-#endif
-
-static inline SimdFInt32 gmx_simdcall selectByMask(SimdFInt32 a, SimdFIBool m)
-{
- return { vandq_s32(a.simdInternal_, vreinterpretq_s32_u32(m.simdInternal_)) };
-}
-
-static inline SimdFInt32 gmx_simdcall selectByNotMask(SimdFInt32 a, SimdFIBool m)
-{
- return { vbicq_s32(a.simdInternal_, vreinterpretq_s32_u32(m.simdInternal_)) };
-}
-
-static inline SimdFInt32 gmx_simdcall blend(SimdFInt32 a, SimdFInt32 b, SimdFIBool sel)
-{
- return { vbslq_s32(sel.simdInternal_, b.simdInternal_, a.simdInternal_) };
-}
-
-// Override for Neon-Asimd
-#if GMX_SIMD_ARM_NEON
-static inline SimdFInt32 gmx_simdcall cvtR2I(SimdFloat a)
-{
- float32x4_t signBitOfA = vreinterpretq_f32_u32(
- vandq_u32(vdupq_n_u32(0x80000000), vreinterpretq_u32_f32(a.simdInternal_)));
- float32x4_t half = vdupq_n_f32(0.5F);
- float32x4_t corr = vreinterpretq_f32_u32(
- vorrq_u32(vreinterpretq_u32_f32(half), vreinterpretq_u32_f32(signBitOfA)));
-
- return { vcvtq_s32_f32(vaddq_f32(a.simdInternal_, corr)) };
-}
-#endif
-
-static inline SimdFInt32 gmx_simdcall cvttR2I(SimdFloat a)
-{
- return { vcvtq_s32_f32(a.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall cvtI2R(SimdFInt32 a)
-{
- return { vcvtq_f32_s32(a.simdInternal_) };
-}
-
-static inline SimdFIBool gmx_simdcall cvtB2IB(SimdFBool a)
-{
- return { a.simdInternal_ };
-}
-
-static inline SimdFBool gmx_simdcall cvtIB2B(SimdFIBool a)
-{
- return { a.simdInternal_ };
-}
-
-// Override for Neon-Asimd
-#if GMX_SIMD_ARM_NEON
-static inline SimdFloat gmx_simdcall round(SimdFloat x)
-{
- return cvtI2R(cvtR2I(x));
-}
-
-static inline SimdFloat gmx_simdcall trunc(SimdFloat x)
-{
- return cvtI2R(cvttR2I(x));
-}
-#endif
-
-} // namespace gmx
-
-#endif // GMX_SIMD_IMPL_ARM_NEON_SIMD_FLOAT_H
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 2014,2015,2016,2017,2018 by the GROMACS development team.
- * Copyright (c) 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.
- *
- * 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.
- */
-#ifndef GMX_SIMD_IMPL_ARM_NEON_UTIL_FLOAT_H
-#define GMX_SIMD_IMPL_ARM_NEON_UTIL_FLOAT_H
-
-#include "config.h"
-
-#include <cassert>
-#include <cstddef>
-#include <cstdint>
-
-#include <arm_neon.h>
-
-#include "gromacs/utility/basedefinitions.h"
-
-#include "impl_arm_neon_simd_float.h"
-
-
-namespace gmx
-{
-
-template<int align>
-static inline void gmx_simdcall gatherLoadTranspose(const float* base,
- const std::int32_t offset[],
- SimdFloat* v0,
- SimdFloat* v1,
- SimdFloat* v2,
- SimdFloat* v3)
-{
- assert(std::size_t(offset) % 16 == 0);
- assert(std::size_t(base) % 16 == 0);
- assert(align % 4 == 0);
-
- // Unfortunately we cannot use the beautiful Neon structured load
- // instructions since the data comes from four different memory locations.
- float32x4x2_t t0 =
- vuzpq_f32(vld1q_f32(base + align * offset[0]), vld1q_f32(base + align * offset[2]));
- float32x4x2_t t1 =
- vuzpq_f32(vld1q_f32(base + align * offset[1]), vld1q_f32(base + align * offset[3]));
- float32x4x2_t t2 = vtrnq_f32(t0.val[0], t1.val[0]);
- float32x4x2_t t3 = vtrnq_f32(t0.val[1], t1.val[1]);
- v0->simdInternal_ = t2.val[0];
- v1->simdInternal_ = t3.val[0];
- v2->simdInternal_ = t2.val[1];
- v3->simdInternal_ = t3.val[1];
-}
-
-template<int align>
-static inline void gmx_simdcall
- gatherLoadTranspose(const float* base, const std::int32_t offset[], SimdFloat* v0, SimdFloat* v1)
-{
- assert(std::size_t(offset) % 16 == 0);
- assert(std::size_t(base) % 8 == 0);
- assert(align % 2 == 0);
-
- v0->simdInternal_ =
- vcombine_f32(vld1_f32(base + align * offset[0]), vld1_f32(base + align * offset[2]));
- v1->simdInternal_ =
- vcombine_f32(vld1_f32(base + align * offset[1]), vld1_f32(base + align * offset[3]));
-
- float32x4x2_t tmp = vtrnq_f32(v0->simdInternal_, v1->simdInternal_);
-
- v0->simdInternal_ = tmp.val[0];
- v1->simdInternal_ = tmp.val[1];
-}
-
-static const int c_simdBestPairAlignmentFloat = 2;
-
-template<int align>
-static inline void gmx_simdcall gatherLoadUTranspose(const float* base,
- const std::int32_t offset[],
- SimdFloat* v0,
- SimdFloat* v1,
- SimdFloat* v2)
-{
- assert(std::size_t(offset) % 16 == 0);
-
- float32x4x2_t t0 =
- vuzpq_f32(vld1q_f32(base + align * offset[0]), vld1q_f32(base + align * offset[2]));
- float32x4x2_t t1 =
- vuzpq_f32(vld1q_f32(base + align * offset[1]), vld1q_f32(base + align * offset[3]));
- float32x4x2_t t2 = vtrnq_f32(t0.val[0], t1.val[0]);
- float32x4x2_t t3 = vtrnq_f32(t0.val[1], t1.val[1]);
- v0->simdInternal_ = t2.val[0];
- v1->simdInternal_ = t3.val[0];
- v2->simdInternal_ = t2.val[1];
-}
-
-
-template<int align>
-static inline void gmx_simdcall
- transposeScatterStoreU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2)
-{
- assert(std::size_t(offset) % 16 == 0);
-
- float32x4x2_t tmp = vtrnq_f32(v0.simdInternal_, v1.simdInternal_);
-
- vst1_f32(base + align * offset[0], vget_low_f32(tmp.val[0]));
- vst1_f32(base + align * offset[1], vget_low_f32(tmp.val[1]));
- vst1_f32(base + align * offset[2], vget_high_f32(tmp.val[0]));
- vst1_f32(base + align * offset[3], vget_high_f32(tmp.val[1]));
-
- vst1q_lane_f32(base + align * offset[0] + 2, v2.simdInternal_, 0);
- vst1q_lane_f32(base + align * offset[1] + 2, v2.simdInternal_, 1);
- vst1q_lane_f32(base + align * offset[2] + 2, v2.simdInternal_, 2);
- vst1q_lane_f32(base + align * offset[3] + 2, v2.simdInternal_, 3);
-}
-
-
-template<int align>
-static inline void gmx_simdcall
- transposeScatterIncrU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2)
-{
- assert(std::size_t(offset) % 16 == 0);
-
- if (align < 4)
- {
- float32x2_t t0, t1, t2, t3;
- float32x4x2_t tmp = vtrnq_f32(v0.simdInternal_, v1.simdInternal_);
-
- t0 = vget_low_f32(tmp.val[0]);
- t1 = vget_low_f32(tmp.val[1]);
- t2 = vget_high_f32(tmp.val[0]);
- t3 = vget_high_f32(tmp.val[1]);
-
- t0 = vadd_f32(t0, vld1_f32(base + align * offset[0]));
- vst1_f32(base + align * offset[0], t0);
- base[align * offset[0] + 2] += vgetq_lane_f32(v2.simdInternal_, 0);
-
- t1 = vadd_f32(t1, vld1_f32(base + align * offset[1]));
- vst1_f32(base + align * offset[1], t1);
- base[align * offset[1] + 2] += vgetq_lane_f32(v2.simdInternal_, 1);
-
- t2 = vadd_f32(t2, vld1_f32(base + align * offset[2]));
- vst1_f32(base + align * offset[2], t2);
- base[align * offset[2] + 2] += vgetq_lane_f32(v2.simdInternal_, 2);
-
- t3 = vadd_f32(t3, vld1_f32(base + align * offset[3]));
- vst1_f32(base + align * offset[3], t3);
- base[align * offset[3] + 2] += vgetq_lane_f32(v2.simdInternal_, 3);
- }
- else
- {
- // Extra elements means we can use full width-4 load/store operations
- float32x4x2_t t0 = vuzpq_f32(v0.simdInternal_, v2.simdInternal_);
- float32x4x2_t t1 = vuzpq_f32(v1.simdInternal_, vdupq_n_f32(0.0F));
- float32x4x2_t t2 = vtrnq_f32(t0.val[0], t1.val[0]);
- float32x4x2_t t3 = vtrnq_f32(t0.val[1], t1.val[1]);
- float32x4_t t4 = t2.val[0];
- float32x4_t t5 = t3.val[0];
- float32x4_t t6 = t2.val[1];
- float32x4_t t7 = t3.val[1];
-
- vst1q_f32(base + align * offset[0], vaddq_f32(t4, vld1q_f32(base + align * offset[0])));
- vst1q_f32(base + align * offset[1], vaddq_f32(t5, vld1q_f32(base + align * offset[1])));
- vst1q_f32(base + align * offset[2], vaddq_f32(t6, vld1q_f32(base + align * offset[2])));
- vst1q_f32(base + align * offset[3], vaddq_f32(t7, vld1q_f32(base + align * offset[3])));
- }
-}
-
-template<int align>
-static inline void gmx_simdcall
- transposeScatterDecrU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2)
-{
- assert(std::size_t(offset) % 16 == 0);
-
- if (align < 4)
- {
- float32x2_t t0, t1, t2, t3;
- float32x4x2_t tmp = vtrnq_f32(v0.simdInternal_, v1.simdInternal_);
-
- t0 = vget_low_f32(tmp.val[0]);
- t1 = vget_low_f32(tmp.val[1]);
- t2 = vget_high_f32(tmp.val[0]);
- t3 = vget_high_f32(tmp.val[1]);
-
- t0 = vsub_f32(vld1_f32(base + align * offset[0]), t0);
- vst1_f32(base + align * offset[0], t0);
- base[align * offset[0] + 2] -= vgetq_lane_f32(v2.simdInternal_, 0);
-
- t1 = vsub_f32(vld1_f32(base + align * offset[1]), t1);
- vst1_f32(base + align * offset[1], t1);
- base[align * offset[1] + 2] -= vgetq_lane_f32(v2.simdInternal_, 1);
-
- t2 = vsub_f32(vld1_f32(base + align * offset[2]), t2);
- vst1_f32(base + align * offset[2], t2);
- base[align * offset[2] + 2] -= vgetq_lane_f32(v2.simdInternal_, 2);
-
- t3 = vsub_f32(vld1_f32(base + align * offset[3]), t3);
- vst1_f32(base + align * offset[3], t3);
- base[align * offset[3] + 2] -= vgetq_lane_f32(v2.simdInternal_, 3);
- }
- else
- {
- // Extra elements means we can use full width-4 load/store operations
- float32x4x2_t t0 = vuzpq_f32(v0.simdInternal_, v2.simdInternal_);
- float32x4x2_t t1 = vuzpq_f32(v1.simdInternal_, vdupq_n_f32(0.0F));
- float32x4x2_t t2 = vtrnq_f32(t0.val[0], t1.val[0]);
- float32x4x2_t t3 = vtrnq_f32(t0.val[1], t1.val[1]);
- float32x4_t t4 = t2.val[0];
- float32x4_t t5 = t3.val[0];
- float32x4_t t6 = t2.val[1];
- float32x4_t t7 = t3.val[1];
-
- vst1q_f32(base + align * offset[0], vsubq_f32(vld1q_f32(base + align * offset[0]), t4));
- vst1q_f32(base + align * offset[1], vsubq_f32(vld1q_f32(base + align * offset[1]), t5));
- vst1q_f32(base + align * offset[2], vsubq_f32(vld1q_f32(base + align * offset[2]), t6));
- vst1q_f32(base + align * offset[3], vsubq_f32(vld1q_f32(base + align * offset[3]), t7));
- }
-}
-
-static inline void gmx_simdcall expandScalarsToTriplets(SimdFloat scalar,
- SimdFloat* triplets0,
- SimdFloat* triplets1,
- SimdFloat* triplets2)
-{
- float32x2_t lo, hi;
- float32x4_t t0, t1, t2, t3;
-
- lo = vget_low_f32(scalar.simdInternal_);
- hi = vget_high_f32(scalar.simdInternal_);
-
- t0 = vdupq_lane_f32(lo, 0);
- t1 = vdupq_lane_f32(lo, 1);
- t2 = vdupq_lane_f32(hi, 0);
- t3 = vdupq_lane_f32(hi, 1);
-
- triplets0->simdInternal_ = vextq_f32(t0, t1, 1);
- triplets1->simdInternal_ = vextq_f32(t1, t2, 2);
- triplets2->simdInternal_ = vextq_f32(t2, t3, 3);
-}
-
-
-template<int align>
-static inline void gmx_simdcall gatherLoadBySimdIntTranspose(const float* base,
- SimdFInt32 offset,
- SimdFloat* v0,
- SimdFloat* v1,
- SimdFloat* v2,
- SimdFloat* v3)
-{
- alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_FINT32_WIDTH];
-
- assert(std::size_t(base) % 16 == 0);
- assert(align % 4 == 0);
-
- store(ioffset, offset);
- gatherLoadTranspose<align>(base, ioffset, v0, v1, v2, v3);
-}
-
-template<int align>
-static inline void gmx_simdcall
- gatherLoadBySimdIntTranspose(const float* base, SimdFInt32 offset, SimdFloat* v0, SimdFloat* v1)
-{
- alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_FINT32_WIDTH];
-
- store(ioffset, offset);
- gatherLoadTranspose<align>(base, ioffset, v0, v1);
-}
-
-
-template<int align>
-static inline void gmx_simdcall
- gatherLoadUBySimdIntTranspose(const float* base, SimdFInt32 offset, SimdFloat* v0, SimdFloat* v1)
-{
- alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_FINT32_WIDTH];
-
- store(ioffset, offset);
- v0->simdInternal_ =
- vcombine_f32(vld1_f32(base + align * ioffset[0]), vld1_f32(base + align * ioffset[2]));
- v1->simdInternal_ =
- vcombine_f32(vld1_f32(base + align * ioffset[1]), vld1_f32(base + align * ioffset[3]));
- float32x4x2_t tmp = vtrnq_f32(v0->simdInternal_, v1->simdInternal_);
- v0->simdInternal_ = tmp.val[0];
- v1->simdInternal_ = tmp.val[1];
-}
-
-static inline float gmx_simdcall reduceIncr4ReturnSum(float* m, SimdFloat v0, SimdFloat v1, SimdFloat v2, SimdFloat v3)
-{
- assert(std::size_t(m) % 16 == 0);
-
- float32x4x2_t t0 = vuzpq_f32(v0.simdInternal_, v2.simdInternal_);
- float32x4x2_t t1 = vuzpq_f32(v1.simdInternal_, v3.simdInternal_);
- float32x4x2_t t2 = vtrnq_f32(t0.val[0], t1.val[0]);
- float32x4x2_t t3 = vtrnq_f32(t0.val[1], t1.val[1]);
- v0.simdInternal_ = t2.val[0];
- v1.simdInternal_ = t3.val[0];
- v2.simdInternal_ = t2.val[1];
- v3.simdInternal_ = t3.val[1];
-
- v0 = v0 + v1;
- v2 = v2 + v3;
- v0 = v0 + v2;
- v2 = v0 + simdLoad(m);
- store(m, v2);
-
- return reduce(v0);
-}
-
-} // namespace gmx
-
-#endif // GMX_SIMD_IMPL_ARM_NEON_UTIL_FLOAT_H
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015,2019,2021, 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.
* To help us fund GROMACS development, we humbly ask that you cite
* the research papers on the package. Check out http://www.gromacs.org.
*/
-
#ifndef GMX_SIMD_IMPL_ARM_NEON_ASIMD_GENERAL_H
#define GMX_SIMD_IMPL_ARM_NEON_ASIMD_GENERAL_H
-#include "gromacs/simd/impl_arm_neon/impl_arm_neon_general.h"
+namespace gmx
+{
+
+static inline void simdPrefetch(void* m)
+{
+#ifdef __GNUC__
+ __builtin_prefetch(m);
+#endif
+}
+
+} // namespace gmx
#endif // GMX_SIMD_IMPL_ARM_NEON_ASIMD_GENERAL_H
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015,2019,2021, 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.
* To help us fund GROMACS development, we humbly ask that you cite
* the research papers on the package. Check out http://www.gromacs.org.
*/
-
#ifndef GMX_SIMD_IMPL_ARM_NEON_ASIMD_SIMD4_FLOAT_H
#define GMX_SIMD_IMPL_ARM_NEON_ASIMD_SIMD4_FLOAT_H
#include "config.h"
-#include <arm_neon.h>
+#include <cassert>
+#include <cstddef>
-#include "gromacs/simd/impl_arm_neon/impl_arm_neon_simd4_float.h"
+#include <arm_neon.h>
namespace gmx
{
+class Simd4Float
+{
+public:
+ Simd4Float() {}
+
+ Simd4Float(float f) : simdInternal_(vdupq_n_f32(f)) {}
+
+ // Internal utility constructor to simplify return statements
+ Simd4Float(float32x4_t simd) : simdInternal_(simd) {}
+
+ float32x4_t simdInternal_;
+};
+
+class Simd4FBool
+{
+public:
+ Simd4FBool() {}
+
+ //! \brief Construct from scalar bool
+ Simd4FBool(bool b) : simdInternal_(vdupq_n_u32(b ? 0xFFFFFFFF : 0)) {}
+
+ // Internal utility constructor to simplify return statements
+ Simd4FBool(uint32x4_t simd) : simdInternal_(simd) {}
+
+ uint32x4_t simdInternal_;
+};
+
+static inline Simd4Float gmx_simdcall load4(const float* m)
+{
+ assert(size_t(m) % 16 == 0);
+ return { vld1q_f32(m) };
+}
+
+static inline void gmx_simdcall store4(float* m, Simd4Float a)
+{
+ assert(size_t(m) % 16 == 0);
+ vst1q_f32(m, a.simdInternal_);
+}
+
+static inline Simd4Float gmx_simdcall load4U(const float* m)
+{
+ return { vld1q_f32(m) };
+}
+
+static inline void gmx_simdcall store4U(float* m, Simd4Float a)
+{
+ vst1q_f32(m, a.simdInternal_);
+}
+
+static inline Simd4Float gmx_simdcall simd4SetZeroF()
+{
+ return { vdupq_n_f32(0.0F) };
+}
+
+static inline Simd4Float gmx_simdcall operator&(Simd4Float a, Simd4Float b)
+{
+ return { vreinterpretq_f32_s32(vandq_s32(vreinterpretq_s32_f32(a.simdInternal_),
+ vreinterpretq_s32_f32(b.simdInternal_))) };
+}
+
+static inline Simd4Float gmx_simdcall andNot(Simd4Float a, Simd4Float b)
+{
+ return { vreinterpretq_f32_s32(vbicq_s32(vreinterpretq_s32_f32(b.simdInternal_),
+ vreinterpretq_s32_f32(a.simdInternal_))) };
+}
+
+static inline Simd4Float gmx_simdcall operator|(Simd4Float a, Simd4Float b)
+{
+ return { vreinterpretq_f32_s32(vorrq_s32(vreinterpretq_s32_f32(a.simdInternal_),
+ vreinterpretq_s32_f32(b.simdInternal_))) };
+}
+
+static inline Simd4Float gmx_simdcall operator^(Simd4Float a, Simd4Float b)
+{
+ return { vreinterpretq_f32_s32(veorq_s32(vreinterpretq_s32_f32(a.simdInternal_),
+ vreinterpretq_s32_f32(b.simdInternal_))) };
+}
+
+static inline Simd4Float gmx_simdcall operator+(Simd4Float a, Simd4Float b)
+{
+ return { vaddq_f32(a.simdInternal_, b.simdInternal_) };
+}
+
+static inline Simd4Float gmx_simdcall operator-(Simd4Float a, Simd4Float b)
+{
+ return { vsubq_f32(a.simdInternal_, b.simdInternal_) };
+}
+
+static inline Simd4Float gmx_simdcall operator-(Simd4Float x)
+{
+ return { vnegq_f32(x.simdInternal_) };
+}
+
+static inline Simd4Float gmx_simdcall operator*(Simd4Float a, Simd4Float b)
+{
+ return { vmulq_f32(a.simdInternal_, b.simdInternal_) };
+}
+
+static inline Simd4Float gmx_simdcall rsqrt(Simd4Float x)
+{
+ return { vrsqrteq_f32(x.simdInternal_) };
+}
+
+static inline Simd4Float gmx_simdcall abs(Simd4Float x)
+{
+ return { vabsq_f32(x.simdInternal_) };
+}
+
+static inline Simd4Float gmx_simdcall max(Simd4Float a, Simd4Float b)
+{
+ return { vmaxq_f32(a.simdInternal_, b.simdInternal_) };
+}
+
+static inline Simd4Float gmx_simdcall min(Simd4Float a, Simd4Float b)
+{
+ return { vminq_f32(a.simdInternal_, b.simdInternal_) };
+}
+
+static inline void gmx_simdcall transpose(Simd4Float* v0, Simd4Float* v1, Simd4Float* v2, Simd4Float* v3)
+{
+ float32x4x2_t t0 = vuzpq_f32(v0->simdInternal_, v2->simdInternal_);
+ float32x4x2_t t1 = vuzpq_f32(v1->simdInternal_, v3->simdInternal_);
+ float32x4x2_t t2 = vtrnq_f32(t0.val[0], t1.val[0]);
+ float32x4x2_t t3 = vtrnq_f32(t0.val[1], t1.val[1]);
+ v0->simdInternal_ = t2.val[0];
+ v1->simdInternal_ = t3.val[0];
+ v2->simdInternal_ = t2.val[1];
+ v3->simdInternal_ = t3.val[1];
+}
+
+static inline Simd4FBool gmx_simdcall operator==(Simd4Float a, Simd4Float b)
+{
+ return { vceqq_f32(a.simdInternal_, b.simdInternal_) };
+}
+
+static inline Simd4FBool gmx_simdcall operator!=(Simd4Float a, Simd4Float b)
+{
+ return { vmvnq_u32(vceqq_f32(a.simdInternal_, b.simdInternal_)) };
+}
+
+static inline Simd4FBool gmx_simdcall operator<(Simd4Float a, Simd4Float b)
+{
+ return { vcltq_f32(a.simdInternal_, b.simdInternal_) };
+}
+
+static inline Simd4FBool gmx_simdcall operator<=(Simd4Float a, Simd4Float b)
+{
+ return { vcleq_f32(a.simdInternal_, b.simdInternal_) };
+}
+
+static inline Simd4FBool gmx_simdcall operator&&(Simd4FBool a, Simd4FBool b)
+{
+ return { vandq_u32(a.simdInternal_, b.simdInternal_) };
+}
+
+static inline Simd4FBool gmx_simdcall operator||(Simd4FBool a, Simd4FBool b)
+{
+ return { vorrq_u32(a.simdInternal_, b.simdInternal_) };
+}
+
+static inline Simd4Float gmx_simdcall selectByMask(Simd4Float a, Simd4FBool m)
+{
+ return { vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(a.simdInternal_), m.simdInternal_)) };
+}
+
+static inline Simd4Float gmx_simdcall selectByNotMask(Simd4Float a, Simd4FBool m)
+{
+ return { vreinterpretq_f32_u32(vbicq_u32(vreinterpretq_u32_f32(a.simdInternal_), m.simdInternal_)) };
+}
+
+static inline Simd4Float gmx_simdcall blend(Simd4Float a, Simd4Float b, Simd4FBool sel)
+{
+ return { vbslq_f32(sel.simdInternal_, b.simdInternal_, a.simdInternal_) };
+}
+
static inline Simd4Float gmx_simdcall fma(Simd4Float a, Simd4Float b, Simd4Float c)
{
return { vfmaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_) };
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015,2016,2017,2019,2020, by the GROMACS development team.
+ * Copyright (c) 2021, 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.
* To help us fund GROMACS development, we humbly ask that you cite
* the research papers on the package. Check out http://www.gromacs.org.
*/
-
#ifndef GMX_SIMD_IMPL_ARM_NEON_ASIMD_SIMD_FLOAT_H
#define GMX_SIMD_IMPL_ARM_NEON_ASIMD_SIMD_FLOAT_H
#include "config.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+
#include <arm_neon.h>
-#include "gromacs/simd/impl_arm_neon/impl_arm_neon_simd_float.h"
+#include "gromacs/math/utilities.h"
namespace gmx
{
+class SimdFloat
+{
+public:
+ SimdFloat() {}
+
+ SimdFloat(float f) : simdInternal_(vdupq_n_f32(f)) {}
+
+ // Internal utility constructor to simplify return statements
+ SimdFloat(float32x4_t simd) : simdInternal_(simd) {}
+
+ float32x4_t simdInternal_;
+};
+
+class SimdFInt32
+{
+public:
+ SimdFInt32() {}
+
+ SimdFInt32(std::int32_t i) : simdInternal_(vdupq_n_s32(i)) {}
+
+ // Internal utility constructor to simplify return statements
+ SimdFInt32(int32x4_t simd) : simdInternal_(simd) {}
+
+ int32x4_t simdInternal_;
+};
+
+class SimdFBool
+{
+public:
+ SimdFBool() {}
+
+ SimdFBool(bool b) : simdInternal_(vdupq_n_u32(b ? 0xFFFFFFFF : 0)) {}
+
+ // Internal utility constructor to simplify return statements
+ SimdFBool(uint32x4_t simd) : simdInternal_(simd) {}
+
+ uint32x4_t simdInternal_;
+};
+
+class SimdFIBool
+{
+public:
+ SimdFIBool() {}
+
+ SimdFIBool(bool b) : simdInternal_(vdupq_n_u32(b ? 0xFFFFFFFF : 0)) {}
+
+ // Internal utility constructor to simplify return statements
+ SimdFIBool(uint32x4_t simd) : simdInternal_(simd) {}
+
+ uint32x4_t simdInternal_;
+};
+
+static inline SimdFloat gmx_simdcall simdLoad(const float* m, SimdFloatTag = {})
+{
+ assert(std::size_t(m) % 16 == 0);
+ return { vld1q_f32(m) };
+}
+
+static inline void gmx_simdcall store(float* m, SimdFloat a)
+{
+ assert(std::size_t(m) % 16 == 0);
+ vst1q_f32(m, a.simdInternal_);
+}
+
+static inline SimdFloat gmx_simdcall simdLoadU(const float* m, SimdFloatTag = {})
+{
+ return { vld1q_f32(m) };
+}
+
+static inline void gmx_simdcall storeU(float* m, SimdFloat a)
+{
+ vst1q_f32(m, a.simdInternal_);
+}
+
+static inline SimdFloat gmx_simdcall setZeroF()
+{
+ return { vdupq_n_f32(0.0F) };
+}
+
+static inline SimdFInt32 gmx_simdcall simdLoad(const std::int32_t* m, SimdFInt32Tag)
+{
+ assert(std::size_t(m) % 16 == 0);
+ return { vld1q_s32(m) };
+}
+
+static inline void gmx_simdcall store(std::int32_t* m, SimdFInt32 a)
+{
+ assert(std::size_t(m) % 16 == 0);
+ vst1q_s32(m, a.simdInternal_);
+}
+
+static inline SimdFInt32 gmx_simdcall simdLoadU(const std::int32_t* m, SimdFInt32Tag)
+{
+ return { vld1q_s32(m) };
+}
+
+static inline void gmx_simdcall storeU(std::int32_t* m, SimdFInt32 a)
+{
+ vst1q_s32(m, a.simdInternal_);
+}
+
+static inline SimdFInt32 gmx_simdcall setZeroFI()
+{
+ return { vdupq_n_s32(0) };
+}
+
+template<int index>
+gmx_simdcall static inline std::int32_t extract(SimdFInt32 a)
+{
+ return vgetq_lane_s32(a.simdInternal_, index);
+}
+
+static inline SimdFloat gmx_simdcall operator&(SimdFloat a, SimdFloat b)
+{
+ return { vreinterpretq_f32_s32(vandq_s32(vreinterpretq_s32_f32(a.simdInternal_),
+ vreinterpretq_s32_f32(b.simdInternal_))) };
+}
+
+static inline SimdFloat gmx_simdcall andNot(SimdFloat a, SimdFloat b)
+{
+ return { vreinterpretq_f32_s32(vbicq_s32(vreinterpretq_s32_f32(b.simdInternal_),
+ vreinterpretq_s32_f32(a.simdInternal_))) };
+}
+
+static inline SimdFloat gmx_simdcall operator|(SimdFloat a, SimdFloat b)
+{
+ return { vreinterpretq_f32_s32(vorrq_s32(vreinterpretq_s32_f32(a.simdInternal_),
+ vreinterpretq_s32_f32(b.simdInternal_))) };
+}
+
+static inline SimdFloat gmx_simdcall operator^(SimdFloat a, SimdFloat b)
+{
+ return { vreinterpretq_f32_s32(veorq_s32(vreinterpretq_s32_f32(a.simdInternal_),
+ vreinterpretq_s32_f32(b.simdInternal_))) };
+}
+
+static inline SimdFloat gmx_simdcall operator+(SimdFloat a, SimdFloat b)
+{
+ return { vaddq_f32(a.simdInternal_, b.simdInternal_) };
+}
+
+static inline SimdFloat gmx_simdcall operator-(SimdFloat a, SimdFloat b)
+{
+ return { vsubq_f32(a.simdInternal_, b.simdInternal_) };
+}
+
+static inline SimdFloat gmx_simdcall operator-(SimdFloat x)
+{
+ return { vnegq_f32(x.simdInternal_) };
+}
+
+static inline SimdFloat gmx_simdcall operator*(SimdFloat a, SimdFloat b)
+{
+ return { vmulq_f32(a.simdInternal_, b.simdInternal_) };
+}
+
+static inline SimdFloat gmx_simdcall rsqrt(SimdFloat x)
+{
+ return { vrsqrteq_f32(x.simdInternal_) };
+}
+
+// The SIMD implementation seems to overflow when we square lu for
+// values close to FLOAT_MAX, so we fall back on the version in
+// simd_math.h, which is probably slightly slower.
+#if GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT
+static inline SimdFloat gmx_simdcall rsqrtIter(SimdFloat lu, SimdFloat x)
+{
+ return { vmulq_f32(lu.simdInternal_,
+ vrsqrtsq_f32(vmulq_f32(lu.simdInternal_, lu.simdInternal_), x.simdInternal_)) };
+}
+#endif
+
+static inline SimdFloat gmx_simdcall rcp(SimdFloat x)
+{
+ return { vrecpeq_f32(x.simdInternal_) };
+}
+
+static inline SimdFloat gmx_simdcall rcpIter(SimdFloat lu, SimdFloat x)
+{
+ return { vmulq_f32(lu.simdInternal_, vrecpsq_f32(lu.simdInternal_, x.simdInternal_)) };
+}
+
+static inline SimdFloat gmx_simdcall maskAdd(SimdFloat a, SimdFloat b, SimdFBool m)
+{
+ b.simdInternal_ =
+ vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(b.simdInternal_), m.simdInternal_));
+
+ return { vaddq_f32(a.simdInternal_, b.simdInternal_) };
+}
+
+static inline SimdFloat gmx_simdcall maskzMul(SimdFloat a, SimdFloat b, SimdFBool m)
+{
+ SimdFloat tmp = a * b;
+
+ return { vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(tmp.simdInternal_), m.simdInternal_)) };
+}
+
+static inline SimdFloat gmx_simdcall maskzFma(SimdFloat a, SimdFloat b, SimdFloat c, SimdFBool m)
+{
+#ifdef __ARM_FEATURE_FMA
+ float32x4_t tmp = vfmaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_);
+#else
+ float32x4_t tmp = vmlaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_);
+#endif
+
+ return { vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(tmp), m.simdInternal_)) };
+}
+
+static inline SimdFloat gmx_simdcall maskzRsqrt(SimdFloat x, SimdFBool m)
+{
+ // The result will always be correct since we mask the result with m, but
+ // for debug builds we also want to make sure not to generate FP exceptions
+#ifndef NDEBUG
+ x.simdInternal_ = vbslq_f32(m.simdInternal_, x.simdInternal_, vdupq_n_f32(1.0F));
+#endif
+ return { vreinterpretq_f32_u32(
+ vandq_u32(vreinterpretq_u32_f32(vrsqrteq_f32(x.simdInternal_)), m.simdInternal_)) };
+}
+
+static inline SimdFloat gmx_simdcall maskzRcp(SimdFloat x, SimdFBool m)
+{
+ // The result will always be correct since we mask the result with m, but
+ // for debug builds we also want to make sure not to generate FP exceptions
+#ifndef NDEBUG
+ x.simdInternal_ = vbslq_f32(m.simdInternal_, x.simdInternal_, vdupq_n_f32(1.0F));
+#endif
+ return { vreinterpretq_f32_u32(
+ vandq_u32(vreinterpretq_u32_f32(vrecpeq_f32(x.simdInternal_)), m.simdInternal_)) };
+}
+
+static inline SimdFloat gmx_simdcall abs(SimdFloat x)
+{
+ return { vabsq_f32(x.simdInternal_) };
+}
+
+static inline SimdFloat gmx_simdcall max(SimdFloat a, SimdFloat b)
+{
+ return { vmaxq_f32(a.simdInternal_, b.simdInternal_) };
+}
+
+static inline SimdFloat gmx_simdcall min(SimdFloat a, SimdFloat b)
+{
+ return { vminq_f32(a.simdInternal_, b.simdInternal_) };
+}
+
+// Round and trunc operations are defined at the end of this file, since they
+// need to use float-to-integer and integer-to-float conversions.
+
+template<MathOptimization opt = MathOptimization::Safe>
+static inline SimdFloat gmx_simdcall frexp(SimdFloat value, SimdFInt32* exponent)
+{
+ const int32x4_t exponentMask = vdupq_n_s32(0x7F800000);
+ const int32x4_t mantissaMask = vdupq_n_s32(0x807FFFFF);
+ const int32x4_t exponentBias = vdupq_n_s32(126); // add 1 to make our definition identical to frexp()
+ 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);
+
+ float32x4_t result = 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>
+static inline SimdFloat gmx_simdcall ldexp(SimdFloat value, SimdFInt32 exponent)
+{
+ const int32x4_t exponentBias = vdupq_n_s32(127);
+ int32x4_t iExponent = vaddq_s32(exponent.simdInternal_, exponentBias);
+
+ if (opt == MathOptimization::Safe)
+ {
+ // Make sure biased argument is not negative
+ iExponent = vmaxq_s32(iExponent, vdupq_n_s32(0));
+ }
+
+ iExponent = vshlq_n_s32(iExponent, 23);
+
+ return { vmulq_f32(value.simdInternal_, vreinterpretq_f32_s32(iExponent)) };
+}
+
+static inline SimdFBool gmx_simdcall operator==(SimdFloat a, SimdFloat b)
+{
+ return { vceqq_f32(a.simdInternal_, b.simdInternal_) };
+}
+
+static inline SimdFBool gmx_simdcall operator!=(SimdFloat a, SimdFloat b)
+{
+ return { vmvnq_u32(vceqq_f32(a.simdInternal_, b.simdInternal_)) };
+}
+
+static inline SimdFBool gmx_simdcall operator<(SimdFloat a, SimdFloat b)
+{
+ return { vcltq_f32(a.simdInternal_, b.simdInternal_) };
+}
+
+static inline SimdFBool gmx_simdcall operator<=(SimdFloat a, SimdFloat b)
+{
+ return { vcleq_f32(a.simdInternal_, b.simdInternal_) };
+}
+
+static inline SimdFBool gmx_simdcall testBits(SimdFloat a)
+{
+ uint32x4_t tmp = vreinterpretq_u32_f32(a.simdInternal_);
+
+ return { vtstq_u32(tmp, tmp) };
+}
+
+static inline SimdFBool gmx_simdcall operator&&(SimdFBool a, SimdFBool b)
+{
+
+ return { vandq_u32(a.simdInternal_, b.simdInternal_) };
+}
+
+static inline SimdFBool gmx_simdcall operator||(SimdFBool a, SimdFBool b)
+{
+ return { vorrq_u32(a.simdInternal_, b.simdInternal_) };
+}
+
+static inline SimdFloat gmx_simdcall selectByMask(SimdFloat a, SimdFBool m)
+{
+ return { vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(a.simdInternal_), m.simdInternal_)) };
+}
+
+static inline SimdFloat gmx_simdcall selectByNotMask(SimdFloat a, SimdFBool m)
+{
+ return { vreinterpretq_f32_u32(vbicq_u32(vreinterpretq_u32_f32(a.simdInternal_), m.simdInternal_)) };
+}
+
+static inline SimdFloat gmx_simdcall blend(SimdFloat a, SimdFloat b, SimdFBool sel)
+{
+ return { vbslq_f32(sel.simdInternal_, b.simdInternal_, a.simdInternal_) };
+}
+
+static inline SimdFInt32 gmx_simdcall operator&(SimdFInt32 a, SimdFInt32 b)
+{
+ return { vandq_s32(a.simdInternal_, b.simdInternal_) };
+}
+
+static inline SimdFInt32 gmx_simdcall andNot(SimdFInt32 a, SimdFInt32 b)
+{
+ return { vbicq_s32(b.simdInternal_, a.simdInternal_) };
+}
+
+static inline SimdFInt32 gmx_simdcall operator|(SimdFInt32 a, SimdFInt32 b)
+{
+ return { vorrq_s32(a.simdInternal_, b.simdInternal_) };
+}
+
+static inline SimdFInt32 gmx_simdcall operator^(SimdFInt32 a, SimdFInt32 b)
+{
+ return { veorq_s32(a.simdInternal_, b.simdInternal_) };
+}
+
+static inline SimdFInt32 gmx_simdcall operator+(SimdFInt32 a, SimdFInt32 b)
+{
+ return { vaddq_s32(a.simdInternal_, b.simdInternal_) };
+}
+
+static inline SimdFInt32 gmx_simdcall operator-(SimdFInt32 a, SimdFInt32 b)
+{
+ return { vsubq_s32(a.simdInternal_, b.simdInternal_) };
+}
+
+static inline SimdFInt32 gmx_simdcall operator*(SimdFInt32 a, SimdFInt32 b)
+{
+ return { vmulq_s32(a.simdInternal_, b.simdInternal_) };
+}
+
+static inline SimdFIBool gmx_simdcall operator==(SimdFInt32 a, SimdFInt32 b)
+{
+ return { vceqq_s32(a.simdInternal_, b.simdInternal_) };
+}
+
+static inline SimdFIBool gmx_simdcall testBits(SimdFInt32 a)
+{
+ return { vtstq_s32(a.simdInternal_, a.simdInternal_) };
+}
+
+static inline SimdFIBool gmx_simdcall operator<(SimdFInt32 a, SimdFInt32 b)
+{
+ return { vcltq_s32(a.simdInternal_, b.simdInternal_) };
+}
+
+static inline SimdFIBool gmx_simdcall operator&&(SimdFIBool a, SimdFIBool b)
+{
+ return { vandq_u32(a.simdInternal_, b.simdInternal_) };
+}
+
+static inline SimdFIBool gmx_simdcall operator||(SimdFIBool a, SimdFIBool b)
+{
+ return { vorrq_u32(a.simdInternal_, b.simdInternal_) };
+}
+
+static inline SimdFInt32 gmx_simdcall selectByMask(SimdFInt32 a, SimdFIBool m)
+{
+ return { vandq_s32(a.simdInternal_, vreinterpretq_s32_u32(m.simdInternal_)) };
+}
+
+static inline SimdFInt32 gmx_simdcall selectByNotMask(SimdFInt32 a, SimdFIBool m)
+{
+ return { vbicq_s32(a.simdInternal_, vreinterpretq_s32_u32(m.simdInternal_)) };
+}
+
+static inline SimdFInt32 gmx_simdcall blend(SimdFInt32 a, SimdFInt32 b, SimdFIBool sel)
+{
+ return { vbslq_s32(sel.simdInternal_, b.simdInternal_, a.simdInternal_) };
+}
+
+static inline SimdFInt32 gmx_simdcall cvttR2I(SimdFloat a)
+{
+ return { vcvtq_s32_f32(a.simdInternal_) };
+}
+
+static inline SimdFloat gmx_simdcall cvtI2R(SimdFInt32 a)
+{
+ return { vcvtq_f32_s32(a.simdInternal_) };
+}
+
+static inline SimdFIBool gmx_simdcall cvtB2IB(SimdFBool a)
+{
+ return { a.simdInternal_ };
+}
+
+static inline SimdFBool gmx_simdcall cvtIB2B(SimdFIBool a)
+{
+ return { a.simdInternal_ };
+}
+
static inline SimdFloat gmx_simdcall fma(SimdFloat a, SimdFloat b, SimdFloat c)
{
return { vfmaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_) };
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015,2016,2017,2018 by the GROMACS development team.
+ * Copyright (c) 2019,2020,2021, 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.
* To help us fund GROMACS development, we humbly ask that you cite
* the research papers on the package. Check out http://www.gromacs.org.
*/
-
#ifndef GMX_SIMD_IMPL_ARM_NEON_ASIMD_UTIL_FLOAT_H
#define GMX_SIMD_IMPL_ARM_NEON_ASIMD_UTIL_FLOAT_H
-#include "gromacs/simd/impl_arm_neon/impl_arm_neon_util_float.h"
+#include "config.h"
+
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+
+#include <arm_neon.h>
+
+#include "gromacs/utility/basedefinitions.h"
+
+
+namespace gmx
+{
+
+template<int align>
+static inline void gmx_simdcall gatherLoadTranspose(const float* base,
+ const std::int32_t offset[],
+ SimdFloat* v0,
+ SimdFloat* v1,
+ SimdFloat* v2,
+ SimdFloat* v3)
+{
+ assert(std::size_t(offset) % 16 == 0);
+ assert(std::size_t(base) % 16 == 0);
+ assert(align % 4 == 0);
+
+ // Unfortunately we cannot use the beautiful Neon structured load
+ // instructions since the data comes from four different memory locations.
+ float32x4x2_t t0 =
+ vuzpq_f32(vld1q_f32(base + align * offset[0]), vld1q_f32(base + align * offset[2]));
+ float32x4x2_t t1 =
+ vuzpq_f32(vld1q_f32(base + align * offset[1]), vld1q_f32(base + align * offset[3]));
+ float32x4x2_t t2 = vtrnq_f32(t0.val[0], t1.val[0]);
+ float32x4x2_t t3 = vtrnq_f32(t0.val[1], t1.val[1]);
+ v0->simdInternal_ = t2.val[0];
+ v1->simdInternal_ = t3.val[0];
+ v2->simdInternal_ = t2.val[1];
+ v3->simdInternal_ = t3.val[1];
+}
+
+template<int align>
+static inline void gmx_simdcall
+ gatherLoadTranspose(const float* base, const std::int32_t offset[], SimdFloat* v0, SimdFloat* v1)
+{
+ assert(std::size_t(offset) % 16 == 0);
+ assert(std::size_t(base) % 8 == 0);
+ assert(align % 2 == 0);
+
+ v0->simdInternal_ =
+ vcombine_f32(vld1_f32(base + align * offset[0]), vld1_f32(base + align * offset[2]));
+ v1->simdInternal_ =
+ vcombine_f32(vld1_f32(base + align * offset[1]), vld1_f32(base + align * offset[3]));
+
+ float32x4x2_t tmp = vtrnq_f32(v0->simdInternal_, v1->simdInternal_);
+
+ v0->simdInternal_ = tmp.val[0];
+ v1->simdInternal_ = tmp.val[1];
+}
+
+static const int c_simdBestPairAlignmentFloat = 2;
+
+template<int align>
+static inline void gmx_simdcall gatherLoadUTranspose(const float* base,
+ const std::int32_t offset[],
+ SimdFloat* v0,
+ SimdFloat* v1,
+ SimdFloat* v2)
+{
+ assert(std::size_t(offset) % 16 == 0);
+
+ float32x4x2_t t0 =
+ vuzpq_f32(vld1q_f32(base + align * offset[0]), vld1q_f32(base + align * offset[2]));
+ float32x4x2_t t1 =
+ vuzpq_f32(vld1q_f32(base + align * offset[1]), vld1q_f32(base + align * offset[3]));
+ float32x4x2_t t2 = vtrnq_f32(t0.val[0], t1.val[0]);
+ float32x4x2_t t3 = vtrnq_f32(t0.val[1], t1.val[1]);
+ v0->simdInternal_ = t2.val[0];
+ v1->simdInternal_ = t3.val[0];
+ v2->simdInternal_ = t2.val[1];
+}
+
+
+template<int align>
+static inline void gmx_simdcall
+ transposeScatterStoreU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2)
+{
+ assert(std::size_t(offset) % 16 == 0);
+
+ float32x4x2_t tmp = vtrnq_f32(v0.simdInternal_, v1.simdInternal_);
+
+ vst1_f32(base + align * offset[0], vget_low_f32(tmp.val[0]));
+ vst1_f32(base + align * offset[1], vget_low_f32(tmp.val[1]));
+ vst1_f32(base + align * offset[2], vget_high_f32(tmp.val[0]));
+ vst1_f32(base + align * offset[3], vget_high_f32(tmp.val[1]));
+
+ vst1q_lane_f32(base + align * offset[0] + 2, v2.simdInternal_, 0);
+ vst1q_lane_f32(base + align * offset[1] + 2, v2.simdInternal_, 1);
+ vst1q_lane_f32(base + align * offset[2] + 2, v2.simdInternal_, 2);
+ vst1q_lane_f32(base + align * offset[3] + 2, v2.simdInternal_, 3);
+}
+
+
+template<int align>
+static inline void gmx_simdcall
+ transposeScatterIncrU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2)
+{
+ assert(std::size_t(offset) % 16 == 0);
+
+ if (align < 4)
+ {
+ float32x2_t t0, t1, t2, t3;
+ float32x4x2_t tmp = vtrnq_f32(v0.simdInternal_, v1.simdInternal_);
+
+ t0 = vget_low_f32(tmp.val[0]);
+ t1 = vget_low_f32(tmp.val[1]);
+ t2 = vget_high_f32(tmp.val[0]);
+ t3 = vget_high_f32(tmp.val[1]);
+
+ t0 = vadd_f32(t0, vld1_f32(base + align * offset[0]));
+ vst1_f32(base + align * offset[0], t0);
+ base[align * offset[0] + 2] += vgetq_lane_f32(v2.simdInternal_, 0);
+
+ t1 = vadd_f32(t1, vld1_f32(base + align * offset[1]));
+ vst1_f32(base + align * offset[1], t1);
+ base[align * offset[1] + 2] += vgetq_lane_f32(v2.simdInternal_, 1);
+
+ t2 = vadd_f32(t2, vld1_f32(base + align * offset[2]));
+ vst1_f32(base + align * offset[2], t2);
+ base[align * offset[2] + 2] += vgetq_lane_f32(v2.simdInternal_, 2);
+
+ t3 = vadd_f32(t3, vld1_f32(base + align * offset[3]));
+ vst1_f32(base + align * offset[3], t3);
+ base[align * offset[3] + 2] += vgetq_lane_f32(v2.simdInternal_, 3);
+ }
+ else
+ {
+ // Extra elements means we can use full width-4 load/store operations
+ float32x4x2_t t0 = vuzpq_f32(v0.simdInternal_, v2.simdInternal_);
+ float32x4x2_t t1 = vuzpq_f32(v1.simdInternal_, vdupq_n_f32(0.0F));
+ float32x4x2_t t2 = vtrnq_f32(t0.val[0], t1.val[0]);
+ float32x4x2_t t3 = vtrnq_f32(t0.val[1], t1.val[1]);
+ float32x4_t t4 = t2.val[0];
+ float32x4_t t5 = t3.val[0];
+ float32x4_t t6 = t2.val[1];
+ float32x4_t t7 = t3.val[1];
+
+ vst1q_f32(base + align * offset[0], vaddq_f32(t4, vld1q_f32(base + align * offset[0])));
+ vst1q_f32(base + align * offset[1], vaddq_f32(t5, vld1q_f32(base + align * offset[1])));
+ vst1q_f32(base + align * offset[2], vaddq_f32(t6, vld1q_f32(base + align * offset[2])));
+ vst1q_f32(base + align * offset[3], vaddq_f32(t7, vld1q_f32(base + align * offset[3])));
+ }
+}
+
+template<int align>
+static inline void gmx_simdcall
+ transposeScatterDecrU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2)
+{
+ assert(std::size_t(offset) % 16 == 0);
+
+ if (align < 4)
+ {
+ float32x2_t t0, t1, t2, t3;
+ float32x4x2_t tmp = vtrnq_f32(v0.simdInternal_, v1.simdInternal_);
+
+ t0 = vget_low_f32(tmp.val[0]);
+ t1 = vget_low_f32(tmp.val[1]);
+ t2 = vget_high_f32(tmp.val[0]);
+ t3 = vget_high_f32(tmp.val[1]);
+
+ t0 = vsub_f32(vld1_f32(base + align * offset[0]), t0);
+ vst1_f32(base + align * offset[0], t0);
+ base[align * offset[0] + 2] -= vgetq_lane_f32(v2.simdInternal_, 0);
+
+ t1 = vsub_f32(vld1_f32(base + align * offset[1]), t1);
+ vst1_f32(base + align * offset[1], t1);
+ base[align * offset[1] + 2] -= vgetq_lane_f32(v2.simdInternal_, 1);
+
+ t2 = vsub_f32(vld1_f32(base + align * offset[2]), t2);
+ vst1_f32(base + align * offset[2], t2);
+ base[align * offset[2] + 2] -= vgetq_lane_f32(v2.simdInternal_, 2);
+
+ t3 = vsub_f32(vld1_f32(base + align * offset[3]), t3);
+ vst1_f32(base + align * offset[3], t3);
+ base[align * offset[3] + 2] -= vgetq_lane_f32(v2.simdInternal_, 3);
+ }
+ else
+ {
+ // Extra elements means we can use full width-4 load/store operations
+ float32x4x2_t t0 = vuzpq_f32(v0.simdInternal_, v2.simdInternal_);
+ float32x4x2_t t1 = vuzpq_f32(v1.simdInternal_, vdupq_n_f32(0.0F));
+ float32x4x2_t t2 = vtrnq_f32(t0.val[0], t1.val[0]);
+ float32x4x2_t t3 = vtrnq_f32(t0.val[1], t1.val[1]);
+ float32x4_t t4 = t2.val[0];
+ float32x4_t t5 = t3.val[0];
+ float32x4_t t6 = t2.val[1];
+ float32x4_t t7 = t3.val[1];
+
+ vst1q_f32(base + align * offset[0], vsubq_f32(vld1q_f32(base + align * offset[0]), t4));
+ vst1q_f32(base + align * offset[1], vsubq_f32(vld1q_f32(base + align * offset[1]), t5));
+ vst1q_f32(base + align * offset[2], vsubq_f32(vld1q_f32(base + align * offset[2]), t6));
+ vst1q_f32(base + align * offset[3], vsubq_f32(vld1q_f32(base + align * offset[3]), t7));
+ }
+}
+
+static inline void gmx_simdcall expandScalarsToTriplets(SimdFloat scalar,
+ SimdFloat* triplets0,
+ SimdFloat* triplets1,
+ SimdFloat* triplets2)
+{
+ float32x2_t lo, hi;
+ float32x4_t t0, t1, t2, t3;
+
+ lo = vget_low_f32(scalar.simdInternal_);
+ hi = vget_high_f32(scalar.simdInternal_);
+
+ t0 = vdupq_lane_f32(lo, 0);
+ t1 = vdupq_lane_f32(lo, 1);
+ t2 = vdupq_lane_f32(hi, 0);
+ t3 = vdupq_lane_f32(hi, 1);
+
+ triplets0->simdInternal_ = vextq_f32(t0, t1, 1);
+ triplets1->simdInternal_ = vextq_f32(t1, t2, 2);
+ triplets2->simdInternal_ = vextq_f32(t2, t3, 3);
+}
+
+
+template<int align>
+static inline void gmx_simdcall gatherLoadBySimdIntTranspose(const float* base,
+ SimdFInt32 offset,
+ SimdFloat* v0,
+ SimdFloat* v1,
+ SimdFloat* v2,
+ SimdFloat* v3)
+{
+ alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_FINT32_WIDTH];
+
+ assert(std::size_t(base) % 16 == 0);
+ assert(align % 4 == 0);
+
+ store(ioffset, offset);
+ gatherLoadTranspose<align>(base, ioffset, v0, v1, v2, v3);
+}
+
+template<int align>
+static inline void gmx_simdcall
+ gatherLoadBySimdIntTranspose(const float* base, SimdFInt32 offset, SimdFloat* v0, SimdFloat* v1)
+{
+ alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_FINT32_WIDTH];
+
+ store(ioffset, offset);
+ gatherLoadTranspose<align>(base, ioffset, v0, v1);
+}
+
+
+template<int align>
+static inline void gmx_simdcall
+ gatherLoadUBySimdIntTranspose(const float* base, SimdFInt32 offset, SimdFloat* v0, SimdFloat* v1)
+{
+ alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_FINT32_WIDTH];
+
+ store(ioffset, offset);
+ v0->simdInternal_ =
+ vcombine_f32(vld1_f32(base + align * ioffset[0]), vld1_f32(base + align * ioffset[2]));
+ v1->simdInternal_ =
+ vcombine_f32(vld1_f32(base + align * ioffset[1]), vld1_f32(base + align * ioffset[3]));
+ float32x4x2_t tmp = vtrnq_f32(v0->simdInternal_, v1->simdInternal_);
+ v0->simdInternal_ = tmp.val[0];
+ v1->simdInternal_ = tmp.val[1];
+}
+
+static inline float gmx_simdcall reduceIncr4ReturnSum(float* m, SimdFloat v0, SimdFloat v1, SimdFloat v2, SimdFloat v3)
+{
+ assert(std::size_t(m) % 16 == 0);
+
+ float32x4x2_t t0 = vuzpq_f32(v0.simdInternal_, v2.simdInternal_);
+ float32x4x2_t t1 = vuzpq_f32(v1.simdInternal_, v3.simdInternal_);
+ float32x4x2_t t2 = vtrnq_f32(t0.val[0], t1.val[0]);
+ float32x4x2_t t3 = vtrnq_f32(t0.val[1], t1.val[1]);
+ v0.simdInternal_ = t2.val[0];
+ v1.simdInternal_ = t3.val[0];
+ v2.simdInternal_ = t2.val[1];
+ v3.simdInternal_ = t3.val[1];
+
+ v0 = v0 + v1;
+ v2 = v2 + v3;
+ v0 = v0 + v2;
+ v2 = v0 + simdLoad(m);
+ store(m, v2);
+
+ return reduce(v0);
+}
+
+} // namespace gmx
#endif // GMX_SIMD_IMPL_ARM_NEON_ASIMD_UTIL_FLOAT_H
static inline Simd4Double gmx_simdcall operator&(Simd4Double a, Simd4Double b)
{
svbool_t pg = svptrue_b64();
- return { svreinterpret_f64_s64(svand_s64_z(pg, svreinterpret_s64_f64(a.simdInternal_),
- svreinterpret_s64_f64(b.simdInternal_))) };
+ return { svreinterpret_f64_s64(svand_s64_z(
+ pg, svreinterpret_s64_f64(a.simdInternal_), svreinterpret_s64_f64(b.simdInternal_))) };
}
static inline Simd4Double gmx_simdcall andNot(Simd4Double a, Simd4Double b)
{
svbool_t pg = svptrue_b64();
- return { svreinterpret_f64_s64(svbic_s64_z(pg, svreinterpret_s64_f64(b.simdInternal_),
- svreinterpret_s64_f64(a.simdInternal_))) };
+ return { svreinterpret_f64_s64(svbic_s64_z(
+ pg, svreinterpret_s64_f64(b.simdInternal_), svreinterpret_s64_f64(a.simdInternal_))) };
}
static inline Simd4Double gmx_simdcall operator|(Simd4Double a, Simd4Double b)
{
svbool_t pg = svptrue_b64();
- return { svreinterpret_f64_s64(svorr_s64_z(pg, svreinterpret_s64_f64(a.simdInternal_),
- svreinterpret_s64_f64(b.simdInternal_))) };
+ return { svreinterpret_f64_s64(svorr_s64_z(
+ pg, svreinterpret_s64_f64(a.simdInternal_), svreinterpret_s64_f64(b.simdInternal_))) };
}
static inline Simd4Double gmx_simdcall operator^(Simd4Double a, Simd4Double b)
{
svbool_t pg = svptrue_b64();
- return { svreinterpret_f64_s64(sveor_s64_z(pg, svreinterpret_s64_f64(a.simdInternal_),
- svreinterpret_s64_f64(b.simdInternal_))) };
+ return { svreinterpret_f64_s64(sveor_s64_z(
+ pg, svreinterpret_s64_f64(a.simdInternal_), svreinterpret_s64_f64(b.simdInternal_))) };
}
static inline Simd4Double gmx_simdcall operator+(Simd4Double a, Simd4Double b)
{
assert(0 == (std::size_t(m) % GMX_SIMD_ALIGNMENT));
svbool_t pg = svwhilelt_b32(0, (int32_t)GMX_SIMD_DINT32_WIDTH);
- svst1_s32(pg, m,
- svuzp1(svreinterpret_s32_s64(a.simdInternal_), svreinterpret_s32_s64(a.simdInternal_)));
+ svst1_s32(pg, m, svuzp1(svreinterpret_s32_s64(a.simdInternal_), svreinterpret_s32_s64(a.simdInternal_)));
}
static inline SimdDInt32 gmx_simdcall simdLoadU(const std::int32_t* m, SimdDInt32Tag)
static inline void gmx_simdcall storeU(std::int32_t* m, SimdDInt32 a)
{
svbool_t pg = svwhilelt_b32(0, (int32_t)GMX_SIMD_DINT32_WIDTH);
- svst1_s32(pg, m,
- svuzp1(svreinterpret_s32_s64(a.simdInternal_), svreinterpret_s32_s64(a.simdInternal_)));
+ svst1_s32(pg, m, svuzp1(svreinterpret_s32_s64(a.simdInternal_), svreinterpret_s32_s64(a.simdInternal_)));
}
static inline SimdDInt32 gmx_simdcall setZeroDI()
static inline SimdDouble gmx_simdcall operator&(SimdDouble a, SimdDouble b)
{
svbool_t pg = svptrue_b64();
- return { svreinterpret_f64_s64(svand_s64_x(pg, svreinterpret_s64_f64(a.simdInternal_),
- svreinterpret_s64_f64(b.simdInternal_))) };
+ return { svreinterpret_f64_s64(svand_s64_x(
+ pg, svreinterpret_s64_f64(a.simdInternal_), svreinterpret_s64_f64(b.simdInternal_))) };
}
static inline SimdDouble gmx_simdcall andNot(SimdDouble a, SimdDouble b)
{
svbool_t pg = svptrue_b64();
- return { svreinterpret_f64_s64(svbic_s64_x(pg, svreinterpret_s64_f64(b.simdInternal_),
- svreinterpret_s64_f64(a.simdInternal_))) };
+ return { svreinterpret_f64_s64(svbic_s64_x(
+ pg, svreinterpret_s64_f64(b.simdInternal_), svreinterpret_s64_f64(a.simdInternal_))) };
}
static inline SimdDouble gmx_simdcall operator|(SimdDouble a, SimdDouble b)
{
svbool_t pg = svptrue_b64();
- return { svreinterpret_f64_s64(svorr_s64_x(pg, svreinterpret_s64_f64(a.simdInternal_),
- svreinterpret_s64_f64(b.simdInternal_))) };
+ return { svreinterpret_f64_s64(svorr_s64_x(
+ pg, svreinterpret_s64_f64(a.simdInternal_), svreinterpret_s64_f64(b.simdInternal_))) };
}
static inline SimdDouble gmx_simdcall operator^(SimdDouble a, SimdDouble b)
{
svbool_t pg = svptrue_b64();
- return { svreinterpret_f64_s64(sveor_s64_x(pg, svreinterpret_s64_f64(a.simdInternal_),
- svreinterpret_s64_f64(b.simdInternal_))) };
+ return { svreinterpret_f64_s64(sveor_s64_x(
+ pg, svreinterpret_s64_f64(a.simdInternal_), svreinterpret_s64_f64(b.simdInternal_))) };
}
static inline SimdDouble gmx_simdcall operator+(SimdDouble a, SimdDouble b)
pg, svreinterpret_s64_u64(svlsr_n_u64_x(pg, svreinterpret_u64_s64(iExponent), 52)), exponentBias);
- svfloat64_t result = svreinterpret_f64_s64(svorr_s64_x(
- pg, svand_s64_x(pg, svreinterpret_s64_f64(value.simdInternal_), mantissaMask),
- svreinterpret_s64_f64(half)));
+ svfloat64_t result = svreinterpret_f64_s64(
+ svorr_s64_x(pg,
+ svand_s64_x(pg, svreinterpret_s64_f64(value.simdInternal_), mantissaMask),
+ svreinterpret_s64_f64(half)));
if (opt == MathOptimization::Safe)
{
static inline SimdFloat gmx_simdcall operator&(SimdFloat a, SimdFloat b)
{
svbool_t pg = svptrue_b32();
- return { svreinterpret_f32_s32(svand_s32_x(pg, svreinterpret_s32_f32(a.simdInternal_),
- svreinterpret_s32_f32(b.simdInternal_))) };
+ return { svreinterpret_f32_s32(svand_s32_x(
+ pg, svreinterpret_s32_f32(a.simdInternal_), svreinterpret_s32_f32(b.simdInternal_))) };
}
static inline SimdFloat gmx_simdcall andNot(SimdFloat a, SimdFloat b)
{
svbool_t pg = svptrue_b32();
- return { svreinterpret_f32_s32(svbic_s32_x(pg, svreinterpret_s32_f32(b.simdInternal_),
- svreinterpret_s32_f32(a.simdInternal_))) };
+ return { svreinterpret_f32_s32(svbic_s32_x(
+ pg, svreinterpret_s32_f32(b.simdInternal_), svreinterpret_s32_f32(a.simdInternal_))) };
}
static inline SimdFloat gmx_simdcall operator|(SimdFloat a, SimdFloat b)
{
svbool_t pg = svptrue_b32();
- return { svreinterpret_f32_s32(svorr_s32_x(pg, svreinterpret_s32_f32(a.simdInternal_),
- svreinterpret_s32_f32(b.simdInternal_))) };
+ return { svreinterpret_f32_s32(svorr_s32_x(
+ pg, svreinterpret_s32_f32(a.simdInternal_), svreinterpret_s32_f32(b.simdInternal_))) };
}
static inline SimdFloat gmx_simdcall operator^(SimdFloat a, SimdFloat b)
{
svbool_t pg = svptrue_b32();
- return { svreinterpret_f32_s32(sveor_s32_x(pg, svreinterpret_s32_f32(a.simdInternal_),
- svreinterpret_s32_f32(b.simdInternal_))) };
+ return { svreinterpret_f32_s32(sveor_s32_x(
+ pg, svreinterpret_s32_f32(a.simdInternal_), svreinterpret_s32_f32(b.simdInternal_))) };
}
static inline SimdFloat gmx_simdcall operator+(SimdFloat a, SimdFloat b)
iExponent = svsub_s32_x(
pg, svreinterpret_s32_u32(svlsr_n_u32_x(pg, svreinterpret_u32_s32(iExponent), 23)), exponentBias);
-
- svfloat32_t result = svreinterpret_f32_s32(svorr_s32_x(
- pg, svand_s32_x(pg, svreinterpret_s32_f32(value.simdInternal_), mantissaMask),
- svreinterpret_s32_f32(half)));
+ svfloat32_t result = svreinterpret_f32_s32(
+ svorr_s32_x(pg,
+ svand_s32_x(pg, svreinterpret_s32_f32(value.simdInternal_), mantissaMask),
+ svreinterpret_s32_f32(half)));
if (opt == MathOptimization::Safe)
{
svint64_t offsets;
svbool_t pg = svptrue_b64();
offsets = svmul_n_s64_x(
- pg, svunpklo_s64(svld1_s32(svwhilelt_b32(0, (int32_t)GMX_SIMD_DINT32_WIDTH), offset)),
+ pg,
+ svunpklo_s64(svld1_s32(svwhilelt_b32(0, (int32_t)GMX_SIMD_DINT32_WIDTH), offset)),
align * sizeof(double));
v0->simdInternal_ = svld1_gather_s64offset_f64(pg, base, offsets);
offsets = svadd_n_s64_x(pg, offsets, sizeof(double));
svint64_t offsets;
svbool_t pg = svptrue_b64();
offsets = svmul_n_s64_x(
- pg, svunpklo_s64(svld1_s32(svwhilelt_b32(0, (int32_t)GMX_SIMD_DINT32_WIDTH), offset)),
+ pg,
+ svunpklo_s64(svld1_s32(svwhilelt_b32(0, (int32_t)GMX_SIMD_DINT32_WIDTH), offset)),
align * sizeof(double));
v0->simdInternal_ = svld1_gather_s64offset_f64(pg, base, offsets);
offsets = svadd_n_s64_x(pg, offsets, sizeof(double));
svint64_t offsets;
svbool_t pg = svptrue_b64();
offsets = svmul_n_s64_x(
- pg, svunpklo_s64(svld1_s32(svwhilelt_b32(0, (int32_t)GMX_SIMD_DINT32_WIDTH), offset)),
+ pg,
+ svunpklo_s64(svld1_s32(svwhilelt_b32(0, (int32_t)GMX_SIMD_DINT32_WIDTH), offset)),
align * sizeof(double));
svst1_scatter_s64offset_f64(pg, base, offsets, v0.simdInternal_);
offsets = svadd_n_s64_x(pg, offsets, sizeof(double));
svbool_t pg = svwhilelt_b64(0, (int32_t)GMX_SIMD_DOUBLE_WIDTH / 2);
svfloat64_t _v0, _v1;
offsets = svmul_n_s64_x(
- pg, svunpklo(svld1_s32(svwhilelt_b32(0, (int32_t)GMX_SIMD_DINT32_WIDTH / 2), offset)),
+ pg,
+ svunpklo(svld1_s32(svwhilelt_b32(0, (int32_t)GMX_SIMD_DINT32_WIDTH / 2), offset)),
align * sizeof(double));
_v0 = svld1_gather_s64offset_f64(pg, base0, offsets);
_v1 = svld1_gather_s64offset_f64(pg, base1, offsets);
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 2014,2015,2016, 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.
- */
-
-#ifndef GMX_SIMD_IMPLEMENTATION_IBM_VMX_H
-#define GMX_SIMD_IMPLEMENTATION_IBM_VMX_H
-
-#include "impl_ibm_vmx_definitions.h"
-#include "impl_ibm_vmx_general.h"
-// No double precision available for VMX
-#include "impl_ibm_vmx_simd4_float.h"
-#include "impl_ibm_vmx_simd_float.h"
-#include "impl_ibm_vmx_util_float.h"
-
-#endif // GMX_SIMD_IMPLEMENTATION_IBM_VMX_H
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 2014,2015,2017,2018,2019,2020, by the GROMACS development team, led by
- * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
- * and including many others, as listed in the AUTHORS file in the
- * top-level source directory and at http://www.gromacs.org.
- *
- * 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.
- */
-
-#ifndef GMX_SIMD_IMPLEMENTATION_IBM_VMX_DEFINITIONS_H
-#define GMX_SIMD_IMPLEMENTATION_IBM_VMX_DEFINITIONS_H
-
-#include <altivec.h>
-
-#if defined(__GNUC__) && !defined(__ibmxl__) && !defined(__xlC__)
-// According to G++ documentation, when using altivec in C++ we
-// must undefine vector & bool macros after including altivec.h
-# undef vector
-# undef bool
-# define vmxBool __bool
-#else
-// We cannot undefine bool on xlc, but somehow it works anyway
-# define vmxBool bool
-#endif
-
-#define GMX_SIMD 1
-#define GMX_SIMD_HAVE_FLOAT 1
-#define GMX_SIMD_HAVE_DOUBLE 0
-#define GMX_SIMD_HAVE_LOADU 0
-#define GMX_SIMD_HAVE_STOREU 0
-
-#define GMX_SIMD_HAVE_LOGICAL 1
-#define GMX_SIMD_HAVE_FMA 1
-#define GMX_SIMD_HAVE_FINT32_EXTRACT 0
-#define GMX_SIMD_HAVE_FINT32_LOGICAL 1
-#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 1
-#define GMX_SIMD_HAVE_DINT32_EXTRACT 0
-#define GMX_SIMD_HAVE_DINT32_LOGICAL 0
-#define GMX_SIMD_HAVE_DINT32_ARITHMETICS 0
-#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_FLOAT 0
-#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT 0
-#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_FLOAT 0
-#define GMX_SIMD_HAVE_NATIVE_LOG_FLOAT 0
-#define GMX_SIMD_HAVE_NATIVE_EXP2_FLOAT 0
-#define GMX_SIMD_HAVE_NATIVE_EXP_FLOAT 0
-#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_DOUBLE 0
-#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_DOUBLE 0
-#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_DOUBLE 0
-#define GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE 0
-#define GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE 0
-#define GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE 0
-#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT 0
-#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE 0
-#define GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT 0 // No need for half-simd, width is 4
-#define GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE 0
-
-#define GMX_SIMD4_HAVE_FLOAT 1
-#define GMX_SIMD4_HAVE_DOUBLE 0
-
-// Implementation details
-#define GMX_SIMD_FLOAT_WIDTH 4
-#undef GMX_SIMD_DOUBLE_WIDTH
-#define GMX_SIMD_FINT32_WIDTH 4
-#undef GMX_SIMD_DINT32_WIDTH
-#define GMX_SIMD4_WIDTH 4
-#define GMX_SIMD_ALIGNMENT 16 // Bytes (4*single)
-#define GMX_SIMD_RSQRT_BITS 14
-#define GMX_SIMD_RCP_BITS 14
-
-#endif // GMX_SIMD_IMPLEMENTATION_IBM_VMX_DEFINITIONS_H
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by
- * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
- * and including many others, as listed in the AUTHORS file in the
- * top-level source directory and at http://www.gromacs.org.
- *
- * GROMACS is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * GROMACS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with GROMACS; if not, see
- * http://www.gnu.org/licenses, or write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * If you want to redistribute modifications to GROMACS, please
- * consider that scientific software is very special. Version
- * control is crucial - bugs must be traceable. We will be happy to
- * consider code for inclusion in the official distribution, but
- * derived work must not be called official GROMACS. Details are found
- * in the README & COPYING files - if they are missing, get the
- * official version at http://www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org.
- */
-
-#ifndef GMX_SIMD_IMPLEMENTATION_IBM_VMX_GENERAL_H
-#define GMX_SIMD_IMPLEMENTATION_IBM_VMX_GENERAL_H
-
-namespace gmx
-{
-
-static inline void simdPrefetch(const void* m)
-{
-#if defined(__ibmxl__) || defined(__xlC__)
- __dcbt(m);
-#elif defined __GNUC__
- __builtin_prefetch(m);
-#endif
-}
-
-} // namespace gmx
-
-#endif // GMX_SIMD_IMPLEMENTATION_IBM_VMX_GENERAL_H
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by
- * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
- * and including many others, as listed in the AUTHORS file in the
- * top-level source directory and at http://www.gromacs.org.
- *
- * GROMACS is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * GROMACS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with GROMACS; if not, see
- * http://www.gnu.org/licenses, or write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * If you want to redistribute modifications to GROMACS, please
- * consider that scientific software is very special. Version
- * control is crucial - bugs must be traceable. We will be happy to
- * consider code for inclusion in the official distribution, but
- * derived work must not be called official GROMACS. Details are found
- * in the README & COPYING files - if they are missing, get the
- * official version at http://www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org.
- */
-
-#ifndef GMX_SIMD_IMPLEMENTATION_IBM_VMX_SIMD4_FLOAT_H
-#define GMX_SIMD_IMPLEMENTATION_IBM_VMX_SIMD4_FLOAT_H
-
-#include "config.h"
-
-#include "gromacs/utility/basedefinitions.h"
-
-#include "impl_ibm_vmx_definitions.h"
-
-namespace gmx
-{
-
-class Simd4Float
-{
-public:
- Simd4Float() {}
-
- Simd4Float(float f)
- {
- __vector unsigned char perm;
-
- simdInternal_ = vec_lde(0, const_cast<float*>(&f));
- perm = vec_lvsl(0, const_cast<float*>(&f));
- simdInternal_ = vec_perm(simdInternal_, simdInternal_, perm);
- simdInternal_ = vec_splat(simdInternal_, 0);
- }
-
- // Internal utility constructor to simplify return statements
- Simd4Float(__vector float simd) : simdInternal_(simd) {}
-
- __vector float simdInternal_;
-};
-
-class Simd4FBool
-{
-public:
- Simd4FBool() {}
-
- Simd4FBool(bool b)
- {
- simdInternal_ = reinterpret_cast<__vector vmxBool int>(vec_splat_u32(b ? 0xFFFFFFFF : 0));
- }
-
- // Internal utility constructor to simplify return statements
- Simd4FBool(__vector vmxBool int simd) : simdInternal_(simd) {}
-
- __vector vmxBool int simdInternal_;
-};
-
-static inline Simd4Float gmx_simdcall load4(const float* m)
-{
- return { vec_ld(0, const_cast<float*>(m)) };
-}
-
-static inline void gmx_simdcall store4(float* m, Simd4Float a)
-{
- vec_st(a.simdInternal_, 0, const_cast<float*>(m));
-}
-
-static inline Simd4Float gmx_simdcall simd4SetZeroF()
-{
- return { reinterpret_cast<__vector float>(vec_splat_u32(0)) };
-}
-
-static inline Simd4Float gmx_simdcall operator&(Simd4Float a, Simd4Float b)
-{
- return { vec_and(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline Simd4Float gmx_simdcall andNot(Simd4Float a, Simd4Float b)
-{
- return { vec_andc(b.simdInternal_, a.simdInternal_) };
-}
-
-static inline Simd4Float gmx_simdcall operator|(Simd4Float a, Simd4Float b)
-{
- return { vec_or(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline Simd4Float gmx_simdcall operator^(Simd4Float a, Simd4Float b)
-{
- return { vec_xor(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline Simd4Float gmx_simdcall operator+(Simd4Float a, Simd4Float b)
-{
- return { vec_add(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline Simd4Float gmx_simdcall operator-(Simd4Float a, Simd4Float b)
-{
- return { vec_sub(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline Simd4Float gmx_simdcall operator-(Simd4Float x)
-{
- return { vec_xor(x.simdInternal_,
- reinterpret_cast<__vector float>(vec_sl(vec_splat_u32(-1), vec_splat_u32(-1)))) };
-}
-
-static inline Simd4Float gmx_simdcall operator*(Simd4Float a, Simd4Float b)
-{
- return { vec_madd(a.simdInternal_, b.simdInternal_,
- reinterpret_cast<__vector float>(vec_splat_u32(0))) };
-}
-
-static inline Simd4Float gmx_simdcall fma(Simd4Float a, Simd4Float b, Simd4Float c)
-{
- return { vec_madd(a.simdInternal_, b.simdInternal_, c.simdInternal_) };
-}
-
-static inline Simd4Float gmx_simdcall fms(Simd4Float a, Simd4Float b, Simd4Float c)
-{
- return { vec_madd(a.simdInternal_, b.simdInternal_, -c.simdInternal_) };
-}
-
-static inline Simd4Float gmx_simdcall fnma(Simd4Float a, Simd4Float b, Simd4Float c)
-{
- return { vec_nmsub(a.simdInternal_, b.simdInternal_, c.simdInternal_) };
-}
-
-static inline Simd4Float gmx_simdcall fnms(Simd4Float a, Simd4Float b, Simd4Float c)
-{
- return { -vec_madd(a.simdInternal_, b.simdInternal_, c.simdInternal_) };
-}
-
-static inline Simd4Float gmx_simdcall rsqrt(Simd4Float x)
-{
- return { vec_rsqrte(x.simdInternal_) };
-}
-
-static inline Simd4Float gmx_simdcall abs(Simd4Float x)
-{
- return { vec_abs(x.simdInternal_) };
-}
-
-static inline Simd4Float gmx_simdcall max(Simd4Float a, Simd4Float b)
-{
- return { vec_max(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline Simd4Float gmx_simdcall min(Simd4Float a, Simd4Float b)
-{
- return { vec_min(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline Simd4Float gmx_simdcall round(Simd4Float x)
-{
- return { vec_round(x.simdInternal_) };
-}
-
-static inline Simd4Float gmx_simdcall trunc(Simd4Float x)
-{
- return { vec_trunc(x.simdInternal_) };
-}
-
-static inline float gmx_simdcall dotProduct(Simd4Float a, Simd4Float b)
-{
- float res;
-
- __vector float c = vec_madd(a.simdInternal_, b.simdInternal_,
- reinterpret_cast<__vector float>(vec_splat_u32(0)));
- // Keep only elements 0,1,2 by shifting in zero from right (xor of a vector with itself is 0)
- c = vec_sld(c, vec_xor(a.simdInternal_, a.simdInternal_), 4);
- // calculate sum
- c = vec_add(c, vec_sld(c, c, 8));
- c = vec_add(c, vec_sld(c, c, 4));
- vec_ste(c, 0, &res);
- return res;
-}
-
-static inline void gmx_simdcall transpose(Simd4Float* v0, Simd4Float* v1, Simd4Float* v2, Simd4Float* v3)
-{
- __vector float t0 = vec_mergeh(v0->simdInternal_, v2->simdInternal_);
- __vector float t1 = vec_mergel(v0->simdInternal_, v2->simdInternal_);
- __vector float t2 = vec_mergeh(v1->simdInternal_, v3->simdInternal_);
- __vector float t3 = vec_mergel(v1->simdInternal_, v3->simdInternal_);
- v0->simdInternal_ = vec_mergeh(t0, t2);
- v1->simdInternal_ = vec_mergel(t0, t2);
- v2->simdInternal_ = vec_mergeh(t1, t3);
- v3->simdInternal_ = vec_mergel(t1, t3);
-}
-
-static inline Simd4FBool gmx_simdcall operator==(Simd4Float a, Simd4Float b)
-{
- return { vec_cmpeq(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline Simd4FBool gmx_simdcall operator!=(Simd4Float a, Simd4Float b)
-{
- return { vec_or(vec_cmpgt(a.simdInternal_, b.simdInternal_),
- vec_cmplt(a.simdInternal_, b.simdInternal_)) };
-}
-
-static inline Simd4FBool gmx_simdcall operator<(Simd4Float a, Simd4Float b)
-{
- return { vec_cmplt(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline Simd4FBool gmx_simdcall operator<=(Simd4Float a, Simd4Float b)
-{
- return { vec_cmple(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline Simd4FBool gmx_simdcall operator&&(Simd4FBool a, Simd4FBool b)
-{
- return { vec_and(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline Simd4FBool gmx_simdcall operator||(Simd4FBool a, Simd4FBool b)
-{
- return { vec_or(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline bool gmx_simdcall anyTrue(Simd4FBool a)
-{
- return vec_any_ne(a.simdInternal_, reinterpret_cast<__vector vmxBool int>(vec_splat_u32(0)));
-}
-
-static inline Simd4Float gmx_simdcall selectByMask(Simd4Float a, Simd4FBool m)
-{
- return { vec_and(a.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_)) };
-}
-
-static inline Simd4Float gmx_simdcall selectByNotMask(Simd4Float a, Simd4FBool m)
-{
- return { vec_andc(a.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_)) };
-}
-
-static inline Simd4Float gmx_simdcall blend(Simd4Float a, Simd4Float b, Simd4FBool sel)
-{
- return { vec_sel(a.simdInternal_, b.simdInternal_, sel.simdInternal_) };
-}
-
-static inline float gmx_simdcall reduce(Simd4Float a)
-{
- __vector float c = a.simdInternal_;
- float res;
-
- // calculate sum
- c = vec_add(c, vec_sld(c, c, 8));
- c = vec_add(c, vec_sld(c, c, 4));
- vec_ste(c, 0, &res);
- return res;
-}
-
-} // namespace gmx
-
-#endif // GMX_SIMD_IMPLEMENTATION_IBM_VMX_SIMD4_FLOAT_H
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 2014,2015,2016,2017,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.
- *
- * 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.
- */
-
-#ifndef GMX_SIMD_IMPLEMENTATION_IBM_VMX_SIMD_FLOAT_H
-#define GMX_SIMD_IMPLEMENTATION_IBM_VMX_SIMD_FLOAT_H
-
-#include "config.h"
-
-#include <cstdint>
-
-#include "gromacs/math/utilities.h"
-#include "gromacs/utility/basedefinitions.h"
-
-#include "impl_ibm_vmx_definitions.h"
-
-namespace gmx
-{
-
-class SimdFloat
-{
-public:
- SimdFloat() {}
-
- SimdFloat(float f)
- {
- __vector unsigned char perm;
-
- simdInternal_ = vec_lde(0, const_cast<float*>(&f));
- perm = vec_lvsl(0, const_cast<float*>(&f));
- simdInternal_ = vec_perm(simdInternal_, simdInternal_, perm);
- simdInternal_ = vec_splat(simdInternal_, 0);
- }
-
- // Internal utility constructor to simplify return statements
- SimdFloat(__vector float simd) : simdInternal_(simd) {}
-
- __vector float simdInternal_;
-};
-
-class SimdFInt32
-{
-public:
- SimdFInt32() {}
-
- SimdFInt32(std::int32_t i)
- {
- __vector unsigned char perm;
-
- simdInternal_ = vec_lde(0, const_cast<int*>(&i));
- perm = vec_lvsl(0, const_cast<int*>(&i));
- simdInternal_ = vec_perm(simdInternal_, simdInternal_, perm);
- simdInternal_ = vec_splat(simdInternal_, 0);
- }
-
-
- // Internal utility constructor to simplify return statements
- SimdFInt32(__vector signed int simd) : simdInternal_(simd) {}
-
- __vector signed int simdInternal_;
-};
-
-class SimdFBool
-{
-public:
- SimdFBool() {}
-
- SimdFBool(bool b) :
- simdInternal_(reinterpret_cast<__vector vmxBool int>(vec_splats(b ? 0xFFFFFFFF : 0)))
- {
- }
-
- // Internal utility constructor to simplify return statements
- SimdFBool(__vector vmxBool int simd) : simdInternal_(simd) {}
-
- __vector vmxBool int simdInternal_;
-};
-
-class SimdFIBool
-{
-public:
- SimdFIBool() {}
-
- SimdFIBool(bool b) :
- simdInternal_(reinterpret_cast<__vector vmxBool int>(vec_splat_u32(b ? 0xFFFFFFFF : 0)))
- {
- }
-
- // Internal utility constructor to simplify return statements
- SimdFIBool(__vector vmxBool int simd) : simdInternal_(simd) {}
-
- __vector vmxBool int simdInternal_;
-};
-
-static inline SimdFloat gmx_simdcall simdLoad(const float* m, SimdFloatTag = {})
-{
- return { vec_ld(0, const_cast<float*>(m)) };
-}
-
-static inline void gmx_simdcall store(float* m, SimdFloat a)
-{
- vec_st(a.simdInternal_, 0, const_cast<float*>(m));
-}
-
-static inline SimdFloat gmx_simdcall setZeroF()
-{
- return { reinterpret_cast<__vector float>(vec_splat_u32(0)) };
-}
-
-static inline SimdFInt32 gmx_simdcall simdLoad(const std::int32_t* m, SimdFInt32Tag)
-{
- return { vec_ld(0, const_cast<int*>(m)) };
-}
-
-static inline void gmx_simdcall store(std::int32_t* m, SimdFInt32 a)
-{
- vec_st(a.simdInternal_, 0, const_cast<int*>(m));
-}
-
-static inline SimdFInt32 gmx_simdcall setZeroFI()
-{
- return { vec_splat_s32(0) };
-}
-
-static inline SimdFloat gmx_simdcall operator&(SimdFloat a, SimdFloat b)
-{
- return { vec_and(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall andNot(SimdFloat a, SimdFloat b)
-{
- return { vec_andc(b.simdInternal_, a.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall operator|(SimdFloat a, SimdFloat b)
-{
- return { vec_or(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall operator^(SimdFloat a, SimdFloat b)
-{
- return { vec_xor(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall operator+(SimdFloat a, SimdFloat b)
-{
- return { vec_add(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall operator-(SimdFloat a, SimdFloat b)
-{
- return { vec_sub(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall operator-(SimdFloat x)
-{
- return { vec_xor(x.simdInternal_,
- reinterpret_cast<__vector float>(vec_sl(vec_splat_u32(-1), vec_splat_u32(-1)))) };
-}
-
-static inline SimdFloat gmx_simdcall operator*(SimdFloat a, SimdFloat b)
-{
- return { vec_madd(a.simdInternal_, b.simdInternal_,
- reinterpret_cast<__vector float>(vec_splat_u32(0))) };
-}
-
-static inline SimdFloat gmx_simdcall fma(SimdFloat a, SimdFloat b, SimdFloat c)
-{
- return { vec_madd(a.simdInternal_, b.simdInternal_, c.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall fms(SimdFloat a, SimdFloat b, SimdFloat c)
-{
- return { vec_madd(a.simdInternal_, b.simdInternal_, -c.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall fnma(SimdFloat a, SimdFloat b, SimdFloat c)
-{
- return { vec_nmsub(a.simdInternal_, b.simdInternal_, c.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall fnms(SimdFloat a, SimdFloat b, SimdFloat c)
-{
- return { -vec_madd(a.simdInternal_, b.simdInternal_, c.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall rsqrt(SimdFloat x)
-{
- return { vec_rsqrte(x.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall rcp(SimdFloat x)
-{
- return { vec_re(x.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall maskAdd(SimdFloat a, SimdFloat b, SimdFBool m)
-{
- return { vec_add(a.simdInternal_,
- vec_and(b.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_))) };
-}
-
-static inline SimdFloat gmx_simdcall maskzMul(SimdFloat a, SimdFloat b, SimdFBool m)
-{
- SimdFloat prod = a * b;
-
- return { vec_and(prod.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_)) };
-}
-
-static inline SimdFloat gmx_simdcall maskzFma(SimdFloat a, SimdFloat b, SimdFloat c, SimdFBool m)
-{
- SimdFloat prod = fma(a, b, c);
-
- return { vec_and(prod.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_)) };
-}
-
-static inline SimdFloat gmx_simdcall maskzRsqrt(SimdFloat x, SimdFBool m)
-{
-#ifndef NDEBUG
- SimdFloat one(1.0F);
- x.simdInternal_ = vec_sel(one.simdInternal_, x.simdInternal_, m.simdInternal_);
-#endif
- return { vec_and(vec_rsqrte(x.simdInternal_), reinterpret_cast<__vector float>(m.simdInternal_)) };
-}
-
-static inline SimdFloat gmx_simdcall maskzRcp(SimdFloat x, SimdFBool m)
-{
-#ifndef NDEBUG
- SimdFloat one(1.0F);
- x.simdInternal_ = vec_sel(one.simdInternal_, x.simdInternal_, m.simdInternal_);
-#endif
- return { vec_and(vec_re(x.simdInternal_), reinterpret_cast<__vector float>(m.simdInternal_)) };
-}
-
-static inline SimdFloat gmx_simdcall abs(SimdFloat x)
-{
- return { vec_abs(x.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall max(SimdFloat a, SimdFloat b)
-{
- return { vec_max(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall min(SimdFloat a, SimdFloat b)
-{
- return { vec_min(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall round(SimdFloat x)
-{
- return { vec_round(x.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall trunc(SimdFloat x)
-{
- return { vec_trunc(x.simdInternal_) };
-}
-
-template<MathOptimization opt = MathOptimization::Safe>
-static inline SimdFloat gmx_simdcall frexp(SimdFloat value, SimdFInt32* exponent)
-{
- // Generate constants without memory operations
- const __vector signed int exponentMask =
- vec_sl(vec_add(vec_splat_s32(15), vec_sl(vec_splat_s32(15), vec_splat_u32(4))),
- vec_add(vec_splat_u32(15), vec_splat_u32(8))); // 0x7F800000
- const __vector signed int exponentBias =
- vec_sub(vec_sl(vec_splat_s32(1), vec_splat_u32(7)), vec_splat_s32(2)); // 126
- const SimdFloat half(0.5F);
- __vector signed int iExponent;
-
- __vector vmxBool int valueIsZero =
- vec_cmpeq(value.simdInternal_, reinterpret_cast<__vector float>(vec_splat_u32(0)));
-
- iExponent = vec_and(reinterpret_cast<__vector signed int>(value.simdInternal_), exponentMask);
- iExponent = vec_sr(iExponent, vec_add(vec_splat_u32(15), vec_splat_u32(8)));
- iExponent = vec_sub(iExponent, exponentBias);
- iExponent = vec_andc(iExponent, reinterpret_cast<__vector int>(valueIsZero));
-
- __vector float result =
- vec_or(vec_andc(value.simdInternal_, reinterpret_cast<__vector float>(exponentMask)),
- half.simdInternal_);
- result = vec_sel(result, value.simdInternal_, valueIsZero);
-
- exponent->simdInternal_ = iExponent;
-
- return { result };
-}
-
-template<MathOptimization opt = MathOptimization::Safe>
-static inline SimdFloat gmx_simdcall ldexp(SimdFloat value, SimdFInt32 exponent)
-{
- const __vector signed int exponentBias =
- vec_sub(vec_sl(vec_splat_s32(1), vec_splat_u32(7)), vec_splat_s32(1)); // 127
- __vector signed int iExponent;
-
- iExponent = vec_add(exponent.simdInternal_, exponentBias);
-
- if (opt == MathOptimization::Safe)
- {
- // Make sure biased argument is not negative
- iExponent = vec_max(iExponent, vec_splat_s32(0));
- }
-
- iExponent = vec_sl(iExponent, vec_add(vec_splat_u32(15), vec_splat_u32(8)));
-
- return { vec_madd(value.simdInternal_, reinterpret_cast<__vector float>(iExponent),
- reinterpret_cast<__vector float>(vec_splat_u32(0))) };
-}
-
-static inline float gmx_simdcall reduce(SimdFloat a)
-{
- __vector float c = a.simdInternal_;
- float res;
-
- // calculate sum
- c = vec_add(c, vec_sld(c, c, 8));
- c = vec_add(c, vec_sld(c, c, 4));
- vec_ste(c, 0, &res);
- return res;
-}
-
-static inline SimdFBool gmx_simdcall operator==(SimdFloat a, SimdFloat b)
-{
- return { vec_cmpeq(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFBool gmx_simdcall operator!=(SimdFloat a, SimdFloat b)
-{
- return { vec_or(vec_cmpgt(a.simdInternal_, b.simdInternal_),
- vec_cmplt(a.simdInternal_, b.simdInternal_)) };
-}
-
-static inline SimdFBool gmx_simdcall operator<(SimdFloat a, SimdFloat b)
-{
- return { vec_cmplt(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFBool gmx_simdcall operator<=(SimdFloat a, SimdFloat b)
-{
- return { vec_cmple(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFBool gmx_simdcall testBits(SimdFloat a)
-{
- return { vec_cmpgt(reinterpret_cast<__vector unsigned int>(a.simdInternal_), vec_splat_u32(0)) };
-}
-
-static inline SimdFBool gmx_simdcall operator&&(SimdFBool a, SimdFBool b)
-{
- return { vec_and(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFBool gmx_simdcall operator||(SimdFBool a, SimdFBool b)
-{
- return { vec_or(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline bool gmx_simdcall anyTrue(SimdFBool a)
-{
- return vec_any_ne(a.simdInternal_, reinterpret_cast<__vector vmxBool int>(vec_splat_u32(0)));
-}
-
-static inline SimdFloat gmx_simdcall selectByMask(SimdFloat a, SimdFBool m)
-{
- return { vec_and(a.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_)) };
-}
-
-static inline SimdFloat gmx_simdcall selectByNotMask(SimdFloat a, SimdFBool m)
-{
- return { vec_andc(a.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_)) };
-}
-
-static inline SimdFloat gmx_simdcall blend(SimdFloat a, SimdFloat b, SimdFBool sel)
-{
- return { vec_sel(a.simdInternal_, b.simdInternal_, sel.simdInternal_) };
-}
-
-static inline SimdFInt32 gmx_simdcall operator&(SimdFInt32 a, SimdFInt32 b)
-{
- return { vec_and(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFInt32 gmx_simdcall andNot(SimdFInt32 a, SimdFInt32 b)
-{
- return { vec_andc(b.simdInternal_, a.simdInternal_) };
-}
-
-static inline SimdFInt32 gmx_simdcall operator|(SimdFInt32 a, SimdFInt32 b)
-{
- return { vec_or(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFInt32 gmx_simdcall operator^(SimdFInt32 a, SimdFInt32 b)
-{
- return { vec_xor(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFInt32 gmx_simdcall operator+(SimdFInt32 a, SimdFInt32 b)
-{
- return { vec_add(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFInt32 gmx_simdcall operator-(SimdFInt32 a, SimdFInt32 b)
-{
- return { vec_sub(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFInt32 gmx_simdcall operator*(SimdFInt32 a, SimdFInt32 b)
-{
- return { a.simdInternal_ * b.simdInternal_ };
-}
-
-static inline SimdFIBool gmx_simdcall operator==(SimdFInt32 a, SimdFInt32 b)
-{
- return { vec_cmpeq(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFIBool gmx_simdcall testBits(SimdFInt32 a)
-{
- return { vec_cmpgt(reinterpret_cast<__vector unsigned int>(a.simdInternal_), vec_splat_u32(0)) };
-}
-
-static inline SimdFIBool gmx_simdcall operator<(SimdFInt32 a, SimdFInt32 b)
-{
- return { vec_cmplt(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFIBool gmx_simdcall operator&&(SimdFIBool a, SimdFIBool b)
-{
- return { vec_and(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFIBool gmx_simdcall operator||(SimdFIBool a, SimdFIBool b)
-{
- return { vec_or(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline bool gmx_simdcall anyTrue(SimdFIBool a)
-{
- return vec_any_ne(a.simdInternal_, reinterpret_cast<__vector vmxBool int>(vec_splat_u32(0)));
-}
-
-static inline SimdFInt32 gmx_simdcall selectByMask(SimdFInt32 a, SimdFIBool m)
-{
- return { vec_and(a.simdInternal_, reinterpret_cast<__vector signed int>(m.simdInternal_)) };
-}
-
-static inline SimdFInt32 gmx_simdcall selectByNotMask(SimdFInt32 a, SimdFIBool m)
-{
- return { vec_andc(a.simdInternal_, reinterpret_cast<__vector signed int>(m.simdInternal_)) };
-}
-
-static inline SimdFInt32 gmx_simdcall blend(SimdFInt32 a, SimdFInt32 b, SimdFIBool sel)
-{
- return { vec_sel(a.simdInternal_, b.simdInternal_, sel.simdInternal_) };
-}
-
-static inline SimdFInt32 gmx_simdcall cvtR2I(SimdFloat a)
-{
- return { vec_cts(vec_round(a.simdInternal_), 0) };
-}
-
-static inline SimdFInt32 gmx_simdcall cvttR2I(SimdFloat a)
-{
- return { vec_cts(a.simdInternal_, 0) };
-}
-
-static inline SimdFloat gmx_simdcall cvtI2R(SimdFInt32 a)
-{
- return { vec_ctf(a.simdInternal_, 0) };
-}
-
-static inline SimdFIBool gmx_simdcall cvtB2IB(SimdFBool a)
-{
- return { a.simdInternal_ };
-}
-
-static inline SimdFBool gmx_simdcall cvtIB2B(SimdFIBool a)
-{
- return { a.simdInternal_ };
-}
-
-} // namespace gmx
-
-#endif // GMX_SIMD_IMPLEMENTATION_IBM_VMX_SIMD_FLOAT_H
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 2014,2015,2016,2017,2018 by the GROMACS development team.
- * Copyright (c) 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.
- *
- * 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.
- */
-#ifndef GMX_SIMD_IMPL_IBM_VMX_UTIL_FLOAT_H
-#define GMX_SIMD_IMPL_IBM_VMX_UTIL_FLOAT_H
-
-#include "config.h"
-
-#include <cstddef>
-#include <cstdint>
-
-#include "gromacs/utility/basedefinitions.h"
-
-#include "impl_ibm_vmx_definitions.h"
-#include "impl_ibm_vmx_simd_float.h"
-
-namespace gmx
-{
-
-template<int align>
-static inline void gmx_simdcall gatherLoadTranspose(const float* base,
- const std::int32_t offset[],
- SimdFloat* v0,
- SimdFloat* v1,
- SimdFloat* v2,
- SimdFloat* v3)
-{
- *v0 = simdLoad(base + align * offset[0]);
- *v1 = simdLoad(base + align * offset[1]);
- *v2 = simdLoad(base + align * offset[2]);
- *v3 = simdLoad(base + align * offset[3]);
-
- __vector float t0 = vec_mergeh(v0->simdInternal_, v2->simdInternal_);
- __vector float t1 = vec_mergel(v0->simdInternal_, v2->simdInternal_);
- __vector float t2 = vec_mergeh(v1->simdInternal_, v3->simdInternal_);
- __vector float t3 = vec_mergel(v1->simdInternal_, v3->simdInternal_);
- v0->simdInternal_ = vec_mergeh(t0, t2);
- v1->simdInternal_ = vec_mergel(t0, t2);
- v2->simdInternal_ = vec_mergeh(t1, t3);
- v3->simdInternal_ = vec_mergel(t1, t3);
-}
-
-template<int align>
-static inline void gmx_simdcall
- gatherLoadTranspose(const float* base, const std::int32_t offset[], SimdFloat* v0, SimdFloat* v1)
-{
- if (align % 4 == 0)
- {
- SimdFloat t2, t3;
-
- gatherLoadTranspose<align>(base, offset, v0, v1, &t2, &t3);
- }
- else
- {
- __vector float t0, t1, t2, t3, t4, t5, t6, t7;
- __vector unsigned char p0, p1, p2, p3;
-
- // This is REALLY slow, since we have no choice but to load individual
- // elements when we cannot guarantee that we can access beyond the end of
- // the memory. Fortunately, 99% of the usage should be the aligned-to-4
- // case above instead.
- t0 = vec_lde(0, base + align * offset[0]);
- t1 = vec_lde(0, base + align * offset[1]);
- t2 = vec_lde(0, base + align * offset[2]);
- t3 = vec_lde(0, base + align * offset[3]);
- p0 = vec_lvsl(0, base + align * offset[0]);
- p1 = vec_lvsl(0, base + align * offset[1]);
- p2 = vec_lvsl(0, base + align * offset[2]);
- p3 = vec_lvsl(0, base + align * offset[3]);
- t0 = vec_perm(t0, t0, p0);
- t1 = vec_perm(t1, t1, p1);
- t2 = vec_perm(t2, t2, p2);
- t3 = vec_perm(t3, t3, p3);
- t0 = vec_mergeh(t0, t2);
- t1 = vec_mergeh(t1, t3);
- v0->simdInternal_ = vec_mergeh(t0, t1);
-
- t4 = vec_lde(0, base + align * offset[0] + 1);
- t5 = vec_lde(0, base + align * offset[1] + 1);
- t6 = vec_lde(0, base + align * offset[2] + 1);
- t7 = vec_lde(0, base + align * offset[3] + 1);
- p0 = vec_lvsl(0, base + align * offset[0] + 1);
- p1 = vec_lvsl(0, base + align * offset[1] + 1);
- p2 = vec_lvsl(0, base + align * offset[2] + 1);
- p3 = vec_lvsl(0, base + align * offset[3] + 1);
- t4 = vec_perm(t4, t4, p0);
- t5 = vec_perm(t5, t5, p1);
- t6 = vec_perm(t6, t6, p2);
- t7 = vec_perm(t7, t7, p3);
- t4 = vec_mergeh(t4, t6);
- t5 = vec_mergeh(t5, t7);
- v1->simdInternal_ = vec_mergeh(t4, t5);
- }
-}
-
-static const int c_simdBestPairAlignmentFloat = 2;
-
-template<int align>
-static inline void gmx_simdcall gatherLoadUTranspose(const float* base,
- const std::int32_t offset[],
- SimdFloat* v0,
- SimdFloat* v1,
- SimdFloat* v2)
-{
- if (align % 4 == 0)
- {
- SimdFloat t3;
- gatherLoadTranspose<align>(base, offset, v0, v1, v2, &t3);
- }
- else
- {
- __vector float t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11;
- __vector unsigned char p0, p1, p2, p3;
-
- // This is REALLY slow, since we have no choice but to load individual
- // elements when we cannot guarantee that we can access beyond the end of
- // the memory. Unfortunately this is likely the most common case.
- t0 = vec_lde(0, base + align * offset[0]);
- t1 = vec_lde(0, base + align * offset[1]);
- t2 = vec_lde(0, base + align * offset[2]);
- t3 = vec_lde(0, base + align * offset[3]);
- p0 = vec_lvsl(0, base + align * offset[0]);
- p1 = vec_lvsl(0, base + align * offset[1]);
- p2 = vec_lvsl(0, base + align * offset[2]);
- p3 = vec_lvsl(0, base + align * offset[3]);
- t0 = vec_perm(t0, t0, p0);
- t1 = vec_perm(t1, t1, p1);
- t2 = vec_perm(t2, t2, p2);
- t3 = vec_perm(t3, t3, p3);
- t0 = vec_mergeh(t0, t2);
- t1 = vec_mergeh(t1, t3);
- v0->simdInternal_ = vec_mergeh(t0, t1);
-
- t4 = vec_lde(0, base + align * offset[0] + 1);
- t5 = vec_lde(0, base + align * offset[1] + 1);
- t6 = vec_lde(0, base + align * offset[2] + 1);
- t7 = vec_lde(0, base + align * offset[3] + 1);
- p0 = vec_lvsl(0, base + align * offset[0] + 1);
- p1 = vec_lvsl(0, base + align * offset[1] + 1);
- p2 = vec_lvsl(0, base + align * offset[2] + 1);
- p3 = vec_lvsl(0, base + align * offset[3] + 1);
- t4 = vec_perm(t4, t4, p0);
- t5 = vec_perm(t5, t5, p1);
- t6 = vec_perm(t6, t6, p2);
- t7 = vec_perm(t7, t7, p3);
- t4 = vec_mergeh(t4, t6);
- t5 = vec_mergeh(t5, t7);
- v1->simdInternal_ = vec_mergeh(t4, t5);
-
- t8 = vec_lde(0, base + align * offset[0] + 2);
- t9 = vec_lde(0, base + align * offset[1] + 2);
- t10 = vec_lde(0, base + align * offset[2] + 2);
- t11 = vec_lde(0, base + align * offset[3] + 2);
- p0 = vec_lvsl(0, base + align * offset[0] + 2);
- p1 = vec_lvsl(0, base + align * offset[1] + 2);
- p2 = vec_lvsl(0, base + align * offset[2] + 2);
- p3 = vec_lvsl(0, base + align * offset[3] + 2);
- t8 = vec_perm(t8, t8, p0);
- t9 = vec_perm(t9, t9, p1);
- t10 = vec_perm(t10, t10, p2);
- t11 = vec_perm(t11, t11, p3);
- t8 = vec_mergeh(t8, t10);
- t9 = vec_mergeh(t9, t11);
- v2->simdInternal_ = vec_mergeh(t8, t9);
- }
-}
-
-
-template<int align>
-static inline void gmx_simdcall
- transposeScatterStoreU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2)
-{
- __vector unsigned char p0, p1, p2, p3;
-
- __vector float t0 = vec_mergeh(v0.simdInternal_, v2.simdInternal_);
- __vector float t1 = vec_mergel(v0.simdInternal_, v2.simdInternal_);
- __vector float t2 = vec_mergeh(v1.simdInternal_, v2.simdInternal_);
- __vector float t3 = vec_mergel(v1.simdInternal_, v2.simdInternal_);
- __vector float t4 = vec_mergeh(t0, t2);
- __vector float t5 = vec_mergel(t0, t2);
- __vector float t6 = vec_mergeh(t1, t3);
- __vector float t7 = vec_mergel(t1, t3);
-
- p0 = vec_lvsr(0, base + align * offset[0]);
- p1 = vec_lvsr(0, base + align * offset[1]);
- p2 = vec_lvsr(0, base + align * offset[2]);
- p3 = vec_lvsr(0, base + align * offset[3]);
-
- t4 = vec_perm(t4, t4, p0);
- t5 = vec_perm(t5, t5, p1);
- t6 = vec_perm(t6, t6, p2);
- t7 = vec_perm(t7, t7, p3);
-
- vec_ste(t4, 0, base + align * offset[0]);
- vec_ste(t4, 4, base + align * offset[0]);
- vec_ste(t4, 8, base + align * offset[0]);
- vec_ste(t5, 0, base + align * offset[1]);
- vec_ste(t5, 4, base + align * offset[1]);
- vec_ste(t5, 8, base + align * offset[1]);
- vec_ste(t6, 0, base + align * offset[2]);
- vec_ste(t6, 4, base + align * offset[2]);
- vec_ste(t6, 8, base + align * offset[2]);
- vec_ste(t7, 0, base + align * offset[3]);
- vec_ste(t7, 4, base + align * offset[3]);
- vec_ste(t7, 8, base + align * offset[3]);
-}
-
-
-template<int align>
-static inline void gmx_simdcall
- transposeScatterIncrU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2)
-{
- if (align % 4 == 0)
- {
- __vector float zero = reinterpret_cast<__vector float>(vec_splat_u32(0));
- __vector float t0 = vec_mergeh(v0.simdInternal_, v2.simdInternal_);
- __vector float t1 = vec_mergel(v0.simdInternal_, v2.simdInternal_);
- __vector float t2 = vec_mergeh(v1.simdInternal_, zero);
- __vector float t3 = vec_mergel(v1.simdInternal_, zero);
- __vector float t4 = vec_mergeh(t0, t2);
- __vector float t5 = vec_mergel(t0, t2);
- __vector float t6 = vec_mergeh(t1, t3);
- __vector float t7 = vec_mergel(t1, t3);
-
- vec_st(vec_add(vec_ld(0, base + align * offset[0]), t4), 0, base + align * offset[0]);
- vec_st(vec_add(vec_ld(0, base + align * offset[1]), t5), 0, base + align * offset[1]);
- vec_st(vec_add(vec_ld(0, base + align * offset[2]), t6), 0, base + align * offset[2]);
- vec_st(vec_add(vec_ld(0, base + align * offset[3]), t7), 0, base + align * offset[3]);
- }
- else
- {
- alignas(GMX_SIMD_ALIGNMENT) float rdata0[GMX_SIMD_FLOAT_WIDTH];
- alignas(GMX_SIMD_ALIGNMENT) float rdata1[GMX_SIMD_FLOAT_WIDTH];
- alignas(GMX_SIMD_ALIGNMENT) float rdata2[GMX_SIMD_FLOAT_WIDTH];
-
- vec_st(v0.simdInternal_, 0, rdata0);
- vec_st(v1.simdInternal_, 0, rdata1);
- vec_st(v2.simdInternal_, 0, rdata2);
-
- base[align * offset[0] + 0] += rdata0[0];
- base[align * offset[0] + 1] += rdata1[0];
- base[align * offset[0] + 2] += rdata2[0];
- base[align * offset[1] + 0] += rdata0[1];
- base[align * offset[1] + 1] += rdata1[1];
- base[align * offset[1] + 2] += rdata2[1];
- base[align * offset[2] + 0] += rdata0[2];
- base[align * offset[2] + 1] += rdata1[2];
- base[align * offset[2] + 2] += rdata2[2];
- base[align * offset[3] + 0] += rdata0[3];
- base[align * offset[3] + 1] += rdata1[3];
- base[align * offset[3] + 2] += rdata2[3];
- }
-}
-
-template<int align>
-static inline void gmx_simdcall
- transposeScatterDecrU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2)
-{
- if (align % 4 == 0)
- {
- __vector float zero = reinterpret_cast<__vector float>(vec_splat_u32(0));
- __vector float t0 = vec_mergeh(v0.simdInternal_, v2.simdInternal_);
- __vector float t1 = vec_mergel(v0.simdInternal_, v2.simdInternal_);
- __vector float t2 = vec_mergeh(v1.simdInternal_, zero);
- __vector float t3 = vec_mergel(v1.simdInternal_, zero);
- __vector float t4 = vec_mergeh(t0, t2);
- __vector float t5 = vec_mergel(t0, t2);
- __vector float t6 = vec_mergeh(t1, t3);
- __vector float t7 = vec_mergel(t1, t3);
-
- vec_st(vec_sub(vec_ld(0, base + align * offset[0]), t4), 0, base + align * offset[0]);
- vec_st(vec_sub(vec_ld(0, base + align * offset[1]), t5), 0, base + align * offset[1]);
- vec_st(vec_sub(vec_ld(0, base + align * offset[2]), t6), 0, base + align * offset[2]);
- vec_st(vec_sub(vec_ld(0, base + align * offset[3]), t7), 0, base + align * offset[3]);
- }
- else
- {
- alignas(GMX_SIMD_ALIGNMENT) float rdata0[GMX_SIMD_FLOAT_WIDTH];
- alignas(GMX_SIMD_ALIGNMENT) float rdata1[GMX_SIMD_FLOAT_WIDTH];
- alignas(GMX_SIMD_ALIGNMENT) float rdata2[GMX_SIMD_FLOAT_WIDTH];
-
- vec_st(v0.simdInternal_, 0, rdata0);
- vec_st(v1.simdInternal_, 0, rdata1);
- vec_st(v2.simdInternal_, 0, rdata2);
-
- base[align * offset[0] + 0] -= rdata0[0];
- base[align * offset[0] + 1] -= rdata1[0];
- base[align * offset[0] + 2] -= rdata2[0];
- base[align * offset[1] + 0] -= rdata0[1];
- base[align * offset[1] + 1] -= rdata1[1];
- base[align * offset[1] + 2] -= rdata2[1];
- base[align * offset[2] + 0] -= rdata0[2];
- base[align * offset[2] + 1] -= rdata1[2];
- base[align * offset[2] + 2] -= rdata2[2];
- base[align * offset[3] + 0] -= rdata0[3];
- base[align * offset[3] + 1] -= rdata1[3];
- base[align * offset[3] + 2] -= rdata2[3];
- }
-}
-
-static inline void gmx_simdcall expandScalarsToTriplets(SimdFloat scalar,
- SimdFloat* triplets0,
- SimdFloat* triplets1,
- SimdFloat* triplets2)
-{
- const __vector unsigned char perm0 = { 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7 };
- const __vector unsigned char perm1 = { 4, 5, 6, 7, 4, 5, 6, 7, 8, 9, 10, 11, 8, 9, 10, 11 };
- const __vector unsigned char perm2 = { 8, 9, 10, 11, 12, 13, 14, 15,
- 12, 13, 14, 15, 12, 13, 14, 15 };
-
- triplets0->simdInternal_ = vec_perm(scalar.simdInternal_, scalar.simdInternal_, perm0);
- triplets1->simdInternal_ = vec_perm(scalar.simdInternal_, scalar.simdInternal_, perm1);
- triplets2->simdInternal_ = vec_perm(scalar.simdInternal_, scalar.simdInternal_, perm2);
-}
-
-
-template<int align>
-static inline void gmx_simdcall gatherLoadBySimdIntTranspose(const float* base,
- SimdFInt32 offset,
- SimdFloat* v0,
- SimdFloat* v1,
- SimdFloat* v2,
- SimdFloat* v3)
-{
- alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_FINT32_WIDTH];
-
- vec_st(offset.simdInternal_, 0, ioffset);
- gatherLoadTranspose<align>(base, ioffset, v0, v1, v2, v3);
-}
-
-template<int align>
-static inline void gmx_simdcall
- gatherLoadBySimdIntTranspose(const float* base, SimdFInt32 offset, SimdFloat* v0, SimdFloat* v1)
-{
- alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_FINT32_WIDTH];
-
- vec_st(offset.simdInternal_, 0, ioffset);
- gatherLoadTranspose<align>(base, ioffset, v0, v1);
-}
-
-
-static inline float gmx_simdcall reduceIncr4ReturnSum(float* m, SimdFloat v0, SimdFloat v1, SimdFloat v2, SimdFloat v3)
-{
- __vector float t0 = vec_mergeh(v0.simdInternal_, v2.simdInternal_);
- __vector float t1 = vec_mergel(v0.simdInternal_, v2.simdInternal_);
- __vector float t2 = vec_mergeh(v1.simdInternal_, v3.simdInternal_);
- __vector float t3 = vec_mergel(v1.simdInternal_, v3.simdInternal_);
- v0.simdInternal_ = vec_mergeh(t0, t2);
- v1.simdInternal_ = vec_mergel(t0, t2);
- v2.simdInternal_ = vec_mergeh(t1, t3);
- v3.simdInternal_ = vec_mergel(t1, t3);
-
- v0 = v0 + v1;
- v2 = v2 + v3;
- v0 = v0 + v2;
- v2 = v0 + simdLoad(m);
- store(m, v2);
-
- return reduce(v0);
-}
-
-} // namespace gmx
-
-#endif // GMX_SIMD_IMPL_IBM_VMX_UTIL_FLOAT_H
const __vector unsigned char perm = { 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7 };
#ifdef __xlC__
/* old xlc version 12 does not understand vec_perm() with double arguments */
- x.simdInternal_ = vec_add(
- x.simdInternal_, reinterpret_cast<__vector double>(vec_perm(
- reinterpret_cast<__vector signed int>(x.simdInternal_),
- reinterpret_cast<__vector signed int>(x.simdInternal_), perm)));
+ x.simdInternal_ = vec_add(x.simdInternal_,
+ reinterpret_cast<__vector double>(vec_perm(
+ reinterpret_cast<__vector signed int>(x.simdInternal_),
+ reinterpret_cast<__vector signed int>(x.simdInternal_),
+ perm)));
#else
x.simdInternal_ = vec_add(x.simdInternal_, vec_perm(x.simdInternal_, x.simdInternal_, perm));
#endif
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 2014,2015, 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.
- */
-
-#ifndef GMX_SIMD_IMPL_SPARC64_HPC_ACE_H
-#define GMX_SIMD_IMPL_SPARC64_HPC_ACE_H
-
-#include "impl_sparc64_hpc_ace_simd_double.h"
-#include "impl_sparc64_hpc_ace_simd_float.h"
-/* No SIMD4 support, since both single & double are only 2-wide */
-
-#endif /* GMX_SIMD_IMPL_SPARC64_HPC_ACE_H */
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 2014,2015,2018,2019, by the GROMACS development team, led by
- * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
- * and including many others, as listed in the AUTHORS file in the
- * top-level source directory and at http://www.gromacs.org.
- *
- * GROMACS is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * GROMACS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with GROMACS; if not, see
- * http://www.gnu.org/licenses, or write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * If you want to redistribute modifications to GROMACS, please
- * consider that scientific software is very special. Version
- * control is crucial - bugs must be traceable. We will be happy to
- * consider code for inclusion in the official distribution, but
- * derived work must not be called official GROMACS. Details are found
- * in the README & COPYING files - if they are missing, get the
- * official version at http://www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org.
- */
-
-#ifndef GMX_SIMD_IMPL_SPARC64_HPC_ACE_COMMON_H
-#define GMX_SIMD_IMPL_SPARC64_HPC_ACE_COMMON_H
-
-/* Capability definitions for Sparc64 HPC-ACE */
-/* HPC-ACE is actually double-only on the register level, but we also implement
- * a single-precision interface where we only offer single-precision accuracy
- * in math functions - this can save quite a few cycles.
- */
-#define GMX_SIMD 1
-#define GMX_SIMD_HAVE_FLOAT 1
-#define GMX_SIMD_HAVE_DOUBLE 1
-#define GMX_SIMD_HAVE_LOADU 0
-#define GMX_SIMD_HAVE_STOREU 0
-#define GMX_SIMD_HAVE_LOGICAL 1
-#define GMX_SIMD_HAVE_FMA 1
-#define GMX_SIMD_HAVE_FINT32_EXTRACT 1
-#define GMX_SIMD_HAVE_FINT32_LOGICAL 1
-#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 0
-#define GMX_SIMD_HAVE_DINT32_EXTRACT 1
-#define GMX_SIMD_HAVE_DINT32_LOGICAL 1
-#define GMX_SIMD_HAVE_DINT32_ARITHMETICS 0
-#define GMX_SIMD4_HAVE_FLOAT 0
-#define GMX_SIMD4_HAVE_DOUBLE 0
-
-/* Implementation details */
-#define GMX_SIMD_FLOAT_WIDTH 2
-#define GMX_SIMD_DOUBLE_WIDTH 2
-#define GMX_SIMD_FINT32_WIDTH 2
-#define GMX_SIMD_DINT32_WIDTH 2
-/* No SIMD4 support in either single or double */
-#define GMX_SIMD_RSQRT_BITS 10
-#define GMX_SIMD_RCP_BITS 9
-
-#endif /* GMX_SIMD_IMPL_SPARC64_HPC_ACE_COMMON_H */
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by
- * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
- * and including many others, as listed in the AUTHORS file in the
- * top-level source directory and at http://www.gromacs.org.
- *
- * GROMACS is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * GROMACS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with GROMACS; if not, see
- * http://www.gnu.org/licenses, or write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * If you want to redistribute modifications to GROMACS, please
- * consider that scientific software is very special. Version
- * control is crucial - bugs must be traceable. We will be happy to
- * consider code for inclusion in the official distribution, but
- * derived work must not be called official GROMACS. Details are found
- * in the README & COPYING files - if they are missing, get the
- * official version at http://www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org.
- */
-
-#ifndef GMX_SIMD_IMPL_SPARC64_HPC_ACE_SIMD_DOUBLE_H
-#define GMX_SIMD_IMPL_SPARC64_HPC_ACE_SIMD_DOUBLE_H
-
-/* Fujitsu header borrows the name from SSE2, since some instructions have aliases.
- * Environment/compiler version GM-1.2.0-17 seems to be buggy; when -Xg is
- * defined to enable GNUC extensions, this sets _ISOC99_SOURCE, which in
- * turn causes all intrinsics to be declared inline _instead_ of static. This
- * leads to duplicate symbol errors at link time.
- * To work around this we unset this before including the HPC-ACE header, and
- * reset the value afterwards.
- */
-#ifdef _ISOC99_SOURCE
-# undef _ISOC99_SOURCE
-# define SAVE_ISOC99_SOURCE
-#endif
-
-#include <emmintrin.h>
-
-#ifdef SAVE_ISOC99_SOURCE
-# define _ISOC99_SOURCE
-# undef SAVE_ISOC99_SOURCE
-#endif
-
-#include <cmath>
-#include <cstdint>
-
-#include "impl_sparc64_hpc_ace_common.h"
-
-/****************************************************
- * DOUBLE PRECISION SIMD IMPLEMENTATION *
- ****************************************************/
-#define SimdDouble _fjsp_v2r8
-#define simdLoadD _fjsp_load_v2r8
-#define simdLoad1D(m) _fjsp_set_v2r8((*m), (*m))
-#define simdSet1D(a) _fjsp_set_v2r8(a, a)
-#define simdStoreD _fjsp_store_v2r8
-#define simdLoadUD simdLoadD
-/* No unaligned store of SimdDouble */
-#define simdSetZeroD _fjsp_setzero_v2r8
-#define simdAddD _fjsp_add_v2r8
-#define simdSubD _fjsp_sub_v2r8
-#define simdMulD _fjsp_mul_v2r8
-#define simdFmaddD(a, b, c) _fjsp_madd_v2r8(a, b, c)
-#define simdFmsubD(a, b, c) _fjsp_msub_v2r8(a, b, c)
-#define simdFnmaddD(a, b, c) _fjsp_nmsub_v2r8(a, b, c)
-#define simdFnmsubD(a, b, c) _fjsp_nmadd_v2r8(a, b, c)
-#define simdAndD _fjsp_and_v2r8
-#define simdAndNotD _fjsp_andnot1_v2r8
-#define simdOrD _fjsp_or_v2r8
-#define simdXorD _fjsp_xor_v2r8
-#define simdRsqrtD(x) _fjsp_rsqrta_v2r8(x)
-#define simdRcpD(x) _fjsp_rcpa_v2r8(x)
-#define simdAbsD(x) _fjsp_abs_v2r8(x)
-#define simdNegD(x) _fjsp_neg_v2r8(x)
-#define simdMaxD _fjsp_max_v2r8
-#define simdMinD _fjsp_min_v2r8
-#define simdRoundD(x) simdCvtI2D(simdCvtD2I(x))
-#define simdTruncD(x) simdCvtI2D(simdCvttD2I(x))
-#define simdFractionD(x) simdSubD(x, simdTruncD(x))
-#define simdGetExponentD simdGetExponentD_sparc64_hpc_ace
-#define simdGetMantissaD simdGetMantissaD_sparc64_hpc_ace
-#define simdSetExponentD simdSetExponentD_sparc64_hpc_ace
-/* integer datatype corresponding to double: SimdDInt32 */
-#define SimdDInt32 _fjsp_v2r8
-#define simdLoadDI(m) simdLoadDI_sparc64_hpc_ace(m)
-#define simdSet1DI(i) simdSet1DI_sparc64_hpc_ace(i)
-#define simdStoreDI(m, x) simdStoreDI_sparc64_hpc_ace(m, x)
-#define simdLoadUDI simdLoadDI
-/* No unaligned store of SimdDInt32 */
-#define simdSetZeroDI _fjsp_setzero_v2r8
-#define simdCvtD2I simdCvtD2I_sparc64_hpc_ace
-#define simdCvttD2I _fjsp_dtox_v2r8
-#define simdCvtI2D _fjsp_xtod_v2r8
-#define simdExtractDI simdExtractDI_sparc64_hpc_ace
-/* Integer logical ops on SimdDInt32 */
-#define simdSlliDI simdSlliDI_sparc64_hpc_ace
-#define simdSrliDI simdSrliDI_sparc64_hpc_ace
-#define simdAndDI _fjsp_and_v2r8
-#define simdAndNotDI _fjsp_andnot1_v2r8
-#define simdOrDI _fjsp_or_v2r8
-#define simdXorDI _fjsp_xor_v2r8
-/* Integer arithmetic ops on integer datatype corresponding to double */
-/* Boolean & comparison operations on SimdDouble */
-#define SimdDBool _fjsp_v2r8
-#define simdCmpEqD _fjsp_cmpeq_v2r8
-#define simdCmpLtD _fjsp_cmplt_v2r8
-#define simdCmpLeD _fjsp_cmple_v2r8
-#define simdAndDB _fjsp_and_v2r8
-#define simdOrDB _fjsp_or_v2r8
-#define simdAnyTrueDB gmx_simd_anytrue_d_sparc64_hpc_ace
-#define simdMaskD _fjsp_and_v2r8
-#define simdMaskNotD(a, sel) _fjsp_andnot1_v2r8(sel, a)
-#define simdBlendD(a, b, sel) _fjsp_selmov_v2r8(b, a, sel)
-#define simdReduceD(a) simdReduceD_sparc64_hpc_ace(a)
-
-/* No boolean & comparison operations on SimdDInt32 */
-/* Float/double conversion */
-#define simdCvtF2D(f) (f)
-#define simdCvtD2F(d) (d)
-
-
-/****************************************************
- * DOUBLE PRECISION IMPLEMENTATION HELPER FUNCTIONS *
- ****************************************************/
-static inline SimdDInt32 simdLoadDI_sparc64_hpc_ace(const int* m)
-{
- union {
- _fjsp_v2r8 simd;
- long long int i[2];
- } conv;
-
- conv.i[0] = m[0];
- conv.i[1] = m[1];
-
- return _fjsp_load_v2r8((double*)&(conv.simd));
-}
-
-static inline void simdStoreDI_sparc64_hpc_ace(int* m, SimdDInt32 x)
-{
- union {
- _fjsp_v2r8 simd;
- long long int i[2];
- } conv;
-
- _fjsp_store_v2r8((double*)&(conv.simd), x);
-
- m[0] = conv.i[0];
- m[1] = conv.i[1];
-}
-
-static inline SimdDInt32 simdSet1DI_sparc64_hpc_ace(int i)
-{
- union {
- _fjsp_v2r8 simd;
- long long int i[2];
- } conv;
-
- conv.i[0] = i;
- conv.i[1] = i;
-
- return _fjsp_load_v2r8((double*)&(conv.simd));
-}
-
-static inline int simdExtractDI_sparc64_hpc_ace(SimdDInt32 x, int i)
-{
- long long int res;
- /* This conditional should be optimized away at compile time */
- if (i == 0)
- {
- _fjsp_storel_v2r8((double*)&res, x);
- }
- else
- {
- _fjsp_storeh_v2r8((double*)&res, x);
- }
- return (int)res;
-}
-
-static inline SimdDInt32 simdSlliDI_sparc64_hpc_ace(SimdDInt32 x, int i)
-{
- _fjsp_v2i8 ix = *((_fjsp_v2i8*)&x);
- ix = _fjsp_slli_v2i8(ix, i);
- x = *((_fjsp_v2r8*)&ix);
- return x;
-}
-
-static inline SimdDInt32 simdSrliDI_sparc64_hpc_ace(SimdDInt32 x, int i)
-{
- _fjsp_v2i8 ix = *((_fjsp_v2i8*)&x);
- ix = _fjsp_srli_v2i8(ix, i);
- x = *((_fjsp_v2r8*)&ix);
- return x;
-}
-
-static inline SimdDInt32 simdCvtD2I_sparc64_hpc_ace(SimdDouble x)
-{
- _fjsp_v2r8 signbit = _fjsp_set_v2r8(-0.0, -0.0);
- _fjsp_v2r8 half = _fjsp_set_v2r8(0.5, 0.5);
-
- x = _fjsp_add_v2r8(x, _fjsp_or_v2r8(_fjsp_and_v2r8(signbit, x), half));
- return _fjsp_dtox_v2r8(x);
-}
-
-static inline int gmx_simd_anytrue_d_sparc64_hpc_ace(SimdDBool x)
-{
- long long int i;
- x = _fjsp_or_v2r8(x, _fjsp_unpackhi_v2r8(x, x));
- _fjsp_storel_v2r8((double*)&i, x);
- return (i != 0LL);
-}
-
-static inline double simdReduceD_sparc64_hpc_ace(SimdDouble x)
-{
- double d;
- x = _fjsp_add_v2r8(x, _fjsp_unpackhi_v2r8(x, x));
- _fjsp_storel_v2r8(&d, x);
- return d;
-}
-
-
-static inline SimdDouble simdGetExponentD_sparc64_hpc_ace(SimdDouble x)
-{
- /* HPC-ACE cannot cast _fjsp_v2r8 to _fjsp_v4i4, so to perform shifts we
- * would need to store and reload. Since we are only operating on two
- * numbers it is likely more efficient to do the operations directly on
- * normal registers.
- */
- const std::int64_t expmask = 0x7ff0000000000000LL;
- const std::int64_t expbias = 1023LL;
-
- union {
- _fjsp_v2r8 simd;
- long long int i[2];
- } conv;
-
- _fjsp_store_v2r8((double*)&conv.simd, x);
- conv.i[0] = ((conv.i[0] & expmask) >> 52) - expbias;
- conv.i[1] = ((conv.i[1] & expmask) >> 52) - expbias;
- x = _fjsp_load_v2r8((double*)&conv.simd);
- return _fjsp_xtod_v2r8(x);
-}
-
-static inline SimdDouble simdGetMantissaD_sparc64_hpc_ace(SimdDouble x)
-{
- std::int64_t mantmask[2] = { 0x000fffffffffffffLL, 0x000fffffffffffffLL };
- SimdDouble one = _fjsp_set_v2r8(1.0, 1.0);
-
- x = _fjsp_and_v2r8(x, _fjsp_load_v2r8((double*)mantmask));
- return _fjsp_or_v2r8(x, one);
-}
-
-static inline SimdDouble simdSetExponentD_sparc64_hpc_ace(SimdDouble x)
-{
- const std::int64_t expbias = 1023;
- union {
- _fjsp_v2r8 simd;
- long long int i[2];
- } conv;
-
-
- _fjsp_store_v2r8((double*)&conv.simd, simdCvtD2I_sparc64_hpc_ace(x));
- conv.i[0] = (conv.i[0] + expbias) << 52;
- conv.i[1] = (conv.i[1] + expbias) << 52;
-
- return _fjsp_load_v2r8((double*)&conv.simd);
-}
-
-#endif /* GMX_SIMD_IMPL_SPARC64_HPC_ACE_SIMD_DOUBLE_H */
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by
- * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
- * and including many others, as listed in the AUTHORS file in the
- * top-level source directory and at http://www.gromacs.org.
- *
- * GROMACS is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * GROMACS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with GROMACS; if not, see
- * http://www.gnu.org/licenses, or write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * If you want to redistribute modifications to GROMACS, please
- * consider that scientific software is very special. Version
- * control is crucial - bugs must be traceable. We will be happy to
- * consider code for inclusion in the official distribution, but
- * derived work must not be called official GROMACS. Details are found
- * in the README & COPYING files - if they are missing, get the
- * official version at http://www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org.
- */
-
-#ifndef GMX_SIMD_IMPL_SPARC64_HPC_ACE_SIMD_FLOAT_H
-#define GMX_SIMD_IMPL_SPARC64_HPC_ACE_SIMD_FLOAT_H
-
-/* Fujitsu header borrows the name from SSE2, since some instructions have aliases.
- * Environment/compiler version GM-1.2.0-17 seems to be buggy; when -Xg is
- * defined to enable GNUC extensions, this sets _ISOC99_SOURCE, which in
- * turn causes all intrinsics to be declared inline _instead_ of static. This
- * leads to duplicate symbol errors at link time.
- * To work around this we unset this before including the HPC-ACE header, and
- * reset the value afterwards.
- */
-#ifdef _ISOC99_SOURCE
-# undef _ISOC99_SOURCE
-# define SAVE_ISOC99_SOURCE
-#endif
-
-#include <emmintrin.h>
-
-#ifdef SAVE_ISOC99_SOURCE
-# define _ISOC99_SOURCE
-# undef SAVE_ISOC99_SOURCE
-#endif
-
-#include <math.h>
-
-#include "impl_sparc64_hpc_ace_common.h"
-
-/* HPC-ACE is a bit strange; some instructions like
- * shifts only work on _integer_ versions of SIMD
- * registers, but there are no intrinsics to load
- * or convert, or even to cast. The only way to use
- * them is to declare unions with the SIMD integer
- * type. However, this will lead to extra load ops,
- * and the normal real-to-int and int-to-real
- * conversions work purely on the v2r8 fp regs.
- * Since our most common usage is to convert and
- * then extract the result for table lookups, we
- * define the SimdFInt32 datatype to use
- * the v2r8 rather than v2i8 SIMD type.
- */
-
-/****************************************************
- * SINGLE PRECISION SIMD IMPLEMENTATION *
- ****************************************************/
-#define SimdFloat _fjsp_v2r8
-#define simdLoadF simdLoadF_sparc64_hpc_ace
-#define simdLoad1F(m) _fjsp_set_v2r8((*m), (*m))
-#define simdSet1F(a) _fjsp_set_v2r8(a, a)
-#define simdStoreF simdStoreF_sparc64_hpc_ace
-#define simdLoadUF simdLoadF
-/* No unaligned store of SimdFloat */
-#define simdSetZeroF _fjsp_setzero_v2r8
-#define simdAddF _fjsp_add_v2r8
-#define simdSubF _fjsp_sub_v2r8
-#define simdMulF _fjsp_mul_v2r8
-#define simdFmaddF(a, b, c) _fjsp_madd_v2r8(a, b, c)
-#define simdFmsubF(a, b, c) _fjsp_msub_v2r8(a, b, c)
-#define simdFnmaddF(a, b, c) _fjsp_nmsub_v2r8(a, b, c)
-#define simdFnmsubF(a, b, c) _fjsp_nmadd_v2r8(a, b, c)
-#define simdAndF _fjsp_and_v2r8
-#define simdAndNotF _fjsp_andnot1_v2r8
-#define simdOrF _fjsp_or_v2r8
-#define simdXorF _fjsp_xor_v2r8
-#define simdRsqrtF _fjsp_rsqrta_v2r8
-#define simdRcpF _fjsp_rcpa_v2r8
-#define simdAbsF(x) _fjsp_abs_v2r8(x)
-#define simdNegF(x) _fjsp_neg_v2r8(x)
-#define simdMaxF _fjsp_max_v2r8
-#define simdMinF _fjsp_min_v2r8
-#define simdRoundF(x) simdRoundD(x)
-#define simdTruncF(x) simdTruncD(x)
-#define simdFractionF(x) simdSubF(x, simdTruncF(x))
-#define simdGetExponentF simdGetExponentD_sparc64_hpc_ace
-#define simdGetMantissaF simdGetMantissaD_sparc64_hpc_ace
-#define simdSetExponentF simdSetExponentD_sparc64_hpc_ace
-/* integer datatype corresponding to float: SimdFInt32 */
-#define SimdFInt32 _fjsp_v2r8
-#define simdLoadFI(m) simdLoadDI_sparc64_hpc_ace(m)
-#define simdSet1FI(i) simdSet1DI_sparc64_hpc_ace(i)
-#define simdStoreFI(m, x) simdStoreDI_sparc64_hpc_ace(m, x)
-#define simdLoadUFI simdLoadFI
-/* No unaligned store of SimdFInt32 */
-#define simdSetZeroFI _fjsp_setzero_v2r8
-#define simdCvtF2I simdCvtD2I
-#define simdCvttF2I _fjsp_dtox_v2r8
-#define simdCvtI2F _fjsp_xtod_v2r8
-#define simdExtractFI simdExtractDI_sparc64_hpc_ace
-/* Integer logical ops on SimdFInt32 */
-/* Shifts are horrible since they require memory re-loads. */
-#define simdSlliFI simdSlliDI_sparc64_hpc_ace
-#define simdSrliFI simdSrliDI_sparc64_hpc_ace
-#define simdAndFI _fjsp_and_v2r8
-#define simdAndNotFI(a, b) _fjsp_andnot1_v2r8(a, b)
-#define simdOrFI _fjsp_or_v2r8
-#define simdXorFI _fjsp_xor_v2r8
-/* No integer arithmetic ops on SimdFInt32 */
-/* Boolean & comparison operations on SimdFloat */
-#define SimdFBool _fjsp_v2r8
-#define simdCmpEqF _fjsp_cmpeq_v2r8
-#define simdCmpLtF _fjsp_cmplt_v2r8
-#define simdCmpLeF _fjsp_cmple_v2r8
-#define simdAndFB _fjsp_and_v2r8
-#define simdOrFB _fjsp_or_v2r8
-#define simdAnyTrueFB gmx_simd_anytrue_d_sparc64_hpc_ace
-#define simdMaskF _fjsp_and_v2r8
-#define simdMaskNotF(a, sel) _fjsp_andnot1_v2r8(sel, a)
-#define simdBlendF(a, b, s) _fjsp_selmov_v2r8(b, a, s)
-#define simdReduceF(a) simdReduceD_sparc64_hpc_ace(a)
-/* No boolean & comparison operations on SimdFInt32 */
-/* No conversions between different booleans */
-
-/****************************************************
- * SINGLE PRECISION IMPLEMENTATION HELPER FUNCTIONS *
- ****************************************************/
-static inline SimdFloat simdLoadF_sparc64_hpc_ace(const float* m)
-{
- /* We are not allowed to cast single-to-double registers, but we can
- * masquerade the memory location as a variable of type _fjsp_v2r4.
- */
- const _fjsp_v2r4* p = (const _fjsp_v2r4*)m;
- _fjsp_v2r4 simd;
-
- simd = *p;
- return _fjsp_stod_v2r8(simd);
-}
-
-static inline void simdStoreF_sparc64_hpc_ace(float* m, SimdFloat x)
-{
- /* We are not allowed to cast single-to-double registers, but we can
- * masquerade the memory location as a variable of type _fjsp_v2r4.
- */
- _fjsp_v2r4* p = (_fjsp_v2r4*)m;
- *p = _fjsp_dtos_v2r4(x);
-}
-
-/* Note that some single precision defines refer to the double precision helpers */
-
-#endif /* GMX_SIMD_IMPL_SPARC64_HPC_ACE_SIMD_FLOAT_H */
// precision fields, but a bit below we'll need a corresponding integer variable with 4x
// 32-bit fields. Since AVX1 does not support shuffling across the upper/lower 128-bit
// lanes, we need to extract those first, and then shuffle between two 128-bit variables.
- __m128i iValueIsZero = _mm_castps_si128(_mm_shuffle_ps(
- _mm256_extractf128_ps(_mm256_castpd_ps(valueIsZero), 0x0),
- _mm256_extractf128_ps(_mm256_castpd_ps(valueIsZero), 0x1), _MM_SHUFFLE(2, 0, 2, 0)));
+ __m128i iValueIsZero = _mm_castps_si128(
+ _mm_shuffle_ps(_mm256_extractf128_ps(_mm256_castpd_ps(valueIsZero), 0x0),
+ _mm256_extractf128_ps(_mm256_castpd_ps(valueIsZero), 0x1),
+ _MM_SHUFFLE(2, 0, 2, 0)));
// Set exponent to 0 when input value was zero
iExponentLow = _mm_andnot_si128(iValueIsZero, iExponentLow);
// we can use aligned loads since base should also be aligned in this case
assert(std::size_t(base) % 16 == 0);
t1 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_load_ps(base + align * offset[0])),
- _mm_load_ps(base + align * offset[4]), 0x1);
+ _mm_load_ps(base + align * offset[4]),
+ 0x1);
t2 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_load_ps(base + align * offset[1])),
- _mm_load_ps(base + align * offset[5]), 0x1);
+ _mm_load_ps(base + align * offset[5]),
+ 0x1);
t3 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_load_ps(base + align * offset[2])),
- _mm_load_ps(base + align * offset[6]), 0x1);
+ _mm_load_ps(base + align * offset[6]),
+ 0x1);
t4 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_load_ps(base + align * offset[3])),
- _mm_load_ps(base + align * offset[7]), 0x1);
+ _mm_load_ps(base + align * offset[7]),
+ 0x1);
}
else
{
// Use unaligned loads
t1 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(base + align * offset[0])),
- _mm_loadu_ps(base + align * offset[4]), 0x1);
+ _mm_loadu_ps(base + align * offset[4]),
+ 0x1);
t2 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(base + align * offset[1])),
- _mm_loadu_ps(base + align * offset[5]), 0x1);
+ _mm_loadu_ps(base + align * offset[5]),
+ 0x1);
t3 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(base + align * offset[2])),
- _mm_loadu_ps(base + align * offset[6]), 0x1);
+ _mm_loadu_ps(base + align * offset[6]),
+ 0x1);
t4 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(base + align * offset[3])),
- _mm_loadu_ps(base + align * offset[7]), 0x1);
+ _mm_loadu_ps(base + align * offset[7]),
+ 0x1);
}
t5 = _mm256_unpacklo_ps(t1, t2);
_mm_add_ps(_mm_load_ps(base + align * offset[2]), _mm256_castps256_ps128(t7)));
_mm_store_ps(base + align * offset[3],
_mm_add_ps(_mm_load_ps(base + align * offset[3]), _mm256_castps256_ps128(t8)));
- _mm_store_ps(base + align * offset[4], _mm_add_ps(_mm_load_ps(base + align * offset[4]),
- _mm256_extractf128_ps(t5, 0x1)));
- _mm_store_ps(base + align * offset[5], _mm_add_ps(_mm_load_ps(base + align * offset[5]),
- _mm256_extractf128_ps(t6, 0x1)));
- _mm_store_ps(base + align * offset[6], _mm_add_ps(_mm_load_ps(base + align * offset[6]),
- _mm256_extractf128_ps(t7, 0x1)));
- _mm_store_ps(base + align * offset[7], _mm_add_ps(_mm_load_ps(base + align * offset[7]),
- _mm256_extractf128_ps(t8, 0x1)));
+ _mm_store_ps(base + align * offset[4],
+ _mm_add_ps(_mm_load_ps(base + align * offset[4]), _mm256_extractf128_ps(t5, 0x1)));
+ _mm_store_ps(base + align * offset[5],
+ _mm_add_ps(_mm_load_ps(base + align * offset[5]), _mm256_extractf128_ps(t6, 0x1)));
+ _mm_store_ps(base + align * offset[6],
+ _mm_add_ps(_mm_load_ps(base + align * offset[6]), _mm256_extractf128_ps(t7, 0x1)));
+ _mm_store_ps(base + align * offset[7],
+ _mm_add_ps(_mm_load_ps(base + align * offset[7]), _mm256_extractf128_ps(t8, 0x1)));
}
else
{
// alignment >=5, but not a multiple of 4
- _mm_storeu_ps(base + align * offset[0], _mm_add_ps(_mm_loadu_ps(base + align * offset[0]),
- _mm256_castps256_ps128(t5)));
- _mm_storeu_ps(base + align * offset[1], _mm_add_ps(_mm_loadu_ps(base + align * offset[1]),
- _mm256_castps256_ps128(t6)));
- _mm_storeu_ps(base + align * offset[2], _mm_add_ps(_mm_loadu_ps(base + align * offset[2]),
- _mm256_castps256_ps128(t7)));
- _mm_storeu_ps(base + align * offset[3], _mm_add_ps(_mm_loadu_ps(base + align * offset[3]),
- _mm256_castps256_ps128(t8)));
- _mm_storeu_ps(base + align * offset[4], _mm_add_ps(_mm_loadu_ps(base + align * offset[4]),
- _mm256_extractf128_ps(t5, 0x1)));
- _mm_storeu_ps(base + align * offset[5], _mm_add_ps(_mm_loadu_ps(base + align * offset[5]),
- _mm256_extractf128_ps(t6, 0x1)));
- _mm_storeu_ps(base + align * offset[6], _mm_add_ps(_mm_loadu_ps(base + align * offset[6]),
- _mm256_extractf128_ps(t7, 0x1)));
- _mm_storeu_ps(base + align * offset[7], _mm_add_ps(_mm_loadu_ps(base + align * offset[7]),
- _mm256_extractf128_ps(t8, 0x1)));
+ _mm_storeu_ps(base + align * offset[0],
+ _mm_add_ps(_mm_loadu_ps(base + align * offset[0]), _mm256_castps256_ps128(t5)));
+ _mm_storeu_ps(base + align * offset[1],
+ _mm_add_ps(_mm_loadu_ps(base + align * offset[1]), _mm256_castps256_ps128(t6)));
+ _mm_storeu_ps(base + align * offset[2],
+ _mm_add_ps(_mm_loadu_ps(base + align * offset[2]), _mm256_castps256_ps128(t7)));
+ _mm_storeu_ps(base + align * offset[3],
+ _mm_add_ps(_mm_loadu_ps(base + align * offset[3]), _mm256_castps256_ps128(t8)));
+ _mm_storeu_ps(
+ base + align * offset[4],
+ _mm_add_ps(_mm_loadu_ps(base + align * offset[4]), _mm256_extractf128_ps(t5, 0x1)));
+ _mm_storeu_ps(
+ base + align * offset[5],
+ _mm_add_ps(_mm_loadu_ps(base + align * offset[5]), _mm256_extractf128_ps(t6, 0x1)));
+ _mm_storeu_ps(
+ base + align * offset[6],
+ _mm_add_ps(_mm_loadu_ps(base + align * offset[6]), _mm256_extractf128_ps(t7, 0x1)));
+ _mm_storeu_ps(
+ base + align * offset[7],
+ _mm_add_ps(_mm_loadu_ps(base + align * offset[7]), _mm256_extractf128_ps(t8, 0x1)));
}
}
}
_mm_sub_ps(_mm_load_ps(base + align * offset[2]), _mm256_castps256_ps128(t7)));
_mm_store_ps(base + align * offset[3],
_mm_sub_ps(_mm_load_ps(base + align * offset[3]), _mm256_castps256_ps128(t8)));
- _mm_store_ps(base + align * offset[4], _mm_sub_ps(_mm_load_ps(base + align * offset[4]),
- _mm256_extractf128_ps(t5, 0x1)));
- _mm_store_ps(base + align * offset[5], _mm_sub_ps(_mm_load_ps(base + align * offset[5]),
- _mm256_extractf128_ps(t6, 0x1)));
- _mm_store_ps(base + align * offset[6], _mm_sub_ps(_mm_load_ps(base + align * offset[6]),
- _mm256_extractf128_ps(t7, 0x1)));
- _mm_store_ps(base + align * offset[7], _mm_sub_ps(_mm_load_ps(base + align * offset[7]),
- _mm256_extractf128_ps(t8, 0x1)));
+ _mm_store_ps(base + align * offset[4],
+ _mm_sub_ps(_mm_load_ps(base + align * offset[4]), _mm256_extractf128_ps(t5, 0x1)));
+ _mm_store_ps(base + align * offset[5],
+ _mm_sub_ps(_mm_load_ps(base + align * offset[5]), _mm256_extractf128_ps(t6, 0x1)));
+ _mm_store_ps(base + align * offset[6],
+ _mm_sub_ps(_mm_load_ps(base + align * offset[6]), _mm256_extractf128_ps(t7, 0x1)));
+ _mm_store_ps(base + align * offset[7],
+ _mm_sub_ps(_mm_load_ps(base + align * offset[7]), _mm256_extractf128_ps(t8, 0x1)));
}
else
{
// alignment >=5, but not a multiple of 4
- _mm_storeu_ps(base + align * offset[0], _mm_sub_ps(_mm_loadu_ps(base + align * offset[0]),
- _mm256_castps256_ps128(t5)));
- _mm_storeu_ps(base + align * offset[1], _mm_sub_ps(_mm_loadu_ps(base + align * offset[1]),
- _mm256_castps256_ps128(t6)));
- _mm_storeu_ps(base + align * offset[2], _mm_sub_ps(_mm_loadu_ps(base + align * offset[2]),
- _mm256_castps256_ps128(t7)));
- _mm_storeu_ps(base + align * offset[3], _mm_sub_ps(_mm_loadu_ps(base + align * offset[3]),
- _mm256_castps256_ps128(t8)));
- _mm_storeu_ps(base + align * offset[4], _mm_sub_ps(_mm_loadu_ps(base + align * offset[4]),
- _mm256_extractf128_ps(t5, 0x1)));
- _mm_storeu_ps(base + align * offset[5], _mm_sub_ps(_mm_loadu_ps(base + align * offset[5]),
- _mm256_extractf128_ps(t6, 0x1)));
- _mm_storeu_ps(base + align * offset[6], _mm_sub_ps(_mm_loadu_ps(base + align * offset[6]),
- _mm256_extractf128_ps(t7, 0x1)));
- _mm_storeu_ps(base + align * offset[7], _mm_sub_ps(_mm_loadu_ps(base + align * offset[7]),
- _mm256_extractf128_ps(t8, 0x1)));
+ _mm_storeu_ps(base + align * offset[0],
+ _mm_sub_ps(_mm_loadu_ps(base + align * offset[0]), _mm256_castps256_ps128(t5)));
+ _mm_storeu_ps(base + align * offset[1],
+ _mm_sub_ps(_mm_loadu_ps(base + align * offset[1]), _mm256_castps256_ps128(t6)));
+ _mm_storeu_ps(base + align * offset[2],
+ _mm_sub_ps(_mm_loadu_ps(base + align * offset[2]), _mm256_castps256_ps128(t7)));
+ _mm_storeu_ps(base + align * offset[3],
+ _mm_sub_ps(_mm_loadu_ps(base + align * offset[3]), _mm256_castps256_ps128(t8)));
+ _mm_storeu_ps(
+ base + align * offset[4],
+ _mm_sub_ps(_mm_loadu_ps(base + align * offset[4]), _mm256_extractf128_ps(t5, 0x1)));
+ _mm_storeu_ps(
+ base + align * offset[5],
+ _mm_sub_ps(_mm_loadu_ps(base + align * offset[5]), _mm256_extractf128_ps(t6, 0x1)));
+ _mm_storeu_ps(
+ base + align * offset[6],
+ _mm_sub_ps(_mm_loadu_ps(base + align * offset[6]), _mm256_extractf128_ps(t7, 0x1)));
+ _mm_storeu_ps(
+ base + align * offset[7],
+ _mm_sub_ps(_mm_loadu_ps(base + align * offset[7]), _mm256_extractf128_ps(t8, 0x1)));
}
}
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014,2015,2016,2017,2019, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015,2016,2017,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.
static inline Simd4DBool gmx_simdcall operator==(Simd4Double a, Simd4Double b)
{
- return { _mm512_mask_cmp_pd_mask(avx512Int2Mask(0xF), _mm512_castpd256_pd512(a.simdInternal_),
- _mm512_castpd256_pd512(b.simdInternal_), _CMP_EQ_OQ) };
+ return { _mm512_mask_cmp_pd_mask(avx512Int2Mask(0xF),
+ _mm512_castpd256_pd512(a.simdInternal_),
+ _mm512_castpd256_pd512(b.simdInternal_),
+ _CMP_EQ_OQ) };
}
static inline Simd4DBool gmx_simdcall operator!=(Simd4Double a, Simd4Double b)
{
- return { _mm512_mask_cmp_pd_mask(avx512Int2Mask(0xF), _mm512_castpd256_pd512(a.simdInternal_),
- _mm512_castpd256_pd512(b.simdInternal_), _CMP_NEQ_OQ) };
+ return { _mm512_mask_cmp_pd_mask(avx512Int2Mask(0xF),
+ _mm512_castpd256_pd512(a.simdInternal_),
+ _mm512_castpd256_pd512(b.simdInternal_),
+ _CMP_NEQ_OQ) };
}
static inline Simd4DBool gmx_simdcall operator<(Simd4Double a, Simd4Double b)
{
- return { _mm512_mask_cmp_pd_mask(avx512Int2Mask(0xF), _mm512_castpd256_pd512(a.simdInternal_),
- _mm512_castpd256_pd512(b.simdInternal_), _CMP_LT_OQ) };
+ return { _mm512_mask_cmp_pd_mask(avx512Int2Mask(0xF),
+ _mm512_castpd256_pd512(a.simdInternal_),
+ _mm512_castpd256_pd512(b.simdInternal_),
+ _CMP_LT_OQ) };
}
static inline Simd4DBool gmx_simdcall operator<=(Simd4Double a, Simd4Double b)
{
- return { _mm512_mask_cmp_pd_mask(avx512Int2Mask(0xF), _mm512_castpd256_pd512(a.simdInternal_),
- _mm512_castpd256_pd512(b.simdInternal_), _CMP_LE_OQ) };
+ return { _mm512_mask_cmp_pd_mask(avx512Int2Mask(0xF),
+ _mm512_castpd256_pd512(a.simdInternal_),
+ _mm512_castpd256_pd512(b.simdInternal_),
+ _CMP_LE_OQ) };
}
static inline Simd4DBool gmx_simdcall operator&&(Simd4DBool a, Simd4DBool b)
static inline Simd4Double gmx_simdcall selectByMask(Simd4Double a, Simd4DBool m)
{
- return { _mm512_castpd512_pd256(_mm512_mask_mov_pd(_mm512_setzero_pd(), m.simdInternal_,
- _mm512_castpd256_pd512(a.simdInternal_))) };
+ return { _mm512_castpd512_pd256(_mm512_mask_mov_pd(
+ _mm512_setzero_pd(), m.simdInternal_, _mm512_castpd256_pd512(a.simdInternal_))) };
}
static inline Simd4Double gmx_simdcall selectByNotMask(Simd4Double a, Simd4DBool m)
{
- return { _mm512_castpd512_pd256(_mm512_mask_mov_pd(_mm512_castpd256_pd512(a.simdInternal_),
- m.simdInternal_, _mm512_setzero_pd())) };
+ return { _mm512_castpd512_pd256(_mm512_mask_mov_pd(
+ _mm512_castpd256_pd512(a.simdInternal_), m.simdInternal_, _mm512_setzero_pd())) };
}
static inline Simd4Double gmx_simdcall blend(Simd4Double a, Simd4Double b, Simd4DBool sel)
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014,2015,2016,2019, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015,2016,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.
static inline Simd4FBool gmx_simdcall operator==(Simd4Float a, Simd4Float b)
{
- return { _mm512_mask_cmp_ps_mask(avx512Int2Mask(0xF), _mm512_castps128_ps512(a.simdInternal_),
- _mm512_castps128_ps512(b.simdInternal_), _CMP_EQ_OQ) };
+ return { _mm512_mask_cmp_ps_mask(avx512Int2Mask(0xF),
+ _mm512_castps128_ps512(a.simdInternal_),
+ _mm512_castps128_ps512(b.simdInternal_),
+ _CMP_EQ_OQ) };
}
static inline Simd4FBool gmx_simdcall operator!=(Simd4Float a, Simd4Float b)
{
- return { _mm512_mask_cmp_ps_mask(avx512Int2Mask(0xF), _mm512_castps128_ps512(a.simdInternal_),
- _mm512_castps128_ps512(b.simdInternal_), _CMP_NEQ_OQ) };
+ return { _mm512_mask_cmp_ps_mask(avx512Int2Mask(0xF),
+ _mm512_castps128_ps512(a.simdInternal_),
+ _mm512_castps128_ps512(b.simdInternal_),
+ _CMP_NEQ_OQ) };
}
static inline Simd4FBool gmx_simdcall operator<(Simd4Float a, Simd4Float b)
{
- return { _mm512_mask_cmp_ps_mask(avx512Int2Mask(0xF), _mm512_castps128_ps512(a.simdInternal_),
- _mm512_castps128_ps512(b.simdInternal_), _CMP_LT_OQ) };
+ return { _mm512_mask_cmp_ps_mask(avx512Int2Mask(0xF),
+ _mm512_castps128_ps512(a.simdInternal_),
+ _mm512_castps128_ps512(b.simdInternal_),
+ _CMP_LT_OQ) };
}
static inline Simd4FBool gmx_simdcall operator<=(Simd4Float a, Simd4Float b)
{
- return { _mm512_mask_cmp_ps_mask(avx512Int2Mask(0xF), _mm512_castps128_ps512(a.simdInternal_),
- _mm512_castps128_ps512(b.simdInternal_), _CMP_LE_OQ) };
+ return { _mm512_mask_cmp_ps_mask(avx512Int2Mask(0xF),
+ _mm512_castps128_ps512(a.simdInternal_),
+ _mm512_castps128_ps512(b.simdInternal_),
+ _CMP_LE_OQ) };
}
static inline Simd4FBool gmx_simdcall operator&&(Simd4FBool a, Simd4FBool b)
static inline Simd4Float gmx_simdcall selectByMask(Simd4Float a, Simd4FBool m)
{
- return { _mm512_castps512_ps128(_mm512_mask_mov_ps(_mm512_setzero_ps(), m.simdInternal_,
- _mm512_castps128_ps512(a.simdInternal_))) };
+ return { _mm512_castps512_ps128(_mm512_mask_mov_ps(
+ _mm512_setzero_ps(), m.simdInternal_, _mm512_castps128_ps512(a.simdInternal_))) };
}
static inline Simd4Float gmx_simdcall selectByNotMask(Simd4Float a, Simd4FBool m)
{
- return { _mm512_castps512_ps128(_mm512_mask_mov_ps(_mm512_castps128_ps512(a.simdInternal_),
- m.simdInternal_, _mm512_setzero_ps())) };
+ return { _mm512_castps512_ps128(_mm512_mask_mov_ps(
+ _mm512_castps128_ps512(a.simdInternal_), m.simdInternal_, _mm512_setzero_ps())) };
}
static inline Simd4Float gmx_simdcall blend(Simd4Float a, Simd4Float b, Simd4FBool sel)
iExponent = _mm256_add_epi32(iExponent, _mm256_set1_epi32(1));
// Set result to value (+-0) when it is zero.
- result = _mm512_mask_getmant_pd(value.simdInternal_, valueIsNonZero, value.simdInternal_,
- _MM_MANT_NORM_p5_1, _MM_MANT_SIGN_src);
+ result = _mm512_mask_getmant_pd(
+ value.simdInternal_, valueIsNonZero, value.simdInternal_, _MM_MANT_NORM_p5_1, _MM_MANT_SIGN_src);
}
else
{
{
return { _mm512_castsi512_pd(_mm512_ternarylogic_epi64(_mm512_castpd_si512(a.simdInternal_),
_mm512_castpd_si512(b.simdInternal_),
- _mm512_set1_epi64(INT64_MIN), 0xD8)) };
+ _mm512_set1_epi64(INT64_MIN),
+ 0xD8)) };
}
static inline SimdDInt32 gmx_simdcall operator&(SimdDInt32 a, SimdDInt32 b)
static inline SimdDIBool gmx_simdcall operator==(SimdDInt32 a, SimdDInt32 b)
{
- return { _mm512_mask_cmp_epi32_mask(avx512Int2Mask(0xFF), _mm512_castsi256_si512(a.simdInternal_),
- _mm512_castsi256_si512(b.simdInternal_), _MM_CMPINT_EQ) };
+ return { _mm512_mask_cmp_epi32_mask(avx512Int2Mask(0xFF),
+ _mm512_castsi256_si512(a.simdInternal_),
+ _mm512_castsi256_si512(b.simdInternal_),
+ _MM_CMPINT_EQ) };
}
static inline SimdDIBool gmx_simdcall testBits(SimdDInt32 a)
{
- return { _mm512_mask_test_epi32_mask(avx512Int2Mask(0xFF), _mm512_castsi256_si512(a.simdInternal_),
+ return { _mm512_mask_test_epi32_mask(avx512Int2Mask(0xFF),
+ _mm512_castsi256_si512(a.simdInternal_),
_mm512_castsi256_si512(a.simdInternal_)) };
}
static inline SimdDIBool gmx_simdcall operator<(SimdDInt32 a, SimdDInt32 b)
{
- return { _mm512_mask_cmp_epi32_mask(avx512Int2Mask(0xFF), _mm512_castsi256_si512(a.simdInternal_),
- _mm512_castsi256_si512(b.simdInternal_), _MM_CMPINT_LT) };
+ return { _mm512_mask_cmp_epi32_mask(avx512Int2Mask(0xFF),
+ _mm512_castsi256_si512(a.simdInternal_),
+ _mm512_castsi256_si512(b.simdInternal_),
+ _MM_CMPINT_LT) };
}
static inline SimdDIBool gmx_simdcall operator&&(SimdDIBool a, SimdDIBool b)
static inline SimdDInt32 gmx_simdcall blend(SimdDInt32 a, SimdDInt32 b, SimdDIBool sel)
{
- return { _mm512_castsi512_si256(
- _mm512_mask_blend_epi32(sel.simdInternal_, _mm512_castsi256_si512(a.simdInternal_),
- _mm512_castsi256_si512(b.simdInternal_))) };
+ return { _mm512_castsi512_si256(_mm512_mask_blend_epi32(sel.simdInternal_,
+ _mm512_castsi256_si512(a.simdInternal_),
+ _mm512_castsi256_si512(b.simdInternal_))) };
}
static inline SimdDInt32 gmx_simdcall cvtR2I(SimdDouble a)
iExponent = _mm512_mask_add_epi32(iExponent, valueIsNonZero, iExponent, _mm512_set1_epi32(1));
// Set result to input value when the latter is +-0
- result = _mm512_mask_getmant_ps(value.simdInternal_, valueIsNonZero, value.simdInternal_,
- _MM_MANT_NORM_p5_1, _MM_MANT_SIGN_src);
+ result = _mm512_mask_getmant_ps(
+ value.simdInternal_, valueIsNonZero, value.simdInternal_, _MM_MANT_NORM_p5_1, _MM_MANT_SIGN_src);
}
else
{
{
return { _mm512_castsi512_ps(_mm512_ternarylogic_epi32(_mm512_castps_si512(a.simdInternal_),
_mm512_castps_si512(b.simdInternal_),
- _mm512_set1_epi32(INT32_MIN), 0xD8)) };
+ _mm512_set1_epi32(INT32_MIN),
+ 0xD8)) };
}
static inline SimdFInt32 gmx_simdcall operator&(SimdFInt32 a, SimdFInt32 b)
__m512d t[4], t5, t6, t7, t8;
alignas(GMX_SIMD_ALIGNMENT) std::int64_t o[8];
// TODO: should use fastMultiply
- _mm512_store_epi64(o, _mm512_cvtepi32_epi64(_mm256_mullo_epi32(
- _mm256_load_si256((const __m256i*)(offset)), _mm256_set1_epi32(align))));
+ _mm512_store_epi64(o,
+ _mm512_cvtepi32_epi64(_mm256_mullo_epi32(
+ _mm256_load_si256((const __m256i*)(offset)), _mm256_set1_epi32(align))));
t5 = _mm512_unpacklo_pd(v0.simdInternal_, v1.simdInternal_);
t6 = _mm512_unpackhi_pd(v0.simdInternal_, v1.simdInternal_);
t7 = _mm512_unpacklo_pd(v2.simdInternal_, _mm512_setzero_pd());
{
for (int i = 0; i < 4; i++)
{
- _mm512_mask_storeu_pd(base + o[0 + i], avx512Int2Mask(7),
+ _mm512_mask_storeu_pd(base + o[0 + i],
+ avx512Int2Mask(7),
_mm512_castpd256_pd512(_mm256_add_pd(_mm256_loadu_pd(base + o[0 + i]),
_mm512_castpd512_pd256(t[i]))));
_mm512_mask_storeu_pd(
- base + o[4 + i], avx512Int2Mask(7),
+ base + o[4 + i],
+ avx512Int2Mask(7),
_mm512_castpd256_pd512(_mm256_add_pd(_mm256_loadu_pd(base + o[4 + i]),
_mm512_extractf64x4_pd(t[i], 1))));
}
{
for (int i = 0; i < 4; i++)
{
- _mm256_store_pd(base + o[0 + i], _mm256_add_pd(_mm256_load_pd(base + o[0 + i]),
- _mm512_castpd512_pd256(t[i])));
- _mm256_store_pd(base + o[4 + i], _mm256_add_pd(_mm256_load_pd(base + o[4 + i]),
- _mm512_extractf64x4_pd(t[i], 1)));
+ _mm256_store_pd(
+ base + o[0 + i],
+ _mm256_add_pd(_mm256_load_pd(base + o[0 + i]), _mm512_castpd512_pd256(t[i])));
+ _mm256_store_pd(base + o[4 + i],
+ _mm256_add_pd(_mm256_load_pd(base + o[4 + i]),
+ _mm512_extractf64x4_pd(t[i], 1)));
}
}
else
{
for (int i = 0; i < 4; i++)
{
- _mm256_storeu_pd(base + o[0 + i], _mm256_add_pd(_mm256_loadu_pd(base + o[0 + i]),
- _mm512_castpd512_pd256(t[i])));
- _mm256_storeu_pd(base + o[4 + i], _mm256_add_pd(_mm256_loadu_pd(base + o[4 + i]),
- _mm512_extractf64x4_pd(t[i], 1)));
+ _mm256_storeu_pd(
+ base + o[0 + i],
+ _mm256_add_pd(_mm256_loadu_pd(base + o[0 + i]), _mm512_castpd512_pd256(t[i])));
+ _mm256_storeu_pd(base + o[4 + i],
+ _mm256_add_pd(_mm256_loadu_pd(base + o[4 + i]),
+ _mm512_extractf64x4_pd(t[i], 1)));
}
}
}
__m512d t[4], t5, t6, t7, t8;
alignas(GMX_SIMD_ALIGNMENT) std::int64_t o[8];
// TODO: should use fastMultiply
- _mm512_store_epi64(o, _mm512_cvtepi32_epi64(_mm256_mullo_epi32(
- _mm256_load_si256((const __m256i*)(offset)), _mm256_set1_epi32(align))));
+ _mm512_store_epi64(o,
+ _mm512_cvtepi32_epi64(_mm256_mullo_epi32(
+ _mm256_load_si256((const __m256i*)(offset)), _mm256_set1_epi32(align))));
t5 = _mm512_unpacklo_pd(v0.simdInternal_, v1.simdInternal_);
t6 = _mm512_unpackhi_pd(v0.simdInternal_, v1.simdInternal_);
t7 = _mm512_unpacklo_pd(v2.simdInternal_, _mm512_setzero_pd());
{
for (int i = 0; i < 4; i++)
{
- _mm512_mask_storeu_pd(base + o[0 + i], avx512Int2Mask(7),
+ _mm512_mask_storeu_pd(base + o[0 + i],
+ avx512Int2Mask(7),
_mm512_castpd256_pd512(_mm256_sub_pd(_mm256_loadu_pd(base + o[0 + i]),
_mm512_castpd512_pd256(t[i]))));
_mm512_mask_storeu_pd(
- base + o[4 + i], avx512Int2Mask(7),
+ base + o[4 + i],
+ avx512Int2Mask(7),
_mm512_castpd256_pd512(_mm256_sub_pd(_mm256_loadu_pd(base + o[4 + i]),
_mm512_extractf64x4_pd(t[i], 1))));
}
{
for (int i = 0; i < 4; i++)
{
- _mm256_store_pd(base + o[0 + i], _mm256_sub_pd(_mm256_load_pd(base + o[0 + i]),
- _mm512_castpd512_pd256(t[i])));
- _mm256_store_pd(base + o[4 + i], _mm256_sub_pd(_mm256_load_pd(base + o[4 + i]),
- _mm512_extractf64x4_pd(t[i], 1)));
+ _mm256_store_pd(
+ base + o[0 + i],
+ _mm256_sub_pd(_mm256_load_pd(base + o[0 + i]), _mm512_castpd512_pd256(t[i])));
+ _mm256_store_pd(base + o[4 + i],
+ _mm256_sub_pd(_mm256_load_pd(base + o[4 + i]),
+ _mm512_extractf64x4_pd(t[i], 1)));
}
}
else
{
for (int i = 0; i < 4; i++)
{
- _mm256_storeu_pd(base + o[0 + i], _mm256_sub_pd(_mm256_loadu_pd(base + o[0 + i]),
- _mm512_castpd512_pd256(t[i])));
- _mm256_storeu_pd(base + o[4 + i], _mm256_sub_pd(_mm256_loadu_pd(base + o[4 + i]),
- _mm512_extractf64x4_pd(t[i], 1)));
+ _mm256_storeu_pd(
+ base + o[0 + i],
+ _mm256_sub_pd(_mm256_loadu_pd(base + o[0 + i]), _mm512_castpd512_pd256(t[i])));
+ _mm256_storeu_pd(base + o[4 + i],
+ _mm256_sub_pd(_mm256_loadu_pd(base + o[4 + i]),
+ _mm512_extractf64x4_pd(t[i], 1)));
}
}
}
t0 = _mm512_add_pd(v0.simdInternal_, _mm512_permute_pd(v0.simdInternal_, 0x55));
t2 = _mm512_add_pd(v2.simdInternal_, _mm512_permute_pd(v2.simdInternal_, 0x55));
- t0 = _mm512_mask_add_pd(t0, avx512Int2Mask(0xAA), v1.simdInternal_,
- _mm512_permute_pd(v1.simdInternal_, 0x55));
- t2 = _mm512_mask_add_pd(t2, avx512Int2Mask(0xAA), v3.simdInternal_,
- _mm512_permute_pd(v3.simdInternal_, 0x55));
+ t0 = _mm512_mask_add_pd(
+ t0, avx512Int2Mask(0xAA), v1.simdInternal_, _mm512_permute_pd(v1.simdInternal_, 0x55));
+ t2 = _mm512_mask_add_pd(
+ t2, avx512Int2Mask(0xAA), v3.simdInternal_, _mm512_permute_pd(v3.simdInternal_, 0x55));
t0 = _mm512_add_pd(t0, _mm512_shuffle_f64x2(t0, t0, 0x4E));
t0 = _mm512_mask_add_pd(t0, avx512Int2Mask(0xF0), t2, _mm512_shuffle_f64x2(t2, t2, 0x4E));
t0 = _mm512_add_pd(t0, _mm512_shuffle_f64x2(t0, t0, 0xB1));
static inline SimdDouble gmx_simdcall loadU1DualHsimd(const double* m)
{
- return { _mm512_insertf64x4(_mm512_broadcastsd_pd(_mm_load_sd(m)),
- _mm256_broadcastsd_pd(_mm_load_sd(m + 1)), 1) };
+ return { _mm512_insertf64x4(
+ _mm512_broadcastsd_pd(_mm_load_sd(m)), _mm256_broadcastsd_pd(_mm_load_sd(m + 1)), 1) };
}
assert(std::size_t(m) % 32 == 0);
t0 = _mm512_add_pd(v0.simdInternal_, _mm512_permutex_pd(v0.simdInternal_, 0x4E));
- t0 = _mm512_mask_add_pd(t0, avx512Int2Mask(0xCC), v1.simdInternal_,
- _mm512_permutex_pd(v1.simdInternal_, 0x4E));
+ t0 = _mm512_mask_add_pd(
+ t0, avx512Int2Mask(0xCC), v1.simdInternal_, _mm512_permutex_pd(v1.simdInternal_, 0x4E));
t0 = _mm512_add_pd(t0, _mm512_permutex_pd(t0, 0xB1));
t0 = _mm512_mask_shuffle_f64x2(t0, avx512Int2Mask(0xAA), t0, t0, 0xEE);
static inline SimdDouble gmx_simdcall loadU4NOffset(const double* m, int offset)
{
- return { _mm512_insertf64x4(_mm512_castpd256_pd512(_mm256_loadu_pd(m)),
- _mm256_loadu_pd(m + offset), 1) };
+ return { _mm512_insertf64x4(
+ _mm512_castpd256_pd512(_mm256_loadu_pd(m)), _mm256_loadu_pd(m + offset), 1) };
}
} // namespace gmx
t[3] = _mm512_shuffle_ps(t6, v2.simdInternal_, _MM_SHUFFLE(3, 3, 3, 2));
for (i = 0; i < 4; i++)
{
- _mm512_mask_storeu_ps(base + o[i], avx512Int2Mask(7),
+ _mm512_mask_storeu_ps(base + o[i],
+ avx512Int2Mask(7),
_mm512_castps128_ps512(_mm_add_ps(_mm_loadu_ps(base + o[i]),
_mm512_castps512_ps128(t[i]))));
- _mm512_mask_storeu_ps(base + o[4 + i], avx512Int2Mask(7),
+ _mm512_mask_storeu_ps(base + o[4 + i],
+ avx512Int2Mask(7),
_mm512_castps128_ps512(_mm_add_ps(_mm_loadu_ps(base + o[4 + i]),
_mm512_extractf32x4_ps(t[i], 1))));
- _mm512_mask_storeu_ps(base + o[8 + i], avx512Int2Mask(7),
+ _mm512_mask_storeu_ps(base + o[8 + i],
+ avx512Int2Mask(7),
_mm512_castps128_ps512(_mm_add_ps(_mm_loadu_ps(base + o[8 + i]),
_mm512_extractf32x4_ps(t[i], 2))));
- _mm512_mask_storeu_ps(base + o[12 + i], avx512Int2Mask(7),
+ _mm512_mask_storeu_ps(base + o[12 + i],
+ avx512Int2Mask(7),
_mm512_castps128_ps512(_mm_add_ps(_mm_loadu_ps(base + o[12 + i]),
_mm512_extractf32x4_ps(t[i], 3))));
}
_mm_add_ps(_mm_load_ps(base + o[4 + i]), _mm512_extractf32x4_ps(t[i], 1)));
_mm_store_ps(base + o[8 + i],
_mm_add_ps(_mm_load_ps(base + o[8 + i]), _mm512_extractf32x4_ps(t[i], 2)));
- _mm_store_ps(base + o[12 + i], _mm_add_ps(_mm_load_ps(base + o[12 + i]),
- _mm512_extractf32x4_ps(t[i], 3)));
+ _mm_store_ps(base + o[12 + i],
+ _mm_add_ps(_mm_load_ps(base + o[12 + i]), _mm512_extractf32x4_ps(t[i], 3)));
}
}
else
{
_mm_storeu_ps(base + o[i],
_mm_add_ps(_mm_loadu_ps(base + o[i]), _mm512_castps512_ps128(t[i])));
- _mm_storeu_ps(base + o[4 + i], _mm_add_ps(_mm_loadu_ps(base + o[4 + i]),
- _mm512_extractf32x4_ps(t[i], 1)));
- _mm_storeu_ps(base + o[8 + i], _mm_add_ps(_mm_loadu_ps(base + o[8 + i]),
- _mm512_extractf32x4_ps(t[i], 2)));
- _mm_storeu_ps(base + o[12 + i], _mm_add_ps(_mm_loadu_ps(base + o[12 + i]),
- _mm512_extractf32x4_ps(t[i], 3)));
+ _mm_storeu_ps(base + o[4 + i],
+ _mm_add_ps(_mm_loadu_ps(base + o[4 + i]), _mm512_extractf32x4_ps(t[i], 1)));
+ _mm_storeu_ps(base + o[8 + i],
+ _mm_add_ps(_mm_loadu_ps(base + o[8 + i]), _mm512_extractf32x4_ps(t[i], 2)));
+ _mm_storeu_ps(base + o[12 + i],
+ _mm_add_ps(_mm_loadu_ps(base + o[12 + i]), _mm512_extractf32x4_ps(t[i], 3)));
}
}
}
t[3] = _mm512_shuffle_ps(t6, v2.simdInternal_, _MM_SHUFFLE(3, 3, 3, 2));
for (i = 0; i < 4; i++)
{
- _mm512_mask_storeu_ps(base + o[i], avx512Int2Mask(7),
+ _mm512_mask_storeu_ps(base + o[i],
+ avx512Int2Mask(7),
_mm512_castps128_ps512(_mm_sub_ps(_mm_loadu_ps(base + o[i]),
_mm512_castps512_ps128(t[i]))));
- _mm512_mask_storeu_ps(base + o[4 + i], avx512Int2Mask(7),
+ _mm512_mask_storeu_ps(base + o[4 + i],
+ avx512Int2Mask(7),
_mm512_castps128_ps512(_mm_sub_ps(_mm_loadu_ps(base + o[4 + i]),
_mm512_extractf32x4_ps(t[i], 1))));
- _mm512_mask_storeu_ps(base + o[8 + i], avx512Int2Mask(7),
+ _mm512_mask_storeu_ps(base + o[8 + i],
+ avx512Int2Mask(7),
_mm512_castps128_ps512(_mm_sub_ps(_mm_loadu_ps(base + o[8 + i]),
_mm512_extractf32x4_ps(t[i], 2))));
- _mm512_mask_storeu_ps(base + o[12 + i], avx512Int2Mask(7),
+ _mm512_mask_storeu_ps(base + o[12 + i],
+ avx512Int2Mask(7),
_mm512_castps128_ps512(_mm_sub_ps(_mm_loadu_ps(base + o[12 + i]),
_mm512_extractf32x4_ps(t[i], 3))));
}
_mm_sub_ps(_mm_load_ps(base + o[4 + i]), _mm512_extractf32x4_ps(t[i], 1)));
_mm_store_ps(base + o[8 + i],
_mm_sub_ps(_mm_load_ps(base + o[8 + i]), _mm512_extractf32x4_ps(t[i], 2)));
- _mm_store_ps(base + o[12 + i], _mm_sub_ps(_mm_load_ps(base + o[12 + i]),
- _mm512_extractf32x4_ps(t[i], 3)));
+ _mm_store_ps(base + o[12 + i],
+ _mm_sub_ps(_mm_load_ps(base + o[12 + i]), _mm512_extractf32x4_ps(t[i], 3)));
}
}
else
{
_mm_storeu_ps(base + o[i],
_mm_sub_ps(_mm_loadu_ps(base + o[i]), _mm512_castps512_ps128(t[i])));
- _mm_storeu_ps(base + o[4 + i], _mm_sub_ps(_mm_loadu_ps(base + o[4 + i]),
- _mm512_extractf32x4_ps(t[i], 1)));
- _mm_storeu_ps(base + o[8 + i], _mm_sub_ps(_mm_loadu_ps(base + o[8 + i]),
- _mm512_extractf32x4_ps(t[i], 2)));
- _mm_storeu_ps(base + o[12 + i], _mm_sub_ps(_mm_loadu_ps(base + o[12 + i]),
- _mm512_extractf32x4_ps(t[i], 3)));
+ _mm_storeu_ps(base + o[4 + i],
+ _mm_sub_ps(_mm_loadu_ps(base + o[4 + i]), _mm512_extractf32x4_ps(t[i], 1)));
+ _mm_storeu_ps(base + o[8 + i],
+ _mm_sub_ps(_mm_loadu_ps(base + o[8 + i]), _mm512_extractf32x4_ps(t[i], 2)));
+ _mm_storeu_ps(base + o[12 + i],
+ _mm_sub_ps(_mm_loadu_ps(base + o[12 + i]), _mm512_extractf32x4_ps(t[i], 3)));
}
}
}
assert(std::size_t(m) % 16 == 0);
t0 = _mm512_add_ps(v0.simdInternal_, _mm512_permute_ps(v0.simdInternal_, 0x4E));
- t0 = _mm512_mask_add_ps(t0, avx512Int2Mask(0xCCCC), v2.simdInternal_,
- _mm512_permute_ps(v2.simdInternal_, 0x4E));
+ t0 = _mm512_mask_add_ps(
+ t0, avx512Int2Mask(0xCCCC), v2.simdInternal_, _mm512_permute_ps(v2.simdInternal_, 0x4E));
t1 = _mm512_add_ps(v1.simdInternal_, _mm512_permute_ps(v1.simdInternal_, 0x4E));
- t1 = _mm512_mask_add_ps(t1, avx512Int2Mask(0xCCCC), v3.simdInternal_,
- _mm512_permute_ps(v3.simdInternal_, 0x4E));
+ t1 = _mm512_mask_add_ps(
+ t1, avx512Int2Mask(0xCCCC), v3.simdInternal_, _mm512_permute_ps(v3.simdInternal_, 0x4E));
t2 = _mm512_add_ps(t0, _mm512_permute_ps(t0, 0xB1));
t2 = _mm512_mask_add_ps(t2, avx512Int2Mask(0xAAAA), t1, _mm512_permute_ps(t1, 0xB1));
return { _mm512_castpd_ps(_mm512_insertf64x4(
_mm512_castpd256_pd512(_mm256_load_pd(reinterpret_cast<const double*>(m0))),
- _mm256_load_pd(reinterpret_cast<const double*>(m1)), 1)) };
+ _mm256_load_pd(reinterpret_cast<const double*>(m1)),
+ 1)) };
}
static inline SimdFloat gmx_simdcall loadDuplicateHsimd(const float* m)
static inline SimdFloat gmx_simdcall loadU1DualHsimd(const float* m)
{
- return { _mm512_shuffle_f32x4(_mm512_broadcastss_ps(_mm_load_ss(m)),
- _mm512_broadcastss_ps(_mm_load_ss(m + 1)), 0x44) };
+ return { _mm512_shuffle_f32x4(
+ _mm512_broadcastss_ps(_mm_load_ss(m)), _mm512_broadcastss_ps(_mm_load_ss(m + 1)), 0x44) };
}
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 2014,2015, 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.
- */
-
-#ifndef GMX_SIMD_IMPL_X86_MIC_H
-#define GMX_SIMD_IMPL_X86_MIC_H
-
-#include "impl_x86_mic_definitions.h"
-#include "impl_x86_mic_general.h"
-#include "impl_x86_mic_simd4_double.h"
-#include "impl_x86_mic_simd4_float.h"
-#include "impl_x86_mic_simd_double.h"
-#include "impl_x86_mic_simd_float.h"
-#include "impl_x86_mic_util_double.h"
-#include "impl_x86_mic_util_float.h"
-
-#endif // GMX_SIMD_IMPL_X86_MIC_H
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 2014,2015,2017,2018,2019,2020, by the GROMACS development team, led by
- * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
- * and including many others, as listed in the AUTHORS file in the
- * top-level source directory and at http://www.gromacs.org.
- *
- * 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.
- */
-
-#ifndef GMX_SIMD_IMPL_X86_MIC_DEFINITIONS_H
-#define GMX_SIMD_IMPL_X86_MIC_DEFINITIONS_H
-
-#define GMX_SIMD 1
-#define GMX_SIMD_HAVE_FLOAT 1
-#define GMX_SIMD_HAVE_DOUBLE 1
-#define GMX_SIMD_HAVE_LOADU 1
-#define GMX_SIMD_HAVE_STOREU 1
-#define GMX_SIMD_HAVE_LOGICAL 1
-#define GMX_SIMD_HAVE_FMA 1
-#define GMX_SIMD_HAVE_FINT32_EXTRACT 1
-#define GMX_SIMD_HAVE_FINT32_LOGICAL 1
-#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 1
-#define GMX_SIMD_HAVE_DINT32_EXTRACT 1
-#define GMX_SIMD_HAVE_DINT32_LOGICAL 1
-#define GMX_SIMD_HAVE_DINT32_ARITHMETICS 1
-#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_FLOAT 0
-#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT 0
-#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_FLOAT 0
-#define GMX_SIMD_HAVE_NATIVE_LOG_FLOAT 1
-#define GMX_SIMD_HAVE_NATIVE_EXP2_FLOAT 1
-#define GMX_SIMD_HAVE_NATIVE_EXP_FLOAT 1
-#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_DOUBLE 0
-#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_DOUBLE 0
-#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_DOUBLE 0
-#define GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE 0
-#define GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE 0
-#define GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE 0
-#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT 1
-#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE 1
-#define GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT 1
-#define GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE 1
-
-#define GMX_SIMD4_HAVE_FLOAT 1
-#define GMX_SIMD4_HAVE_DOUBLE 1
-
-// Implementation details
-#define GMX_SIMD_FLOAT_WIDTH 16
-#define GMX_SIMD_DOUBLE_WIDTH 8
-#define GMX_SIMD_FINT32_WIDTH 16
-#define GMX_SIMD_DINT32_WIDTH 8
-#define GMX_SIMD4_WIDTH 4
-#define GMX_SIMD_ALIGNMENT 64 // Bytes (16*single or 8*double)
-#define GMX_SIMD_RSQRT_BITS 23
-#define GMX_SIMD_RCP_BITS 23
-
-#endif // GMX_SIMD_IMPL_X86_MIC_DEFINITIONS_H
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by
- * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
- * and including many others, as listed in the AUTHORS file in the
- * top-level source directory and at http://www.gromacs.org.
- *
- * GROMACS is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * GROMACS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with GROMACS; if not, see
- * http://www.gnu.org/licenses, or write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * If you want to redistribute modifications to GROMACS, please
- * consider that scientific software is very special. Version
- * control is crucial - bugs must be traceable. We will be happy to
- * consider code for inclusion in the official distribution, but
- * derived work must not be called official GROMACS. Details are found
- * in the README & COPYING files - if they are missing, get the
- * official version at http://www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org.
- */
-
-#ifndef GMX_SIMD_IMPL_X86_MIC_GENERAL_H
-#define GMX_SIMD_IMPL_X86_MIC_GENERAL_H
-
-#include <immintrin.h>
-
-namespace gmx
-{
-
-static inline void simdPrefetch(const void* m)
-{
- _mm_prefetch((const char*)m, _MM_HINT_T0);
-}
-
-} // namespace gmx
-
-#endif // GMX_SIMD_IMPL_X86_MIC_OTHER_H
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 2014,2015,2017,2019, by the GROMACS development team, led by
- * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
- * and including many others, as listed in the AUTHORS file in the
- * top-level source directory and at http://www.gromacs.org.
- *
- * GROMACS is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * GROMACS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with GROMACS; if not, see
- * http://www.gnu.org/licenses, or write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * If you want to redistribute modifications to GROMACS, please
- * consider that scientific software is very special. Version
- * control is crucial - bugs must be traceable. We will be happy to
- * consider code for inclusion in the official distribution, but
- * derived work must not be called official GROMACS. Details are found
- * in the README & COPYING files - if they are missing, get the
- * official version at http://www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org.
- */
-
-#ifndef GMX_SIMD_IMPL_X86_MIC_SIMD4_DOUBLE_H
-#define GMX_SIMD_IMPL_X86_MIC_SIMD4_DOUBLE_H
-
-#include "config.h"
-
-#include <cassert>
-
-#include <immintrin.h>
-
-#include "gromacs/utility/basedefinitions.h"
-
-#include "impl_x86_mic_simd_double.h"
-
-namespace gmx
-{
-
-class Simd4Double
-{
-public:
- Simd4Double() {}
-
- Simd4Double(double d) : simdInternal_(_mm512_set1_pd(d)) {}
-
- // Internal utility constructor to simplify return statements
- Simd4Double(__m512d simd) : simdInternal_(simd) {}
-
- __m512d simdInternal_;
-};
-
-class Simd4DBool
-{
-public:
- Simd4DBool() {}
-
- // Internal utility constructor to simplify return statements
- Simd4DBool(__mmask16 simd) : simdInternal_(simd) {}
-
- __mmask16 simdInternal_;
-};
-
-static inline Simd4Double gmx_simdcall load4(const double* m)
-{
- assert(size_t(m) % 32 == 0);
- return { _mm512_mask_extload_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), m,
- _MM_UPCONV_PD_NONE, _MM_BROADCAST_4X8, _MM_HINT_NONE) };
-}
-
-static inline void gmx_simdcall store4(double* m, Simd4Double a)
-{
- assert(size_t(m) % 32 == 0);
- _mm512_mask_packstorelo_pd(m, _mm512_int2mask(0xF), a.simdInternal_);
-}
-
-static inline Simd4Double gmx_simdcall load4U(const double* m)
-{
- return { _mm512_mask_loadunpackhi_pd(
- _mm512_mask_loadunpacklo_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), m),
- _mm512_int2mask(0xF), m + 8) };
-}
-
-static inline void gmx_simdcall store4U(double* m, Simd4Double a)
-{
- _mm512_mask_packstorelo_pd(m, _mm512_int2mask(0xF), a.simdInternal_);
- _mm512_mask_packstorehi_pd(m + 8, _mm512_int2mask(0xF), a.simdInternal_);
-}
-
-static inline Simd4Double gmx_simdcall simd4SetZeroD()
-{
- return { _mm512_setzero_pd() };
-}
-
-static inline Simd4Double gmx_simdcall operator&(Simd4Double a, Simd4Double b)
-{
- return { _mm512_castsi512_pd(_mm512_mask_and_epi32(
- _mm512_undefined_epi32(), _mm512_int2mask(0x00FF), _mm512_castpd_si512(a.simdInternal_),
- _mm512_castpd_si512(b.simdInternal_))) };
-}
-
-static inline Simd4Double gmx_simdcall andNot(Simd4Double a, Simd4Double b)
-{
- return { _mm512_castsi512_pd(_mm512_mask_andnot_epi32(
- _mm512_undefined_epi32(), _mm512_int2mask(0x00FF), _mm512_castpd_si512(a.simdInternal_),
- _mm512_castpd_si512(b.simdInternal_))) };
-}
-
-static inline Simd4Double gmx_simdcall operator|(Simd4Double a, Simd4Double b)
-{
- return { _mm512_castsi512_pd(_mm512_mask_or_epi32(
- _mm512_undefined_epi32(), _mm512_int2mask(0x00FF), _mm512_castpd_si512(a.simdInternal_),
- _mm512_castpd_si512(b.simdInternal_))) };
-}
-
-static inline Simd4Double gmx_simdcall operator^(Simd4Double a, Simd4Double b)
-{
- return { _mm512_castsi512_pd(_mm512_mask_xor_epi32(
- _mm512_undefined_epi32(), _mm512_int2mask(0x00FF), _mm512_castpd_si512(a.simdInternal_),
- _mm512_castpd_si512(b.simdInternal_))) };
-}
-
-static inline Simd4Double gmx_simdcall operator+(Simd4Double a, Simd4Double b)
-{
- return { _mm512_mask_add_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), a.simdInternal_,
- b.simdInternal_) };
-}
-
-static inline Simd4Double gmx_simdcall operator-(Simd4Double a, Simd4Double b)
-{
- return { _mm512_mask_sub_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), a.simdInternal_,
- b.simdInternal_) };
-}
-
-static inline Simd4Double gmx_simdcall operator-(Simd4Double x)
-{
- return { _mm512_mask_addn_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), x.simdInternal_,
- _mm512_setzero_pd()) };
-}
-
-static inline Simd4Double gmx_simdcall operator*(Simd4Double a, Simd4Double b)
-{
- return { _mm512_mask_mul_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), a.simdInternal_,
- b.simdInternal_) };
-}
-
-static inline Simd4Double gmx_simdcall fma(Simd4Double a, Simd4Double b, Simd4Double c)
-{
- return { _mm512_mask_fmadd_pd(a.simdInternal_, _mm512_int2mask(0xF), b.simdInternal_, c.simdInternal_) };
-}
-
-static inline Simd4Double gmx_simdcall fms(Simd4Double a, Simd4Double b, Simd4Double c)
-{
- return { _mm512_mask_fmsub_pd(a.simdInternal_, _mm512_int2mask(0xF), b.simdInternal_, c.simdInternal_) };
-}
-
-static inline Simd4Double gmx_simdcall fnma(Simd4Double a, Simd4Double b, Simd4Double c)
-{
- return { _mm512_mask_fnmadd_pd(a.simdInternal_, _mm512_int2mask(0xF), b.simdInternal_, c.simdInternal_) };
-}
-
-static inline Simd4Double gmx_simdcall fnms(Simd4Double a, Simd4Double b, Simd4Double c)
-{
- return { _mm512_mask_fnmsub_pd(a.simdInternal_, _mm512_int2mask(0xF), b.simdInternal_, c.simdInternal_) };
-}
-
-static inline Simd4Double gmx_simdcall rsqrt(Simd4Double x)
-{
- return { _mm512_mask_cvtpslo_pd(
- _mm512_undefined_pd(), _mm512_int2mask(0xF),
- _mm512_mask_rsqrt23_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF),
- _mm512_mask_cvtpd_pslo(_mm512_undefined_ps(),
- _mm512_int2mask(0xF), x.simdInternal_))) };
-}
-
-static inline Simd4Double gmx_simdcall abs(Simd4Double x)
-{
- return { _mm512_castsi512_pd(_mm512_mask_andnot_epi32(
- _mm512_undefined_epi32(), _mm512_int2mask(0x00FF),
- _mm512_castpd_si512(_mm512_set1_pd(GMX_DOUBLE_NEGZERO)), _mm512_castpd_si512(x.simdInternal_)))
-
- };
-}
-
-static inline Simd4Double gmx_simdcall max(Simd4Double a, Simd4Double b)
-{
- return { _mm512_mask_gmax_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), a.simdInternal_,
- b.simdInternal_) };
-}
-
-static inline Simd4Double gmx_simdcall min(Simd4Double a, Simd4Double b)
-{
- return { _mm512_mask_gmin_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), a.simdInternal_,
- b.simdInternal_) };
-}
-
-static inline Simd4Double gmx_simdcall round(Simd4Double x)
-{
- return { _mm512_mask_roundfxpnt_adjust_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), x.simdInternal_,
- _MM_FROUND_TO_NEAREST_INT, _MM_EXPADJ_NONE) };
-}
-
-static inline Simd4Double gmx_simdcall trunc(Simd4Double x)
-{
- return { _mm512_mask_roundfxpnt_adjust_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF),
- x.simdInternal_, _MM_FROUND_TO_ZERO, _MM_EXPADJ_NONE) };
-}
-
-static inline double gmx_simdcall dotProduct(Simd4Double a, Simd4Double b)
-{
- return _mm512_mask_reduce_add_pd(_mm512_int2mask(7),
- _mm512_mask_mul_pd(_mm512_undefined_pd(), _mm512_int2mask(7),
- a.simdInternal_, b.simdInternal_));
-}
-
-static inline void gmx_simdcall transpose(Simd4Double* v0, Simd4Double* v1, Simd4Double* v2, Simd4Double* v3)
-{
- __m512i t0 = _mm512_mask_permute4f128_epi32(_mm512_castpd_si512(v0->simdInternal_), 0xFF00,
- _mm512_castpd_si512(v1->simdInternal_), _MM_PERM_BABA);
- __m512i t1 = _mm512_mask_permute4f128_epi32(_mm512_castpd_si512(v2->simdInternal_), 0xFF00,
- _mm512_castpd_si512(v3->simdInternal_), _MM_PERM_BABA);
-
- t0 = _mm512_permutevar_epi32(
- _mm512_set_epi32(15, 14, 7, 6, 13, 12, 5, 4, 11, 10, 3, 2, 9, 8, 1, 0), t0);
- t1 = _mm512_permutevar_epi32(
- _mm512_set_epi32(15, 14, 7, 6, 13, 12, 5, 4, 11, 10, 3, 2, 9, 8, 1, 0), t1);
-
- v0->simdInternal_ = _mm512_mask_swizzle_pd(_mm512_castsi512_pd(t0), _mm512_int2mask(0xCC),
- _mm512_castsi512_pd(t1), _MM_SWIZ_REG_BADC);
- v1->simdInternal_ = _mm512_mask_swizzle_pd(_mm512_castsi512_pd(t1), _mm512_int2mask(0x33),
- _mm512_castsi512_pd(t0), _MM_SWIZ_REG_BADC);
-
- v2->simdInternal_ =
- _mm512_castps_pd(_mm512_permute4f128_ps(_mm512_castpd_ps(v0->simdInternal_), _MM_PERM_DCDC));
- v3->simdInternal_ =
- _mm512_castps_pd(_mm512_permute4f128_ps(_mm512_castpd_ps(v1->simdInternal_), _MM_PERM_DCDC));
-}
-
-// Picky, picky, picky:
-// icc-16 complains about "Illegal value of immediate argument to intrinsic"
-// unless we use
-// 1) Ordered-quiet for ==
-// 2) Unordered-quiet for !=
-// 3) Ordered-signaling for < and <=
-
-static inline Simd4DBool gmx_simdcall operator==(Simd4Double a, Simd4Double b)
-{
- return { _mm512_mask_cmp_pd_mask(_mm512_int2mask(0xF), a.simdInternal_, b.simdInternal_, _CMP_EQ_OQ) };
-}
-
-static inline Simd4DBool gmx_simdcall operator!=(Simd4Double a, Simd4Double b)
-{
- return { _mm512_mask_cmp_pd_mask(_mm512_int2mask(0xF), a.simdInternal_, b.simdInternal_, _CMP_NEQ_UQ) };
-}
-
-static inline Simd4DBool gmx_simdcall operator<(Simd4Double a, Simd4Double b)
-{
- return { _mm512_mask_cmp_pd_mask(_mm512_int2mask(0xF), a.simdInternal_, b.simdInternal_, _CMP_LT_OS) };
-}
-
-static inline Simd4DBool gmx_simdcall operator<=(Simd4Double a, Simd4Double b)
-{
- return { _mm512_mask_cmp_pd_mask(_mm512_int2mask(0xF), a.simdInternal_, b.simdInternal_, _CMP_LE_OS) };
-}
-
-static inline Simd4DBool gmx_simdcall operator&&(Simd4DBool a, Simd4DBool b)
-{
- return { _mm512_kand(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline Simd4DBool gmx_simdcall operator||(Simd4DBool a, Simd4DBool b)
-{
- return { _mm512_kor(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline bool gmx_simdcall anyTrue(Simd4DBool a)
-{
- return (_mm512_mask2int(a.simdInternal_) & 0xF) != 0;
-}
-
-static inline Simd4Double gmx_simdcall selectByMask(Simd4Double a, Simd4DBool m)
-{
- return { _mm512_mask_mov_pd(_mm512_setzero_pd(), m.simdInternal_, a.simdInternal_) };
-}
-
-static inline Simd4Double gmx_simdcall selectByNotMask(Simd4Double a, Simd4DBool m)
-{
- return { _mm512_mask_mov_pd(_mm512_setzero_pd(), _mm512_knot(m.simdInternal_), a.simdInternal_) };
-}
-
-static inline Simd4Double gmx_simdcall blend(Simd4Double a, Simd4Double b, Simd4DBool sel)
-{
- return { _mm512_mask_blend_pd(sel.simdInternal_, a.simdInternal_, b.simdInternal_) };
-}
-
-static inline double gmx_simdcall reduce(Simd4Double a)
-{
- return _mm512_mask_reduce_add_pd(_mm512_int2mask(0xF), a.simdInternal_);
-}
-
-} // namespace gmx
-
-#endif // GMX_SIMD_IMPL_X86_MIC_SIMD4_DOUBLE_H
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by
- * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
- * and including many others, as listed in the AUTHORS file in the
- * top-level source directory and at http://www.gromacs.org.
- *
- * GROMACS is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * GROMACS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with GROMACS; if not, see
- * http://www.gnu.org/licenses, or write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * If you want to redistribute modifications to GROMACS, please
- * consider that scientific software is very special. Version
- * control is crucial - bugs must be traceable. We will be happy to
- * consider code for inclusion in the official distribution, but
- * derived work must not be called official GROMACS. Details are found
- * in the README & COPYING files - if they are missing, get the
- * official version at http://www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org.
- */
-
-#ifndef GMX_SIMD_IMPL_X86_MIC_SIMD4_FLOAT_H
-#define GMX_SIMD_IMPL_X86_MIC_SIMD4_FLOAT_H
-
-#include "config.h"
-
-#include <cassert>
-
-#include <immintrin.h>
-
-#include "gromacs/utility/basedefinitions.h"
-
-#include "impl_x86_mic_simd_float.h"
-
-namespace gmx
-{
-
-class Simd4Float
-{
-public:
- Simd4Float() {}
-
- Simd4Float(float f) : simdInternal_(_mm512_set1_ps(f)) {}
-
- // Internal utility constructor to simplify return statements
- Simd4Float(__m512 simd) : simdInternal_(simd) {}
-
- __m512 simdInternal_;
-};
-
-class Simd4FBool
-{
-public:
- Simd4FBool() {}
-
- // Internal utility constructor to simplify return statements
- Simd4FBool(__mmask16 simd) : simdInternal_(simd) {}
-
- __mmask16 simdInternal_;
-};
-
-static inline Simd4Float gmx_simdcall load4(const float* m)
-{
- assert(size_t(m) % 16 == 0);
- return { _mm512_mask_extload_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), m,
- _MM_UPCONV_PS_NONE, _MM_BROADCAST_4X16, _MM_HINT_NONE) };
-}
-
-static inline void gmx_simdcall store4(float* m, Simd4Float a)
-{
- assert(size_t(m) % 16 == 0);
- _mm512_mask_packstorelo_ps(m, _mm512_int2mask(0xF), a.simdInternal_);
-}
-
-static inline Simd4Float gmx_simdcall load4U(const float* m)
-{
- return { _mm512_mask_loadunpackhi_ps(
- _mm512_mask_loadunpacklo_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), m),
- _mm512_int2mask(0xF), m + 16) };
-}
-
-static inline void gmx_simdcall store4U(float* m, Simd4Float a)
-{
- _mm512_mask_packstorelo_ps(m, _mm512_int2mask(0xF), a.simdInternal_);
- _mm512_mask_packstorehi_ps(m + 16, _mm512_int2mask(0xF), a.simdInternal_);
-}
-
-static inline Simd4Float gmx_simdcall simd4SetZeroF()
-{
- return { _mm512_setzero_ps() };
-}
-
-static inline Simd4Float gmx_simdcall operator&(Simd4Float a, Simd4Float b)
-{
- return { _mm512_castsi512_ps(_mm512_mask_and_epi32(_mm512_undefined_epi32(), _mm512_int2mask(0xF),
- _mm512_castps_si512(a.simdInternal_),
- _mm512_castps_si512(b.simdInternal_))) };
-}
-
-static inline Simd4Float gmx_simdcall andNot(Simd4Float a, Simd4Float b)
-{
- return { _mm512_castsi512_ps(_mm512_mask_andnot_epi32(
- _mm512_undefined_epi32(), _mm512_int2mask(0xF), _mm512_castps_si512(a.simdInternal_),
- _mm512_castps_si512(b.simdInternal_))) };
-}
-
-static inline Simd4Float gmx_simdcall operator|(Simd4Float a, Simd4Float b)
-{
- return { _mm512_castsi512_ps(_mm512_mask_or_epi32(_mm512_undefined_epi32(), _mm512_int2mask(0xF),
- _mm512_castps_si512(a.simdInternal_),
- _mm512_castps_si512(b.simdInternal_))) };
-}
-
-static inline Simd4Float gmx_simdcall operator^(Simd4Float a, Simd4Float b)
-{
- return { _mm512_castsi512_ps(_mm512_mask_xor_epi32(_mm512_undefined_epi32(), _mm512_int2mask(0xF),
- _mm512_castps_si512(a.simdInternal_),
- _mm512_castps_si512(b.simdInternal_))) };
-}
-
-static inline Simd4Float gmx_simdcall operator+(Simd4Float a, Simd4Float b)
-{
- return { _mm512_mask_add_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), a.simdInternal_,
- b.simdInternal_) };
-}
-
-static inline Simd4Float gmx_simdcall operator-(Simd4Float a, Simd4Float b)
-{
- return { _mm512_mask_sub_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), a.simdInternal_,
- b.simdInternal_) };
-}
-
-static inline Simd4Float gmx_simdcall operator-(Simd4Float x)
-{
- return { _mm512_mask_addn_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), x.simdInternal_,
- _mm512_setzero_ps()) };
-}
-
-static inline Simd4Float gmx_simdcall operator*(Simd4Float a, Simd4Float b)
-{
- return { _mm512_mask_mul_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), a.simdInternal_,
- b.simdInternal_) };
-}
-
-static inline Simd4Float gmx_simdcall fma(Simd4Float a, Simd4Float b, Simd4Float c)
-{
- return { _mm512_mask_fmadd_ps(a.simdInternal_, _mm512_int2mask(0xF), b.simdInternal_, c.simdInternal_) };
-}
-
-static inline Simd4Float gmx_simdcall fms(Simd4Float a, Simd4Float b, Simd4Float c)
-{
- return { _mm512_mask_fmsub_ps(a.simdInternal_, _mm512_int2mask(0xF), b.simdInternal_, c.simdInternal_) };
-}
-
-static inline Simd4Float gmx_simdcall fnma(Simd4Float a, Simd4Float b, Simd4Float c)
-{
- return { _mm512_mask_fnmadd_ps(a.simdInternal_, _mm512_int2mask(0xF), b.simdInternal_, c.simdInternal_) };
-}
-
-static inline Simd4Float gmx_simdcall fnms(Simd4Float a, Simd4Float b, Simd4Float c)
-{
- return { _mm512_mask_fnmsub_ps(a.simdInternal_, _mm512_int2mask(0xF), b.simdInternal_, c.simdInternal_) };
-}
-
-static inline Simd4Float gmx_simdcall rsqrt(Simd4Float x)
-{
- return { _mm512_mask_rsqrt23_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), x.simdInternal_) };
-}
-
-static inline Simd4Float gmx_simdcall abs(Simd4Float x)
-{
- return { _mm512_castsi512_ps(_mm512_mask_andnot_epi32(
- _mm512_undefined_epi32(), _mm512_int2mask(0xF),
- _mm512_castps_si512(_mm512_set1_ps(GMX_FLOAT_NEGZERO)), _mm512_castps_si512(x.simdInternal_))) };
-}
-
-static inline Simd4Float gmx_simdcall max(Simd4Float a, Simd4Float b)
-{
- return { _mm512_mask_gmax_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), a.simdInternal_,
- b.simdInternal_) };
-}
-
-static inline Simd4Float gmx_simdcall min(Simd4Float a, Simd4Float b)
-{
- return { _mm512_mask_gmin_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), a.simdInternal_,
- b.simdInternal_) };
-}
-
-static inline Simd4Float gmx_simdcall round(Simd4Float x)
-{
- return { _mm512_mask_round_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), x.simdInternal_,
- _MM_FROUND_TO_NEAREST_INT, _MM_EXPADJ_NONE) };
-}
-
-static inline Simd4Float gmx_simdcall trunc(Simd4Float x)
-{
- return { _mm512_mask_round_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), x.simdInternal_,
- _MM_FROUND_TO_ZERO, _MM_EXPADJ_NONE) };
-}
-
-static inline float gmx_simdcall dotProduct(Simd4Float a, Simd4Float b)
-{
- __m512 x = _mm512_mask_mul_ps(_mm512_setzero_ps(), _mm512_int2mask(0x7), a.simdInternal_,
- b.simdInternal_);
- x = _mm512_add_ps(x, _mm512_swizzle_ps(x, _MM_SWIZ_REG_BADC));
- x = _mm512_add_ps(x, _mm512_swizzle_ps(x, _MM_SWIZ_REG_CDAB));
- float f;
- _mm512_mask_packstorelo_ps(&f, _mm512_mask2int(0x1), x);
- return f;
-}
-
-static inline void gmx_simdcall transpose(Simd4Float* v0, Simd4Float* v1, Simd4Float* v2, Simd4Float* v3)
-{
- v0->simdInternal_ = _mm512_mask_permute4f128_ps(v0->simdInternal_, _mm512_int2mask(0x00F0),
- v1->simdInternal_, _MM_PERM_AAAA);
- v2->simdInternal_ = _mm512_mask_permute4f128_ps(v2->simdInternal_, _mm512_int2mask(0x00F0),
- v3->simdInternal_, _MM_PERM_AAAA);
- v0->simdInternal_ = _mm512_mask_permute4f128_ps(v0->simdInternal_, _mm512_int2mask(0xFF00),
- v2->simdInternal_, _MM_PERM_BABA);
- v0->simdInternal_ = _mm512_castsi512_ps(_mm512_permutevar_epi32(
- _mm512_set_epi32(15, 11, 7, 3, 14, 10, 6, 2, 13, 9, 5, 1, 12, 8, 4, 0),
- _mm512_castps_si512(v0->simdInternal_)));
- v1->simdInternal_ = _mm512_mask_permute4f128_ps(_mm512_setzero_ps(), _mm512_int2mask(0x000F),
- v0->simdInternal_, _MM_PERM_BBBB);
- v2->simdInternal_ = _mm512_mask_permute4f128_ps(_mm512_setzero_ps(), _mm512_int2mask(0x000F),
- v0->simdInternal_, _MM_PERM_CCCC);
- v3->simdInternal_ = _mm512_mask_permute4f128_ps(_mm512_setzero_ps(), _mm512_int2mask(0x000F),
- v0->simdInternal_, _MM_PERM_DDDD);
-}
-
-// Picky, picky, picky:
-// icc-16 complains about "Illegal value of immediate argument to intrinsic"
-// unless we use
-// 1) Ordered-quiet for ==
-// 2) Unordered-quiet for !=
-// 3) Ordered-signaling for < and <=
-
-static inline Simd4FBool gmx_simdcall operator==(Simd4Float a, Simd4Float b)
-{
- return { _mm512_mask_cmp_ps_mask(_mm512_int2mask(0xF), a.simdInternal_, b.simdInternal_, _CMP_EQ_OQ) };
-}
-
-static inline Simd4FBool gmx_simdcall operator!=(Simd4Float a, Simd4Float b)
-{
- return { _mm512_mask_cmp_ps_mask(_mm512_int2mask(0xF), a.simdInternal_, b.simdInternal_, _CMP_NEQ_UQ) };
-}
-
-static inline Simd4FBool gmx_simdcall operator<(Simd4Float a, Simd4Float b)
-{
- return { _mm512_mask_cmp_ps_mask(_mm512_int2mask(0xF), a.simdInternal_, b.simdInternal_, _CMP_LT_OS) };
-}
-
-static inline Simd4FBool gmx_simdcall operator<=(Simd4Float a, Simd4Float b)
-{
- return { _mm512_mask_cmp_ps_mask(_mm512_int2mask(0xF), a.simdInternal_, b.simdInternal_, _CMP_LE_OS) };
-}
-
-static inline Simd4FBool gmx_simdcall operator&&(Simd4FBool a, Simd4FBool b)
-{
- return { _mm512_kand(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline Simd4FBool gmx_simdcall operator||(Simd4FBool a, Simd4FBool b)
-{
- return { _mm512_kor(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline bool gmx_simdcall anyTrue(Simd4FBool a)
-{
- return (_mm512_mask2int(a.simdInternal_) & 0xF) != 0;
-}
-
-static inline Simd4Float gmx_simdcall selectByMask(Simd4Float a, Simd4FBool m)
-{
- return { _mm512_mask_mov_ps(_mm512_setzero_ps(), m.simdInternal_, a.simdInternal_) };
-}
-
-static inline Simd4Float gmx_simdcall selectByNotMask(Simd4Float a, Simd4FBool m)
-{
- return { _mm512_mask_mov_ps(_mm512_setzero_ps(), _mm512_knot(m.simdInternal_), a.simdInternal_) };
-}
-
-static inline Simd4Float gmx_simdcall blend(Simd4Float a, Simd4Float b, Simd4FBool sel)
-{
- return { _mm512_mask_blend_ps(sel.simdInternal_, a.simdInternal_, b.simdInternal_) };
-}
-
-static inline float gmx_simdcall reduce(Simd4Float a)
-{
- __m512 x = a.simdInternal_;
- x = _mm512_add_ps(x, _mm512_swizzle_ps(x, _MM_SWIZ_REG_BADC));
- x = _mm512_add_ps(x, _mm512_swizzle_ps(x, _MM_SWIZ_REG_CDAB));
- float f;
- _mm512_mask_packstorelo_ps(&f, _mm512_mask2int(0x1), x);
- return f;
-}
-
-} // namespace gmx
-
-#endif // GMX_SIMD_IMPL_X86_MIC_SIMD4_FLOAT_H
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 2014,2015,2016,2017,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.
- *
- * 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.
- */
-
-#ifndef GMX_SIMD_IMPL_X86_MIC_SIMD_DOUBLE_H
-#define GMX_SIMD_IMPL_X86_MIC_SIMD_DOUBLE_H
-
-#include "config.h"
-
-#include <cassert>
-#include <cstdint>
-
-#include <immintrin.h>
-
-#include "gromacs/math/utilities.h"
-#include "gromacs/utility/basedefinitions.h"
-
-#include "impl_x86_mic_simd_float.h"
-
-namespace gmx
-{
-
-class SimdDouble
-{
-public:
- SimdDouble() {}
-
- SimdDouble(double d) : simdInternal_(_mm512_set1_pd(d)) {}
-
- // Internal utility constructor to simplify return statements
- SimdDouble(__m512d simd) : simdInternal_(simd) {}
-
- __m512d simdInternal_;
-};
-
-class SimdDInt32
-{
-public:
- SimdDInt32() {}
-
- SimdDInt32(std::int32_t i) : simdInternal_(_mm512_set1_epi32(i)) {}
-
- // Internal utility constructor to simplify return statements
- SimdDInt32(__m512i simd) : simdInternal_(simd) {}
-
- __m512i simdInternal_;
-};
-
-class SimdDBool
-{
-public:
- SimdDBool() {}
-
- // Internal utility constructor to simplify return statements
- SimdDBool(__mmask8 simd) : simdInternal_(simd) {}
-
- __mmask8 simdInternal_;
-};
-
-class SimdDIBool
-{
-public:
- SimdDIBool() {}
-
- // Internal utility constructor to simplify return statements
- SimdDIBool(__mmask16 simd) : simdInternal_(simd) {}
-
- __mmask16 simdInternal_;
-};
-
-static inline SimdDouble gmx_simdcall simdLoad(const double* m, SimdDoubleTag = {})
-{
- assert(std::size_t(m) % 64 == 0);
- return { _mm512_load_pd(m) };
-}
-
-static inline void gmx_simdcall store(double* m, SimdDouble a)
-{
- assert(std::size_t(m) % 64 == 0);
- _mm512_store_pd(m, a.simdInternal_);
-}
-
-static inline SimdDouble gmx_simdcall simdLoadU(const double* m, SimdDoubleTag = {})
-{
- return { _mm512_loadunpackhi_pd(_mm512_loadunpacklo_pd(_mm512_undefined_pd(), m), m + 8) };
-}
-
-static inline void gmx_simdcall storeU(double* m, SimdDouble a)
-{
- _mm512_packstorelo_pd(m, a.simdInternal_);
- _mm512_packstorehi_pd(m + 8, a.simdInternal_);
-}
-
-static inline SimdDouble gmx_simdcall setZeroD()
-{
- return { _mm512_setzero_pd() };
-}
-
-static inline SimdDInt32 gmx_simdcall simdLoad(const std::int32_t* m, SimdDInt32Tag)
-{
- assert(std::size_t(m) % 32 == 0);
- return { _mm512_extload_epi64(m, _MM_UPCONV_EPI64_NONE, _MM_BROADCAST_4X8, _MM_HINT_NONE) };
-}
-
-static inline void gmx_simdcall store(std::int32_t* m, SimdDInt32 a)
-{
- assert(std::size_t(m) % 32 == 0);
- _mm512_mask_packstorelo_epi32(m, _mm512_int2mask(0x00FF), a.simdInternal_);
-}
-
-static inline SimdDInt32 gmx_simdcall simdLoadU(const std::int32_t* m, SimdDInt32Tag)
-{
- return { _mm512_mask_loadunpackhi_epi32(
- _mm512_mask_loadunpacklo_epi32(_mm512_undefined_epi32(), _mm512_int2mask(0x00FF), m),
- _mm512_int2mask(0x00FF), m + 16) };
-}
-
-static inline void gmx_simdcall storeU(std::int32_t* m, SimdDInt32 a)
-{
- _mm512_mask_packstorelo_epi32(m, _mm512_int2mask(0x00FF), a.simdInternal_);
- _mm512_mask_packstorehi_epi32(m + 16, _mm512_int2mask(0x00FF), a.simdInternal_);
-}
-
-static inline SimdDInt32 gmx_simdcall setZeroDI()
-{
- return { _mm512_setzero_epi32() };
-}
-
-template<int index>
-static inline std::int32_t gmx_simdcall extract(SimdDInt32 a)
-{
- int r;
- _mm512_mask_packstorelo_epi32(&r, _mm512_mask2int(1 << index), a.simdInternal_);
- return r;
-}
-
-static inline SimdDouble gmx_simdcall operator&(SimdDouble a, SimdDouble b)
-{
- return { _mm512_castsi512_pd(_mm512_and_epi32(_mm512_castpd_si512(a.simdInternal_),
- _mm512_castpd_si512(b.simdInternal_))) };
-}
-
-static inline SimdDouble gmx_simdcall andNot(SimdDouble a, SimdDouble b)
-{
- return { _mm512_castsi512_pd(_mm512_andnot_epi32(_mm512_castpd_si512(a.simdInternal_),
- _mm512_castpd_si512(b.simdInternal_))) };
-}
-
-static inline SimdDouble gmx_simdcall operator|(SimdDouble a, SimdDouble b)
-{
- return { _mm512_castsi512_pd(_mm512_or_epi32(_mm512_castpd_si512(a.simdInternal_),
- _mm512_castpd_si512(b.simdInternal_))) };
-}
-
-static inline SimdDouble gmx_simdcall operator^(SimdDouble a, SimdDouble b)
-{
- return { _mm512_castsi512_pd(_mm512_xor_epi32(_mm512_castpd_si512(a.simdInternal_),
- _mm512_castpd_si512(b.simdInternal_))) };
-}
-
-static inline SimdDouble gmx_simdcall operator+(SimdDouble a, SimdDouble b)
-{
- return { _mm512_add_pd(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdDouble gmx_simdcall operator-(SimdDouble a, SimdDouble b)
-{
- return { _mm512_sub_pd(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdDouble gmx_simdcall operator-(SimdDouble x)
-{
- return { _mm512_addn_pd(x.simdInternal_, _mm512_setzero_pd()) };
-}
-
-static inline SimdDouble gmx_simdcall operator*(SimdDouble a, SimdDouble b)
-{
- return { _mm512_mul_pd(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdDouble gmx_simdcall fma(SimdDouble a, SimdDouble b, SimdDouble c)
-{
- return { _mm512_fmadd_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) };
-}
-
-static inline SimdDouble gmx_simdcall fms(SimdDouble a, SimdDouble b, SimdDouble c)
-{
- return { _mm512_fmsub_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) };
-}
-
-static inline SimdDouble gmx_simdcall fnma(SimdDouble a, SimdDouble b, SimdDouble c)
-{
- return { _mm512_fnmadd_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) };
-}
-
-static inline SimdDouble gmx_simdcall fnms(SimdDouble a, SimdDouble b, SimdDouble c)
-{
- return { _mm512_fnmsub_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) };
-}
-
-static inline SimdDouble gmx_simdcall rsqrt(SimdDouble x)
-{
- return { _mm512_cvtpslo_pd(_mm512_rsqrt23_ps(_mm512_cvtpd_pslo(x.simdInternal_))) };
-}
-
-static inline SimdDouble gmx_simdcall rcp(SimdDouble x)
-{
- return { _mm512_cvtpslo_pd(_mm512_rcp23_ps(_mm512_cvtpd_pslo(x.simdInternal_))) };
-}
-
-static inline SimdDouble gmx_simdcall maskAdd(SimdDouble a, SimdDouble b, SimdDBool m)
-{
- return { _mm512_mask_add_pd(a.simdInternal_, m.simdInternal_, a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdDouble gmx_simdcall maskzMul(SimdDouble a, SimdDouble b, SimdDBool m)
-{
- return { _mm512_mask_mul_pd(_mm512_setzero_pd(), m.simdInternal_, a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdDouble gmx_simdcall maskzFma(SimdDouble a, SimdDouble b, SimdDouble c, SimdDBool m)
-{
- return { _mm512_mask_mov_pd(_mm512_setzero_pd(), m.simdInternal_,
- _mm512_fmadd_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_)) };
-}
-
-static inline SimdDouble gmx_simdcall maskzRsqrt(SimdDouble x, SimdDBool m)
-{
- return { _mm512_cvtpslo_pd(_mm512_mask_rsqrt23_ps(_mm512_setzero_ps(), m.simdInternal_,
- _mm512_cvtpd_pslo(x.simdInternal_))) };
-}
-
-static inline SimdDouble gmx_simdcall maskzRcp(SimdDouble x, SimdDBool m)
-{
- return { _mm512_cvtpslo_pd(_mm512_mask_rcp23_ps(_mm512_setzero_ps(), m.simdInternal_,
- _mm512_cvtpd_pslo(x.simdInternal_))) };
-}
-
-static inline SimdDouble gmx_simdcall abs(SimdDouble x)
-{
- return { _mm512_castsi512_pd(_mm512_andnot_epi32(_mm512_castpd_si512(_mm512_set1_pd(GMX_DOUBLE_NEGZERO)),
- _mm512_castpd_si512(x.simdInternal_))) };
-}
-
-static inline SimdDouble gmx_simdcall max(SimdDouble a, SimdDouble b)
-{
- return { _mm512_gmax_pd(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdDouble gmx_simdcall min(SimdDouble a, SimdDouble b)
-{
- return { _mm512_gmin_pd(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdDouble gmx_simdcall round(SimdDouble x)
-{
- return { _mm512_roundfxpnt_adjust_pd(x.simdInternal_, _MM_FROUND_TO_NEAREST_INT, _MM_EXPADJ_NONE) };
-}
-
-static inline SimdDouble gmx_simdcall trunc(SimdDouble x)
-{
- return { _mm512_roundfxpnt_adjust_pd(x.simdInternal_, _MM_FROUND_TO_ZERO, _MM_EXPADJ_NONE) };
-}
-
-template<MathOptimization opt = MathOptimization::Safe>
-static inline SimdDouble frexp(SimdDouble value, SimdDInt32* exponent)
-{
- __m512d rExponent;
- __m512i iExponent;
- __m512d result;
-
- if (opt == MathOptimization::Safe)
- {
- // For the safe branch, we use the masked operations to only assign results if the
- // input value was nonzero, and otherwise set exponent to 0, and the fraction to the input (+-0).
- __mmask8 valueIsNonZero =
- _mm512_cmp_pd_mask(_mm512_setzero_pd(), value.simdInternal_, _CMP_NEQ_OQ);
- rExponent = _mm512_mask_getexp_pd(_mm512_setzero_pd(), valueIsNonZero, value.simdInternal_);
-
- // Create an integer -1 value, and use masking in the conversion as the result for
- // zero-value input. When we later add 1 to all fields, the fields that were formerly -1
- // (corresponding to zero exponent) will be assigned -1 + 1 = 0.
- iExponent = _mm512_mask_cvtfxpnt_roundpd_epi32lo(_mm512_set_epi32(-1), valueIsNonZero,
- rExponent, _MM_FROUND_TO_NEAREST_INT);
- iExponent = _mm512__add_epi32(iExponent, _mm512_set1_epi32(1));
-
- // Set result to value (+-0) when it is zero.
- result = _mm512_mask_getmant_pd(value.simdInternal_, valueIsNonZero, value.simdInternal_,
- _MM_MANT_NORM_p5_1, _MM_MANT_SIGN_src);
- }
- else
- {
- rExponent = _mm512_getexp_pd(value.simdInternal_);
- iExponent = _mm512_cvtfxpnt_roundpd_epi32lo(rExponent, _MM_FROUND_TO_NEAREST_INT);
- iExponent = _mm512_add_epi32(iExponent, _mm512_set1_epi32(1));
- result = _mm512_getmant_pd(value.simdInternal_, _MM_MANT_NORM_p5_1, _MM_MANT_SIGN_src);
- }
-
- exponent->simdInternal_ = iExponent;
-
- return { result };
-}
-
-template<MathOptimization opt = MathOptimization::Safe>
-static inline SimdDouble ldexp(SimdDouble value, SimdDInt32 exponent)
-{
- const __m512i exponentBias = _mm512_set1_epi32(1023);
- __m512i iExponent = _mm512_add_epi32(exponent.simdInternal_, exponentBias);
-
- if (opt == MathOptimization::Safe)
- {
- // Make sure biased argument is not negative
- iExponent = _mm512_max_epi32(iExponent, _mm512_setzero_epi32());
- }
-
- iExponent = _mm512_permutevar_epi32(
- _mm512_set_epi32(7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0), iExponent);
- iExponent = _mm512_mask_slli_epi32(_mm512_setzero_epi32(), _mm512_int2mask(0xAAAA), iExponent, 20);
- return _mm512_mul_pd(_mm512_castsi512_pd(iExponent), value.simdInternal_);
-}
-
-static inline double gmx_simdcall reduce(SimdDouble a)
-{
- return _mm512_reduce_add_pd(a.simdInternal_);
-}
-
-// Picky, picky, picky:
-// icc-16 complains about "Illegal value of immediate argument to intrinsic"
-// unless we use
-// 1) Ordered-quiet for ==
-// 2) Unordered-quiet for !=
-// 3) Ordered-signaling for < and <=
-
-static inline SimdDBool gmx_simdcall operator==(SimdDouble a, SimdDouble b)
-{
- return { _mm512_cmp_pd_mask(a.simdInternal_, b.simdInternal_, _CMP_EQ_OQ) };
-}
-
-static inline SimdDBool gmx_simdcall operator!=(SimdDouble a, SimdDouble b)
-{
- return { _mm512_cmp_pd_mask(a.simdInternal_, b.simdInternal_, _CMP_NEQ_UQ) };
-}
-
-static inline SimdDBool gmx_simdcall operator<(SimdDouble a, SimdDouble b)
-{
- return { _mm512_cmp_pd_mask(a.simdInternal_, b.simdInternal_, _CMP_LT_OS) };
-}
-
-static inline SimdDBool gmx_simdcall operator<=(SimdDouble a, SimdDouble b)
-{
- return { _mm512_cmp_pd_mask(a.simdInternal_, b.simdInternal_, _CMP_LE_OS) };
-}
-
-static inline SimdDBool gmx_simdcall testBits(SimdDouble a)
-{
- // This is a bit problematic since Knight's corner does not have any 64-bit integer comparisons,
- // and we cannot use floating-point since values with just a single bit set can evaluate to 0.0.
- // Instead, we do it as
- // 1) Do a logical or of the high/low 32 bits
- // 2) Do a permute so we have the low 32 bits of each value in the low 8 32-bit elements
- // 3) Do an integer comparison, and cast so we just keep the low 8 bits of the mask.
- //
- // By default we will use integers for the masks in the nonbonded kernels, so this shouldn't
- // have any significant performance drawbacks.
-
- __m512i ia = _mm512_castpd_si512(a.simdInternal_);
-
- ia = _mm512_or_epi32(ia, _mm512_swizzle_epi32(ia, _MM_SWIZ_REG_CDAB));
- ia = _mm512_permutevar_epi32(
- _mm512_set_epi32(15, 13, 11, 9, 7, 5, 3, 1, 14, 12, 10, 8, 6, 4, 2, 0), ia);
-
- return { static_cast<__mmask8>(_mm512_cmp_epi32_mask(ia, _mm512_setzero_si512(), _MM_CMPINT_NE)) };
-}
-
-static inline SimdDBool gmx_simdcall operator&&(SimdDBool a, SimdDBool b)
-{
- return { static_cast<__mmask8>(_mm512_kand(a.simdInternal_, b.simdInternal_)) };
-}
-
-static inline SimdDBool gmx_simdcall operator||(SimdDBool a, SimdDBool b)
-{
- return { static_cast<__mmask8>(_mm512_kor(a.simdInternal_, b.simdInternal_)) };
-}
-
-static inline bool gmx_simdcall anyTrue(SimdDBool a)
-{
- return _mm512_mask2int(a.simdInternal_) != 0;
-}
-
-static inline SimdDouble gmx_simdcall selectByMask(SimdDouble a, SimdDBool m)
-{
- return { _mm512_mask_mov_pd(_mm512_setzero_pd(), m.simdInternal_, a.simdInternal_) };
-}
-
-static inline SimdDouble gmx_simdcall selectByNotMask(SimdDouble a, SimdDBool m)
-{
- return { _mm512_mask_mov_pd(a.simdInternal_, m.simdInternal_, _mm512_setzero_pd()) };
-}
-
-static inline SimdDouble gmx_simdcall blend(SimdDouble a, SimdDouble b, SimdDBool sel)
-{
- return { _mm512_mask_blend_pd(sel.simdInternal_, a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdDInt32 gmx_simdcall operator&(SimdDInt32 a, SimdDInt32 b)
-{
- return { _mm512_and_epi32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdDInt32 gmx_simdcall andNot(SimdDInt32 a, SimdDInt32 b)
-{
- return { _mm512_andnot_epi32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdDInt32 gmx_simdcall operator|(SimdDInt32 a, SimdDInt32 b)
-{
- return { _mm512_or_epi32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdDInt32 gmx_simdcall operator^(SimdDInt32 a, SimdDInt32 b)
-{
- return { _mm512_xor_epi32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdDInt32 gmx_simdcall operator+(SimdDInt32 a, SimdDInt32 b)
-{
- return { _mm512_add_epi32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdDInt32 gmx_simdcall operator-(SimdDInt32 a, SimdDInt32 b)
-{
- return { _mm512_sub_epi32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdDInt32 gmx_simdcall operator*(SimdDInt32 a, SimdDInt32 b)
-{
- return { _mm512_mullo_epi32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdDIBool gmx_simdcall operator==(SimdDInt32 a, SimdDInt32 b)
-{
- return { _mm512_cmp_epi32_mask(a.simdInternal_, b.simdInternal_, _MM_CMPINT_EQ) };
-}
-
-static inline SimdDIBool gmx_simdcall testBits(SimdDInt32 a)
-{
- return { _mm512_cmp_epi32_mask(a.simdInternal_, _mm512_setzero_si512(), _MM_CMPINT_NE) };
-}
-
-static inline SimdDIBool gmx_simdcall operator<(SimdDInt32 a, SimdDInt32 b)
-{
- return { _mm512_cmp_epi32_mask(a.simdInternal_, b.simdInternal_, _MM_CMPINT_LT) };
-}
-
-static inline SimdDIBool gmx_simdcall operator&&(SimdDIBool a, SimdDIBool b)
-{
- return { _mm512_kand(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdDIBool gmx_simdcall operator||(SimdDIBool a, SimdDIBool b)
-{
- return { _mm512_kor(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline bool gmx_simdcall anyTrue(SimdDIBool a)
-{
- return (_mm512_mask2int(a.simdInternal_) & 0xFF) != 0;
-}
-
-static inline SimdDInt32 gmx_simdcall selectByMask(SimdDInt32 a, SimdDIBool m)
-{
- return { _mm512_mask_mov_epi32(_mm512_setzero_epi32(), m.simdInternal_, a.simdInternal_) };
-}
-
-static inline SimdDInt32 gmx_simdcall selectByNotMask(SimdDInt32 a, SimdDIBool m)
-{
- return { _mm512_mask_mov_epi32(a.simdInternal_, m.simdInternal_, _mm512_setzero_epi32()) };
-}
-
-static inline SimdDInt32 gmx_simdcall blend(SimdDInt32 a, SimdDInt32 b, SimdDIBool sel)
-{
- return { _mm512_mask_blend_epi32(sel.simdInternal_, a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdDInt32 gmx_simdcall cvtR2I(SimdDouble a)
-{
- return { _mm512_cvtfxpnt_roundpd_epi32lo(a.simdInternal_, _MM_FROUND_TO_NEAREST_INT) };
-}
-
-static inline SimdDInt32 gmx_simdcall cvttR2I(SimdDouble a)
-{
- return { _mm512_cvtfxpnt_roundpd_epi32lo(a.simdInternal_, _MM_FROUND_TO_ZERO) };
-}
-
-static inline SimdDouble gmx_simdcall cvtI2R(SimdDInt32 a)
-{
- return { _mm512_cvtepi32lo_pd(a.simdInternal_) };
-}
-
-static inline SimdDIBool gmx_simdcall cvtB2IB(SimdDBool a)
-{
- return { a.simdInternal_ };
-}
-
-static inline SimdDBool gmx_simdcall cvtIB2B(SimdDIBool a)
-{
- return { static_cast<__mmask8>(a.simdInternal_) };
-}
-
-static inline void gmx_simdcall cvtF2DD(SimdFloat f, SimdDouble* d0, SimdDouble* d1)
-{
- __m512i i1 = _mm512_permute4f128_epi32(_mm512_castps_si512(f.simdInternal_), _MM_PERM_DCDC);
-
- *d0 = _mm512_cvtpslo_pd(f.simdInternal_);
- *d1 = _mm512_cvtpslo_pd(_mm512_castsi512_ps(i1));
-}
-
-static inline SimdFloat gmx_simdcall cvtDD2F(SimdDouble d0, SimdDouble d1)
-{
- __m512 f0 = _mm512_cvtpd_pslo(d0.simdInternal_);
- __m512 f1 = _mm512_cvtpd_pslo(d1.simdInternal_);
- return { _mm512_mask_permute4f128_ps(f0, _mm512_int2mask(0xFF00), f1, _MM_PERM_BABA) };
-}
-
-} // namespace gmx
-
-#endif // GMX_SIMD_IMPL_X86_MIC_SIMD_DOUBLE_H
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 2014,2015,2016,2017,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.
- *
- * 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.
- */
-
-#ifndef GMX_SIMD_IMPL_X86_MIC_SIMD_FLOAT_H
-#define GMX_SIMD_IMPL_X86_MIC_SIMD_FLOAT_H
-
-#include "config.h"
-
-#include <cassert>
-#include <cstdint>
-
-#include <immintrin.h>
-
-#include "gromacs/math/utilities.h"
-
-namespace gmx
-{
-
-class SimdFloat
-{
-public:
- SimdFloat() {}
-
- SimdFloat(float f) : simdInternal_(_mm512_set1_ps(f)) {}
-
- // Internal utility constructor to simplify return statements
- SimdFloat(__m512 simd) : simdInternal_(simd) {}
-
- __m512 simdInternal_;
-};
-
-class SimdFInt32
-{
-public:
- SimdFInt32() {}
-
- SimdFInt32(std::int32_t i) : simdInternal_(_mm512_set1_epi32(i)) {}
-
- // Internal utility constructor to simplify return statements
- SimdFInt32(__m512i simd) : simdInternal_(simd) {}
-
- __m512i simdInternal_;
-};
-
-class SimdFBool
-{
-public:
- SimdFBool() {}
-
- SimdFBool(bool b) : simdInternal_(_mm512_int2mask(b ? 0xFFFF : 0)) {}
-
- // Internal utility constructor to simplify return statements
- SimdFBool(__mmask16 simd) : simdInternal_(simd) {}
-
- __mmask16 simdInternal_;
-};
-
-class SimdFIBool
-{
-public:
- SimdFIBool() {}
-
- SimdFIBool(bool b) : simdInternal_(_mm512_int2mask(b ? 0xFFFF : 0)) {}
-
- // Internal utility constructor to simplify return statements
- SimdFIBool(__mmask16 simd) : simdInternal_(simd) {}
-
- __mmask16 simdInternal_;
-};
-
-static inline SimdFloat gmx_simdcall simdLoad(const float* m, SimdFloatTag = {})
-{
- assert(std::size_t(m) % 64 == 0);
- return { _mm512_load_ps(m) };
-}
-
-static inline void gmx_simdcall store(float* m, SimdFloat a)
-{
- assert(std::size_t(m) % 64 == 0);
- _mm512_store_ps(m, a.simdInternal_);
-}
-
-static inline SimdFloat gmx_simdcall simdLoadU(const float* m, SimdFloatTag = {})
-{
- return { _mm512_loadunpackhi_ps(_mm512_loadunpacklo_ps(_mm512_undefined_ps(), m), m + 16) };
-}
-
-static inline void gmx_simdcall storeU(float* m, SimdFloat a)
-{
- _mm512_packstorelo_ps(m, a.simdInternal_);
- _mm512_packstorehi_ps(m + 16, a.simdInternal_);
-}
-
-static inline SimdFloat gmx_simdcall setZeroF()
-{
- return { _mm512_setzero_ps() };
-}
-
-static inline SimdFInt32 gmx_simdcall simdLoad(const std::int32_t* m, SimdFInt32Tag)
-{
- assert(std::size_t(m) % 64 == 0);
- return { _mm512_load_epi32(m) };
-}
-
-static inline void gmx_simdcall store(std::int32_t* m, SimdFInt32 a)
-{
- assert(std::size_t(m) % 64 == 0);
- _mm512_store_epi32(m, a.simdInternal_);
-}
-
-static inline SimdFInt32 gmx_simdcall simdLoadU(const std::int32_t* m, SimdFInt32Tag)
-{
- return { _mm512_loadunpackhi_epi32(_mm512_loadunpacklo_epi32(_mm512_undefined_epi32(), m), m + 16) };
-}
-
-static inline void gmx_simdcall storeU(std::int32_t* m, SimdFInt32 a)
-{
- _mm512_packstorelo_epi32(m, a.simdInternal_);
- _mm512_packstorehi_epi32(m + 16, a.simdInternal_);
-}
-
-static inline SimdFInt32 gmx_simdcall setZeroFI()
-{
- return { _mm512_setzero_si512() };
-}
-
-
-template<int index>
-static inline std::int32_t gmx_simdcall extract(SimdFInt32 a)
-{
- int r;
- _mm512_mask_packstorelo_epi32(&r, _mm512_mask2int(1 << index), a.simdInternal_);
- return r;
-}
-
-static inline SimdFloat gmx_simdcall operator&(SimdFloat a, SimdFloat b)
-{
- return { _mm512_castsi512_ps(_mm512_and_epi32(_mm512_castps_si512(a.simdInternal_),
- _mm512_castps_si512(b.simdInternal_))) };
-}
-
-static inline SimdFloat gmx_simdcall andNot(SimdFloat a, SimdFloat b)
-{
- return { _mm512_castsi512_ps(_mm512_andnot_epi32(_mm512_castps_si512(a.simdInternal_),
- _mm512_castps_si512(b.simdInternal_))) };
-}
-
-static inline SimdFloat gmx_simdcall operator|(SimdFloat a, SimdFloat b)
-{
- return { _mm512_castsi512_ps(_mm512_or_epi32(_mm512_castps_si512(a.simdInternal_),
- _mm512_castps_si512(b.simdInternal_))) };
-}
-
-static inline SimdFloat gmx_simdcall operator^(SimdFloat a, SimdFloat b)
-{
- return { _mm512_castsi512_ps(_mm512_xor_epi32(_mm512_castps_si512(a.simdInternal_),
- _mm512_castps_si512(b.simdInternal_))) };
-}
-
-static inline SimdFloat gmx_simdcall operator+(SimdFloat a, SimdFloat b)
-{
- return { _mm512_add_ps(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall operator-(SimdFloat a, SimdFloat b)
-{
- return { _mm512_sub_ps(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall operator-(SimdFloat x)
-{
- return { _mm512_addn_ps(x.simdInternal_, _mm512_setzero_ps()) };
-}
-
-static inline SimdFloat gmx_simdcall operator*(SimdFloat a, SimdFloat b)
-{
- return { _mm512_mul_ps(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall fma(SimdFloat a, SimdFloat b, SimdFloat c)
-{
- return { _mm512_fmadd_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall fms(SimdFloat a, SimdFloat b, SimdFloat c)
-{
- return { _mm512_fmsub_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall fnma(SimdFloat a, SimdFloat b, SimdFloat c)
-{
- return { _mm512_fnmadd_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall fnms(SimdFloat a, SimdFloat b, SimdFloat c)
-{
- return { _mm512_fnmsub_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall rsqrt(SimdFloat x)
-{
- return { _mm512_rsqrt23_ps(x.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall rcp(SimdFloat x)
-{
- return { _mm512_rcp23_ps(x.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall maskAdd(SimdFloat a, SimdFloat b, SimdFBool m)
-{
- return { _mm512_mask_add_ps(a.simdInternal_, m.simdInternal_, a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall maskzMul(SimdFloat a, SimdFloat b, SimdFBool m)
-{
- return { _mm512_mask_mul_ps(_mm512_setzero_ps(), m.simdInternal_, a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall maskzFma(SimdFloat a, SimdFloat b, SimdFloat c, SimdFBool m)
-{
- return { _mm512_mask_mov_ps(_mm512_setzero_ps(), m.simdInternal_,
- _mm512_fmadd_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_)) };
-}
-
-static inline SimdFloat gmx_simdcall maskzRsqrt(SimdFloat x, SimdFBool m)
-{
- return { _mm512_mask_rsqrt23_ps(_mm512_setzero_ps(), m.simdInternal_, x.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall maskzRcp(SimdFloat x, SimdFBool m)
-{
- return { _mm512_mask_rcp23_ps(_mm512_setzero_ps(), m.simdInternal_, x.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall abs(SimdFloat x)
-{
- return { _mm512_castsi512_ps(_mm512_andnot_epi32(_mm512_castps_si512(_mm512_set1_ps(GMX_FLOAT_NEGZERO)),
- _mm512_castps_si512(x.simdInternal_))) };
-}
-
-static inline SimdFloat gmx_simdcall max(SimdFloat a, SimdFloat b)
-{
- return { _mm512_gmax_ps(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall min(SimdFloat a, SimdFloat b)
-{
- return { _mm512_gmin_ps(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall round(SimdFloat x)
-{
- return { _mm512_round_ps(x.simdInternal_, _MM_FROUND_TO_NEAREST_INT, _MM_EXPADJ_NONE) };
-}
-
-static inline SimdFloat gmx_simdcall trunc(SimdFloat x)
-{
- return { _mm512_round_ps(x.simdInternal_, _MM_FROUND_TO_ZERO, _MM_EXPADJ_NONE) };
-}
-
-template<MathOptimization opt = MathOptimization::Safe>
-static inline SimdFloat gmx_simdcall frexp(SimdFloat value, SimdFInt32* exponent)
-{
- __m512 rExponent;
- __m512i iExponent;
- __m512 result;
-
- if (opt == MathOptimization::Safe)
- {
- // For the safe branch, we use the masked operations to only assign results if the
- // input value was nonzero, and otherwise set exponent to 0, and the fraction to the input (+-0).
- __mmask16 valueIsNonZero =
- _mm512_cmp_ps_mask(_mm512_setzero_ps(), value.simdInternal_, _CMP_NEQ_OQ);
- rExponent = _mm512_mask_getexp_ps(_mm512_setzero_ps(), valueIsNonZero, value.simdInternal_);
- iExponent = _mm512_cvtfxpnt_round_adjustps_epi32(rExponent, _MM_FROUND_TO_NEAREST_INT,
- _MM_EXPADJ_NONE);
- iExponent = _mm512_mask_add_epi32(iExponent, valueIsNonZero, iExponent, _mm512_set1_epi32(1));
-
- // Set result to input value when the latter is +-0
- result = _mm512_mask_getmant_ps(value.simdInternal_, valueIsNonZero, value.simdInternal_,
- _MM_MANT_NORM_p5_1, _MM_MANT_SIGN_src);
- }
- else
- {
- rExponent = _mm512_getexp_ps(value.simdInternal_);
- iExponent = _mm512_cvtfxpnt_round_adjustps_epi32(rExponent, _MM_FROUND_TO_NEAREST_INT,
- _MM_EXPADJ_NONE);
- iExponent = _mm512_add_epi32(iExponent, _mm512_set1_epi32(1));
- result = _mm512_getmant_ps(value.simdInternal_, _MM_MANT_NORM_p5_1, _MM_MANT_SIGN_src);
- }
-
- exponent->simdInternal_ = iExponent;
-
- return { result };
-}
-
-template<MathOptimization opt = MathOptimization::Safe>
-static inline SimdFloat gmx_simdcall ldexp(SimdFloat value, SimdFInt32 exponent)
-{
- const __m512i exponentBias = _mm512_set1_epi32(127);
- __m512i iExponent = _mm512_add_epi32(exponent.simdInternal_, exponentBias);
-
- if (opt == MathOptimization::Safe)
- {
- // Make sure biased argument is not negative
- iExponent = _mm512_max_epi32(iExponent, _mm512_setzero_epi32());
- }
-
- iExponent = _mm512_slli_epi32(iExponent, 23);
-
- return { _mm512_mul_ps(value.simdInternal_, _mm512_castsi512_ps(iExponent)) };
-}
-
-static inline float gmx_simdcall reduce(SimdFloat a)
-{
- return _mm512_reduce_add_ps(a.simdInternal_);
-}
-
-// Picky, picky, picky:
-// icc-16 complains about "Illegal value of immediate argument to intrinsic"
-// unless we use
-// 1) Ordered-quiet for ==
-// 2) Unordered-quiet for !=
-// 3) Ordered-signaling for < and <=
-
-static inline SimdFBool gmx_simdcall operator==(SimdFloat a, SimdFloat b)
-{
- return { _mm512_cmp_ps_mask(a.simdInternal_, b.simdInternal_, _CMP_EQ_OQ) };
-}
-
-static inline SimdFBool gmx_simdcall operator!=(SimdFloat a, SimdFloat b)
-{
- return { _mm512_cmp_ps_mask(a.simdInternal_, b.simdInternal_, _CMP_NEQ_UQ) };
-}
-
-static inline SimdFBool gmx_simdcall operator<(SimdFloat a, SimdFloat b)
-{
- return { _mm512_cmp_ps_mask(a.simdInternal_, b.simdInternal_, _CMP_LT_OS) };
-}
-
-static inline SimdFBool gmx_simdcall operator<=(SimdFloat a, SimdFloat b)
-{
- return { _mm512_cmp_ps_mask(a.simdInternal_, b.simdInternal_, _CMP_LE_OS) };
-}
-
-static inline SimdFBool gmx_simdcall testBits(SimdFloat a)
-{
- return { _mm512_test_epi32_mask(_mm512_castps_si512(a.simdInternal_),
- _mm512_castps_si512(a.simdInternal_)) };
-}
-
-static inline SimdFBool gmx_simdcall operator&&(SimdFBool a, SimdFBool b)
-{
- return { _mm512_kand(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFBool gmx_simdcall operator||(SimdFBool a, SimdFBool b)
-{
- return { _mm512_kor(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline bool gmx_simdcall anyTrue(SimdFBool a)
-{
- return _mm512_mask2int(a.simdInternal_) != 0;
-}
-
-static inline SimdFloat gmx_simdcall selectByMask(SimdFloat a, SimdFBool m)
-{
- return { _mm512_mask_mov_ps(_mm512_setzero_ps(), m.simdInternal_, a.simdInternal_) };
-}
-
-static inline SimdFloat gmx_simdcall selectByNotMask(SimdFloat a, SimdFBool m)
-{
- return { _mm512_mask_mov_ps(a.simdInternal_, m.simdInternal_, _mm512_setzero_ps()) };
-}
-
-static inline SimdFloat gmx_simdcall blend(SimdFloat a, SimdFloat b, SimdFBool sel)
-{
- return { _mm512_mask_blend_ps(sel.simdInternal_, a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFInt32 gmx_simdcall operator&(SimdFInt32 a, SimdFInt32 b)
-{
- return { _mm512_and_epi32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFInt32 gmx_simdcall andNot(SimdFInt32 a, SimdFInt32 b)
-{
- return { _mm512_andnot_epi32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFInt32 gmx_simdcall operator|(SimdFInt32 a, SimdFInt32 b)
-{
- return { _mm512_or_epi32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFInt32 gmx_simdcall operator^(SimdFInt32 a, SimdFInt32 b)
-{
- return { _mm512_xor_epi32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFInt32 gmx_simdcall operator+(SimdFInt32 a, SimdFInt32 b)
-{
- return { _mm512_add_epi32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFInt32 gmx_simdcall operator-(SimdFInt32 a, SimdFInt32 b)
-{
- return { _mm512_sub_epi32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFInt32 gmx_simdcall operator*(SimdFInt32 a, SimdFInt32 b)
-{
- return { _mm512_mullo_epi32(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFIBool gmx_simdcall operator==(SimdFInt32 a, SimdFInt32 b)
-{
- return { _mm512_cmp_epi32_mask(a.simdInternal_, b.simdInternal_, _MM_CMPINT_EQ) };
-}
-
-static inline SimdFIBool gmx_simdcall testBits(SimdFInt32 a)
-{
- return { _mm512_test_epi32_mask(a.simdInternal_, a.simdInternal_) };
-}
-
-static inline SimdFIBool gmx_simdcall operator<(SimdFInt32 a, SimdFInt32 b)
-{
- return { _mm512_cmp_epi32_mask(a.simdInternal_, b.simdInternal_, _MM_CMPINT_LT) };
-}
-
-static inline SimdFIBool gmx_simdcall operator&&(SimdFIBool a, SimdFIBool b)
-{
- return { _mm512_kand(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFIBool gmx_simdcall operator||(SimdFIBool a, SimdFIBool b)
-{
- return { _mm512_kor(a.simdInternal_, b.simdInternal_) };
-}
-
-static inline bool gmx_simdcall anyTrue(SimdFIBool a)
-{
- return _mm512_mask2int(a.simdInternal_) != 0;
-}
-
-static inline SimdFInt32 gmx_simdcall selectByMask(SimdFInt32 a, SimdFIBool m)
-{
- return { _mm512_mask_mov_epi32(_mm512_setzero_epi32(), m.simdInternal_, a.simdInternal_) };
-}
-
-static inline SimdFInt32 gmx_simdcall selectByNotMask(SimdFInt32 a, SimdFIBool m)
-{
- return { _mm512_mask_mov_epi32(a.simdInternal_, m.simdInternal_, _mm512_setzero_epi32()) };
-}
-
-static inline SimdFInt32 gmx_simdcall blend(SimdFInt32 a, SimdFInt32 b, SimdFIBool sel)
-{
- return { _mm512_mask_blend_epi32(sel.simdInternal_, a.simdInternal_, b.simdInternal_) };
-}
-
-static inline SimdFInt32 gmx_simdcall cvtR2I(SimdFloat a)
-{
- return { _mm512_cvtfxpnt_round_adjustps_epi32(a.simdInternal_, _MM_FROUND_TO_NEAREST_INT,
- _MM_EXPADJ_NONE) };
-}
-
-static inline SimdFInt32 gmx_simdcall cvttR2I(SimdFloat a)
-{
- return { _mm512_cvtfxpnt_round_adjustps_epi32(a.simdInternal_, _MM_FROUND_TO_ZERO, _MM_EXPADJ_NONE) };
-}
-
-static inline SimdFloat gmx_simdcall cvtI2R(SimdFInt32 a)
-{
- return { _mm512_cvtfxpnt_round_adjustepi32_ps(a.simdInternal_, _MM_FROUND_TO_NEAREST_INT,
- _MM_EXPADJ_NONE) };
-}
-
-static inline SimdFIBool gmx_simdcall cvtB2IB(SimdFBool a)
-{
- return { a.simdInternal_ };
-}
-
-static inline SimdFBool gmx_simdcall cvtIB2B(SimdFIBool a)
-{
- return { a.simdInternal_ };
-}
-
-
-template<MathOptimization opt = MathOptimization::Safe>
-static inline SimdFloat gmx_simdcall exp2(SimdFloat x)
-{
- return { _mm512_exp223_ps(_mm512_cvtfxpnt_round_adjustps_epi32(
- x.simdInternal_, _MM_ROUND_MODE_NEAREST, _MM_EXPADJ_24)) };
-}
-
-template<MathOptimization opt = MathOptimization::Safe>
-static inline SimdFloat gmx_simdcall exp(SimdFloat x)
-{
- const __m512 argscale = _mm512_set1_ps(1.44269504088896341F);
- const __m512 invargscale = _mm512_set1_ps(-0.69314718055994528623F);
-
- if (opt == MathOptimization::Safe)
- {
- // Set the limit to gurantee flush to zero
- const SimdFloat smallArgLimit(-88.f);
- // Since we multiply the argument by 1.44, for the safe version we need to make
- // sure this doesn't result in overflow
- x = max(x, smallArgLimit);
- }
-
- __m512 xscaled = _mm512_mul_ps(x.simdInternal_, argscale);
- __m512 r = _mm512_exp223_ps(
- _mm512_cvtfxpnt_round_adjustps_epi32(xscaled, _MM_ROUND_MODE_NEAREST, _MM_EXPADJ_24));
-
- // exp2a23_ps provides 23 bits of accuracy, but we ruin some of that with our argument
- // scaling. To correct this, we find the difference between the scaled argument and
- // the true one (extended precision arithmetics does not appear to be necessary to
- // fulfill our accuracy requirements) and then multiply by the exponent of this
- // correction since exp(a+b)=exp(a)*exp(b).
- // Note that this only adds two instructions (and maybe some constant loads).
-
- // find the difference
- x = _mm512_fmadd_ps(invargscale, xscaled, x.simdInternal_);
- // x will now be a _very_ small number, so approximate exp(x)=1+x.
- // We should thus apply the correction as r'=r*(1+x)=r+r*x
- r = _mm512_fmadd_ps(r, x.simdInternal_, r);
- return { r };
-}
-
-static inline SimdFloat gmx_simdcall log(SimdFloat x)
-{
- return { _mm512_mul_ps(_mm512_set1_ps(0.693147180559945286226764F),
- _mm512_log2ae23_ps(x.simdInternal_)) };
-}
-
-} // namespace gmx
-
-#endif // GMX_SIMD_IMPL_X86_MIC_SIMD_FLOAT_H
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 2014,2015,2016,2017,2018 by the GROMACS development team.
- * Copyright (c) 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.
- *
- * 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.
- */
-
-#ifndef GMX_SIMD_IMPL_X86_MIC_UTIL_DOUBLE_H
-#define GMX_SIMD_IMPL_X86_MIC_UTIL_DOUBLE_H
-
-#include "config.h"
-
-#include <cassert>
-#include <cstdint>
-
-#include <immintrin.h>
-
-#include "gromacs/utility/basedefinitions.h"
-
-#include "impl_x86_mic_simd_double.h"
-
-namespace gmx
-{
-
-namespace
-{
-/* This is an internal helper function used by decr3Hsimd(...).
- */
-inline void gmx_simdcall decrHsimd(double* m, SimdDouble a)
-{
- __m512d t;
-
- assert(std::size_t(m) % 32 == 0);
-
- t = _mm512_extload_pd(m, _MM_UPCONV_PD_NONE, _MM_BROADCAST_4X8, _MM_HINT_NONE);
- a.simdInternal_ = _mm512_add_pd(
- a.simdInternal_,
- _mm512_castps_pd(_mm512_permute4f128_ps(_mm512_castpd_ps(a.simdInternal_), _MM_PERM_BADC)));
- t = _mm512_sub_pd(t, a.simdInternal_);
- _mm512_mask_packstorelo_pd(m, _mm512_int2mask(0x0F), t);
-}
-} // namespace
-
-// On MIC it is better to use scatter operations, so we define the load routines
-// that use a SIMD offset variable first.
-
-template<int align>
-static inline void gmx_simdcall gatherLoadBySimdIntTranspose(const double* base,
- SimdDInt32 simdoffset,
- SimdDouble* v0,
- SimdDouble* v1,
- SimdDouble* v2,
- SimdDouble* v3)
-{
- assert((size_t)base % 32 == 0);
- assert(align % 4 == 0);
-
- // All instructions might be latency ~4 on MIC, so we use shifts where we
- // only need a single instruction (since the shift parameter is an immediate),
- // but multiplication otherwise.
- if (align == 4)
- {
- simdoffset.simdInternal_ = _mm512_slli_epi32(simdoffset.simdInternal_, 2);
- }
- else if (align == 8)
- {
- simdoffset.simdInternal_ = _mm512_slli_epi32(simdoffset.simdInternal_, 3);
- }
- else
- {
- simdoffset = simdoffset * SimdDInt32(align);
- }
-
- v0->simdInternal_ = _mm512_i32logather_pd(simdoffset.simdInternal_, base, sizeof(double));
- v1->simdInternal_ = _mm512_i32logather_pd(simdoffset.simdInternal_, base + 1, sizeof(double));
- v2->simdInternal_ = _mm512_i32logather_pd(simdoffset.simdInternal_, base + 2, sizeof(double));
- v3->simdInternal_ = _mm512_i32logather_pd(simdoffset.simdInternal_, base + 3, sizeof(double));
-}
-
-template<int align>
-static inline void gmx_simdcall gatherLoadUBySimdIntTranspose(const double* base,
- SimdDInt32 simdoffset,
- SimdDouble* v0,
- SimdDouble* v1)
-{
- // All instructions might be latency ~4 on MIC, so we use shifts where we
- // only need a single instruction (since the shift parameter is an immediate),
- // but multiplication otherwise.
- if (align == 2)
- {
- simdoffset.simdInternal_ = _mm512_slli_epi32(simdoffset.simdInternal_, 1);
- }
- else if (align == 4)
- {
- simdoffset.simdInternal_ = _mm512_slli_epi32(simdoffset.simdInternal_, 2);
- }
- else if (align == 8)
- {
- simdoffset.simdInternal_ = _mm512_slli_epi32(simdoffset.simdInternal_, 3);
- }
- else
- {
- simdoffset = simdoffset * SimdDInt32(align);
- }
-
- v0->simdInternal_ = _mm512_i32logather_pd(simdoffset.simdInternal_, base, sizeof(double));
- v1->simdInternal_ = _mm512_i32logather_pd(simdoffset.simdInternal_, base + 1, sizeof(double));
-}
-
-template<int align>
-static inline void gmx_simdcall gatherLoadBySimdIntTranspose(const double* base,
- SimdDInt32 simdoffset,
- SimdDouble* v0,
- SimdDouble* v1)
-{
- assert(std::size_t(base) % 16 == 0);
- assert(align % 2 == 0);
- gatherLoadUBySimdIntTranspose<align>(base, simdoffset, v0, v1);
-}
-
-
-template<int align>
-static inline void gmx_simdcall gatherLoadTranspose(const double* base,
- const std::int32_t offset[],
- SimdDouble* v0,
- SimdDouble* v1,
- SimdDouble* v2,
- SimdDouble* v3)
-{
- gatherLoadBySimdIntTranspose<align>(base, simdLoad(offset, SimdDInt32Tag()), v0, v1, v2, v3);
-}
-
-template<int align>
-static inline void gmx_simdcall
- gatherLoadTranspose(const double* base, const std::int32_t offset[], SimdDouble* v0, SimdDouble* v1)
-{
- gatherLoadBySimdIntTranspose<align>(base, simdLoad(offset, SimdDInt32Tag()), v0, v1);
-}
-
-static const int c_simdBestPairAlignmentDouble = 2;
-
-template<int align>
-static inline void gmx_simdcall gatherLoadUTranspose(const double* base,
- const std::int32_t offset[],
- SimdDouble* v0,
- SimdDouble* v1,
- SimdDouble* v2)
-{
- SimdDInt32 simdoffset;
-
- assert(std::size_t(offset) % 32 == 0);
-
- simdoffset = simdLoad(offset, SimdDInt32Tag());
-
- // All instructions might be latency ~4 on MIC, so we use shifts where we
- // only need a single instruction (since the shift parameter is an immediate),
- // but multiplication otherwise.
- if (align == 4)
- {
- simdoffset.simdInternal_ = _mm512_slli_epi32(simdoffset.simdInternal_, 2);
- }
- else if (align == 8)
- {
- simdoffset.simdInternal_ = _mm512_slli_epi32(simdoffset.simdInternal_, 3);
- }
- else
- {
- simdoffset = simdoffset * SimdDInt32(align);
- }
-
- v0->simdInternal_ = _mm512_i32logather_pd(simdoffset.simdInternal_, base, sizeof(double));
- v1->simdInternal_ = _mm512_i32logather_pd(simdoffset.simdInternal_, base + 1, sizeof(double));
- v2->simdInternal_ = _mm512_i32logather_pd(simdoffset.simdInternal_, base + 2, sizeof(double));
-}
-
-template<int align>
-static inline void gmx_simdcall transposeScatterStoreU(double* base,
- const std::int32_t offset[],
- SimdDouble v0,
- SimdDouble v1,
- SimdDouble v2)
-{
- SimdDInt32 simdoffset;
-
- assert(std::size_t(offset) % 32 == 0);
-
- simdoffset = simdLoad(offset, SimdDInt32Tag());
-
- // All instructions might be latency ~4 on MIC, so we use shifts where we
- // only need a single instruction (since the shift parameter is an immediate),
- // but multiplication otherwise.
- if (align == 4)
- {
- simdoffset.simdInternal_ = _mm512_slli_epi32(simdoffset.simdInternal_, 2);
- }
- else if (align == 8)
- {
- simdoffset.simdInternal_ = _mm512_slli_epi32(simdoffset.simdInternal_, 3);
- }
- else
- {
- simdoffset = simdoffset * SimdDInt32(align);
- }
-
- _mm512_i32loscatter_pd(base, simdoffset.simdInternal_, v0.simdInternal_, sizeof(double));
- _mm512_i32loscatter_pd(base + 1, simdoffset.simdInternal_, v1.simdInternal_, sizeof(double));
- _mm512_i32loscatter_pd(base + 2, simdoffset.simdInternal_, v2.simdInternal_, sizeof(double));
-}
-
-template<int align>
-static inline void gmx_simdcall
- transposeScatterIncrU(double* base, const std::int32_t offset[], SimdDouble v0, SimdDouble v1, SimdDouble v2)
-{
- alignas(GMX_SIMD_ALIGNMENT) double rdata0[GMX_SIMD_DOUBLE_WIDTH];
- alignas(GMX_SIMD_ALIGNMENT) double rdata1[GMX_SIMD_DOUBLE_WIDTH];
- alignas(GMX_SIMD_ALIGNMENT) double rdata2[GMX_SIMD_DOUBLE_WIDTH];
-
- store(rdata0, v0);
- store(rdata1, v1);
- store(rdata2, v2);
-
- for (int i = 0; i < GMX_SIMD_DOUBLE_WIDTH; i++)
- {
- base[align * offset[i] + 0] += rdata0[i];
- base[align * offset[i] + 1] += rdata1[i];
- base[align * offset[i] + 2] += rdata2[i];
- }
-}
-
-template<int align>
-static inline void gmx_simdcall
- transposeScatterDecrU(double* base, const std::int32_t offset[], SimdDouble v0, SimdDouble v1, SimdDouble v2)
-{
- alignas(GMX_SIMD_ALIGNMENT) double rdata0[GMX_SIMD_DOUBLE_WIDTH];
- alignas(GMX_SIMD_ALIGNMENT) double rdata1[GMX_SIMD_DOUBLE_WIDTH];
- alignas(GMX_SIMD_ALIGNMENT) double rdata2[GMX_SIMD_DOUBLE_WIDTH];
-
- store(rdata0, v0);
- store(rdata1, v1);
- store(rdata2, v2);
-
- for (int i = 0; i < GMX_SIMD_DOUBLE_WIDTH; i++)
- {
- base[align * offset[i] + 0] -= rdata0[i];
- base[align * offset[i] + 1] -= rdata1[i];
- base[align * offset[i] + 2] -= rdata2[i];
- }
-}
-
-static inline void gmx_simdcall expandScalarsToTriplets(SimdDouble scalar,
- SimdDouble* triplets0,
- SimdDouble* triplets1,
- SimdDouble* triplets2)
-{
- triplets0->simdInternal_ = _mm512_castsi512_pd(
- _mm512_permutevar_epi32(_mm512_set_epi32(5, 4, 5, 4, 3, 2, 3, 2, 3, 2, 1, 0, 1, 0, 1, 0),
- _mm512_castpd_si512(scalar.simdInternal_)));
- triplets1->simdInternal_ = _mm512_castsi512_pd(_mm512_permutevar_epi32(
- _mm512_set_epi32(11, 10, 9, 8, 9, 8, 9, 8, 7, 6, 7, 6, 7, 6, 5, 4),
- _mm512_castpd_si512(scalar.simdInternal_)));
- triplets2->simdInternal_ = _mm512_castsi512_pd(_mm512_permutevar_epi32(
- _mm512_set_epi32(15, 14, 15, 14, 15, 14, 13, 12, 13, 12, 13, 12, 11, 10, 11, 10),
- _mm512_castpd_si512(scalar.simdInternal_)));
-}
-
-
-static inline double gmx_simdcall
- reduceIncr4ReturnSum(double* m, SimdDouble v0, SimdDouble v1, SimdDouble v2, SimdDouble v3)
-{
- double d;
- __m512d t0, t1, t2, t3;
-
- assert(std::size_t(m) % 32 == 0);
-
- t0 = _mm512_swizzle_pd(_mm512_mask_blend_pd(_mm512_int2mask(0x33), v0.simdInternal_, v2.simdInternal_),
- _MM_SWIZ_REG_BADC);
- t2 = _mm512_mask_blend_pd(_mm512_int2mask(0x33), v2.simdInternal_, v0.simdInternal_);
- t1 = _mm512_swizzle_pd(_mm512_mask_blend_pd(_mm512_int2mask(0x33), v1.simdInternal_, v3.simdInternal_),
- _MM_SWIZ_REG_BADC);
- t3 = _mm512_mask_blend_pd(_mm512_int2mask(0x33), v3.simdInternal_, v1.simdInternal_);
- t0 = _mm512_add_pd(t0, t2);
- t1 = _mm512_add_pd(t1, t3);
-
- t2 = _mm512_swizzle_pd(_mm512_mask_blend_pd(_mm512_int2mask(0b01010101), t0, t1), _MM_SWIZ_REG_CDAB);
- t3 = _mm512_mask_blend_pd(_mm512_int2mask(0b01010101), t1, t0);
- t2 = _mm512_add_pd(t2, t3);
-
- t2 = _mm512_add_pd(t2, _mm512_castps_pd(_mm512_permute4f128_ps(_mm512_castpd_ps(t2), _MM_PERM_BADC)));
-
- t0 = _mm512_mask_extload_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), m, _MM_UPCONV_PD_NONE,
- _MM_BROADCAST_4X8, _MM_HINT_NONE);
- t0 = _mm512_add_pd(t0, t2);
- _mm512_mask_packstorelo_pd(m, _mm512_int2mask(0xF), t0);
-
- t2 = _mm512_add_pd(t2, _mm512_swizzle_pd(t2, _MM_SWIZ_REG_BADC));
- t2 = _mm512_add_pd(t2, _mm512_swizzle_pd(t2, _MM_SWIZ_REG_CDAB));
-
- _mm512_mask_packstorelo_pd(&d, _mm512_mask2int(0x01), t2);
- return d;
-}
-
-static inline SimdDouble gmx_simdcall loadDualHsimd(const double* m0, const double* m1)
-{
- assert(std::size_t(m0) % 32 == 0);
- assert(std::size_t(m1) % 32 == 0);
-
- return _mm512_mask_extload_pd(
- _mm512_extload_pd(m0, _MM_UPCONV_PD_NONE, _MM_BROADCAST_4X8, _MM_HINT_NONE),
- _mm512_int2mask(0xF0), m1, _MM_UPCONV_PD_NONE, _MM_BROADCAST_4X8, _MM_HINT_NONE);
-}
-
-static inline SimdDouble gmx_simdcall loadDuplicateHsimd(const double* m)
-{
- assert(std::size_t(m) % 32 == 0);
-
- return _mm512_extload_pd(m, _MM_UPCONV_PD_NONE, _MM_BROADCAST_4X8, _MM_HINT_NONE);
-}
-
-static inline SimdDouble gmx_simdcall loadU1DualHsimd(const double* m)
-{
- return _mm512_mask_extload_pd(
- _mm512_extload_pd(m, _MM_UPCONV_PD_NONE, _MM_BROADCAST_1X8, _MM_HINT_NONE),
- _mm512_int2mask(0xF0), m + 1, _MM_UPCONV_PD_NONE, _MM_BROADCAST_1X8, _MM_HINT_NONE);
-}
-
-
-static inline void gmx_simdcall storeDualHsimd(double* m0, double* m1, SimdDouble a)
-{
- assert(std::size_t(m0) % 32 == 0);
- assert(std::size_t(m1) % 32 == 0);
-
- _mm512_mask_packstorelo_pd(m0, _mm512_int2mask(0x0F), a.simdInternal_);
- _mm512_mask_packstorelo_pd(m1, _mm512_int2mask(0xF0), a.simdInternal_);
-}
-
-static inline void gmx_simdcall incrDualHsimd(double* m0, double* m1, SimdDouble a)
-{
- assert(std::size_t(m0) % 32 == 0);
- assert(std::size_t(m1) % 32 == 0);
-
- __m512d x;
-
- // Update lower half
- x = _mm512_extload_pd(m0, _MM_UPCONV_PD_NONE, _MM_BROADCAST_4X8, _MM_HINT_NONE);
- x = _mm512_add_pd(x, a.simdInternal_);
- _mm512_mask_packstorelo_pd(m0, _mm512_int2mask(0x0F), x);
-
- // Update upper half
- x = _mm512_extload_pd(m1, _MM_UPCONV_PD_NONE, _MM_BROADCAST_4X8, _MM_HINT_NONE);
- x = _mm512_add_pd(x, a.simdInternal_);
- _mm512_mask_packstorelo_pd(m1, _mm512_int2mask(0xF0), x);
-}
-
-static inline void gmx_simdcall decr3Hsimd(double* m, SimdDouble a0, SimdDouble a1, SimdDouble a2)
-{
- assert(std::size_t(m) % 32 == 0);
- decrHsimd(m, a0);
- decrHsimd(m + GMX_SIMD_DOUBLE_WIDTH / 2, a1);
- decrHsimd(m + GMX_SIMD_DOUBLE_WIDTH, a2);
-}
-
-
-template<int align>
-static inline void gmx_simdcall gatherLoadTransposeHsimd(const double* base0,
- const double* base1,
- const std::int32_t offset[],
- SimdDouble* v0,
- SimdDouble* v1)
-{
- __m512i idx0, idx1, idx;
- __m512d tmp1, tmp2;
-
- assert(std::size_t(offset) % 16 == 0);
- assert(std::size_t(base0) % 16 == 0);
- assert(std::size_t(base1) % 16 == 0);
- assert(std::size_t(align) % 2 == 0);
-
- idx0 = _mm512_extload_epi32(offset, _MM_UPCONV_EPI32_NONE, _MM_BROADCAST_4X16, _MM_HINT_NONE);
-
- idx0 = _mm512_mullo_epi32(idx0, _mm512_set1_epi32(align));
- idx1 = _mm512_add_epi32(idx0, _mm512_set1_epi32(1));
-
- idx = _mm512_mask_permute4f128_epi32(idx0, _mm512_int2mask(0x00F0), idx1, _MM_PERM_AAAA);
-
- tmp1 = _mm512_i32logather_pd(idx, base0, sizeof(double));
- tmp2 = _mm512_i32logather_pd(idx, base1, sizeof(double));
-
- v0->simdInternal_ = _mm512_castps_pd(_mm512_mask_permute4f128_ps(
- _mm512_castpd_ps(tmp1), _mm512_int2mask(0xFF00), _mm512_castpd_ps(tmp2), _MM_PERM_BABA));
- v1->simdInternal_ = _mm512_castps_pd(_mm512_mask_permute4f128_ps(
- _mm512_castpd_ps(tmp2), _mm512_int2mask(0x00FF), _mm512_castpd_ps(tmp1), _MM_PERM_DCDC));
-}
-
-static inline double gmx_simdcall reduceIncr4ReturnSumHsimd(double* m, SimdDouble v0, SimdDouble v1)
-{
- double d;
- __m512d t0, t1;
-
- assert(std::size_t(m) % 32 == 0);
-
- t0 = _mm512_add_pd(v0.simdInternal_, _mm512_swizzle_pd(v0.simdInternal_, _MM_SWIZ_REG_BADC));
- t0 = _mm512_mask_add_pd(t0, _mm512_int2mask(0xCC), v1.simdInternal_,
- _mm512_swizzle_pd(v1.simdInternal_, _MM_SWIZ_REG_BADC));
- t0 = _mm512_add_pd(t0, _mm512_swizzle_pd(t0, _MM_SWIZ_REG_CDAB));
- t0 = _mm512_castps_pd(_mm512_mask_permute4f128_ps(_mm512_castpd_ps(t0), _mm512_int2mask(0xCCCC),
- _mm512_castpd_ps(t0), _MM_PERM_DCDC));
-
- t1 = _mm512_mask_extload_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), m, _MM_UPCONV_PD_NONE,
- _MM_BROADCAST_4X8, _MM_HINT_NONE);
- t1 = _mm512_add_pd(t1, t0);
- _mm512_mask_packstorelo_pd(m, _mm512_int2mask(0xF), t1);
-
- t0 = _mm512_add_pd(t0, _mm512_swizzle_pd(t0, _MM_SWIZ_REG_BADC));
- t0 = _mm512_add_pd(t0, _mm512_swizzle_pd(t0, _MM_SWIZ_REG_CDAB));
-
- _mm512_mask_packstorelo_pd(&d, _mm512_mask2int(0x03), t0);
- return d;
-}
-
-} // namespace gmx
-
-#endif // GMX_SIMD_IMPL_X86_MIC_UTIL_DOUBLE_H
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 2014,2015,2016,2017,2018 by the GROMACS development team.
- * Copyright (c) 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.
- *
- * 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.
- */
-
-#ifndef GMX_SIMD_IMPL_X86_MIC_UTIL_FLOAT_H
-#define GMX_SIMD_IMPL_X86_MIC_UTIL_FLOAT_H
-
-#include "config.h"
-
-#include <cassert>
-#include <cstdint>
-
-#include <immintrin.h>
-
-#include "gromacs/utility/basedefinitions.h"
-
-#include "impl_x86_mic_simd_float.h"
-
-namespace gmx
-{
-
-namespace
-{
-/* This is an internal helper function used by decr3Hsimd(...).
- */
-inline void gmx_simdcall decrHsimd(float* m, SimdFloat a)
-{
- __m512 t;
-
- assert(std::size_t(m) % 32 == 0);
-
- t = _mm512_castpd_ps(_mm512_extload_pd(reinterpret_cast<const double*>(m), _MM_UPCONV_PD_NONE,
- _MM_BROADCAST_4X8, _MM_HINT_NONE));
- a = _mm512_add_ps(a.simdInternal_, _mm512_permute4f128_ps(a.simdInternal_, _MM_PERM_BADC));
- t = _mm512_sub_ps(t, a.simdInternal_);
- _mm512_mask_packstorelo_ps(m, _mm512_int2mask(0x00FF), t);
-}
-} // namespace
-
-// On MIC it is better to use scatter operations, so we define the load routines
-// that use a SIMD offset variable first.
-
-template<int align>
-static inline void gmx_simdcall gatherLoadBySimdIntTranspose(const float* base,
- SimdFInt32 simdoffset,
- SimdFloat* v0,
- SimdFloat* v1,
- SimdFloat* v2,
- SimdFloat* v3)
-{
- assert(std::size_t(base) % 16 == 0);
- assert(align % 4 == 0);
-
- // All instructions might be latency ~4 on MIC, so we use shifts where we
- // only need a single instruction (since the shift parameter is an immediate),
- // but multiplication otherwise.
- if (align == 4)
- {
- simdoffset.simdInternal_ = _mm512_slli_epi32(simdoffset.simdInternal_, 2);
- }
- else if (align == 8)
- {
- simdoffset.simdInternal_ = _mm512_slli_epi32(simdoffset.simdInternal_, 3);
- }
- else
- {
- simdoffset = simdoffset * SimdFInt32(align);
- }
-
- v0->simdInternal_ = _mm512_i32gather_ps(simdoffset.simdInternal_, base, sizeof(float));
- v1->simdInternal_ = _mm512_i32gather_ps(simdoffset.simdInternal_, base + 1, sizeof(float));
- v2->simdInternal_ = _mm512_i32gather_ps(simdoffset.simdInternal_, base + 2, sizeof(float));
- v3->simdInternal_ = _mm512_i32gather_ps(simdoffset.simdInternal_, base + 3, sizeof(float));
-}
-
-template<int align>
-static inline void gmx_simdcall
- gatherLoadUBySimdIntTranspose(const float* base, SimdFInt32 simdoffset, SimdFloat* v0, SimdFloat* v1)
-{
- // All instructions might be latency ~4 on MIC, so we use shifts where we
- // only need a single instruction (since the shift parameter is an immediate),
- // but multiplication otherwise.
- // For align == 2 we can merge the constant into the scale parameter,
- // which can take constants up to 8 in total.
- if (align == 2)
- {
- v0->simdInternal_ = _mm512_i32gather_ps(simdoffset.simdInternal_, base, align * sizeof(float));
- v1->simdInternal_ =
- _mm512_i32gather_ps(simdoffset.simdInternal_, base + 1, align * sizeof(float));
- }
- else
- {
- if (align == 4)
- {
- simdoffset.simdInternal_ = _mm512_slli_epi32(simdoffset.simdInternal_, 2);
- }
- else if (align == 8)
- {
- simdoffset.simdInternal_ = _mm512_slli_epi32(simdoffset.simdInternal_, 3);
- }
- else
- {
- simdoffset = simdoffset * SimdFInt32(align);
- }
- v0->simdInternal_ = _mm512_i32gather_ps(simdoffset.simdInternal_, base, sizeof(float));
- v1->simdInternal_ = _mm512_i32gather_ps(simdoffset.simdInternal_, base + 1, sizeof(float));
- }
-}
-
-template<int align>
-static inline void gmx_simdcall
- gatherLoadBySimdIntTranspose(const float* base, SimdFInt32 simdoffset, SimdFloat* v0, SimdFloat* v1)
-{
- assert(std::size_t(base) % 8 == 0);
- assert(align % 2 == 0);
- gatherLoadUBySimdIntTranspose<align>(base, simdoffset, v0, v1);
-}
-
-template<int align>
-static inline void gmx_simdcall gatherLoadTranspose(const float* base,
- const std::int32_t offset[],
- SimdFloat* v0,
- SimdFloat* v1,
- SimdFloat* v2,
- SimdFloat* v3)
-{
- gatherLoadBySimdIntTranspose<align>(base, simdLoad(offset, SimdFInt32Tag()), v0, v1, v2, v3);
-}
-
-template<int align>
-static inline void gmx_simdcall
- gatherLoadTranspose(const float* base, const std::int32_t offset[], SimdFloat* v0, SimdFloat* v1)
-{
- gatherLoadBySimdIntTranspose<align>(base, simdLoad(offset, SimdFInt32Tag()), v0, v1);
-}
-
-static const int c_simdBestPairAlignmentFloat = 2;
-
-template<int align>
-static inline void gmx_simdcall gatherLoadUTranspose(const float* base,
- const std::int32_t offset[],
- SimdFloat* v0,
- SimdFloat* v1,
- SimdFloat* v2)
-{
- SimdFInt32 simdoffset;
-
- assert(std::size_t(offset) % 64 == 0);
-
- simdoffset = simdLoad(offset, SimdFInt32Tag());
-
- // All instructions might be latency ~4 on MIC, so we use shifts where we
- // only need a single instruction (since the shift parameter is an immediate),
- // but multiplication otherwise.
- if (align == 4)
- {
- simdoffset.simdInternal_ = _mm512_slli_epi32(simdoffset.simdInternal_, 2);
- }
- else if (align == 8)
- {
- simdoffset.simdInternal_ = _mm512_slli_epi32(simdoffset.simdInternal_, 3);
- }
- else
- {
- simdoffset = simdoffset * SimdFInt32(align);
- }
-
- v0->simdInternal_ = _mm512_i32gather_ps(simdoffset.simdInternal_, base, sizeof(float));
- v1->simdInternal_ = _mm512_i32gather_ps(simdoffset.simdInternal_, base + 1, sizeof(float));
- v2->simdInternal_ = _mm512_i32gather_ps(simdoffset.simdInternal_, base + 2, sizeof(float));
-}
-
-
-template<int align>
-static inline void gmx_simdcall
- transposeScatterStoreU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2)
-{
- SimdFInt32 simdoffset;
-
- assert(std::size_t(offset) % 64 == 0);
-
- simdoffset = simdLoad(offset, SimdFInt32Tag());
-
- // All instructions might be latency ~4 on MIC, so we use shifts where we
- // only need a single instruction (since the shift parameter is an immediate),
- // but multiplication otherwise.
- if (align == 4)
- {
- simdoffset.simdInternal_ = _mm512_slli_epi32(simdoffset.simdInternal_, 2);
- }
- else if (align == 8)
- {
- simdoffset.simdInternal_ = _mm512_slli_epi32(simdoffset.simdInternal_, 3);
- }
- else
- {
- simdoffset = simdoffset * SimdFInt32(align);
- }
-
- _mm512_i32scatter_ps(base, simdoffset.simdInternal_, v0.simdInternal_, sizeof(float));
- _mm512_i32scatter_ps(base + 1, simdoffset.simdInternal_, v1.simdInternal_, sizeof(float));
- _mm512_i32scatter_ps(base + 2, simdoffset.simdInternal_, v2.simdInternal_, sizeof(float));
-}
-
-
-template<int align>
-static inline void gmx_simdcall
- transposeScatterIncrU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2)
-{
- alignas(GMX_SIMD_ALIGNMENT) float rdata0[GMX_SIMD_FLOAT_WIDTH];
- alignas(GMX_SIMD_ALIGNMENT) float rdata1[GMX_SIMD_FLOAT_WIDTH];
- alignas(GMX_SIMD_ALIGNMENT) float rdata2[GMX_SIMD_FLOAT_WIDTH];
-
- store(rdata0, v0);
- store(rdata1, v1);
- store(rdata2, v2);
-
- for (int i = 0; i < GMX_SIMD_FLOAT_WIDTH; i++)
- {
- base[align * offset[i] + 0] += rdata0[i];
- base[align * offset[i] + 1] += rdata1[i];
- base[align * offset[i] + 2] += rdata2[i];
- }
-}
-
-template<int align>
-static inline void gmx_simdcall
- transposeScatterDecrU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2)
-{
- alignas(GMX_SIMD_ALIGNMENT) float rdata0[GMX_SIMD_FLOAT_WIDTH];
- alignas(GMX_SIMD_ALIGNMENT) float rdata1[GMX_SIMD_FLOAT_WIDTH];
- alignas(GMX_SIMD_ALIGNMENT) float rdata2[GMX_SIMD_FLOAT_WIDTH];
-
- store(rdata0, v0);
- store(rdata1, v1);
- store(rdata2, v2);
-
- for (int i = 0; i < GMX_SIMD_FLOAT_WIDTH; i++)
- {
- base[align * offset[i] + 0] -= rdata0[i];
- base[align * offset[i] + 1] -= rdata1[i];
- base[align * offset[i] + 2] -= rdata2[i];
- }
-}
-
-static inline void gmx_simdcall expandScalarsToTriplets(SimdFloat scalar,
- SimdFloat* triplets0,
- SimdFloat* triplets1,
- SimdFloat* triplets2)
-{
- triplets0->simdInternal_ = _mm512_castsi512_ps(
- _mm512_permutevar_epi32(_mm512_set_epi32(5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 1, 1, 1, 0, 0, 0),
- _mm512_castps_si512(scalar.simdInternal_)));
- triplets1->simdInternal_ = _mm512_castsi512_ps(_mm512_permutevar_epi32(
- _mm512_set_epi32(10, 10, 9, 9, 9, 8, 8, 8, 7, 7, 7, 6, 6, 6, 5, 5),
- _mm512_castps_si512(scalar.simdInternal_)));
- triplets2->simdInternal_ = _mm512_castsi512_ps(_mm512_permutevar_epi32(
- _mm512_set_epi32(15, 15, 15, 14, 14, 14, 13, 13, 13, 12, 12, 12, 11, 11, 11, 10),
- _mm512_castps_si512(scalar.simdInternal_)));
-}
-
-
-static inline float gmx_simdcall reduceIncr4ReturnSum(float* m, SimdFloat v0, SimdFloat v1, SimdFloat v2, SimdFloat v3)
-{
- float f;
- __m512 t0, t1, t2, t3;
-
- assert(std::size_t(m) % 16 == 0);
-
- t0 = _mm512_add_ps(v0.simdInternal_, _mm512_swizzle_ps(v0.simdInternal_, _MM_SWIZ_REG_BADC));
- t0 = _mm512_mask_add_ps(t0, _mm512_int2mask(0xCCCC), v2.simdInternal_,
- _mm512_swizzle_ps(v2.simdInternal_, _MM_SWIZ_REG_BADC));
- t1 = _mm512_add_ps(v1.simdInternal_, _mm512_swizzle_ps(v1.simdInternal_, _MM_SWIZ_REG_BADC));
- t1 = _mm512_mask_add_ps(t1, _mm512_int2mask(0xCCCC), v3.simdInternal_,
- _mm512_swizzle_ps(v3.simdInternal_, _MM_SWIZ_REG_BADC));
- t2 = _mm512_add_ps(t0, _mm512_swizzle_ps(t0, _MM_SWIZ_REG_CDAB));
- t2 = _mm512_mask_add_ps(t2, _mm512_int2mask(0xAAAA), t1, _mm512_swizzle_ps(t1, _MM_SWIZ_REG_CDAB));
-
- t2 = _mm512_add_ps(t2, _mm512_permute4f128_ps(t2, _MM_PERM_BADC));
- t2 = _mm512_add_ps(t2, _mm512_permute4f128_ps(t2, _MM_PERM_CDAB));
-
- t0 = _mm512_mask_extload_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), m, _MM_UPCONV_PS_NONE,
- _MM_BROADCAST_4X16, _MM_HINT_NONE);
- t0 = _mm512_add_ps(t0, t2);
- _mm512_mask_packstorelo_ps(m, _mm512_int2mask(0xF), t0);
-
- t2 = _mm512_add_ps(t2, _mm512_swizzle_ps(t2, _MM_SWIZ_REG_BADC));
- t2 = _mm512_add_ps(t2, _mm512_swizzle_ps(t2, _MM_SWIZ_REG_CDAB));
-
- _mm512_mask_packstorelo_ps(&f, _mm512_mask2int(0x1), t2);
- return f;
-}
-
-static inline SimdFloat gmx_simdcall loadDualHsimd(const float* m0, const float* m1)
-{
- assert(std::size_t(m0) % 32 == 0);
- assert(std::size_t(m1) % 32 == 0);
-
- return _mm512_castpd_ps(_mm512_mask_extload_pd(
- _mm512_extload_pd(reinterpret_cast<const double*>(m0), _MM_UPCONV_PD_NONE,
- _MM_BROADCAST_4X8, _MM_HINT_NONE),
- _mm512_int2mask(0xF0), reinterpret_cast<const double*>(m1), _MM_UPCONV_PD_NONE,
- _MM_BROADCAST_4X8, _MM_HINT_NONE));
-}
-
-static inline SimdFloat gmx_simdcall loadDuplicateHsimd(const float* m)
-{
- assert(std::size_t(m) % 32 == 0);
-
- return _mm512_castpd_ps(_mm512_extload_pd(reinterpret_cast<const double*>(m),
- _MM_UPCONV_PD_NONE, _MM_BROADCAST_4X8, _MM_HINT_NONE));
-}
-
-static inline SimdFloat gmx_simdcall loadU1DualHsimd(const float* m)
-{
- return _mm512_mask_extload_ps(
- _mm512_extload_ps(m, _MM_UPCONV_PS_NONE, _MM_BROADCAST_1X16, _MM_HINT_NONE),
- _mm512_int2mask(0xFF00), m + 1, _MM_UPCONV_PS_NONE, _MM_BROADCAST_1X16, _MM_HINT_NONE);
-}
-
-
-static inline void gmx_simdcall storeDualHsimd(float* m0, float* m1, SimdFloat a)
-{
- __m512 t0;
-
- assert(std::size_t(m0) % 32 == 0);
- assert(std::size_t(m1) % 32 == 0);
-
- _mm512_mask_packstorelo_ps(m0, _mm512_int2mask(0x00FF), a.simdInternal_);
- _mm512_mask_packstorelo_ps(m1, _mm512_int2mask(0xFF00), a.simdInternal_);
-}
-
-static inline void gmx_simdcall incrDualHsimd(float* m0, float* m1, SimdFloat a)
-{
- assert(std::size_t(m0) % 32 == 0);
- assert(std::size_t(m1) % 32 == 0);
-
- __m512 x;
-
- // Update lower half
- x = _mm512_castpd_ps(_mm512_extload_pd(reinterpret_cast<const double*>(m0), _MM_UPCONV_PD_NONE,
- _MM_BROADCAST_4X8, _MM_HINT_NONE));
- x = _mm512_add_ps(x, a.simdInternal_);
- _mm512_mask_packstorelo_ps(m0, _mm512_int2mask(0x00FF), x);
-
- // Update upper half
- x = _mm512_castpd_ps(_mm512_extload_pd(reinterpret_cast<const double*>(m1), _MM_UPCONV_PD_NONE,
- _MM_BROADCAST_4X8, _MM_HINT_NONE));
- x = _mm512_add_ps(x, a.simdInternal_);
- _mm512_mask_packstorelo_ps(m1, _mm512_int2mask(0xFF00), x);
-}
-
-static inline void gmx_simdcall decr3Hsimd(float* m, SimdFloat a0, SimdFloat a1, SimdFloat a2)
-{
- assert(std::size_t(m) % 32 == 0);
- decrHsimd(m, a0);
- decrHsimd(m + GMX_SIMD_FLOAT_WIDTH / 2, a1);
- decrHsimd(m + GMX_SIMD_FLOAT_WIDTH, a2);
-}
-
-
-template<int align>
-static inline void gmx_simdcall gatherLoadTransposeHsimd(const float* base0,
- const float* base1,
- const std::int32_t offset[],
- SimdFloat* v0,
- SimdFloat* v1)
-{
- __m512i idx0, idx1, idx;
- __m512 tmp1, tmp2;
-
- assert(std::size_t(offset) % 32 == 0);
- assert(std::size_t(base0) % 8 == 0);
- assert(std::size_t(base1) % 8 == 0);
- assert(std::size_t(align) % 2 == 0);
-
- idx0 = _mm512_loadunpacklo_epi32(_mm512_undefined_epi32(), offset);
-
- idx0 = _mm512_mullo_epi32(idx0, _mm512_set1_epi32(align));
- idx1 = _mm512_add_epi32(idx0, _mm512_set1_epi32(1));
-
- idx = _mm512_mask_permute4f128_epi32(idx0, _mm512_int2mask(0xFF00), idx1, _MM_PERM_BABA);
-
- tmp1 = _mm512_i32gather_ps(idx, base0, sizeof(float));
- tmp2 = _mm512_i32gather_ps(idx, base1, sizeof(float));
-
- v0->simdInternal_ = _mm512_mask_permute4f128_ps(tmp1, _mm512_int2mask(0xFF00), tmp2, _MM_PERM_BABA);
- v1->simdInternal_ = _mm512_mask_permute4f128_ps(tmp2, _mm512_int2mask(0x00FF), tmp1, _MM_PERM_DCDC);
-}
-
-static inline float gmx_simdcall reduceIncr4ReturnSumHsimd(float* m, SimdFloat v0, SimdFloat v1)
-{
- float f;
- __m512 t0, t1;
-
- assert(std::size_t(m) % 32 == 0);
-
- t0 = _mm512_add_ps(v0.simdInternal_, _mm512_swizzle_ps(v0.simdInternal_, _MM_SWIZ_REG_BADC));
- t0 = _mm512_mask_add_ps(t0, _mm512_int2mask(0xCCCC), v1.simdInternal_,
- _mm512_swizzle_ps(v1.simdInternal_, _MM_SWIZ_REG_BADC));
- t0 = _mm512_add_ps(t0, _mm512_swizzle_ps(t0, _MM_SWIZ_REG_CDAB));
- t0 = _mm512_add_ps(t0, _mm512_castpd_ps(_mm512_swizzle_pd(_mm512_castps_pd(t0), _MM_SWIZ_REG_BADC)));
- t0 = _mm512_mask_permute4f128_ps(t0, _mm512_int2mask(0xAAAA), t0, _MM_PERM_BADC);
- t1 = _mm512_mask_extload_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), m, _MM_UPCONV_PS_NONE,
- _MM_BROADCAST_4X16, _MM_HINT_NONE);
- t1 = _mm512_add_ps(t1, t0);
- _mm512_mask_packstorelo_ps(m, _mm512_int2mask(0xF), t1);
-
- t0 = _mm512_add_ps(t0, _mm512_swizzle_ps(t0, _MM_SWIZ_REG_BADC));
- t0 = _mm512_add_ps(t0, _mm512_swizzle_ps(t0, _MM_SWIZ_REG_CDAB));
-
- _mm512_mask_packstorelo_ps(&f, _mm512_mask2int(0x1), t0);
- return f;
-}
-
-} // namespace gmx
-
-#endif // GMX_SIMD_IMPL_X86_MIC_UTIL_FLOAT_H
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2016,2017,2018,2019,2020, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
return m != 0.0F ? (a * b + c) : 0.0F;
}
+/*! \brief Float 1.0/x, masked version.
+ *
+ * \param x Argument, x>0 for entries where mask is true.
+ * \param m Mask
+ * \return 1/x. The result for masked-out entries will be 0.0.
+ *
+ * \note This function might be superficially meaningless, but it helps us to
+ * write templated SIMD/non-SIMD code. For clarity it should not be used
+ * outside such code.
+ */
+static inline float gmx_simdcall maskzRcp(float x, float m)
+{
+ return m != 0.0F ? 1.0F / x : 0.0F;
+}
+
/*! \brief Float Floating-point abs().
*
* \param a any floating point values
return m != 0.0 ? (a * b + c) : 0.0;
}
+/*! \brief Double 1.0/x, masked version.
+ *
+ * \param x Argument, x>0 for entries where mask is true.
+ * \param m Mask
+ * \return Approximation of 1/x. The result for masked-out entries will be 0.0.
+ *
+ * \note This function might be superficially meaningless, but it helps us to
+ * write templated SIMD/non-SIMD code. For clarity it should not be used
+ * outside such code.
+ */
+static inline double gmx_simdcall maskzRcp(double x, double m)
+{
+ return m != 0.0 ? 1.0 / x : 0.0;
+}
+
/*! \brief double doubleing-point abs().
*
* \param a any doubleing point values
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2017,2019, by the GROMACS development team, led by
+ * Copyright (c) 2016,2017,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.
return std::sqrt(x);
}
+/*! \brief Float cbrt(x). This is the cubic root.
+ *
+ * \param x Argument, should be >= 0.
+ * \result The cubic root of x. Undefined if argument is invalid.
+ *
+ * \note This function might be superficially meaningless, but it helps us to
+ * write templated SIMD/non-SIMD code. For clarity it should not be used
+ * outside such code.
+ */
+template<MathOptimization opt = MathOptimization::Safe>
+static inline float cbrt(float x)
+{
+ return std::cbrt(x);
+}
+
/*! \brief Float log(x). This is the natural logarithm.
*
* \param x Argument, should be >0.
return std::sqrt(x);
}
+/*! \brief Double cbrt(x). This is the cubic root.
+ *
+ * \param x Argument, should be >= 0.
+ * \result The cubic root of x. Undefined if argument is invalid.
+ *
+ * \note This function might be superficially meaningless, but it helps us to
+ * write templated SIMD/non-SIMD code. For clarity it should not be used
+ * outside such code.
+ */
+template<MathOptimization opt = MathOptimization::Safe>
+static inline double cbrt(double x)
+{
+ return std::cbrt(x);
+}
+
/*! \brief Double log(x). This is the natural logarithm.
*
* \param x Argument, should be >0.
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <cstdint>
#include <array>
+#include <memory>
#include <type_traits>
#include "gromacs/utility/basedefinitions.h"
-#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/real.h"
//! \cond libapi
# include "impl_x86_avx2_256/impl_x86_avx2_256.h"
#elif GMX_SIMD_X86_AVX2_128
# include "impl_x86_avx2_128/impl_x86_avx2_128.h"
-#elif GMX_SIMD_X86_MIC
-# include "impl_x86_mic/impl_x86_mic.h"
#elif GMX_SIMD_X86_AVX_512
# include "impl_x86_avx_512/impl_x86_avx_512.h"
#elif GMX_SIMD_X86_AVX_512_KNL
# include "impl_x86_avx_512_knl/impl_x86_avx_512_knl.h"
-#elif GMX_SIMD_ARM_NEON
-# include "impl_arm_neon/impl_arm_neon.h"
#elif GMX_SIMD_ARM_NEON_ASIMD
# include "impl_arm_neon_asimd/impl_arm_neon_asimd.h"
#elif GMX_SIMD_ARM_SVE
# include "impl_arm_sve/impl_arm_sve.h"
-#elif GMX_SIMD_IBM_VMX
-# include "impl_ibm_vmx/impl_ibm_vmx.h"
#elif GMX_SIMD_IBM_VSX
# include "impl_ibm_vsx/impl_ibm_vsx.h"
#elif (GMX_SIMD_REFERENCE || defined DOXYGEN)
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2016,2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,2017,2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
const std::string& simdString(SimdType s)
{
- static const std::map<SimdType, std::string> name = {
- { SimdType::None, "None" },
- { SimdType::Reference, "Reference" },
- { SimdType::Generic, "Generic" },
- { SimdType::X86_Sse2, "SSE2" },
- { SimdType::X86_Sse4_1, "SSE4.1" },
- { SimdType::X86_Avx128Fma, "AVX_128_FMA" },
- { SimdType::X86_Avx, "AVX_256" },
- { SimdType::X86_Avx2, "AVX2_256" },
- { SimdType::X86_Avx2_128, "AVX2_128" },
- { SimdType::X86_Avx512, "AVX_512" },
- { SimdType::X86_Avx512Knl, "AVX_512_KNL" },
- { SimdType::X86_Mic, "X86_MIC" },
- { SimdType::Arm_Neon, "ARM_NEON" },
- { SimdType::Arm_NeonAsimd, "ARM_NEON_ASIMD" },
- { SimdType::Arm_Sve, "ARM_SVE" },
- { SimdType::Ibm_Vmx, "IBM_VMX" },
- { SimdType::Ibm_Vsx, "IBM_VSX" },
- { SimdType::Fujitsu_HpcAce, "Fujitsu HPC-ACE" }
- };
+ static const std::map<SimdType, std::string> name = { { SimdType::None, "None" },
+ { SimdType::Reference, "Reference" },
+ { SimdType::Generic, "Generic" },
+ { SimdType::X86_Sse2, "SSE2" },
+ { SimdType::X86_Sse4_1, "SSE4.1" },
+ { SimdType::X86_Avx128Fma, "AVX_128_FMA" },
+ { SimdType::X86_Avx, "AVX_256" },
+ { SimdType::X86_Avx2, "AVX2_256" },
+ { SimdType::X86_Avx2_128, "AVX2_128" },
+ { SimdType::X86_Avx512, "AVX_512" },
+ { SimdType::X86_Avx512Knl, "AVX_512_KNL" },
+ { SimdType::Arm_NeonAsimd,
+ "ARM_NEON_ASIMD" },
+ { SimdType::Arm_Sve, "ARM_SVE" },
+ { SimdType::Ibm_Vsx, "IBM_VSX" } };
return name.at(s);
}
-namespace
-{
-
-
-//! Helper to detect correct AMD Zen architecture.
-bool cpuIsAmdZen1(const CpuInfo& cpuInfo)
-{
- // Both Zen/Zen+/Zen2 have family==23
- // Model numbers for Zen:
- // 1) Naples, Whitehaven, Summit ridge, and Snowy Owl
- // 17) Raven ridge
- // Model numbers for Zen+:
- // 8) Pinnacle Ridge
- // 24) Picasso
- return (cpuInfo.vendor() == gmx::CpuInfo::Vendor::Amd && cpuInfo.family() == 23
- && (cpuInfo.model() == 1 || cpuInfo.model() == 17 || cpuInfo.model() == 8
- || cpuInfo.model() == 24));
-}
-
-} // namespace
-
-
SimdType simdSuggested(const CpuInfo& c)
{
SimdType suggested = SimdType::None;
}
else if (c.feature(CpuInfo::Feature::Arm_Neon))
{
- suggested = SimdType::Arm_Neon;
+ suggested = SimdType::None;
}
break;
case CpuInfo::Vendor::Ibm:
}
else if (c.feature(CpuInfo::Feature::Ibm_Vmx))
{
- suggested = SimdType::Ibm_Vmx;
+ suggested = SimdType::None;
}
break;
case CpuInfo::Vendor::Fujitsu:
if (c.feature(CpuInfo::Feature::Fujitsu_HpcAce))
{
- suggested = SimdType::Fujitsu_HpcAce;
+ suggested = SimdType::None;
}
break;
default: break;
return SimdType::X86_Avx512Knl;
#elif GMX_SIMD_X86_AVX_512
return SimdType::X86_Avx512;
-#elif GMX_SIMD_X86_MIC
- return SimdType::X86_Mic;
#elif GMX_SIMD_X86_AVX2_256
return SimdType::X86_Avx2;
#elif GMX_SIMD_X86_AVX2_128
return SimdType::X86_Sse4_1;
#elif GMX_SIMD_X86_SSE2
return SimdType::X86_Sse2;
-#elif GMX_SIMD_ARM_NEON
- return SimdType::Arm_Neon;
#elif GMX_SIMD_ARM_NEON_ASIMD
return SimdType::Arm_NeonAsimd;
#elif GMX_SIMD_ARM_SVE
return SimdType::Arm_Sve;
-#elif GMX_SIMD_IBM_VMX
- return SimdType::Ibm_Vmx;
#elif GMX_SIMD_IBM_VSX
return SimdType::Ibm_Vsx;
-#elif GMX_SIMD_SPARC64_HPC_ACE
- return SimdType::Fujitsu_HpcAce;
#elif GMX_SIMD_REFERENCE
return SimdType::Reference;
#else
"which could influence performance. This build might have been configured on "
"a login node with only a single AVX-512 FMA unit (in which case AVX2 is faster), "
"while the node you are running on has dual AVX-512 FMA units.",
- simdString(wanted).c_str(), simdString(compiled).c_str()));
+ simdString(wanted).c_str(),
+ simdString(compiled).c_str()));
warnMsg = wrapper.wrapToString(formatString(
"Compiled SIMD: %s, but for this host/run %s might be better (see log).",
- simdString(compiled).c_str(), simdString(wanted).c_str()));
+ simdString(compiled).c_str(),
+ simdString(wanted).c_str()));
}
else if (compiled == SimdType::X86_Avx512 && wanted == SimdType::X86_Avx2
&& identifyAvx512FmaUnits() == 1)
"which could influence performance."
"This host supports AVX-512, but since it only has 1 AVX-512"
"FMA unit, it would be faster to use AVX2 instead.",
- simdString(wanted).c_str(), simdString(compiled).c_str()));
+ simdString(wanted).c_str(),
+ simdString(compiled).c_str()));
warnMsg = wrapper.wrapToString(formatString(
"Compiled SIMD: %s, but for this host/run %s might be better (see log).",
- simdString(compiled).c_str(), simdString(wanted).c_str()));
+ simdString(compiled).c_str(),
+ simdString(wanted).c_str()));
}
else if (compiled == SimdType::X86_Avx2 && wanted == SimdType::X86_Avx2_128)
{
formatString("Highest SIMD level requested by all nodes in run: %s\n"
"SIMD instructions selected at compile time: %s\n"
"Compiled SIMD newer than requested; program might crash.",
- simdString(wanted).c_str(), simdString(compiled).c_str()));
+ simdString(wanted).c_str(),
+ simdString(compiled).c_str()));
warnMsg = logMsg;
}
else if (wanted != compiled)
"SIMD instructions selected at compile time: %s\n"
"This program was compiled for different hardware than you are running on, "
"which could influence performance.",
- simdString(wanted).c_str(), simdString(compiled).c_str()));
+ simdString(wanted).c_str(),
+ simdString(compiled).c_str()));
warnMsg = wrapper.wrapToString(formatString(
"Compiled SIMD: %s, but for this host/run %s might be better (see log).",
- simdString(compiled).c_str(), simdString(wanted).c_str()));
+ simdString(compiled).c_str(),
+ simdString(wanted).c_str()));
#if GMX_SIMD_ARM_SVE
}
else if ((compiled == SimdType::Arm_Sve) && (svcntb() != GMX_SIMD_ARM_SVE_LENGTH_VALUE / 8))
"This program was compiled for different hardware than you are running on, "
"which will lead to incorrect behavior.\n"
"Aborting",
- GMX_SIMD_ARM_SVE_LENGTH_VALUE, svcntb() * 8));
+ GMX_SIMD_ARM_SVE_LENGTH_VALUE,
+ svcntb() * 8));
warnMsg = wrapper.wrapToString(formatString(
"Compiled SVE Length: %d, but for this process requires %ld (see log).",
- GMX_SIMD_ARM_SVE_LENGTH_VALUE, svcntb() * 8));
+ GMX_SIMD_ARM_SVE_LENGTH_VALUE,
+ svcntb() * 8));
#endif
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2016,2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,2017,2018,2019,2020, by the GROMACS development team.
+ * Copyright (c) 2021, 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.
X86_Avx2_128, //!< 128-bit AVX2, better than 256-bit for AMD Ryzen
X86_Avx512, //!< AVX_512
X86_Avx512Knl, //!< AVX_512_KNL
- X86_Mic, //!< Knight's corner
- Arm_Neon, //!< 32-bit ARM NEON
Arm_NeonAsimd, //!< 64-bit ARM AArch64 Advanced SIMD
Arm_Sve, //!< ARM Scalable Vector Extensions
- Ibm_Vmx, //!< IBM VMX SIMD (Altivec on Power6 and later)
- Ibm_Vsx, //!< IBM VSX SIMD (Power7 and later)
- Fujitsu_HpcAce //!< Fujitsu K-computer
+ Ibm_Vsx //!< IBM VSX SIMD (Power7 and later)
};
/*! \libinternal \brief Return a string with the name of a SIMD type
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014,2015,2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015,2017,2018,2019,2020, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
Simd4Real simdX = rSimd4_c0c1c2;
Simd4Real simdY = rSimd4_c3c4c5;
Simd4Real simdZ = rSimd4_c6c7c8;
- Simd4Real simdR2 = setSimd4RealFrom3R(c0 * c0 + c3 * c3 + c6 * c6, c1 * c1 + c4 * c4 + c7 * c7,
- c2 * c2 + c5 * c5 + c8 * c8);
+ Simd4Real simdR2 = setSimd4RealFrom3R(
+ c0 * c0 + c3 * c3 + c6 * c6, c1 * c1 + c4 * c4 + c7 * c7, c2 * c2 + c5 * c5 + c8 * c8);
setUlpTol(2);
GMX_EXPECT_SIMD4_REAL_NEAR(simdR2, norm2(simdX, simdY, simdZ));
fraction = frexp(rSimd_Exp, &exponent);
- GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(0.609548660288905419513128, 0.5833690139241746175358116,
+ GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(0.609548660288905419513128,
+ 0.5833690139241746175358116,
-0.584452007502232362412542),
fraction);
GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom3I(61, -40, 55), exponent);
// Test the unsafe flavor too, in case they use different branches
fraction = frexp<MathOptimization::Unsafe>(rSimd_Exp, &exponent);
- GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(0.609548660288905419513128, 0.5833690139241746175358116,
+ GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(0.609548660288905419513128,
+ 0.5833690139241746175358116,
-0.584452007502232362412542),
fraction);
GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom3I(61, -40, 55), exponent);
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2015,2017,2018,2019,2020,2021, 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.
mem0_[j] = refmem[j] = (1000.0 + j) * (1.0 + 100 * GMX_REAL_EPS);
}
-# ifdef __INTEL_COMPILER // Bug in (at least) 19u1 and 18u5 (03424712)
-# pragma novector
-# endif
for (std::size_t j = 0; j < GMX_SIMD_REAL_WIDTH; j++)
{
// Subtract values from _reference_ memory (we will then test with mem0_, and compare)
real data[GMX_SIMD_REAL_WIDTH / 4];
std::iota(data, data + GMX_SIMD_REAL_WIDTH / 4, 1);
-# if defined __ICC && __ICC == 1800 || defined __ICL && __ICL == 1800
-# pragma novector /* Work-around for incorrect vectorization for AVX_512(_KNL) */
-# endif
for (i = 0; i < GMX_SIMD_REAL_WIDTH / 4; i++)
{
val0_[i * 4] = val0_[i * 4 + 1] = val0_[i * 4 + 2] = val0_[i * 4 + 3] = data[i];
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014,2015,2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015,2017,2018,2019,2020,2021, 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.
GMX_EXPECT_SIMD_FUNC_NEAR(std::exp2, exp2, settings);
// Subnormal range, require matching, but DTZ is fine
- settings = { Range(lowestRealThatProducesDenormal, lowestRealThatProducesNormal), ulpTol_,
- absTol_, MatchRule::Dtz };
+ settings = { Range(lowestRealThatProducesDenormal, lowestRealThatProducesNormal),
+ ulpTol_,
+ absTol_,
+ MatchRule::Dtz };
GMX_EXPECT_SIMD_FUNC_NEAR(std::exp2, exp2, settings);
// Normal range, standard result expected
- settings = { Range(lowestRealThatProducesNormal, highestRealThatProducesNormal), ulpTol_,
- absTol_, MatchRule::Normal };
+ settings = { Range(lowestRealThatProducesNormal, highestRealThatProducesNormal),
+ ulpTol_,
+ absTol_,
+ MatchRule::Normal };
GMX_EXPECT_SIMD_FUNC_NEAR(std::exp2, exp2, settings);
}
- 1; // adding the significant corresponds to one more unit in exponent
CompareSettings settings{ Range(lowestRealThatProducesNormal, highestRealThatProducesNormal),
- ulpTol_, absTol_, MatchRule::Normal };
+ ulpTol_,
+ absTol_,
+ MatchRule::Normal };
GMX_EXPECT_SIMD_FUNC_NEAR(std::exp2, exp2<MathOptimization::Unsafe>, settings);
}
const real lowestReal = -std::numeric_limits<real>::max();
// In theory the smallest value should be (min_exponent-1)*log(2), but rounding after the multiplication will cause this
// value to be a single ulp too low. This might cause failed tests on CPUs that use different DTZ modes for SIMD vs.
- // non-SIMD arithmetics (ARM v7), so multiply by (1.0-eps) to increase it by a single ulp.
+ // non-SIMD arithmetics (e.g. ARM v7), so multiply by (1.0-eps) to increase it by a single ulp.
const real lowestRealThatProducesNormal = (std::numeric_limits<real>::min_exponent - 1)
* std::log(2.0)
* (1 - std::numeric_limits<real>::epsilon());
GMX_EXPECT_SIMD_FUNC_NEAR(std::exp, exp, settings);
// Subnormal range, require matching, but DTZ is fine
- settings = { Range(lowestRealThatProducesDenormal, lowestRealThatProducesNormal), ulpTol_,
- absTol_, MatchRule::Dtz };
+ settings = { Range(lowestRealThatProducesDenormal, lowestRealThatProducesNormal),
+ ulpTol_,
+ absTol_,
+ MatchRule::Dtz };
GMX_EXPECT_SIMD_FUNC_NEAR(std::exp, exp, settings);
// Normal range, standard result expected
- settings = { Range(lowestRealThatProducesNormal, highestRealThatProducesNormal), ulpTol_,
- absTol_, MatchRule::Normal };
+ settings = { Range(lowestRealThatProducesNormal, highestRealThatProducesNormal),
+ ulpTol_,
+ absTol_,
+ MatchRule::Normal };
GMX_EXPECT_SIMD_FUNC_NEAR(std::exp, exp, settings);
}
(std::numeric_limits<real>::max_exponent - 1) * std::log(2.0);
CompareSettings settings{ Range(lowestRealThatProducesNormal, highestRealThatProducesNormal),
- ulpTol_, absTol_, MatchRule::Normal };
+ ulpTol_,
+ absTol_,
+ MatchRule::Normal };
GMX_EXPECT_SIMD_FUNC_NEAR(std::exp, exp<MathOptimization::Unsafe>, settings);
}
TEST_F(SimdMathTest, erfc)
{
// Our erfc algorithm has 4 ulp accuracy, so relax tolerance a bit to 4*ulpTol
- CompareSettings settings{ Range(-9, 9), 4 * ulpTol_, std::numeric_limits<real>::min(),
- MatchRule::Normal };
+ CompareSettings settings{ Range(-9, 9), 4 * ulpTol_, std::numeric_limits<real>::min(), MatchRule::Normal };
GMX_EXPECT_SIMD_FUNC_NEAR(refErfc, erfc, settings);
}
GMX_EXPECT_SIMD_FUNC_NEAR(std::exp2, exp2SingleAccuracy, settings);
// Subnormal range, require matching, but DTZ is fine
- settings = { Range(lowestRealThatProducesDenormal, lowestRealThatProducesNormal), ulpTol_,
- absTol_, MatchRule::Dtz };
+ settings = { Range(lowestRealThatProducesDenormal, lowestRealThatProducesNormal),
+ ulpTol_,
+ absTol_,
+ MatchRule::Dtz };
GMX_EXPECT_SIMD_FUNC_NEAR(std::exp2, exp2SingleAccuracy, settings);
// Normal range, standard result expected
- settings = { Range(lowestRealThatProducesNormal, highestRealThatProducesNormal), ulpTol_,
- absTol_, MatchRule::Normal };
+ settings = { Range(lowestRealThatProducesNormal, highestRealThatProducesNormal),
+ ulpTol_,
+ absTol_,
+ MatchRule::Normal };
GMX_EXPECT_SIMD_FUNC_NEAR(std::exp2, exp2SingleAccuracy, settings);
}
setUlpTolSingleAccuracy(ulpTol_);
CompareSettings settings{ Range(lowestRealThatProducesNormal, highestRealThatProducesNormal),
- ulpTol_, absTol_, MatchRule::Normal };
+ ulpTol_,
+ absTol_,
+ MatchRule::Normal };
GMX_EXPECT_SIMD_FUNC_NEAR(std::exp2, exp2SingleAccuracy<MathOptimization::Unsafe>, settings);
}
const real lowestReal = -std::numeric_limits<real>::max();
// In theory the smallest value should be (min_exponent-1)*log(2), but rounding after the multiplication will cause this
// value to be a single ulp too low. This might cause failed tests on CPUs that use different DTZ modes for SIMD vs.
- // non-SIMD arithmetics (ARM v7), so multiply by (1.0-eps) to increase it by a single ulp.
+ // non-SIMD arithmetics (e.g. ARM v7), so multiply by (1.0-eps) to increase it by a single ulp.
const real lowestRealThatProducesNormal = (std::numeric_limits<real>::min_exponent - 1)
* std::log(2.0)
* (1.0 - std::numeric_limits<real>::epsilon());
GMX_EXPECT_SIMD_FUNC_NEAR(std::exp, expSingleAccuracy, settings);
// Subnormal range, require matching, but DTZ is fine
- settings = { Range(lowestRealThatProducesDenormal, lowestRealThatProducesNormal), ulpTol_,
- absTol_, MatchRule::Dtz };
+ settings = { Range(lowestRealThatProducesDenormal, lowestRealThatProducesNormal),
+ ulpTol_,
+ absTol_,
+ MatchRule::Dtz };
GMX_EXPECT_SIMD_FUNC_NEAR(std::exp, expSingleAccuracy, settings);
// Normal range, standard result expected
- settings = { Range(lowestRealThatProducesNormal, highestRealThatProducesNormal), ulpTol_,
- absTol_, MatchRule::Normal };
+ settings = { Range(lowestRealThatProducesNormal, highestRealThatProducesNormal),
+ ulpTol_,
+ absTol_,
+ MatchRule::Normal };
GMX_EXPECT_SIMD_FUNC_NEAR(std::exp, expSingleAccuracy, settings);
}
setUlpTolSingleAccuracy(ulpTol_);
CompareSettings settings{ Range(lowestRealThatProducesNormal, highestRealThatProducesNormal),
- ulpTol_, absTol_, MatchRule::Normal };
+ ulpTol_,
+ absTol_,
+ MatchRule::Normal };
GMX_EXPECT_SIMD_FUNC_NEAR(std::exp, expSingleAccuracy<MathOptimization::Unsafe>, settings);
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014,2015,2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015,2017,2018,2019,2020, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
SimdReal bX = rSimd_c3c0c4;
SimdReal bY = rSimd_c4c6c8;
SimdReal bZ = rSimd_c7c2c3;
- SimdReal iprodRef = setSimdRealFrom3R(c0 * c3 + c3 * c4 + c6 * c7, c1 * c0 + c4 * c6 + c7 * c2,
- c2 * c4 + c5 * c8 + c8 * c3);
+ SimdReal iprodRef = setSimdRealFrom3R(
+ c0 * c3 + c3 * c4 + c6 * c7, c1 * c0 + c4 * c6 + c7 * c2, c2 * c4 + c5 * c8 + c8 * c3);
setUlpTol(2);
GMX_EXPECT_SIMD_REAL_NEAR(iprodRef, iprod(aX, aY, aZ, bX, bY, bZ));
SimdReal simdX = rSimd_c0c1c2;
SimdReal simdY = rSimd_c3c4c5;
SimdReal simdZ = rSimd_c6c7c8;
- SimdReal norm2Ref = setSimdRealFrom3R(c0 * c0 + c3 * c3 + c6 * c6, c1 * c1 + c4 * c4 + c7 * c7,
- c2 * c2 + c5 * c5 + c8 * c8);
+ SimdReal norm2Ref = setSimdRealFrom3R(
+ c0 * c0 + c3 * c3 + c6 * c6, c1 * c1 + c4 * c4 + c7 * c7, c2 * c2 + c5 * c5 + c8 * c8);
setUlpTol(2);
GMX_EXPECT_SIMD_REAL_NEAR(norm2Ref, norm2(simdX, simdY, simdZ));
// The SIMD version might use FMA. If we don't force FMA for the reference value, the compiler is free to use FMA
// for either product. If the compiler uses FMA for one product and the SIMD version uses FMA for the other, the
// rounding error of each product adds up and the total possible ulp-error is 12.
- SimdReal refcX = setSimdRealFrom3R(std::fma(-c6, c4, c3 * c7), std::fma(-c7, c6, c4 * c2),
- std::fma(-c8, c8, c5 * c3));
- SimdReal refcY = setSimdRealFrom3R(std::fma(-c0, c7, c6 * c3), std::fma(-c1, c2, c7 * c0),
- std::fma(-c2, c3, c8 * c4));
- SimdReal refcZ = setSimdRealFrom3R(std::fma(-c3, c3, c0 * c4), std::fma(-c4, c0, c1 * c6),
- std::fma(-c5, c4, c2 * c8));
+ SimdReal refcX = setSimdRealFrom3R(
+ std::fma(-c6, c4, c3 * c7), std::fma(-c7, c6, c4 * c2), std::fma(-c8, c8, c5 * c3));
+ SimdReal refcY = setSimdRealFrom3R(
+ std::fma(-c0, c7, c6 * c3), std::fma(-c1, c2, c7 * c0), std::fma(-c2, c3, c8 * c4));
+ SimdReal refcZ = setSimdRealFrom3R(
+ std::fma(-c3, c3, c0 * c4), std::fma(-c4, c0, c1 * c6), std::fma(-c5, c4, c2 * c8));
SimdReal cX, cY, cZ;
// The test assumes that cprod uses FMA on architectures which have FMA so that the compiler
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2014,2015, by the GROMACS development team, led by
+# Copyright (c) 2014,2015,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.
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+# Set up the module library
+add_library(statistics INTERFACE)
file(GLOB STATISTICS_SOURCES *.cpp)
-
set(LIBGROMACS_SOURCES
${LIBGROMACS_SOURCES} ${STATISTICS_SOURCES} PARENT_SCOPE)
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(statistics PUBLIC
+target_include_directories(statistics INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(statistics PUBLIC
+target_link_libraries(statistics INTERFACE
+ legacy_api
+ )
+
+# TODO: when statistics is an OBJECT target
+#target_link_libraries(statistics PUBLIC legacy_api)
+#target_link_libraries(statistics PRIVATE common)
+
+# Module dependencies
+# statistics interfaces convey transitive dependence on these modules.
+#target_link_libraries(statistics PUBLIC
+target_link_libraries(statistics INTERFACE
+ utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(statistics PRIVATE NOTHING)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(statistics PRIVATE legacy_modules)
for (int i = 0; (i < n); i++)
{
int ok;
- if ((ok = gmx_stats_add_point(gstats, x[i], y[i], (nullptr != dx) ? dx[i] : 0,
- (nullptr != dy) ? dy[i] : 0))
+ if ((ok = gmx_stats_add_point(
+ gstats, x[i], y[i], (nullptr != dx) ? dx[i] : 0, (nullptr != dy) ? dy[i] : 0))
!= estatsOK)
{
return ok;
r = std::abs(stats->x[i] - stats->y[i]);
if (r > level * rmsd)
{
- fprintf(stderr, "Removing outlier, iter = %d, rmsd = %g, x = %g, y = %g\n", iter,
- rmsd, stats->x[i], stats->y[i]);
+ fprintf(stderr,
+ "Removing outlier, iter = %d, rmsd = %g, x = %g, y = %g\n",
+ iter,
+ rmsd,
+ stats->x[i],
+ stats->y[i]);
if (i < stats->np - 1)
{
stats->x[i] = stats->x[stats->np - 1];
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
+# Copyright (c) 2013,2014,2015,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.
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+# Set up the module library
+add_library(swap INTERFACE)
file(GLOB SWAP_SOURCES *.cpp)
set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${SWAP_SOURCES} PARENT_SCOPE)
+# Source files have the following dependencies on library infrastructure.
+#target_link_libraries(swap PRIVATE
+# common
+# legacy_modules
+#)
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(swap PUBLIC
+target_include_directories(swap INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(swap PUBLIC
+target_link_libraries(swap INTERFACE
+ legacy_api
+ )
+
+# TODO: when swap is an OBJECT target
+#target_link_libraries(swap PUBLIC legacy_api)
+#target_link_libraries(swap PRIVATE common)
+
+# Module dependencies
+# swap interfaces convey transitive dependence on these modules.
+#target_link_libraries(swap PUBLIC
+target_link_libraries(swap INTERFACE
+ utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(swap PRIVATE NOTHING)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(swap PRIVATE legacy_modules)
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
static const char* SwS = { "SWAP:" }; /**< For output that comes from the swap module */
static const char* SwSEmpty = { " " }; /**< Placeholder for multi-line output */
-static const char* CompStr[eCompNR] = { "A", "B" }; /**< Compartment name */
-static const char* SwapStr[eSwapTypesNR + 1] = { "", "X-", "Y-", "Z-",
- nullptr }; /**< Name for the swap types. */
+static const char* CompStr[eCompNR] = { "A", "B" }; /**< Compartment name */
+static const char* SwapStr[eSwapTypesNR + 1] = { "", "X-", "Y-", "Z-", nullptr }; /**< Name for the swap types. */
static const char* DimStr[DIM + 1] = { "X", "Y", "Z", nullptr }; /**< Name for the swap dimension. */
/** Keep track of through which channel the ions have passed */
eDomainB,
eDomainNr
};
-static const char* DomainString[eDomainNr] = { "not_assigned", "Domain_A",
- "Domain_B" }; /**< Name for the domains */
+static const char* DomainString[eDomainNr] = { "not_assigned", "Domain_A", "Domain_B" }; /**< Name for the domains */
namespace gmx
{
}
// Output center of split groups
- fprintf(s->fpout, "%10g%10g", s->group[eGrpSplit0].center[s->swapdim],
+ fprintf(s->fpout,
+ "%10g%10g",
+ s->group[eGrpSplit0].center[s->swapdim],
s->group[eGrpSplit1].center[s->swapdim]);
// Output ion flux for each channel and ion type
*
* \endcode
*/
-static void detect_flux_per_channel(t_swapgrp* g,
- int iAtom,
- int comp,
- rvec atomPosition,
- unsigned char* comp_now,
- unsigned char* comp_from,
- unsigned char* channel_label,
- t_swapcoords* sc,
- t_swap* s,
- real cyl0_r2,
- real cyl1_r2,
- int64_t step,
- gmx_bool bRerun,
- FILE* fpout)
+static void detect_flux_per_channel(t_swapgrp* g,
+ int iAtom,
+ int comp,
+ rvec atomPosition,
+ unsigned char* comp_now,
+ unsigned char* comp_from,
+ unsigned char* channel_label,
+ const t_swapcoords* sc,
+ t_swap* s,
+ real cyl0_r2,
+ real cyl1_r2,
+ int64_t step,
+ gmx_bool bRerun,
+ FILE* fpout)
{
int sd, chan_nr;
gmx_bool in_cyl0, in_cyl1;
sd = s->swapdim;
/* Check whether ion is inside any of the channels */
- in_cyl0 = is_in_channel(atomPosition, s->group[eGrpSplit0].center, sc->cyl0u, sc->cyl0l,
- cyl0_r2, s->pbc, sd);
- in_cyl1 = is_in_channel(atomPosition, s->group[eGrpSplit1].center, sc->cyl1u, sc->cyl1l,
- cyl1_r2, s->pbc, sd);
+ in_cyl0 = is_in_channel(
+ atomPosition, s->group[eGrpSplit0].center, sc->cyl0u, sc->cyl0l, cyl0_r2, s->pbc, sd);
+ in_cyl1 = is_in_channel(
+ atomPosition, s->group[eGrpSplit1].center, sc->cyl1u, sc->cyl1l, cyl1_r2, s->pbc, sd);
if (in_cyl0 && in_cyl1)
{
case eChHistPassedNone:
++s->fluxleak;
- fprintf(stderr, " %s Warning! Step %s, ion %d moved from %s to %s\n", SwS,
- gmx_step_str(step, buf), iAtom, DomainString[*comp_from],
+ fprintf(stderr,
+ " %s Warning! Step %s, ion %d moved from %s to %s\n",
+ SwS,
+ gmx_step_str(step, buf),
+ iAtom,
+ DomainString[*comp_from],
DomainString[*comp_now]);
if (bRerun)
{
fprintf(s->fpout,
" # Warning: step %s, ion %d moved from %s to %s (probably through the "
"membrane)\n",
- gmx_step_str(step, buf), iAtom, DomainString[*comp_from],
+ gmx_step_str(step, buf),
+ iAtom,
+ DomainString[*comp_from],
DomainString[*comp_now]);
}
break;
{
g->fluxfromAtoB[chan_nr]--;
}
- fprintf(fpout, "# Atom nr. %d finished passing %s.\n", iAtom,
- ChannelString[*channel_label]);
+ fprintf(fpout, "# Atom nr. %d finished passing %s.\n", iAtom, ChannelString[*channel_label]);
break;
default:
gmx_fatal(FARGS, "%s Unknown channel history entry for ion type '%s'\n", SwS, g->molname);
/*! \brief Determines which ions or solvent molecules are in compartment A and B */
-static void sortMoleculesIntoCompartments(t_swapgrp* g,
- t_commrec* cr,
- t_swapcoords* sc,
- t_swap* s,
- const matrix box,
- int64_t step,
- FILE* fpout,
- gmx_bool bRerun,
- gmx_bool bIsSolvent)
+static void sortMoleculesIntoCompartments(t_swapgrp* g,
+ t_commrec* cr,
+ const t_swapcoords* sc,
+ t_swap* s,
+ const matrix box,
+ int64_t step,
+ FILE* fpout,
+ gmx_bool bRerun,
+ gmx_bool bIsSolvent)
{
int nMolNotInComp[eCompNR]; /* consistency check */
real cyl0_r2 = sc->cyl0r * sc->cyl0r;
int sd = s->swapdim;
/* Is this first atom of the molecule in the compartment that we look at? */
- if (compartment_contains_atom(left, right, g->xc[iAtom][sd], box[sd][sd],
- sc->bulkOffset[comp], &dist))
+ if (compartment_contains_atom(
+ left, right, g->xc[iAtom][sd], box[sd][sd], sc->bulkOffset[comp], &dist))
{
/* Add the first atom of this molecule to the list of molecules in this compartment */
add_to_list(iAtom, &g->comp[comp], dist);
if (MASTER(cr) && (g->comp_now != nullptr) && !bIsSolvent)
{
int globalAtomNr = g->atomset.globalIndex()[iAtom] + 1; /* PDB index starts at 1 ... */
- detect_flux_per_channel(g, globalAtomNr, comp, g->xc[iAtom], &g->comp_now[iMol],
- &g->comp_from[iMol], &g->channel_label[iMol], sc, s,
- cyl0_r2, cyl1_r2, step, bRerun, fpout);
+ detect_flux_per_channel(g,
+ globalAtomNr,
+ comp,
+ g->xc[iAtom],
+ &g->comp_now[iMol],
+ &g->comp_from[iMol],
+ &g->channel_label[iMol],
+ sc,
+ s,
+ cyl0_r2,
+ cyl1_r2,
+ step,
+ bRerun,
+ fpout);
}
}
else
"split\n"
"%s cylinder is way too large, or one compartment has collapsed (step "
"%" PRId64 ")\n",
- SwS, g->nCylBoth, SwS, step);
+ SwS,
+ g->nCylBoth,
+ SwS,
+ step);
fprintf(s->fpout, "Warning: %d atoms were assigned to both channels!\n", g->nCylBoth);
if (bIsSolvent && nullptr != fpout)
{
- fprintf(fpout, "# Solv. molecules in comp.%s: %d comp.%s: %d\n", CompStr[eCompA],
- g->comp[eCompA].nMol, CompStr[eCompB], g->comp[eCompB].nMol);
+ fprintf(fpout,
+ "# Solv. molecules in comp.%s: %d comp.%s: %d\n",
+ CompStr[eCompA],
+ g->comp[eCompA].nMol,
+ CompStr[eCompB],
+ g->comp[eCompB].nMol);
}
/* Consistency checks */
fprintf(stderr,
"%s Warning: Inconsistency while assigning '%s' molecules to compartments. !inA: "
"%d, !inB: %d, total molecules %d\n",
- SwS, g->molname, nMolNotInComp[eCompA], nMolNotInComp[eCompB], numMolecules);
+ SwS,
+ g->molname,
+ nMolNotInComp[eCompA],
+ nMolNotInComp[eCompB],
+ numMolecules);
}
int sum = g->comp[eCompA].nMol + g->comp[eCompB].nMol;
fprintf(stderr,
"%s Warning: %d molecules are in group '%s', but altogether %d have been assigned "
"to the compartments.\n",
- SwS, numMolecules, g->molname, sum);
+ SwS,
+ numMolecules,
+ g->molname,
+ sum);
}
}
"Mismatch of the number of %s ions summed over both compartments.\n"
"You requested a total of %d ions (%d in A and %d in B),\n"
"but there are a total of %d ions of this type in the system.\n",
- g->molname, req, g->comp[eCompA].nMolReq, g->comp[eCompB].nMolReq, tot);
+ g->molname,
+ req,
+ g->comp[eCompA].nMolReq,
+ g->comp[eCompB].nMolReq,
+ tot);
}
/* Initialize time-averaging:
if (bVerbose)
{
- fprintf(stderr, "%s ... Influx netto: %d Requested: %d Past values: ", SwS,
- g->comp[ic].inflow_net, g->comp[ic].nMolReq);
+ fprintf(stderr,
+ "%s ... Influx netto: %d Requested: %d Past values: ",
+ SwS,
+ g->comp[ic].inflow_net,
+ g->comp[ic].nMolReq);
}
for (int j = 0; j < sc->nAverage; j++)
{
gmx_bcast(sizeof(g->comp[ic].nMolReq), &(g->comp[ic].nMolReq), cr->mpi_comm_mygroup);
gmx_bcast(sizeof(g->comp[ic].nMol), &(g->comp[ic].nMol), cr->mpi_comm_mygroup);
- gmx_bcast(swap->nAverage * sizeof(g->comp[ic].nMolPast[0]), g->comp[ic].nMolPast,
- cr->mpi_comm_mygroup);
+ gmx_bcast(swap->nAverage * sizeof(g->comp[ic].nMolPast[0]), g->comp[ic].nMolPast, cr->mpi_comm_mygroup);
}
}
}
"groups, or the solvent.\n"
"%s Check the .mdp file settings regarding the swap index groups or the index "
"groups themselves.\n",
- SwS, nMultiple, (1 == nMultiple) ? " is" : "s are", SwSEmpty, SwSEmpty);
+ SwS,
+ nMultiple,
+ (1 == nMultiple) ? " is" : "s are",
+ SwSEmpty,
+ SwSEmpty);
}
}
if (bVerbose)
{
- fprintf(stderr, "%s Checking whether all %s molecules consist of %d atom%s\n", SwS,
- g->molname, apm, apm > 1 ? "s" : "");
+ fprintf(stderr,
+ "%s Checking whether all %s molecules consist of %d atom%s\n",
+ SwS,
+ g->molname,
+ apm,
+ apm > 1 ? "s" : "");
}
/* Check whether this is also true for all other solvent atoms */
snprintf(buf, STRLEN, "%s %s ions (charge %s%g)", CompStr[ic], g->molname, q > 0 ? "+" : "", q);
legend[count++] = gmx_strdup(buf);
- snprintf(buf, STRLEN, "%s av. mismatch to %d %s ions", CompStr[ic],
- s->group[ig].comp[ic].nMolReq, g->molname);
+ snprintf(buf,
+ STRLEN,
+ "%s av. mismatch to %d %s ions",
+ CompStr[ic],
+ s->group[ig].comp[ic].nMolReq,
+ g->molname);
legend[count++] = gmx_strdup(buf);
snprintf(buf, STRLEN, "%s net %s ion influx", CompStr[ic], g->molname);
}
// Center of split groups
- snprintf(buf, STRLEN, "%scenter of %s of split group 0", SwapStr[ir->eSwapCoords],
+ snprintf(buf,
+ STRLEN,
+ "%scenter of %s of split group 0",
+ SwapStr[ir->eSwapCoords],
(nullptr != s->group[eGrpSplit0].m) ? "mass" : "geometry");
legend[count++] = gmx_strdup(buf);
- snprintf(buf, STRLEN, "%scenter of %s of split group 1", SwapStr[ir->eSwapCoords],
+ snprintf(buf,
+ STRLEN,
+ "%scenter of %s of split group 1",
+ SwapStr[ir->eSwapCoords],
(nullptr != s->group[eGrpSplit1].m) ? "mass" : "geometry");
legend[count++] = gmx_strdup(buf);
for (int ic = 0; ic < eChanNR; ic++)
{
- fprintf(stderr, "%s Channel %d flux history for ion type %s (charge %g): ", SwS, ic,
- g->molname, g->q);
+ fprintf(stderr, "%s Channel %d flux history for ion type %s (charge %g): ", SwS, ic, g->molname, g->q);
if (isRestart)
{
g->fluxfromAtoB[ic] = gs->fluxfromAtoB[ic];
"whole.\n"
"%s In case of multimeric channels, please check whether they have the correct PBC "
"representation.\n",
- SwS, SwSEmpty);
+ SwS,
+ SwSEmpty);
- write_sto_conf_mtop("CompELAssumedWholeConfiguration.pdb", *mtop->name, mtop, x, nullptr,
- pbcType, box);
+ write_sto_conf_mtop(
+ "CompELAssumedWholeConfiguration.pdb", *mtop->name, mtop, x, nullptr, pbcType, box);
}
}
{
if (g->nat != (g->nmolReq[eCompA] + g->nmolReq[eCompB]))
{
- gmx_fatal_collective(FARGS, cr->mpi_comm_mysim, MASTER(cr),
+ gmx_fatal_collective(FARGS,
+ cr->mpi_comm_mysim,
+ MASTER(cr),
"%s Inconsistency while importing swap-related data from an old "
"input file version.\n"
"%s The requested ion counts in compartments A (%d) and B (%d)\n"
"%s do not add up to the number of ions (%d) of this type for the "
"group '%s'.\n",
- SwS, SwSEmpty, g->nmolReq[eCompA], g->nmolReq[eCompB], SwSEmpty,
- g->nat, g->molname);
+ SwS,
+ SwSEmpty,
+ g->nmolReq[eCompA],
+ g->nmolReq[eCompB],
+ SwSEmpty,
+ g->nat,
+ g->molname);
}
}
if (bVerbose)
{
- fprintf(stdout, "%s Sorted %d ions into separate groups of %d anions and %d cations.\n",
- SwS, g->nat, nAnions, nCations);
+ fprintf(stdout,
+ "%s Sorted %d ions into separate groups of %d anions and %d cations.\n",
+ SwS,
+ g->nat,
+ nAnions,
+ nCations);
}
for (int ig = eGrpSplit0; ig <= eGrpSplit1; ig++)
{
g = &(s->group[ig]);
- gmx_bcast((g->atomset.numAtomsGlobal()) * sizeof((g->xc_old)[0]), g->xc_old,
- cr->mpi_comm_mygroup);
+ gmx_bcast((g->atomset.numAtomsGlobal()) * sizeof((g->xc_old)[0]), g->xc_old, cr->mpi_comm_mygroup);
}
}
{
if (bVerbose)
{
- fprintf(stderr, "%s Opening output file %s%s\n", SwS, fn,
- restartWithAppending ? " for appending" : "");
+ fprintf(stderr, "%s Opening output file %s%s\n", SwS, fn, restartWithAppending ? " for appending" : "");
}
s->fpout = gmx_fio_fopen(fn, restartWithAppending ? "a" : "w");
for (int ig = 0; ig < s->ngrp; ig++)
{
g = &(s->group[ig]);
- fprintf(s->fpout, "# %s group '%s' contains %d atom%s",
- ig < eSwapFixedGrpNR ? eSwapFixedGrp_names[ig] : "Ion", g->molname,
+ fprintf(s->fpout,
+ "# %s group '%s' contains %d atom%s",
+ ig < eSwapFixedGrpNR ? eSwapFixedGrp_names[ig] : "Ion",
+ g->molname,
static_cast<int>(g->atomset.numAtomsGlobal()),
(g->atomset.numAtomsGlobal() > 1) ? "s" : "");
if (!(eGrpSplit0 == ig || eGrpSplit1 == ig))
{
- fprintf(s->fpout, " with %d atom%s in each molecule of charge %g", g->apm,
- (g->apm > 1) ? "s" : "", g->q);
+ fprintf(s->fpout,
+ " with %d atom%s in each molecule of charge %g",
+ g->apm,
+ (g->apm > 1) ? "s" : "",
+ g->q);
}
fprintf(s->fpout, ".\n");
}
get_center(g->xc, g->m, g->atomset.numAtomsGlobal(), g->center);
if (!restartWithAppending)
{
- fprintf(s->fpout, "# %s group %s-center %5f nm\n", eSwapFixedGrp_names[j],
- DimStr[s->swapdim], g->center[s->swapdim]);
+ fprintf(s->fpout,
+ "# %s group %s-center %5f nm\n",
+ eSwapFixedGrp_names[j],
+ DimStr[s->swapdim],
+ g->center[s->swapdim]);
}
}
}
fprintf(s->fpout, "#\n");
- fprintf(s->fpout, "# Split0 cylinder radius %f nm, up %f nm, down %f nm\n", sc->cyl0r,
- sc->cyl0u, sc->cyl0l);
- fprintf(s->fpout, "# Split1 cylinder radius %f nm, up %f nm, down %f nm\n", sc->cyl1r,
- sc->cyl1u, sc->cyl1l);
+ fprintf(s->fpout,
+ "# Split0 cylinder radius %f nm, up %f nm, down %f nm\n",
+ sc->cyl0r,
+ sc->cyl0u,
+ sc->cyl0l);
+ fprintf(s->fpout,
+ "# Split1 cylinder radius %f nm, up %f nm, down %f nm\n",
+ sc->cyl1r,
+ sc->cyl1u,
+ sc->cyl1l);
fprintf(s->fpout, "#\n");
if (!mdrunOptions.rerun)
fprintf(s->fpout,
"# Coupling constant (number of swap attempt steps to average over): %d "
"(translates to %f ps).\n",
- sc->nAverage, sc->nAverage * sc->nstswap * ir->delta_t);
+ sc->nAverage,
+ sc->nAverage * sc->nstswap * ir->delta_t);
fprintf(s->fpout, "# Threshold is %f\n", sc->threshold);
fprintf(s->fpout, "#\n");
fprintf(s->fpout,
else
{
fprintf(stderr, "%s Determining initial numbers of ions per compartment.\n", SwS);
- get_initial_ioncounts(ir, s, globalState->x.rvec_array(), globalState->box, cr,
- mdrunOptions.rerun);
+ get_initial_ioncounts(
+ ir, s, globalState->x.rvec_array(), globalState->box, cr, mdrunOptions.rerun);
}
/* Prepare (further) checkpoint writes ... */
/* Consistency check */
if (swapstate->nAverage != sc->nAverage)
{
- gmx_fatal(FARGS, "%s Ion count averaging steps mismatch! checkpoint: %d, tpr: %d",
- SwS, swapstate->nAverage, sc->nAverage);
+ gmx_fatal(FARGS,
+ "%s Ion count averaging steps mismatch! checkpoint: %d, tpr: %d",
+ SwS,
+ swapstate->nAverage,
+ sc->nAverage);
}
}
else
* From the requested and average molecule counts we determine whether a swap is needed
* at this time step.
*/
-static gmx_bool need_swap(t_swapcoords* sc, t_swap* s)
+static gmx_bool need_swap(const t_swapcoords* sc, t_swap* s)
{
int ic, ig;
t_swapgrp* g;
gmx_fatal(FARGS,
"Could not get index of %s atom. Compartment contains %d %s molecules before "
"swaps.",
- molname, comp->nMolBefore, molname);
+ molname,
+ comp->nMolBefore,
+ molname);
}
/* Set the distance of this index to infinity such that it won't get selected again in
}
-gmx_bool do_swapcoords(t_commrec* cr,
- int64_t step,
- double t,
- t_inputrec* ir,
- t_swap* s,
- gmx_wallcycle* wcycle,
- rvec x[],
- matrix box,
- gmx_bool bVerbose,
- gmx_bool bRerun)
+gmx_bool do_swapcoords(t_commrec* cr,
+ int64_t step,
+ double t,
+ const t_inputrec* ir,
+ t_swap* s,
+ gmx_wallcycle* wcycle,
+ rvec x[],
+ matrix box,
+ gmx_bool bVerbose,
+ gmx_bool bRerun)
{
- t_swapcoords* sc;
- int j, ic, ig, nswaps;
- int thisC, otherC; /* Index into this compartment and the other one */
- gmx_bool bSwap = FALSE;
- t_swapgrp * g, *gsol;
- int isol, iion;
- rvec com_solvent, com_particle; /* solvent and swap molecule's center of mass */
+ const t_swapcoords* sc = ir->swap;
+ int j, ic, ig, nswaps;
+ int thisC, otherC; /* Index into this compartment and the other one */
+ gmx_bool bSwap = FALSE;
+ t_swapgrp * g, *gsol;
+ int isol, iion;
+ rvec com_solvent, com_particle; /* solvent and swap molecule's center of mass */
wallcycle_start(wcycle, ewcSWAP);
- sc = ir->swap;
-
set_pbc(s->pbc, ir->pbcType, box);
/* Assemble the positions of the split groups, i.e. the channels.
for (ig = eGrpSplit0; ig <= eGrpSplit1; ig++)
{
g = &(s->group[ig]);
- communicate_group_positions(cr, g->xc, g->xc_shifts, g->xc_eshifts, TRUE, x,
- g->atomset.numAtomsGlobal(), g->atomset.numAtomsLocal(),
+ communicate_group_positions(cr,
+ g->xc,
+ g->xc_shifts,
+ g->xc_eshifts,
+ TRUE,
+ x,
+ g->atomset.numAtomsGlobal(),
+ g->atomset.numAtomsLocal(),
g->atomset.localIndex().data(),
- g->atomset.collectiveIndex().data(), g->xc_old, box);
+ g->atomset.collectiveIndex().data(),
+ g->xc_old,
+ box);
get_center(g->xc, g->m, g->atomset.numAtomsGlobal(), g->center); /* center of split groups == channels */
}
for (ig = eSwapFixedGrpNR; ig < s->ngrp; ig++)
{
g = &(s->group[ig]);
- communicate_group_positions(cr, g->xc, nullptr, nullptr, FALSE, x, g->atomset.numAtomsGlobal(),
- g->atomset.numAtomsLocal(), g->atomset.localIndex().data(),
- g->atomset.collectiveIndex().data(), nullptr, nullptr);
+ communicate_group_positions(cr,
+ g->xc,
+ nullptr,
+ nullptr,
+ FALSE,
+ x,
+ g->atomset.numAtomsGlobal(),
+ g->atomset.numAtomsLocal(),
+ g->atomset.localIndex().data(),
+ g->atomset.collectiveIndex().data(),
+ nullptr,
+ nullptr);
/* Determine how many ions of this type each compartment contains */
sortMoleculesIntoCompartments(g, cr, sc, s, box, step, s->fpout, bRerun, FALSE);
/* Since we here know that we have to perform ion/water position exchanges,
* we now assemble the solvent positions */
g = &(s->group[eGrpSolvent]);
- communicate_group_positions(cr, g->xc, nullptr, nullptr, FALSE, x, g->atomset.numAtomsGlobal(),
- g->atomset.numAtomsLocal(), g->atomset.localIndex().data(),
- g->atomset.collectiveIndex().data(), nullptr, nullptr);
+ communicate_group_positions(cr,
+ g->xc,
+ nullptr,
+ nullptr,
+ FALSE,
+ x,
+ g->atomset.numAtomsGlobal(),
+ g->atomset.numAtomsLocal(),
+ g->atomset.localIndex().data(),
+ g->atomset.collectiveIndex().data(),
+ nullptr,
+ nullptr);
/* Determine how many molecules of solvent each compartment contains */
sortMoleculesIntoCompartments(g, cr, sc, s, box, step, s->fpout, bRerun, TRUE);
if (nswaps && bVerbose)
{
- fprintf(stderr, "%s Performed %d swap%s in step %" PRId64 " for iontype %s.\n", SwS,
- nswaps, nswaps > 1 ? "s" : "", step, g->molname);
+ fprintf(stderr,
+ "%s Performed %d swap%s in step %" PRId64 " for iontype %s.\n",
+ SwS,
+ nswaps,
+ nswaps > 1 ? "s" : "",
+ step,
+ g->molname);
}
}
*
* Copyright (c) 2013, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
*
* \returns Whether at least one pair of molecules was swapped.
*/
-gmx_bool do_swapcoords(t_commrec* cr,
- int64_t step,
- double t,
- t_inputrec* ir,
- t_swap* s,
- gmx_wallcycle* wcycle,
- rvec x[],
- matrix box,
- gmx_bool bVerbose,
- gmx_bool bRerun);
+gmx_bool do_swapcoords(t_commrec* cr,
+ int64_t step,
+ double t,
+ const t_inputrec* ir,
+ t_swap* s,
+ gmx_wallcycle* wcycle,
+ rvec x[],
+ matrix box,
+ gmx_bool bVerbose,
+ gmx_bool bRerun);
#endif
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2015,2016, by the GROMACS development team, led by
+# Copyright (c) 2015,2016,200, 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.
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+# Set up the module library
+add_library(tables INTERFACE)
file(GLOB TABLE_SOURCES *.cpp)
set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${TABLE_SOURCES} PARENT_SCOPE)
+# Source files have the following dependencies on library infrastructure.
+#target_link_libraries(tables PRIVATE
+# common
+# legacy_modules
+#)
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(tables PUBLIC
+target_include_directories(tables INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(tables PUBLIC
+target_link_libraries(tables INTERFACE
+ legacy_api
+ )
+
+# TODO: when tables is an OBJECT target
+#target_link_libraries(tables PUBLIC legacy_api)
+#target_link_libraries(tables PRIVATE common)
+
+# Module dependencies
+# tables interfaces convey transitive dependence on these modules.
+#target_link_libraries(tables PUBLIC
+target_link_libraries(tables INTERFACE
+ utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(tables PRIVATE NOTHING)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(tables PRIVATE legacy_modules)
+
if (BUILD_TESTING)
add_subdirectory(tests)
endif()
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2016,2017,2018,2019,2020, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
{
double Y, F, G, H;
- calculateCubicSplineCoefficients(functionValue0, functionValue1, derivativeValue0,
- derivativeValue1, spacing, &Y, &F, &G, &H);
+ calculateCubicSplineCoefficients(
+ functionValue0, functionValue1, derivativeValue0, derivativeValue1, spacing, &Y, &F, &G, &H);
double Fp = fma(fma(H, eps, G), eps, F);
if (functionIsInRange)
{
- calculateCubicSplineCoefficients(tmpFunctionValue, nextHigherFunction, tmpDerivativeValue,
- nextHigherDerivative, spacing, &Y, &F, &G, &H);
+ calculateCubicSplineCoefficients(tmpFunctionValue,
+ nextHigherFunction,
+ tmpDerivativeValue,
+ nextHigherDerivative,
+ spacing,
+ &Y,
+ &F,
+ &G,
+ &H);
lastIndexInRange--;
}
else
if (functionIsInRange)
{
- cubicSplineInterpolationFromFunctionAndDerivative(
- function[index], function[index + 1], derivative[index], derivative[index + 1],
- inputSpacing, eps, &(tmpFunction[i]), &(tmpDerivative[i]));
+ cubicSplineInterpolationFromFunctionAndDerivative(function[index],
+ function[index + 1],
+ derivative[index],
+ derivative[index + 1],
+ inputSpacing,
+ eps,
+ &(tmpFunction[i]),
+ &(tmpDerivative[i]));
lastIndexInRange--;
}
else
double nextFunction = ((i + 1) < endIndex) ? tmpFunction[i + 1] : 0.0;
double nextDerivative = ((i + 1) < endIndex) ? tmpDerivative[i + 1] : 0.0;
- calculateCubicSplineCoefficients(tmpFunction[i], nextFunction, tmpDerivative[i],
- nextDerivative, spacing, &Y, &F, &G, &H);
+ calculateCubicSplineCoefficients(
+ tmpFunction[i], nextFunction, tmpDerivative[i], nextDerivative, spacing, &Y, &F, &G, &H);
(*yfghTableData)[4 * i] = Y;
(*yfghTableData)[4 * i + 1] = F;
(*yfghTableData)[4 * i + 2] = G;
{
std::vector<real> tmpYfghTableData;
- fillSingleCubicSplineTableData(thisFuncInput.function, thisFuncInput.derivative, range_,
- spacing, &tmpYfghTableData);
+ fillSingleCubicSplineTableData(
+ thisFuncInput.function, thisFuncInput.derivative, range_, spacing, &tmpYfghTableData);
- internal::fillMultiplexedTableData(tmpYfghTableData, &yfghMultiTableData_, 4,
- numFuncInTable_, funcIndex);
+ internal::fillMultiplexedTableData(
+ tmpYfghTableData, &yfghMultiTableData_, 4, numFuncInTable_, funcIndex);
funcIndex++;
}
std::vector<real> tmpYfghTableData;
- fillSingleCubicSplineTableData(thisFuncInput.function, thisFuncInput.derivative,
- thisFuncInput.spacing, range, spacing, &tmpYfghTableData);
+ fillSingleCubicSplineTableData(thisFuncInput.function,
+ thisFuncInput.derivative,
+ thisFuncInput.spacing,
+ range,
+ spacing,
+ &tmpYfghTableData);
- internal::fillMultiplexedTableData(tmpYfghTableData, &yfghMultiTableData_, 4,
- numFuncInTable_, funcIndex);
+ internal::fillMultiplexedTableData(
+ tmpYfghTableData, &yfghMultiTableData_, 4, numFuncInTable_, funcIndex);
funcIndex++;
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2016,2017,2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#define GMX_TABLES_CUBICSPLINETABLE_H
#include <initializer_list>
+#include <memory>
#include <vector>
#include "gromacs/simd/simd.h"
// Load Derivative, Delta, Function, and Zero values for each table point.
// The 4 refers to these four values - not any SIMD width.
- gatherLoadBySimdIntTranspose<4 * numFuncInTable>(yfghMultiTableData_.data() + 4 * funcIndex,
- tabIndex, &Y, &F, &G, &H);
+ gatherLoadBySimdIntTranspose<4 * numFuncInTable>(
+ yfghMultiTableData_.data() + 4 * funcIndex, tabIndex, &Y, &F, &G, &H);
*functionValue = fma(fma(fma(H, eps, G), eps, F), eps, Y);
*derivativeValue = tableScale_ * fma(fma(T(3.0) * H, eps, T(2.0) * G), eps, F);
}
// Load Derivative, Delta, Function, and Zero values for each table point.
// The 4 refers to these four values - not any SIMD width.
- gatherLoadBySimdIntTranspose<4 * numFuncInTable>(yfghMultiTableData_.data() + 4 * funcIndex,
- tabIndex, &Y, &F, &G, &H);
+ gatherLoadBySimdIntTranspose<4 * numFuncInTable>(
+ yfghMultiTableData_.data() + 4 * funcIndex, tabIndex, &Y, &F, &G, &H);
*derivativeValue = tableScale_ * fma(fma(T(3.0) * H, eps, T(2.0) * G), eps, F);
}
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
{
GMX_RELEASE_ASSERT(!generateCoulombTables || EEL_PME_EWALD(ic.eeltype),
"Can only use tables with Ewald");
- GMX_RELEASE_ASSERT(!generateVdwTables || EVDW_PME(ic.vdwtype),
- "Can only use tables with Ewald");
+ GMX_RELEASE_ASSERT(!generateVdwTables || EVDW_PME(ic.vdwtype), "Can only use tables with Ewald");
real sc = 0;
if (fp)
{
- fprintf(fp, "Generating forces for table %d, boundary conditions: V''' at %g, %s at %g\n",
- table + 1, start * h, end == nx ? "V'''" : "V'=0", (end - 1) * h);
+ fprintf(fp,
+ "Generating forces for table %d, boundary conditions: V''' at %g, %s at %g\n",
+ table + 1,
+ start * h,
+ end == nx ? "V'''" : "V'=0",
+ (end - 1) * h);
}
spline_forces(end - start, h, v + start, TRUE, end == nx, f + start);
}
int numColumns = xvgData.extent(0);
if (numColumns != nny)
{
- gmx_fatal(FARGS, "Trying to read file %s, but nr columns = %d, should be %d", libfn.c_str(),
- numColumns, nny);
+ gmx_fatal(FARGS, "Trying to read file %s, but nr columns = %d, should be %d", libfn.c_str(), numColumns, nny);
}
int numRows = xvgData.extent(1);
{
if (yy[0][0] != 0.0)
{
- gmx_fatal(FARGS, "The first distance in file %s is %f nm instead of %f nm",
- libfn.c_str(), yy[0][0], 0.0);
+ gmx_fatal(FARGS,
+ "The first distance in file %s is %f nm instead of %f nm",
+ libfn.c_str(),
+ yy[0][0],
+ 0.0);
}
}
else
end = 180.0;
if (yy[0][0] != start || yy[0][numRows - 1] != end)
{
- gmx_fatal(FARGS, "The angles in file %s should go from %f to %f instead of %f to %f\n",
- libfn.c_str(), start, end, yy[0][0], yy[0][numRows - 1]);
+ gmx_fatal(FARGS,
+ "The angles in file %s should go from %f to %f instead of %f to %f\n",
+ libfn.c_str(),
+ start,
+ end,
+ yy[0][0],
+ yy[0][numRows - 1]);
}
}
{
gmx_fatal(FARGS,
"In table file '%s' the x values are not equally spaced: %f %f %f",
- filename, yy[0][i - 2], yy[0][i - 1], yy[0][i]);
+ filename,
+ yy[0][i - 2],
+ yy[0][i - 1],
+ yy[0][i]);
}
}
if (yy[1 + k * 2][i] != 0)
}
if (yy[1 + k * 2][i] > 0.01 * GMX_REAL_MAX || yy[1 + k * 2][i] < -0.01 * GMX_REAL_MAX)
{
- gmx_fatal(FARGS, "Out of range potential value %g in file '%s'",
- yy[1 + k * 2][i], filename);
+ gmx_fatal(FARGS, "Out of range potential value %g in file '%s'", yy[1 + k * 2][i], filename);
}
}
if (yy[1 + k * 2 + 1][i] != 0)
}
if (yy[1 + k * 2 + 1][i] > 0.01 * GMX_REAL_MAX || yy[1 + k * 2 + 1][i] < -0.01 * GMX_REAL_MAX)
{
- gmx_fatal(FARGS, "Out of range force value %g in file '%s'",
- yy[1 + k * 2 + 1][i], filename);
+ gmx_fatal(FARGS, "Out of range force value %g in file '%s'", yy[1 + k * 2 + 1][i], filename);
}
}
}
if (!bZeroV && bZeroF)
{
- set_forces(fp, angle, numRows, 1 / tabscale, yy[1 + k * 2].data(),
- yy[1 + k * 2 + 1].data(), k);
+ set_forces(fp, angle, numRows, 1 / tabscale, yy[1 + k * 2].data(), yy[1 + k * 2 + 1].data(), k);
}
else
{
"For the %d non-zero entries for table %d in %s the forces deviate on "
"average %" PRId64
"%% from minus the numerical derivative of the potential\n",
- ns, k, libfn.c_str(), gmx::roundToInt64(100 * ssd));
+ ns,
+ k,
+ libfn.c_str(),
+ gmx::roundToInt64(100 * ssd));
if (debug)
{
fprintf(debug, "%s", buf);
gmx_fatal(FARGS,
"Cannot apply new potential-shift modifier to interaction type '%s' yet. "
"(%s,%d)",
- tprops[tp].name, __FILE__, __LINE__);
+ tprops[tp].name,
+ __FILE__,
+ __LINE__);
}
}
}
}
-t_forcetable* make_tables(FILE* out, const interaction_const_t* ic, const char* fn, real rtab, int flags)
+std::unique_ptr<t_forcetable>
+make_tables(FILE* fp, const interaction_const_t* ic, const char* fn, real rtab, int flags)
{
t_tabledata* td;
gmx_bool b14only, useUserTable;
int nx0, tabsel[etiNR];
real scalefactor;
- t_forcetable* table = new t_forcetable(GMX_TABLE_INTERACTION_ELEC_VDWREP_VDWDISP,
- GMX_TABLE_FORMAT_CUBICSPLINE_YFGH);
+ auto table = std::make_unique<t_forcetable>(GMX_TABLE_INTERACTION_ELEC_VDWREP_VDWDISP,
+ GMX_TABLE_FORMAT_CUBICSPLINE_YFGH);
b14only = ((flags & GMX_MAKETABLES_14ONLY) != 0);
}
if (useUserTable)
{
- read_tables(out, fn, etiNR, 0, td);
+ read_tables(fp, fn, etiNR, 0, td);
if (rtab == 0 || (flags & GMX_MAKETABLES_14ONLY))
{
table->n = td[0].nx;
gmx_fatal(FARGS,
"Tables in file %s not long enough for cut-off:\n"
"\tshould be at least %f nm\n",
- fn, rtab);
+ fn,
+ rtab);
}
table->n = gmx::roundToInt(rtab * td[0].tabscale);
}
init_table(table->n, nx0, scale, &(td[k]), !useUserTable);
fill_table(&(td[k]), tabsel[k], ic, b14only);
- if (out)
+ if (fp)
{
- fprintf(out,
+ fprintf(fp,
"Generated table with %d data points for %s%s.\n"
"Tabscale = %g points/nm\n",
- td[k].nx, b14only ? "1-4 " : "", tprops[tabsel[k]].name, td[k].tabscale);
+ td[k].nx,
+ b14only ? "1-4 " : "",
+ tprops[tabsel[k]].name,
+ td[k].tabscale);
}
}
scalefactor = 1.0;
}
- copy2table(table->n, k * table->formatsize, table->stride, td[k].x, td[k].v, td[k].f,
- scalefactor, table->data.data());
+ copy2table(table->n,
+ k * table->formatsize,
+ table->stride,
+ td[k].x,
+ td[k].v,
+ td[k].f,
+ scalefactor,
+ table->data.data());
done_tabledata(&(td[k]));
}
GMX_RELEASE_ASSERT(ic->vdwtype != evdwUSER || tabfn,
"With VdW user tables we need a table file name");
- t_forcetable* fullTable = make_tables(fp, ic, tabfn, rtab, 0);
+ std::unique_ptr<t_forcetable> fullTable = make_tables(fp, ic, tabfn, rtab, 0);
/* Copy the contents of the table to one that has just dispersion
* and repulsion, to improve cache performance. We want the table
* data to be aligned to 32-byte boundaries.
dispersionCorrectionTable->data[8 * i + j] = fullTable->data[12 * i + 4 + j];
}
}
- delete fullTable;
return dispersionCorrectionTable;
}
stride(0)
{
}
+
+t_forcetable::~t_forcetable() = default;
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
*
* \return Pointer to inner loop table structure
*/
-t_forcetable* make_tables(FILE* fp, const interaction_const_t* ic, const char* fn, real rtab, int flags);
+std::unique_ptr<t_forcetable>
+make_tables(FILE* fp, const interaction_const_t* ic, const char* fn, real rtab, int flags);
/*! \brief Return a table for bonded interactions,
*
const std::vector<real>& derivativeTableData,
std::vector<real>* ddfzTableData)
{
- GMX_ASSERT(functionTableData.size() == derivativeTableData.size(),
- "Mismatching vector lengths");
+ GMX_ASSERT(functionTableData.size() == derivativeTableData.size(), "Mismatching vector lengths");
std::size_t points = functionTableData.size();
std::vector<real> tmpDerTableData;
std::vector<real> tmpDdfzTableData;
- fillSingleQuadraticSplineTableData(thisFuncInput.function, thisFuncInput.derivative,
- range_, spacing, &tmpFuncTableData, &tmpDerTableData);
+ fillSingleQuadraticSplineTableData(thisFuncInput.function,
+ thisFuncInput.derivative,
+ range_,
+ spacing,
+ &tmpFuncTableData,
+ &tmpDerTableData);
fillDdfzTableData(tmpFuncTableData, tmpDerTableData, &tmpDdfzTableData);
- internal::fillMultiplexedTableData(tmpDerTableData, &derivativeMultiTableData_, 1,
- numFuncInTable_, funcIndex);
+ internal::fillMultiplexedTableData(
+ tmpDerTableData, &derivativeMultiTableData_, 1, numFuncInTable_, funcIndex);
- internal::fillMultiplexedTableData(tmpDdfzTableData, &ddfzMultiTableData_, 4,
- numFuncInTable_, funcIndex);
+ internal::fillMultiplexedTableData(
+ tmpDdfzTableData, &ddfzMultiTableData_, 4, numFuncInTable_, funcIndex);
funcIndex++;
}
std::vector<real> tmpDerTableData;
std::vector<real> tmpDdfzTableData;
- fillSingleQuadraticSplineTableData(thisFuncInput.function, thisFuncInput.derivative,
- thisFuncInput.spacing, range, spacing,
- &tmpFuncTableData, &tmpDerTableData);
+ fillSingleQuadraticSplineTableData(thisFuncInput.function,
+ thisFuncInput.derivative,
+ thisFuncInput.spacing,
+ range,
+ spacing,
+ &tmpFuncTableData,
+ &tmpDerTableData);
fillDdfzTableData(tmpFuncTableData, tmpDerTableData, &tmpDdfzTableData);
- internal::fillMultiplexedTableData(tmpDerTableData, &derivativeMultiTableData_, 1,
- numFuncInTable_, funcIndex);
+ internal::fillMultiplexedTableData(
+ tmpDerTableData, &derivativeMultiTableData_, 1, numFuncInTable_, funcIndex);
- internal::fillMultiplexedTableData(tmpDdfzTableData, &ddfzMultiTableData_, 4,
- numFuncInTable_, funcIndex);
+ internal::fillMultiplexedTableData(
+ tmpDdfzTableData, &ddfzMultiTableData_, 4, numFuncInTable_, funcIndex);
funcIndex++;
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2019, by the GROMACS development team, led by
+ * Copyright (c) 2016,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <functional>
#include <initializer_list>
+#include <memory>
#include <vector>
#include "gromacs/simd/simd.h"
// Load Derivative, Delta, Function, and Zero values for each table point.
// The 4 refers to these four values - not any SIMD width.
- gatherLoadBySimdIntTranspose<4 * numFuncInTable>(ddfzMultiTableData_.data() + 4 * funcIndex,
- tabIndex, &t0, &t1, &t2, &t3);
+ gatherLoadBySimdIntTranspose<4 * numFuncInTable>(
+ ddfzMultiTableData_.data() + 4 * funcIndex, tabIndex, &t0, &t1, &t2, &t3);
t1 = t0 + eps * t1;
*functionValue = fma(eps * T(halfSpacing_), t0 + t1, t2);
if (numFuncInTable == 1)
{
- gatherLoadUBySimdIntTranspose<numFuncInTable>(derivativeMultiTableData_.data() + funcIndex,
- tabIndex, &t0, &t1); // works for scalar T too
+ gatherLoadUBySimdIntTranspose<numFuncInTable>(
+ derivativeMultiTableData_.data() + funcIndex, tabIndex, &t0, &t1); // works for scalar T too
}
else
{
// This is not ideal, but we need a version of gatherLoadUBySimdIntTranspose that
// only loads a single value from memory to implement it better (will be written)
+ gatherLoadUBySimdIntTranspose<numFuncInTable>(
+ derivativeMultiTableData_.data() + funcIndex, tabIndex, &t0, &t2); // works for scalar T too
gatherLoadUBySimdIntTranspose<numFuncInTable>(derivativeMultiTableData_.data() + funcIndex,
- tabIndex, &t0, &t2); // works for scalar T too
- gatherLoadUBySimdIntTranspose<numFuncInTable>(derivativeMultiTableData_.data() + funcIndex,
- tabIndex + T(1), &t1,
+ tabIndex + T(1),
+ &t1,
&t2); // works for scalar T too
}
if (numFuncInTable == 2 && funcIndex0 == 0 && funcIndex1 == 1)
{
T t0A, t0B, t1A, t1B;
- gatherLoadUBySimdIntTranspose<numFuncInTable>(derivativeMultiTableData_.data(), tabIndex,
- &t0A, &t0B); // works for scalar T too
- gatherLoadUBySimdIntTranspose<numFuncInTable>(derivativeMultiTableData_.data() + 2, tabIndex,
- &t1A, &t1B); // works for scalar T too
+ gatherLoadUBySimdIntTranspose<numFuncInTable>(
+ derivativeMultiTableData_.data(), tabIndex, &t0A, &t0B); // works for scalar T too
+ gatherLoadUBySimdIntTranspose<numFuncInTable>(
+ derivativeMultiTableData_.data() + 2, tabIndex, &t1A, &t1B); // works for scalar T too
*derivativeValue1 = fma(t1A - t0A, eps, t0A);
*derivativeValue2 = fma(t1B - t0B, eps, t0B);
}
T t0, t1, t2;
// This is not ideal, but we need a version of gatherLoadUBySimdIntTranspose that
// only loads a single value from memory to implement it better (will be written)
+ gatherLoadUBySimdIntTranspose<numFuncInTable>(
+ derivativeMultiTableData_.data() + funcIndex0, tabIndex, &t0, &t2); // works for scalar T too
gatherLoadUBySimdIntTranspose<numFuncInTable>(derivativeMultiTableData_.data() + funcIndex0,
- tabIndex, &t0, &t2); // works for scalar T too
- gatherLoadUBySimdIntTranspose<numFuncInTable>(derivativeMultiTableData_.data() + funcIndex0,
- tabIndex + T(1), &t1,
+ tabIndex + T(1),
+ &t1,
&t2); // works for scalar T too
*derivativeValue1 = fma(t1 - t0, eps, t0);
+ gatherLoadUBySimdIntTranspose<numFuncInTable>(
+ derivativeMultiTableData_.data() + funcIndex1, tabIndex, &t0, &t2); // works for scalar T too
gatherLoadUBySimdIntTranspose<numFuncInTable>(derivativeMultiTableData_.data() + funcIndex1,
- tabIndex, &t0, &t2); // works for scalar T too
- gatherLoadUBySimdIntTranspose<numFuncInTable>(derivativeMultiTableData_.data() + funcIndex1,
- tabIndex + T(1), &t1,
+ tabIndex + T(1),
+ &t1,
&t2); // works for scalar T too
*derivativeValue2 = fma(t1 - t0, eps, t0);
}
if (numFuncInTable == 3 && funcIndex0 == 0 && funcIndex1 == 1 && funcIndex2 == 2)
{
T t0A, t0B, t0C, t1A, t1B, t1C;
- gatherLoadUBySimdIntTranspose<numFuncInTable>(derivativeMultiTableData_.data(),
- tabIndex, &t0A, &t0B);
- gatherLoadUBySimdIntTranspose<numFuncInTable>(derivativeMultiTableData_.data() + 2,
- tabIndex, &t0C, &t1A);
- gatherLoadUBySimdIntTranspose<numFuncInTable>(derivativeMultiTableData_.data() + 4,
- tabIndex, &t1B, &t1C);
+ gatherLoadUBySimdIntTranspose<numFuncInTable>(
+ derivativeMultiTableData_.data(), tabIndex, &t0A, &t0B);
+ gatherLoadUBySimdIntTranspose<numFuncInTable>(
+ derivativeMultiTableData_.data() + 2, tabIndex, &t0C, &t1A);
+ gatherLoadUBySimdIntTranspose<numFuncInTable>(
+ derivativeMultiTableData_.data() + 4, tabIndex, &t1B, &t1C);
*derivativeValue1 = fma(t1A - t0A, eps, t0A);
*derivativeValue2 = fma(t1B - t0B, eps, t0B);
*derivativeValue3 = fma(t1C - t0C, eps, t0C);
T t0, t1, t2;
// This is not ideal, but we need a version of gatherLoadUBySimdIntTranspose that
// only loads a single value from memory to implement it better (will be written)
+ gatherLoadUBySimdIntTranspose<numFuncInTable>(
+ derivativeMultiTableData_.data() + funcIndex0, tabIndex, &t0, &t2); // works for scalar T too
gatherLoadUBySimdIntTranspose<numFuncInTable>(derivativeMultiTableData_.data() + funcIndex0,
- tabIndex, &t0, &t2); // works for scalar T too
- gatherLoadUBySimdIntTranspose<numFuncInTable>(derivativeMultiTableData_.data() + funcIndex0,
- tabIndex + T(1), &t1,
+ tabIndex + T(1),
+ &t1,
&t2); // works for scalar T too
*derivativeValue1 = fma(t1 - t0, eps, t0);
+ gatherLoadUBySimdIntTranspose<numFuncInTable>(
+ derivativeMultiTableData_.data() + funcIndex1, tabIndex, &t0, &t2); // works for scalar T too
gatherLoadUBySimdIntTranspose<numFuncInTable>(derivativeMultiTableData_.data() + funcIndex1,
- tabIndex, &t0, &t2); // works for scalar T too
- gatherLoadUBySimdIntTranspose<numFuncInTable>(derivativeMultiTableData_.data() + funcIndex1,
- tabIndex + T(1), &t1,
+ tabIndex + T(1),
+ &t1,
&t2); // works for scalar T too
*derivativeValue2 = fma(t1 - t0, eps, t0);
+ gatherLoadUBySimdIntTranspose<numFuncInTable>(
+ derivativeMultiTableData_.data() + funcIndex2, tabIndex, &t0, &t2); // works for scalar T too
gatherLoadUBySimdIntTranspose<numFuncInTable>(derivativeMultiTableData_.data() + funcIndex2,
- tabIndex, &t0, &t2); // works for scalar T too
- gatherLoadUBySimdIntTranspose<numFuncInTable>(derivativeMultiTableData_.data() + funcIndex2,
- tabIndex + T(1), &t1,
+ tabIndex + T(1),
+ &t1,
&t2); // works for scalar T too
*derivativeValue3 = fma(t1 - t0, eps, t0);
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2016,2017,2018,2019,2020, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
}
if (!isConsistent)
{
- GMX_THROW(InconsistentInputError(
- formatString("Derivative inconsistent with numerical vector for elements %zu-%zu",
- minFail + 1, maxFail + 1)));
+ GMX_THROW(InconsistentInputError(formatString(
+ "Derivative inconsistent with numerical vector for elements %zu-%zu", minFail + 1, maxFail + 1)));
}
}
for (std::size_t i = firstIndex + 1; (i + 1) < lastIndex; i++)
{
- minQuotient = std::min(
- minQuotient, quotientOfFunctionAndSecondDerivative(function[i - 1], function[i],
- function[i + 1], inputSpacing));
+ minQuotient = std::min(minQuotient,
+ quotientOfFunctionAndSecondDerivative(
+ function[i - 1], function[i], function[i + 1], inputSpacing));
}
return static_cast<real>(minQuotient);
}
for (double x = newRange.first; x <= newRange.second; x += dx)
{
minQuotient = std::min(minQuotient,
- quotientOfFunctionAndThirdDerivative(f(x - 2 * h), f(x - h), f(x),
- f(x + h), f(x + 2 * h), h));
+ quotientOfFunctionAndThirdDerivative(
+ f(x - 2 * h), f(x - h), f(x), f(x + h), f(x + 2 * h), h));
}
return static_cast<real>(minQuotient);
}
for (std::size_t i = firstIndex + 2; (i + 2) < lastIndex; i++)
{
- minQuotient = std::min(minQuotient, quotientOfFunctionAndThirdDerivative(
- function[i - 2], function[i - 1], function[i],
- function[i + 1], function[i + 2], inputSpacing));
+ minQuotient = std::min(
+ minQuotient,
+ quotientOfFunctionAndThirdDerivative(
+ function[i - 2], function[i - 1], function[i], function[i + 1], function[i + 2], inputSpacing));
}
return static_cast<real>(minQuotient);
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2016,2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,2017,2018,2019,2020, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
real testFuncValue;
real testDerValue;
- table.template evaluateFunctionAndDerivative<numFuncInTable, funcIndex>(x, &testFuncValue,
- &testDerValue);
+ table.template evaluateFunctionAndDerivative<numFuncInTable, funcIndex>(
+ x, &testFuncValue, &testDerValue);
// Check that we get the same values from function/derivative-only methods
real tmpFunc, tmpDer;
TypeParam pmeCorrTable({ { "PMECorr", pmeCorrFunction, pmeCorrDerivative } }, range, tolerance);
TestFixture::setTolerance(tolerance);
- TestFixture::testSplineTableAgainstFunctions("PMECorr", pmeCorrFunction, pmeCorrDerivative,
- pmeCorrTable, range);
+ TestFixture::testSplineTableAgainstFunctions(
+ "PMECorr", pmeCorrFunction, pmeCorrDerivative, pmeCorrTable, range);
}
derivativeValues.push_back(pmeCorrDerivative(x));
}
- TypeParam pmeCorrTable({ { "NumericalPMECorr", functionValues, derivativeValues, inputSpacing } },
- range, tolerance);
+ TypeParam pmeCorrTable(
+ { { "NumericalPMECorr", functionValues, derivativeValues, inputSpacing } }, range, tolerance);
TestFixture::setTolerance(tolerance);
- TestFixture::testSplineTableAgainstFunctions("NumericalPMECorr", pmeCorrFunction,
- pmeCorrDerivative, pmeCorrTable, range);
+ TestFixture::testSplineTableAgainstFunctions(
+ "NumericalPMECorr", pmeCorrFunction, pmeCorrDerivative, pmeCorrTable, range);
}
TYPED_TEST(SplineTableTest, TwoFunctions)
range);
// Test entire range for each function. This will use the method that interpolates a single function
- TestFixture::template testSplineTableAgainstFunctions<2, 0>("LJ6", lj6Function, lj6Derivative,
- table, range);
- TestFixture::template testSplineTableAgainstFunctions<2, 1>("LJ12", lj12Function,
- lj12Derivative, table, range);
+ TestFixture::template testSplineTableAgainstFunctions<2, 0>(
+ "LJ6", lj6Function, lj6Derivative, table, range);
+ TestFixture::template testSplineTableAgainstFunctions<2, 1>(
+ "LJ12", lj12Function, lj12Derivative, table, range);
// Test the methods that evaluated both functions for one value
real x = 0.5 * (range.first + range.second);
range);
// Test entire range for each function
- TestFixture::template testSplineTableAgainstFunctions<3, 0>("Coulomb", coulombFunction,
- coulombDerivative, table, range);
- TestFixture::template testSplineTableAgainstFunctions<3, 1>("LJ6", lj6Function, lj6Derivative,
- table, range);
- TestFixture::template testSplineTableAgainstFunctions<3, 2>("LJ12", lj12Function,
- lj12Derivative, table, range);
+ TestFixture::template testSplineTableAgainstFunctions<3, 0>(
+ "Coulomb", coulombFunction, coulombDerivative, table, range);
+ TestFixture::template testSplineTableAgainstFunctions<3, 1>(
+ "LJ6", lj6Function, lj6Derivative, table, range);
+ TestFixture::template testSplineTableAgainstFunctions<3, 2>(
+ "LJ12", lj12Function, lj12Derivative, table, range);
// Test the methods that evaluated both functions for one value
real x = 0.5 * (range.first + range.second);
EXPECT_EQ(tstDer1, tmpDer1);
// Test that scrambled order interpolation methods work
- table.template evaluateFunctionAndDerivative<3, 2, 1, 0>(x, &tstFunc2, &tstDer2, &tstFunc1,
- &tstDer1, &tstFunc0, &tstDer0);
+ table.template evaluateFunctionAndDerivative<3, 2, 1, 0>(
+ x, &tstFunc2, &tstDer2, &tstFunc1, &tstDer1, &tstFunc0, &tstDer0);
EXPECT_EQ(tstFunc0, tmpFunc0);
EXPECT_EQ(tstFunc1, tmpFunc1);
EXPECT_EQ(tstFunc2, tmpFunc2);
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+# Set up the module library
+add_library(taskassignment INTERFACE)
+file(GLOB TASKASSIGNMENT_SOURCES *.cpp)
+set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${TASKASSIGNMENT_SOURCES} PARENT_SCOPE)
+
# Note that this is a higher-level module that should not need
# special compilation to suit e.g. GPU or MPI dependencies.
# If you find you want to do that, consider a preliminary
# refactoring.
-gmx_add_libgromacs_sources(
- decidegpuusage.cpp
- decidesimulationworkload.cpp
- findallgputasks.cpp
- reportgpuusage.cpp
- resourcedivision.cpp
- taskassignment.cpp
- usergpuids.cpp
- )
+
+# Source files have the following dependencies on library infrastructure.
+#target_link_libraries(taskassignment PRIVATE
+# common
+# legacy_modules
+#)
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(taskassignment PUBLIC
+target_include_directories(taskassignment INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(taskassignment PUBLIC
+target_link_libraries(taskassignment INTERFACE
+ legacy_api
+ )
+
+# TODO: when taskassignment is an OBJECT target
+#target_link_libraries(taskassignment PUBLIC legacy_api)
+#target_link_libraries(taskassignment PRIVATE common)
+
+# Module dependencies
+# taskassignment interfaces convey transitive dependence on these modules.
+#target_link_libraries(taskassignment PUBLIC
+target_link_libraries(taskassignment INTERFACE
+ utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(taskassignment PRIVATE NOTHING)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(taskassignment PRIVATE legacy_modules)
if (BUILD_TESTING)
add_subdirectory(tests)
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2015,2016,2017,2018,2019 by the GROMACS development team.
- * Copyright (c) 2020, by the GROMACS development team, led by
+ * Copyright (c) 2020,2021, 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.
{
errorMessage += "Only the md integrator is supported.\n";
}
- if (inputrec.etc == etcNOSEHOOVER)
+ if (inputrec.etc == TemperatureCoupling::NoseHoover)
{
errorMessage += "Nose-Hoover temperature coupling is not supported.\n";
}
- if (!(inputrec.epc == epcNO || inputrec.epc == epcPARRINELLORAHMAN
- || inputrec.epc == epcBERENDSEN || inputrec.epc == epcCRESCALE))
+ if (!(inputrec.epc == PressureCoupling::No || inputrec.epc == PressureCoupling::ParrinelloRahman
+ || inputrec.epc == PressureCoupling::Berendsen || inputrec.epc == PressureCoupling::CRescale))
{
errorMessage +=
"Only Parrinello-Rahman, Berendsen, and C-rescale pressure coupling are "
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
// to compile warning-free with all versions of MPI headers.
//
// TODO Make an allgather template to deal with this nonsense.
- MPI_Gather(const_cast<int*>(&input), 1, MPI_INT, const_cast<int*>(result.data()), 1,
- MPI_INT, root, communicator);
+ MPI_Gather(const_cast<int*>(&input), 1, MPI_INT, const_cast<int*>(result.data()), 1, MPI_INT, root, communicator);
MPI_Bcast(const_cast<int*>(result.data()), result.size(), MPI_INT, root, communicator);
#else
GMX_UNUSED_VALUE(communicator);
{
std::vector<int> displacements(numRanks + 1);
displacements[0] = 0;
- std::partial_sum(std::begin(extentOnEachRank), std::end(extentOnEachRank),
- std::begin(displacements) + 1);
+ std::partial_sum(
+ std::begin(extentOnEachRank), std::end(extentOnEachRank), std::begin(displacements) + 1);
return displacements;
}
int root = 0;
// Calling a C API with the const T * from data() doesn't seem to compile reliably.
// TODO Make an allgatherv template to deal with this nonsense.
- MPI_Gatherv(const_cast<GpuTask*>(input.data()), input.size(), MPI_INT,
- const_cast<GpuTask*>(result.data()), const_cast<int*>(extentOnEachRank.data()),
- const_cast<int*>(displacementForEachRank.data()), MPI_INT, root, communicator);
+ MPI_Gatherv(const_cast<GpuTask*>(input.data()),
+ input.size(),
+ MPI_INT,
+ const_cast<GpuTask*>(result.data()),
+ const_cast<int*>(extentOnEachRank.data()),
+ const_cast<int*>(displacementForEachRank.data()),
+ MPI_INT,
+ root,
+ communicator);
MPI_Bcast(const_cast<GpuTask*>(result.data()), result.size(), MPI_INT, root, communicator);
#else
GMX_UNUSED_VALUE(communicator);
* the vector. */
auto displacementsForEachRank =
computeDisplacements(numGpuTasksOnEachRankOfThisNode, numRanksOnThisNode);
- auto gpuTasksOnThisNode = allgatherv(gpuTasksOnThisRank, numGpuTasksOnEachRankOfThisNode,
- displacementsForEachRank, communicator);
+ auto gpuTasksOnThisNode = allgatherv(
+ gpuTasksOnThisRank, numGpuTasksOnEachRankOfThisNode, displacementsForEachRank, communicator);
/* Next, we re-use the displacements to break up the vector
* of GPU tasks into something that can be indexed like
do
{
gpuTasksOnRanksOfThisNode.emplace_back(std::vector<GpuTask>());
- for (auto taskOnThisRankIndex = *currentDisplacementIt;
- taskOnThisRankIndex != *nextDisplacementIt; ++taskOnThisRankIndex)
+ for (auto taskOnThisRankIndex = *currentDisplacementIt; taskOnThisRankIndex != *nextDisplacementIt;
+ ++taskOnThisRankIndex)
{
gpuTasksOnRanksOfThisNode.back().push_back(gpuTasksOnThisNode[taskOnThisRankIndex]);
}
output += gmx::formatString(
"%zu GPU%s selected for this run.\n"
"Mapping of GPU IDs to the %zu GPU task%s in the %zu rank%s on this node:\n %s\n",
- numGpusInUse, bPluralGpus ? "s" : "", numGpuTasksOnThisNode,
- (numGpuTasksOnThisNode > 1) ? "s" : "", numRanks, (numRanks > 1) ? "s" : "",
+ numGpusInUse,
+ bPluralGpus ? "s" : "",
+ numGpuTasksOnThisNode,
+ (numGpuTasksOnThisNode > 1) ? "s" : "",
+ numRanks,
+ (numRanks > 1) ? "s" : "",
gpuIdsString.c_str());
// Because there is a GPU in use, there must be a PP task on a GPU.
output += gmx::formatString(
"threads per rank, which is most likely inefficient. The optimum is usually "
"between %d and"
" %d threads per rank.",
- nth_omp_max, nthreads_omp_mpi_ok_min, nthreads_omp_mpi_target_max);
+ nth_omp_max,
+ nthreads_omp_mpi_ok_min,
+ nthreads_omp_mpi_target_max);
if (bNtOmpOptionSet)
{
"%s If you want to run with this setup, specify the -ntomp option. But "
"we suggest to "
"change the number of MPI ranks%s.",
- buf, mpi_option);
+ buf,
+ mpi_option);
}
}
}
//! Dump a \c hw_opt to \c fp.
static void print_hw_opt(FILE* fp, const gmx_hw_opt_t* hw_opt)
{
- fprintf(fp, "hw_opt: nt %d ntmpi %d ntomp %d ntomp_pme %d gpu_id '%s' gputasks '%s'\n",
- hw_opt->nthreads_tot, hw_opt->nthreads_tmpi, hw_opt->nthreads_omp, hw_opt->nthreads_omp_pme,
- hw_opt->gpuIdsAvailable.c_str(), hw_opt->userGpuTaskAssignment.c_str());
+ fprintf(fp,
+ "hw_opt: nt %d ntmpi %d ntomp %d ntomp_pme %d gpu_id '%s' gputasks '%s'\n",
+ hw_opt->nthreads_tot,
+ hw_opt->nthreads_tmpi,
+ hw_opt->nthreads_omp,
+ hw_opt->nthreads_omp_pme,
+ hw_opt->gpuIdsAvailable.c_str(),
+ hw_opt->userGpuTaskAssignment.c_str());
}
void checkAndUpdateHardwareOptions(const gmx::MDLogger& mdlog,
"The total number of threads requested (%d) does not match the thread-MPI "
"ranks (%d) "
"times the OpenMP threads (%d) requested",
- hw_opt->nthreads_tot, hw_opt->nthreads_tmpi, hw_opt->nthreads_omp);
+ hw_opt->nthreads_tot,
+ hw_opt->nthreads_tmpi,
+ hw_opt->nthreads_omp);
}
if (hw_opt->nthreads_tmpi > 0 && hw_opt->nthreads_tot % hw_opt->nthreads_tmpi != 0)
"The total number of threads requested (%d) is not divisible by the number "
"of thread-MPI "
"ranks requested (%d)",
- hw_opt->nthreads_tot, hw_opt->nthreads_tmpi);
+ hw_opt->nthreads_tot,
+ hw_opt->nthreads_tmpi);
}
if (hw_opt->nthreads_omp > 0 && hw_opt->nthreads_tot % hw_opt->nthreads_omp != 0)
"The total number of threads requested (%d) is not divisible by the number "
"of OpenMP "
"threads requested (%d)",
- hw_opt->nthreads_tot, hw_opt->nthreads_omp);
+ hw_opt->nthreads_tot,
+ hw_opt->nthreads_omp);
}
}
"You requested %d OpenMP threads with %d total threads. Choose a total "
"number of threads "
"that is a multiple of the number of OpenMP threads.",
- hw_opt->nthreads_omp, hw_opt->nthreads_tot);
+ hw_opt->nthreads_omp,
+ hw_opt->nthreads_tot);
}
if (hw_opt->nthreads_tmpi > hw_opt->nthreads_tot)
"You requested %d thread-MPI ranks with %d total threads. Choose a total "
"number of "
"threads that is a multiple of the number of thread-MPI ranks.",
- hw_opt->nthreads_tmpi, hw_opt->nthreads_tot);
+ hw_opt->nthreads_tmpi,
+ hw_opt->nthreads_tot);
}
}
bool rankHasPmeTask)
{
size_t numRanksOnThisNode = physicalNodeComm.size_;
- std::vector<GpuTask> gpuTasksOnThisRank = findGpuTasksOnThisRank(
- !gpuIdsToUse.empty(), nonbondedTarget, pmeTarget, bondedTarget, updateTarget,
- useGpuForNonbonded, useGpuForPme, rankHasPpTask, rankHasPmeTask);
+ std::vector<GpuTask> gpuTasksOnThisRank = findGpuTasksOnThisRank(!gpuIdsToUse.empty(),
+ nonbondedTarget,
+ pmeTarget,
+ bondedTarget,
+ updateTarget,
+ useGpuForNonbonded,
+ useGpuForPme,
+ rankHasPpTask,
+ rankHasPmeTask);
/* Communicate among ranks on this node to find each task that can
* be executed on a GPU, on each rank. */
auto gpuTasksOnRanksOfThisNode = findAllGpuTasksOnThisNode(gpuTasksOnThisRank, physicalNodeComm);
"You should reconsider your GPU task assignment, "
"number of ranks, or your use of the -nb, -pme, and -npme options, "
"perhaps after measuring the performance you can get.",
- numGpuTasksOnThisNode, host, gpuIdsToUse.size())));
+ numGpuTasksOnThisNode,
+ host,
+ gpuIdsToUse.size())));
}
gpuIdsForTaskAssignment = generatedGpuIds;
}
"There were %zu GPU tasks assigned on node %s, but %zu GPU tasks were "
"identified, and these must match. Reconsider your GPU task assignment, "
"number of ranks, or your use of the -nb, -pme, and -npme options.",
- userGpuTaskAssignment.size(), host, numGpuTasksOnThisNode)));
+ userGpuTaskAssignment.size(),
+ host,
+ numGpuTasksOnThisNode)));
}
// Did the user choose compatible GPUs?
checkUserGpuIds(hardwareInfo.deviceInfoList, gpuIdsToUse, userGpuTaskAssignment);
PmeRunMode pmeRunMode,
bool useGpuForUpdate)
{
- gmx::reportGpuUsage(mdlog, assignmentForAllRanksOnThisNode_, numGpuTasksOnThisNode_,
- numRanksOnThisNode_, printHostName, useGpuForBonded, pmeRunMode, useGpuForUpdate);
+ gmx::reportGpuUsage(mdlog,
+ assignmentForAllRanksOnThisNode_,
+ numGpuTasksOnThisNode_,
+ numRanksOnThisNode_,
+ printHostName,
+ useGpuForBonded,
+ pmeRunMode,
+ useGpuForUpdate);
}
/*! \brief Function for whether the task of \c mapping has value \c TaskType.
{
const GpuTaskAssignment& gpuTaskAssignment = assignmentForAllRanksOnThisNode_[indexOfThisRank_];
- auto pmeGpuTaskMapping = std::find_if(gpuTaskAssignment.begin(), gpuTaskAssignment.end(),
- hasTaskType<GpuTask::Pme>);
+ auto pmeGpuTaskMapping = std::find_if(
+ gpuTaskAssignment.begin(), gpuTaskAssignment.end(), hasTaskType<GpuTask::Pme>);
const bool thisRankHasPmeGpuTask = (pmeGpuTaskMapping != gpuTaskAssignment.end());
return thisRankHasPmeGpuTask;
if (std::find(compatibleGpus.begin(), compatibleGpus.end(), gpuId) == compatibleGpus.end())
{
foundIncompatibleGpuIds = true;
- message += gmx::formatString(" GPU #%d: %s\n", gpuId,
+ message += gmx::formatString(" GPU #%d: %s\n",
+ gpuId,
getDeviceCompatibilityDescription(deviceInfoList, gpuId).c_str());
}
}
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2013,2014,2015,2019, by the GROMACS development team, led by
+# Copyright (c) 2013,2014,2015,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.
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+# Set up the module library
+add_library(timing INTERFACE)
file(GLOB TIMING_SOURCES *.cpp)
set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${TIMING_SOURCES} PARENT_SCOPE)
+# Source files have the following dependencies on library infrastructure.
+#target_link_libraries(timing PRIVATE
+# common
+# legacy_modules
+#)
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(timing PUBLIC
+target_include_directories(timing INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(timing PUBLIC
+target_link_libraries(timing INTERFACE
+ legacy_api
+ )
+
+# TODO: when timing is an OBJECT target
+#target_link_libraries(timing PUBLIC legacy_api)
+#target_link_libraries(timing PRIVATE common)
+
+# Module dependencies
+# timing interfaces convey transitive dependence on these modules.
+#target_link_libraries(timing PUBLIC
+target_link_libraries(timing INTERFACE
+ utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(timing PRIVATE NOTHING)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(timing PRIVATE legacy_modules)
+
if (BUILD_TESTING)
# add_subdirectory(tests)
endif()
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2008, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
if (wc->count_depth < 0)
{
- gmx_fatal(FARGS, "wallcycle counter depth out of range when stopping %s: %d", wcn[ewc],
- wc->count_depth);
+ gmx_fatal(FARGS, "wallcycle counter depth out of range when stopping %s: %d", wcn[ewc], wc->count_depth);
}
if (wc->counterlist[wc->count_depth] != ewc)
{
- gmx_fatal(FARGS, "wallcycle mismatch at stop, start %s, stop %s",
- wcn[wc->counterlist[wc->count_depth]], wcn[ewc]);
+ gmx_fatal(FARGS,
+ "wallcycle mismatch at stop, start %s, stop %s",
+ wcn[wc->counterlist[wc->count_depth]],
+ wcn[ewc]);
}
}
#endif
if (wc == nullptr)
{
/* Default construction of std::array of non-class T can leave
- the values indeterminate, just like a C array, and icc
- warns about it. */
+ the values indeterminate, just like a C array */
cycles_sum.fill(0);
return cycles_sum;
}
/* Convert the cycle count to wallclock time for this task */
wallt = c_sum * c2t;
- fprintf(fplog, " %-19.19s %4s %4s %10s %10.3f %14.3f %5.1f\n", name, nnodes_str,
- nthreads_str, ncalls_str, wallt, c_sum * 1e-9, percentage);
+ fprintf(fplog,
+ " %-19.19s %4s %4s %10s %10.3f %14.3f %5.1f\n",
+ name,
+ nnodes_str,
+ nthreads_str,
+ ncalls_str,
+ wallt,
+ c_sum * 1e-9,
+ percentage);
}
}
for (j = 0; j < ewcNR; j++)
{
snprintf(buf, 20, "%-9.9s %-9.9s", wcn[i], wcn[j]);
- print_cycles(fplog, c2t_pp, buf, npp, nth_pp, wc->wcc_all[i * ewcNR + j].n,
- wc->wcc_all[i * ewcNR + j].c, tot);
+ print_cycles(fplog,
+ c2t_pp,
+ buf,
+ npp,
+ nth_pp,
+ wc->wcc_all[i * ewcNR + j].n,
+ wc->wcc_all[i * ewcNR + j].c,
+ tot);
}
}
}
fprintf(fplog, "%s\n", hline);
for (auto i : validPmeSubcounterIndices)
{
- print_cycles(fplog, npme > 0 ? c2t_pme : c2t_pp, wcn[i], npme > 0 ? npme : npp,
- nth_pme, wc->wcc[i].n, cyc_sum[i], tot);
+ print_cycles(fplog,
+ npme > 0 ? c2t_pme : c2t_pp,
+ wcn[i],
+ npme > 0 ? npme : npp,
+ nth_pme,
+ wc->wcc[i].n,
+ cyc_sum[i],
+ tot);
}
fprintf(fplog, "%s\n", hline);
}
fprintf(fplog, "\n GPU timings\n%s\n", hline);
fprintf(fplog,
- " Computing: Count Wall t (s) ms/step %c\n", '%');
+ " Computing: Count Wall t (s) ms/step %c\n",
+ '%');
fprintf(fplog, "%s\n", hline);
print_gputimes(fplog, "Pair list H2D", gpu_nbnxn_t->pl_h2d_c, gpu_nbnxn_t->pl_h2d_t, tot_gpu);
print_gputimes(fplog, "X / q H2D", gpu_nbnxn_t->nb_c, gpu_nbnxn_t->nb_h2d_t, tot_gpu);
{
if (gpu_nbnxn_t->ktime[i][j].c)
{
- print_gputimes(fplog, k_log_str[i][j], gpu_nbnxn_t->ktime[i][j].c,
- gpu_nbnxn_t->ktime[i][j].t, tot_gpu);
+ print_gputimes(fplog,
+ k_log_str[i][j],
+ gpu_nbnxn_t->ktime[i][j].c,
+ gpu_nbnxn_t->ktime[i][j].t,
+ tot_gpu);
}
}
}
{
if (gpu_pme_t->timing[k].c)
{
- print_gputimes(fplog, PMEStageNames[k], gpu_pme_t->timing[k].c,
- gpu_pme_t->timing[k].t, tot_gpu);
+ print_gputimes(
+ fplog, PMEStageNames[k], gpu_pme_t->timing[k].c, gpu_pme_t->timing[k].t, tot_gpu);
}
}
}
if (gpu_nbnxn_t->pruneTime.c)
{
- print_gputimes(fplog, "Pruning kernel", gpu_nbnxn_t->pruneTime.c,
- gpu_nbnxn_t->pruneTime.t, tot_gpu);
+ print_gputimes(fplog, "Pruning kernel", gpu_nbnxn_t->pruneTime.c, gpu_nbnxn_t->pruneTime.t, tot_gpu);
}
print_gputimes(fplog, "F D2H", gpu_nbnxn_t->nb_c, gpu_nbnxn_t->nb_d2h_t, tot_gpu);
fprintf(fplog, "%s\n", hline);
* and avoid adding it to tot_gpu as this is not in the force
* overlap. We print the fraction as relative to the rest.
*/
- print_gputimes(fplog, "*Dynamic pruning", gpu_nbnxn_t->dynamicPruneTime.c,
- gpu_nbnxn_t->dynamicPruneTime.t, tot_gpu);
+ print_gputimes(fplog,
+ "*Dynamic pruning",
+ gpu_nbnxn_t->dynamicPruneTime.c,
+ gpu_nbnxn_t->dynamicPruneTime.t,
+ tot_gpu);
fprintf(fplog, "%s\n", hline);
}
gpu_cpu_ratio = tot_gpu / tot_cpu_overlap;
fprintf(fplog,
"\nAverage per-step force GPU/CPU evaluation time ratio: %.3f ms/%.3f ms = "
"%.3f\n",
- tot_gpu / gpu_nbnxn_t->nb_c, tot_cpu_overlap / wc->wcc[ewcFORCE].n, gpu_cpu_ratio);
+ tot_gpu / gpu_nbnxn_t->nb_c,
+ tot_cpu_overlap / wc->wcc[ewcFORCE].n,
+ gpu_cpu_ratio);
}
/* only print notes related to CPU-GPU load balance with PME */
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2014,2015,2018, by the GROMACS development team, led by
+# Copyright (c) 2014,2015,2018,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.
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+# Set up the module library
+add_library(tools INTERFACE)
file(GLOB TOOLS_SOURCES *.cpp)
set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${TOOLS_SOURCES} PARENT_SCOPE)
+# Source files have the following dependencies on library infrastructure.
+#target_link_libraries(tools PRIVATE
+# common
+# legacy_modules
+#)
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(tools PUBLIC
+target_include_directories(tools INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(tools PUBLIC
+target_link_libraries(tools INTERFACE
+ legacy_api
+ )
+
+# TODO: when tools is an OBJECT target
+#target_link_libraries(tools PUBLIC legacy_api)
+#target_link_libraries(tools PRIVATE common)
+
+# Module dependencies
+# tools interfaces convey transitive dependence on these modules.
+#target_link_libraries(tools PUBLIC
+target_link_libraries(tools INTERFACE
+ utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(tools PRIVATE NOTHING)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(tools PRIVATE legacy_modules)
+
+
+
if (BUILD_TESTING)
add_subdirectory(tests)
endif()
deviation = gmx::square(blen - b0);
if (std::sqrt(deviation / gmx::square(b0)) > tol)
{
- fprintf(stderr, "Distance between atoms %d and %d is %.3f, should be %.3f\n",
- ai + 1, aj + 1, blen, b0);
+ fprintf(stderr,
+ "Distance between atoms %d and %d is %.3f, should be %.3f\n",
+ ai + 1,
+ aj + 1,
+ blen,
+ b0);
}
}
}
> 0.1 * (std::fabs(fr.time - old_t1) + std::fabs(old_t1 - old_t2)))
{
bShowTimestep = FALSE;
- fprintf(stderr, "%sTimesteps at t=%g don't match (%g, %g)\n", newline ? "\n" : "",
- old_t1, old_t1 - old_t2, fr.time - old_t1);
+ fprintf(stderr,
+ "%sTimesteps at t=%g don't match (%g, %g)\n",
+ newline ? "\n" : "",
+ old_t1,
+ old_t1 - old_t2,
+ fr.time - old_t1);
}
}
natoms = new_natoms;
"Natoms * %d or Natoms * %d,\n"
"the velocities correspond to a temperature of the system\n"
"of %g K or %g K respectively.\n\n",
- DIM, DIM - 1, temp1, temp2);
+ DIM,
+ DIM - 1,
+ temp1,
+ temp2);
}
/* check coordinates */
fprintf(stderr,
"Checking for atoms closer than %g and not between %g and %g,\n"
"relative to sum of Van der Waals distance:\n",
- vdw_fac, bon_lo, bon_hi);
+ vdw_fac,
+ bon_lo,
+ bon_hi);
snew(atom_vdw, natom);
AtomProperties aps;
for (i = 0; (i < natom); i++)
{
- aps.setAtomProperty(epropVDW, *(atoms->resinfo[atoms->atom[i].resind].name),
- *(atoms->atomname[i]), &(atom_vdw[i]));
+ aps.setAtomProperty(epropVDW,
+ *(atoms->resinfo[atoms->atom[i].resind].name),
+ *(atoms->atomname[i]),
+ &(atom_vdw[i]));
if (debug)
{
- fprintf(debug, "%5d %4s %4s %7g\n", i + 1, *(atoms->resinfo[atoms->atom[i].resind].name),
- *(atoms->atomname[i]), atom_vdw[i]);
+ fprintf(debug,
+ "%5d %4s %4s %7g\n",
+ i + 1,
+ *(atoms->resinfo[atoms->atom[i].resind].name),
+ *(atoms->atomname[i]),
+ atom_vdw[i]);
}
}
if (bB)
{
if (bFirst)
{
- fprintf(stderr, "\r%5s %4s %8s %5s %5s %4s %8s %5s %6s\n", "atom#", "name",
- "residue", "r_vdw", "atom#", "name", "residue", "r_vdw", "distance");
+ fprintf(stderr,
+ "\r%5s %4s %8s %5s %5s %4s %8s %5s %6s\n",
+ "atom#",
+ "name",
+ "residue",
+ "r_vdw",
+ "atom#",
+ "name",
+ "residue",
+ "r_vdw",
+ "distance");
bFirst = FALSE;
}
- fprintf(stderr, "\r%5d %4s %4s%4d %-5.3g %5d %4s %4s%4d %-5.3g %-6.4g\n", i + 1,
- *(atoms->atomname[i]), *(atoms->resinfo[atoms->atom[i].resind].name),
- atoms->resinfo[atoms->atom[i].resind].nr, atom_vdw[i], j + 1,
- *(atoms->atomname[j]), *(atoms->resinfo[atoms->atom[j].resind].name),
- atoms->resinfo[atoms->atom[j].resind].nr, atom_vdw[j], std::sqrt(r2));
+ fprintf(stderr,
+ "\r%5d %4s %4s%4d %-5.3g %5d %4s %4s%4d %-5.3g %-6.4g\n",
+ i + 1,
+ *(atoms->atomname[i]),
+ *(atoms->resinfo[atoms->atom[i].resind].name),
+ atoms->resinfo[atoms->atom[i].resind].nr,
+ atom_vdw[i],
+ j + 1,
+ *(atoms->atomname[j]),
+ *(atoms->resinfo[atoms->atom[j].resind].name),
+ atoms->resinfo[atoms->atom[j].resind].nr,
+ atom_vdw[j],
+ std::sqrt(r2));
}
}
}
"):\n"
"(These may occur often and are normally not a problem)\n"
"%5s %4s %8s %5s %s\n",
- "atom#", "name", "residue", "r_vdw", "coordinate");
+ "atom#",
+ "name",
+ "residue",
+ "r_vdw",
+ "coordinate");
bFirst = FALSE;
}
- fprintf(stderr, "%5d %4s %4s%4d %-5.3g", i, *(atoms->atomname[i]),
+ fprintf(stderr,
+ "%5d %4s %4s%4d %-5.3g",
+ i,
+ *(atoms->atomname[i]),
*(atoms->resinfo[atoms->atom[i].resind].name),
- atoms->resinfo[atoms->atom[i].resind].nr, atom_vdw[i]);
+ atoms->resinfo[atoms->atom[i].resind].nr,
+ atom_vdw[i]);
for (j = 0; (j < DIM); j++)
{
fprintf(stderr, " %6.3g", x[i][j]);
printf("Nr. Group #Entries First Last\n");
for (i = 0; (i < grps->nr); i++)
{
- printf("%4d %-20s%8d%8d%8d\n", i, grpname[i], grps->index[i + 1] - grps->index[i],
- grps->a[grps->index[i]] + 1, grps->a[grps->index[i + 1] - 1] + 1);
+ printf("%4d %-20s%8d%8d%8d\n",
+ i,
+ grpname[i],
+ grps->index[i + 1] - grps->index[i],
+ grps->a[grps->index[i]] + 1,
+ grps->a[grps->index[i + 1] - 1] + 1);
}
}
for (i = 0; (i < grps->nr); i++)
> 0.1 * (fabs(fr->t - old_t1) + std::fabs(old_t1 - old_t2)))
{
bShowTStep = FALSE;
- fprintf(stderr, "\nTimesteps at t=%g don't match (%g, %g)\n", old_t1,
- old_t1 - old_t2, fr->t - old_t1);
+ fprintf(stderr, "\nTimesteps at t=%g don't match (%g, %g)\n", old_t1, old_t1 - old_t2, fr->t - old_t1);
}
}
old_t2 = old_t1;
}
if (fnr == 0)
{
- fprintf(stderr, "\rframe: %6s (index %6d), t: %10.3f\n", gmx_step_str(fr->step, buf),
- fnr, fr->t);
+ fprintf(stderr, "\rframe: %6s (index %6d), t: %10.3f\n", gmx_step_str(fr->step, buf), fnr, fr->t);
}
fnr++;
}
gmx_fatal(FARGS,
"Your index file contains atomnumbers (e.g. %d)\nthat are larger than the number "
"of atoms in the tpr file (%d)",
- (numberInIndexFile), (maxAtomNumber));
+ (numberInIndexFile),
+ (maxAtomNumber));
}
}
}
}
- fprintf(stderr, "Reduced block %8s from %6zu to %6zu index-, %6d to %6d a-entries\n", name,
- src.size(), lists.size(), src.numElements(), lists.numElements());
+ fprintf(stderr,
+ "Reduced block %8s from %6zu to %6zu index-, %6d to %6d a-entries\n",
+ name,
+ src.size(),
+ lists.size(),
+ src.numElements(),
+ lists.numElements());
return lists;
}
ilReduced.push_back(il->iatoms[i], nratoms, newAtoms.data());
}
}
- fprintf(stderr, "Reduced ilist %8s from %6d to %6d entries\n", name,
- il->size() / (nratoms + 1), ilReduced.size() / (nratoms + 1));
+ fprintf(stderr,
+ "Reduced ilist %8s from %6d to %6d entries\n",
+ name,
+ il->size() / (nratoms + 1),
+ ilReduced.size() / (nratoms + 1));
*il = std::move(ilReduced);
}
for (int i = 0; (i < F_NRE); i++)
{
- reduce_ilist(invindex, bKeep, &(top.idef.il[i]), interaction_function[i].nratoms,
+ reduce_ilist(invindex,
+ bKeep,
+ &(top.idef.il[i]),
+ interaction_function[i].nratoms,
interaction_function[i].name);
}
{
ir->nsteps = ir->nsteps - (currentMaxStep - ir->init_step)
+ gmx::roundToInt64(extendTime_ / ir->delta_t);
- printf("Extending remaining runtime of by %g ps (now %s steps)\n", extendTime_,
+ printf("Extending remaining runtime of by %g ps (now %s steps)\n",
+ extendTime_,
gmx_step_str(ir->nsteps, buf));
}
else if (runToMaxTimeIsSet_)
{
printf("nsteps = %s, run_step = %s, current_t = %g, until = %g\n",
- gmx_step_str(ir->nsteps, buf), gmx_step_str(currentMaxStep, buf2),
- currentRunTime, runToMaxTime_);
+ gmx_step_str(ir->nsteps, buf),
+ gmx_step_str(currentMaxStep, buf2),
+ currentRunTime,
+ runToMaxTime_);
ir->nsteps = gmx::roundToInt64((currentMaxRunTime - currentRunTime) / ir->delta_t);
- printf("Extending remaining runtime until %g ps (now %s steps)\n", currentMaxRunTime,
+ printf("Extending remaining runtime until %g ps (now %s steps)\n",
+ currentMaxRunTime,
gmx_step_str(ir->nsteps, buf));
}
else
{
ir->nsteps -= currentMaxStep - ir->init_step;
/* Print message */
- printf("%s steps (%g ps) remaining from first run.\n", gmx_step_str(ir->nsteps, buf),
+ printf("%s steps (%g ps) remaining from first run.\n",
+ gmx_step_str(ir->nsteps, buf),
ir->nsteps * ir->delta_t);
}
}
fprintf(stderr,
"Will write subset %s of original tpx containing %d "
"atoms\n",
- grpname, gnx);
+ grpname,
+ gnx);
reduce_topology_x(gnx, index, &mtop, state.x.rvec_array(), state.v.rvec_array());
state.natoms = gnx;
}
}
double stateTime = ir->init_t + ir->init_step * ir->delta_t;
- sprintf(buf, "Writing statusfile with starting step %s%s and length %s%s steps...\n", "%10",
- PRId64, "%10", PRId64);
+ sprintf(buf,
+ "Writing statusfile with starting step %s%s and length %s%s steps...\n",
+ "%10",
+ PRId64,
+ "%10",
+ PRId64);
fprintf(stderr, buf, ir->init_step, ir->nsteps);
- fprintf(stderr, " time %10.3f and length %10.3f ps\n",
- stateTime, ir->nsteps * ir->delta_t);
+ fprintf(stderr,
+ " time %10.3f and length %10.3f ps\n",
+ stateTime,
+ ir->nsteps * ir->delta_t);
write_tpx_state(outputTprFileName_.c_str(), ir, &state, &mtop);
}
else
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2013, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
{
for (auto group : keysOf(gcount))
{
+ if (group == SimulationAtomGroupType::AccelerationUnused)
+ {
+ continue;
+ }
gcount[group][getGroupType(groups, group, i)]++;
}
}
snew(x, trrheader.natoms);
snew(v, trrheader.natoms);
snew(f, trrheader.natoms);
- if (gmx_trr_read_frame_data(fpread, &trrheader, trrheader.box_size ? box : nullptr,
- trrheader.x_size ? x : nullptr, trrheader.v_size ? v : nullptr,
+ if (gmx_trr_read_frame_data(fpread,
+ &trrheader,
+ trrheader.box_size ? box : nullptr,
+ trrheader.x_size ? x : nullptr,
+ trrheader.v_size ? v : nullptr,
trrheader.f_size ? f : nullptr))
{
sprintf(buf, "%s frame %d", fn, nframe);
indent = 0;
indent = pr_title(stdout, indent, buf);
pr_indent(stdout, indent);
- fprintf(stdout, "natoms=%10d step=%10" PRId64 " time=%12.7e lambda=%10g\n",
- trrheader.natoms, trrheader.step, trrheader.t, trrheader.lambda);
+ fprintf(stdout,
+ "natoms=%10d step=%10" PRId64 " time=%12.7e lambda=%10g\n",
+ trrheader.natoms,
+ trrheader.step,
+ trrheader.t,
+ trrheader.lambda);
if (trrheader.box_size)
{
pr_rvecs(stdout, indent, "box", box, DIM);
indent = 0;
indent = pr_title(stdout, indent, buf);
pr_indent(stdout, indent);
- fprintf(stdout, "natoms=%10d step=%10" PRId64 " time=%12.7e prec=%10g\n", natoms, step,
- time, prec);
+ fprintf(stdout, "natoms=%10d step=%10" PRId64 " time=%12.7e prec=%10g\n", natoms, step, time, prec);
pr_rvecs(stdout, indent, "box", box, DIM);
pr_rvecs(stdout, indent, "x", x, natoms);
nframe++;
int64_t n_values_per_frame, n_atoms;
char block_name[STRLEN];
- gmx_get_tng_data_next_frame_of_block_type(tng, block_ids[i], &values, &step,
- &frame_time, &n_values_per_frame, &n_atoms,
- &prec, block_name, STRLEN, &bOK);
+ gmx_get_tng_data_next_frame_of_block_type(tng,
+ block_ids[i],
+ &values,
+ &step,
+ &frame_time,
+ &n_values_per_frame,
+ &n_atoms,
+ &prec,
+ block_name,
+ STRLEN,
+ &bOK);
if (!bOK)
{
/* Can't write any output because we don't know what
arrays are valid. */
- fprintf(stderr, "\nWARNING: Incomplete frame at time %g, will not write output\n",
- frame_time);
+ fprintf(stderr, "\nWARNING: Incomplete frame at time %g, will not write output\n", frame_time);
}
else
{
- list_tng_inner(fn, (0 == i), values, step, frame_time, n_values_per_frame, n_atoms,
- prec, nframe, block_name);
+ list_tng_inner(
+ fn, (0 == i), values, step, frame_time, n_values_per_frame, n_atoms, prec, nframe, block_name);
}
}
nframe++;
- } while (gmx_get_tng_data_block_types_of_next_frame(tng, step, 0, nullptr, &step, &ndatablocks,
- &block_ids));
+ } while (gmx_get_tng_data_block_types_of_next_frame(
+ tng, step, 0, nullptr, &step, &ndatablocks, &block_ids));
if (block_ids)
{
case efTRR: list_trr(fn); break;
case efTNG: list_tng(fn); break;
default:
- fprintf(stderr, "File %s is of an unsupported type. Try using the command\n 'less %s'\n",
- fn, fn);
+ fprintf(stderr, "File %s is of an unsupported type. Try using the command\n 'less %s'\n", fn, fn);
}
}
{
printf("\n%24s %12.5e %12s %12s\n", "time:", fr->t, "step:", gmx_step_str(fr->step, buf));
printf("%24s %12s %12s %12s\n", "", "", "nsteps:", gmx_step_str(fr->nsteps, buf));
- printf("%24s %12.5e %12s %12s\n", "delta_t:", fr->dt,
- "sum steps:", gmx_step_str(fr->nsum, buf));
+ printf("%24s %12.5e %12s %12s\n", "delta_t:", fr->dt, "sum steps:", gmx_step_str(fr->nsum, buf));
if (fr->nre == nre)
{
- printf("%24s %12s %12s %12s\n", "Component", "Energy", "Av. Energy",
+ printf("%24s %12s %12s %12s\n",
+ "Component",
+ "Energy",
+ "Av. Energy",
"Sum Energy");
if (fr->nsum > 0)
{
for (i = 0; (i < nre); i++)
{
- printf("%24s %12.5e %12.5e %12.5e\n", enm[i].name, fr->ener[i].e,
- fr->ener[i].eav, fr->ener[i].esum);
+ printf("%24s %12.5e %12.5e %12.5e\n",
+ enm[i].name,
+ fr->ener[i].e,
+ fr->ener[i].eav,
+ fr->ener[i].esum);
}
}
else
for (i = 0; i < eb->nsub; i++)
{
t_enxsubblock* sb = &(eb->sub[i]);
- printf(" Sub block %3d (%5d elems, type=%s) values:\n", i, sb->nr,
+ printf(" Sub block %3d (%5d elems, type=%s) values:\n",
+ i,
+ sb->nr,
xdr_datatype_names[sb->type]);
switch (sb->type)
{
if (!inputTprFilename_.empty())
{
- list_tpr(inputTprFilename_.c_str(), bShowNumbers_, bShowParams_,
- outputMdpFilename_.empty() ? nullptr : outputMdpFilename_.c_str(), bSysTop_,
+ list_tpr(inputTprFilename_.c_str(),
+ bShowNumbers_,
+ bShowParams_,
+ outputMdpFilename_.empty() ? nullptr : outputMdpFilename_.c_str(),
+ bSysTop_,
bOriginalInputrec_);
}
else if (!inputTrajectoryFilename_.empty())
fprintf(stderr,
"Energy files don't match, different number of energies:\n"
" %s: %d\n %s: %d\n",
- files[f - 1].c_str(), nresav, files[f].c_str(), fr->nre);
+ files[f - 1].c_str(),
+ nresav,
+ files[f].c_str(),
+ fr->nre);
fprintf(stderr,
"\nContinue conversion using only the first %d terms (n/y)?\n"
"(you should be sure that the energy terms match)\n",
{ "-error", FALSE, etBOOL, { &bError }, "Stop on errors in the file" }
};
- if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa, asize(desc), desc,
- asize(bugs), bugs, &oenv))
+ if (!parse_common_args(
+ &argc, argv, 0, NFILE, fnm, asize(pa), pa, asize(desc), desc, asize(bugs), bugs, &oenv))
{
return 0;
}
if (debug)
{
- fprintf(debug, "fr->step %s, fr->t %.4f, fro->step %s fro->t %.4f, w %s\n",
- gmx_step_str(fr->step, buf), fr->t, gmx_step_str(fro->step, buf2), fro->t,
+ fprintf(debug,
+ "fr->step %s, fr->t %.4f, fro->step %s fro->t %.4f, w %s\n",
+ gmx_step_str(fr->step, buf),
+ fr->t,
+ gmx_step_str(fro->step, buf2),
+ fro->t,
gmx::boolToString(bWrite));
}
if (bNewOutput)
{
bNewOutput = FALSE;
- fprintf(stderr, "\nContinue writing frames from t=%g, step=%s\n", fro->t,
+ fprintf(stderr,
+ "\nContinue writing frames from t=%g, step=%s\n",
+ fro->t,
gmx_step_str(fro->step, buf));
}
"samples away.\n"
" Use g_energy -odh option to extract these "
"samples.\n",
- files[f].c_str(), size);
+ files[f].c_str(),
+ size);
warned_about_dh = TRUE;
break;
}
{
f--;
}
- printf("\nLast step written from %s: t %g, step %s\n", files[f].c_str(), last_t,
+ printf("\nLast step written from %s: t %g, step %s\n",
+ files[f].c_str(),
+ last_t,
gmx_step_str(laststep, buf));
lastfilestep = laststep;
}
else
{
- fprintf(stderr, "Last frame written was at step %s, time %f\n",
- gmx_step_str(fro->step, buf), fro->t);
+ fprintf(stderr, "Last frame written was at step %s, time %f\n", gmx_step_str(fro->step, buf), fro->t);
fprintf(stderr, "Wrote %d frames\n", noutfr);
}
switch (ftype)
{
case F_ANGLES:
- sprintf(buf, "Theta=%.1f_%.2f", idef->iparams[i].harmonic.rA,
+ sprintf(buf,
+ "Theta=%.1f_%.2f",
+ idef->iparams[i].harmonic.rA,
idef->iparams[i].harmonic.krA);
break;
case F_G96ANGLES:
- sprintf(buf, "Cos_th=%.1f_%.2f", idef->iparams[i].harmonic.rA,
+ sprintf(buf,
+ "Cos_th=%.1f_%.2f",
+ idef->iparams[i].harmonic.rA,
idef->iparams[i].harmonic.krA);
break;
case F_UREY_BRADLEY:
- sprintf(buf, "UB_th=%.1f_%.2f2f", idef->iparams[i].u_b.thetaA,
+ sprintf(buf,
+ "UB_th=%.1f_%.2f2f",
+ idef->iparams[i].u_b.thetaA,
idef->iparams[i].u_b.kthetaA);
break;
case F_QUARTIC_ANGLES:
- sprintf(buf, "Q_th=%.1f_%.2f_%.2f", idef->iparams[i].qangle.theta,
- idef->iparams[i].qangle.c[0], idef->iparams[i].qangle.c[1]);
+ sprintf(buf,
+ "Q_th=%.1f_%.2f_%.2f",
+ idef->iparams[i].qangle.theta,
+ idef->iparams[i].qangle.c[0],
+ idef->iparams[i].qangle.c[1]);
break;
case F_TABANGLES:
- sprintf(buf, "Table=%d_%.2f", idef->iparams[i].tab.table,
+ sprintf(buf,
+ "Table=%d_%.2f",
+ idef->iparams[i].tab.table,
idef->iparams[i].tab.kA);
break;
case F_PDIHS:
- sprintf(buf, "Phi=%.1f_%d_%.2f", idef->iparams[i].pdihs.phiA,
- idef->iparams[i].pdihs.mult, idef->iparams[i].pdihs.cpA);
+ sprintf(buf,
+ "Phi=%.1f_%d_%.2f",
+ idef->iparams[i].pdihs.phiA,
+ idef->iparams[i].pdihs.mult,
+ idef->iparams[i].pdihs.cpA);
break;
case F_IDIHS:
- sprintf(buf, "Xi=%.1f_%.2f", idef->iparams[i].harmonic.rA,
+ sprintf(buf,
+ "Xi=%.1f_%.2f",
+ idef->iparams[i].harmonic.rA,
idef->iparams[i].harmonic.krA);
break;
case F_RBDIHS:
case F_RESTRANGLES:
// Fall through intended
case F_RESTRDIHS:
- sprintf(buf, "Theta=%.1f_%.2f", idef->iparams[i].harmonic.rA,
+ sprintf(buf,
+ "Theta=%.1f_%.2f",
+ idef->iparams[i].harmonic.rA,
idef->iparams[i].harmonic.krA);
break;
case F_CBTDIHS:
break;
default:
- gmx_fatal(FARGS, "Unsupported function type '%s' selected",
+ gmx_fatal(FARGS,
+ "Unsupported function type '%s' selected",
interaction_function[ftype].longname);
}
grpnames[ind] = gmx_strdup(buf);
fprintf(stderr,
"Molecule %2d (%5d atoms) q2_mol=%10.3e nr.mol.charges=%5d (%6dx) q2_all=%10.3e "
"tot.charges=%d\n",
- imol, molecule.atoms.nr, q2_mol, nrq_mol, molblock.nmol, q2_all, nrq_all);
+ imol,
+ molecule.atoms.nr,
+ q2_mol,
+ nrq_mol,
+ molblock.nmol,
+ q2_all,
+ nrq_all);
#endif
}
}
if (MASTER(cr))
{
- fprintf(stderr, "\rCalculating reciprocal error part 1 ... %3.0f%%",
+ fprintf(stderr,
+ "\rCalculating reciprocal error part 1 ... %3.0f%%",
100.0 * (nx - startlocal + 1) / (x_per_core));
fflush(stderr);
}
if (bVerbose && MASTER(cr))
{
- fprintf(stdout, "Using %d sample%s to approximate the self interaction error term",
- xtot, xtot == 1 ? "" : "s");
+ fprintf(stdout,
+ "Using %d sample%s to approximate the self interaction error term",
+ xtot,
+ xtot == 1 ? "" : "s");
if (PAR(cr))
{
fprintf(stdout, " (%d sample%s per rank)", x_per_core, x_per_core == 1 ? "" : "s");
fprintf(fp_out, "Ewald_rtol : %g\n", info->ewald_rtol[0]);
fprintf(fp_out, "Ewald parameter beta : %g\n", info->ewald_beta[0]);
fprintf(fp_out, "Interpolation order : %d\n", info->pme_order[0]);
- fprintf(fp_out, "Fourier grid (nx,ny,nz) : %d x %d x %d\n", info->nkx[0], info->nky[0],
- info->nkz[0]);
+ fprintf(fp_out, "Fourier grid (nx,ny,nz) : %d x %d x %d\n", info->nkx[0], info->nky[0], info->nkz[0]);
fflush(fp_out);
}
if (MASTER(cr))
{
i++;
- fprintf(stderr, "difference between real and rec. space error (step %d): %g\n", i,
+ fprintf(stderr,
+ "difference between real and rec. space error (step %d): %g\n",
+ i,
std::abs(derr));
fprintf(stderr, "old beta: %f\n", beta0);
fprintf(stderr, "new beta: %f\n", beta);
t_commrec* cr = commrecHandle.get();
PCA_Flags = PCA_NOEXIT_ON_ARGS;
- if (!parse_common_args(&argc, argv, PCA_Flags, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0,
- nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_Flags, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
info.nkx[0] = 0;
info.nky[0] = 0;
info.nkz[0] = 0;
- calcFftGrid(stdout, state.box, info.fourier_sp[0], minimalPmeGridSize(info.pme_order[0]),
- &(info.nkx[0]), &(info.nky[0]), &(info.nkz[0]));
+ calcFftGrid(stdout,
+ state.box,
+ info.fourier_sp[0],
+ minimalPmeGridSize(info.pme_order[0]),
+ &(info.nkx[0]),
+ &(info.nky[0]),
+ &(info.nkz[0]));
if ((ir.nkx != info.nkx[0]) || (ir.nky != info.nky[0]) || (ir.nkz != info.nkz[0]))
{
gmx_fatal(FARGS,
"Wrong fourierspacing %f nm, input file grid = %d x %d x %d, computed grid = "
"%d x %d x %d",
- fs, ir.nkx, ir.nky, ir.nkz, info.nkx[0], info.nky[0], info.nkz[0]);
+ fs,
+ ir.nkx,
+ ir.nky,
+ ir.nkz,
+ info.nkx[0],
+ info.nky[0],
+ info.nkz[0]);
}
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
}
{
writer->writeLine(formatString("A system of %d molecules (%d atoms) was simulated.",
- gmx_mtop_num_molecules(top), top.natoms - nvsite));
+ gmx_mtop_num_molecules(top),
+ top.natoms - nvsite));
}
if (nvsite)
{
{
writeHeader(writer, "Simulation settings", "subsection", writeFormattedText);
writer->writeLine(formatString("A total of %g ns were simulated with a time step of %g fs.",
- ir.nsteps * ir.delta_t * 0.001, 1000 * ir.delta_t));
+ ir.nsteps * ir.delta_t * 0.001,
+ 1000 * ir.delta_t));
writer->writeLine(formatString("Neighbor searching was performed every %d steps.", ir.nstlist));
writer->writeLine(formatString("The %s algorithm was used for electrostatic interactions.",
EELTYPE(ir.coulombtype)));
writer->writeLine(
formatString("A reciprocal grid of %d x %d x %d cells was used with %dth order "
"B-spline interpolation.",
- ir.nkx, ir.nky, ir.nkz, ir.pme_order));
+ ir.nkx,
+ ir.nky,
+ ir.nkz,
+ ir.pme_order));
}
writer->writeLine(formatString(
"A single cut-off of %g nm was used for Van der Waals interactions.", ir.rlist));
- if (ir.etc != 0)
+ if (ir.etc != TemperatureCoupling::No)
{
writer->writeLine(formatString("Temperature coupling was done with the %s algorithm.",
- etcoupl_names[ir.etc]));
+ enumValueToString(ir.etc)));
}
- if (ir.epc != 0)
+ if (ir.epc != PressureCoupling::No)
{
writer->writeLine(formatString("Pressure coupling was done with the %s algorithm.",
- epcoupl_names[ir.epc]));
+ enumValueToString(ir.epc)));
}
writer->ensureEmptyLine();
}
TEST_F(DumpTest, WorksWithTprAndMdpWriting)
{
- TestFileManager fileManager;
- std::string mdpName = fileManager.getTemporaryFilePath("output.mdp");
- const char* const command[] = { "dump", "-s", s_tprFileHandle->tprName().c_str(), "-om",
- mdpName.c_str() };
- CommandLine cmdline(command);
+ TestFileManager fileManager;
+ std::string mdpName = fileManager.getTemporaryFilePath("output.mdp");
+ const char* const command[] = { "dump", "-s", s_tprFileHandle->tprName().c_str(), "-om", mdpName.c_str() };
+ CommandLine cmdline(command);
runTest(&cmdline);
}
{
const char* const command[] = { "report-methods", "-s", s_tprFileHandle->tprName().c_str() };
CommandLine cmdline(command);
- EXPECT_EQ(0, gmx::test::CommandLineTestHelper::runModuleFactory(&gmx::ReportMethodsInfo::create,
- &cmdline));
+ EXPECT_EQ(0, gmx::test::CommandLineTestHelper::runModuleFactory(&gmx::ReportMethodsInfo::create, &cmdline));
}
} // namespace test
fprintf(stderr,
" File Current start (%s) New start (%s)\n"
"---------------------------------------------------------\n",
- timeUnit.c_str(), timeUnit.c_str());
+ timeUnit.c_str(),
+ timeUnit.c_str());
for (gmx::index i = 0; i < files.ssize(); i++)
{
- fprintf(stderr, "%25s %10.3f %s ", files[i].c_str(),
- output_env_conv_time(oenv, readtime[i]), timeUnit.c_str());
+ fprintf(stderr,
+ "%25s %10.3f %s ",
+ files[i].c_str(),
+ output_env_conv_time(oenv, readtime[i]),
+ timeUnit.c_str());
ok = FALSE;
do
{
switch (cont_type[i])
{
case TIME_EXPLICIT:
- fprintf(stderr, "%25s %10.3f %s %10.3f %s", files[i].c_str(),
- output_env_conv_time(oenv, settime[i]), timeUnit.c_str(),
- output_env_conv_time(oenv, timestep[i]), timeUnit.c_str());
+ fprintf(stderr,
+ "%25s %10.3f %s %10.3f %s",
+ files[i].c_str(),
+ output_env_conv_time(oenv, settime[i]),
+ timeUnit.c_str(),
+ output_env_conv_time(oenv, timestep[i]),
+ timeUnit.c_str());
if (i > 0 && cont_type[i - 1] == TIME_EXPLICIT && settime[i] == settime[i - 1])
{
fprintf(stderr, " WARNING: same Start time as previous");
}
else if (natoms != trx[i].natoms)
{
- gmx_fatal(FARGS, "Trajectory file %s has %d atoms while previous trajs had %d atoms",
- inFiles[i].c_str(), trx[i].natoms, natoms);
+ gmx_fatal(FARGS,
+ "Trajectory file %s has %d atoms while previous trajs had %d atoms",
+ inFiles[i].c_str(),
+ trx[i].natoms,
+ natoms);
}
if (t == -1)
{
}
else if (t != trx[i].time)
{
- gmx_fatal(FARGS, "Trajectory file %s has time %f while previous trajs had time %f",
- inFiles[i].c_str(), trx[i].time, t);
+ gmx_fatal(FARGS,
+ "Trajectory file %s has time %f while previous trajs had time %f",
+ inFiles[i].c_str(),
+ trx[i].time,
+ t);
}
}
#define NFILE asize(fnm)
- if (!parse_common_args(&argc, argv, PCA_TIME_UNIT, NFILE, fnm, asize(pa), pa, asize(desc), desc,
- 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_TIME_UNIT, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
{
nset = 0;
dt_remd = 0;
- val = read_xvg_time(opt2fn("-demux", NFILE, fnm), TRUE, opt2parg_bSet("-b", npargs, pa),
- begin, opt2parg_bSet("-e", npargs, pa), end, 1, &nset, &n, &dt_remd, &t);
+ val = read_xvg_time(opt2fn("-demux", NFILE, fnm),
+ TRUE,
+ opt2parg_bSet("-b", npargs, pa),
+ begin,
+ opt2parg_bSet("-e", npargs, pa),
+ end,
+ 1,
+ &nset,
+ &n,
+ &dt_remd,
+ &t);
printf("Read %d sets of %d points, dt = %g\n\n", nset, n, dt_remd);
if (debug)
{
if (bDeMux && ssize(inFiles) != nset)
{
- gmx_fatal(FARGS, "You have specified %td files and %d entries in the demux table",
- inFiles.ssize(), nset);
+ gmx_fatal(FARGS, "You have specified %td files and %d entries in the demux table", inFiles.ssize(), nset);
}
ftpin = fn2ftp(inFiles[0].c_str());
}
else if (bDeMux && ssize(outFiles) != nset && outFiles.size() != 1)
{
- gmx_fatal(FARGS, "Number of output files should be 1 or %d (#input files), not %td", nset,
+ gmx_fatal(FARGS,
+ "Number of output files should be 1 or %d (#input files), not %td",
+ nset,
outFiles.ssize());
}
if (bDeMux)
}
else if (n_append != -1)
{
- gmx_fatal(FARGS, "Can only append to the first file which is %s (not %s)",
- inFilesEdited[0].c_str(), out_file);
+ gmx_fatal(FARGS,
+ "Can only append to the first file which is %s (not %s)",
+ inFilesEdited[0].c_str(),
+ out_file);
}
/* Not checking input format, could be dangerous :-) */
}
if (bIndex)
{
- trxout = trjtools_gmx_prepare_tng_writing(
- out_file, 'w', nullptr, inFilesEdited[0].c_str(), isize, nullptr,
- gmx::arrayRefFromArray(index, isize), grpname);
+ trxout = trjtools_gmx_prepare_tng_writing(out_file,
+ 'w',
+ nullptr,
+ inFilesEdited[0].c_str(),
+ isize,
+ nullptr,
+ gmx::arrayRefFromArray(index, isize),
+ grpname);
}
else
{
read_next_frame(oenv, status, &fr);
if (std::abs(searchtime - fr.time) > timest[0] * 0.5)
{
- gmx_fatal(FARGS, "Error seeking: attempted to seek to %f but got %f.",
- searchtime, fr.time);
+ gmx_fatal(FARGS, "Error seeking: attempted to seek to %f but got %f.", searchtime, fr.time);
}
lasttime = fr.time;
lastTimeSet = TRUE;
"spacing than the rest,\n"
"might be a gap or overlap that couldn't be corrected "
"automatically.\n",
- output_env_conv_time(oenv, frout.time), timeUnit.c_str());
+ output_env_conv_time(oenv, frout.time),
+ timeUnit.c_str());
}
}
}
"\nContinue writing frames from %s t=%g %s, "
"frame=%d \n",
inFilesEdited[i].c_str(),
- output_env_conv_time(oenv, frout.time), timeUnit.c_str(), frame);
+ output_env_conv_time(oenv, frout.time),
+ timeUnit.c_str(),
+ frame);
bNewFile = FALSE;
}
}
if (((frame % 10) == 0) || (frame < 10))
{
- fprintf(stderr, " -> frame %6d time %8.3f %s \r", frame_out,
- output_env_conv_time(oenv, frout.time), timeUnit.c_str());
+ fprintf(stderr,
+ " -> frame %6d time %8.3f %s \r",
+ frame_out,
+ output_env_conv_time(oenv, frout.time),
+ timeUnit.c_str());
fflush(stderr);
}
}
{
close_trx(trxout);
}
- fprintf(stderr, "\nLast frame written was %d, time %f %s\n", frame,
- output_env_conv_time(oenv, last_ok_t), timeUnit.c_str());
+ fprintf(stderr,
+ "\nLast frame written was %d, time %f %s\n",
+ frame,
+ output_env_conv_time(oenv, last_ok_t),
+ timeUnit.c_str());
}
return 0;
fprintf(stderr,
"Do you REALLY want to truncate this trajectory (%s) at:\n"
"frame %d, time %g, bytes %ld ??? (type YES if so)\n",
- fn, j, t, static_cast<long int>(fpos));
+ fn,
+ j,
+ t,
+ static_cast<long int>(fpos));
if (1 != scanf("%s", yesno))
{
gmx_fatal(FARGS, "Error reading user input");
{ efXVG, "-drop", "drop", ffOPTRD } };
#define NFILE asize(fnm)
- if (!parse_common_args(&argc, argv, PCA_CAN_BEGIN | PCA_CAN_END | PCA_CAN_VIEW | PCA_TIME_UNIT,
- NFILE, fnm, NPA, pa, asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(&argc,
+ argv,
+ PCA_CAN_BEGIN | PCA_CAN_END | PCA_CAN_VIEW | PCA_TIME_UNIT,
+ NFILE,
+ fnm,
+ NPA,
+ pa,
+ asize(desc),
+ desc,
+ 0,
+ nullptr,
+ &oenv))
{
return 0;
}
"WARNING: Option for unitcell representation (-ur %s)\n"
" only has effect in combination with -pbc %s, %s or %s.\n"
" Ingoring unitcell representation.\n\n",
- unitcell_opt[0], pbc_opt[2], pbc_opt[3], pbc_opt[4]);
+ unitcell_opt[0],
+ pbc_opt[2],
+ pbc_opt[3],
+ pbc_opt[4]);
}
}
if (bFit && bPBC)
if (0 == top->mols.nr && (bCluster || bPBCcomMol))
{
- gmx_fatal(FARGS, "Option -pbc %s requires a .tpr file for the -s option",
- pbc_opt[pbc_enum]);
+ gmx_fatal(FARGS, "Option -pbc %s requires a .tpr file for the -s option", pbc_opt[pbc_enum]);
}
/* top_title is only used for gro and pdb,
"Index[%d] %d is larger than the number of atoms in the\n"
"trajectory file (%d). There is a mismatch in the contents\n"
"of your -f, -s and/or -n files.",
- i, index[i] + 1, natoms);
+ i,
+ index[i] + 1,
+ natoms);
}
bCopy = bCopy || (i != index[i]);
}
switch (ftp)
{
case efTNG:
- trxout = trjtools_gmx_prepare_tng_writing(
- out_file, filemode[0], trxin, nullptr, nout, mtop.get(),
- gmx::arrayRefFromArray(index, nout), grpnm);
+ trxout = trjtools_gmx_prepare_tng_writing(out_file,
+ filemode[0],
+ trxin,
+ nullptr,
+ nout,
+ mtop.get(),
+ gmx::arrayRefFromArray(index, nout),
+ grpnm);
break;
case efXTC:
case efTRR:
if (bTDump)
{
- fprintf(stderr, "\nDumping frame at t= %g %s\n",
+ fprintf(stderr,
+ "\nDumping frame at t= %g %s\n",
output_env_conv_time(oenv, frout_time),
output_env_get_time_unit(oenv).c_str());
}
else
{
/* round() is not C89 compatible, so we do this: */
- bDoIt = bRmod(std::floor(frout_time + 0.5), std::floor(tzero + 0.5),
+ bDoIt = bRmod(std::floor(frout_time + 0.5),
+ std::floor(tzero + 0.5),
std::floor(delta_t + 0.5));
}
}
/* print sometimes */
if (((outframe % SKIP) == 0) || (outframe < SKIP))
{
- fprintf(stderr, " -> frame %6d time %8.3f \r", outframe,
+ fprintf(stderr,
+ " -> frame %6d time %8.3f \r",
+ outframe,
output_env_conv_time(oenv, frout_time));
fflush(stderr);
}
put_atoms_in_triclinic_unitcell(ecenter, fr.box, positionsArrayRef);
break;
case euCompact:
- put_atoms_in_compact_unitcell(pbcType, ecenter, fr.box,
- positionsArrayRef);
+ put_atoms_in_compact_unitcell(
+ pbcType, ecenter, fr.box, positionsArrayRef);
break;
}
}
if (bPBCcomRes)
{
- put_residue_com_in_box(unitcell_enum, ecenter, natoms, atoms->atom,
- pbcType, fr.box, fr.x);
+ put_residue_com_in_box(
+ unitcell_enum, ecenter, natoms, atoms->atom, pbcType, fr.box, fr.x);
}
if (bPBCcomMol)
{
- put_molecule_com_in_box(unitcell_enum, ecenter, &top->mols, natoms,
- atoms->atom, pbcType, fr.box, fr.x);
+ put_molecule_com_in_box(
+ unitcell_enum, ecenter, &top->mols, natoms, atoms->atom, pbcType, fr.box, fr.x);
}
/* Copy the input trxframe struct to the output trxframe struct */
frout = fr;
/* round() is not C89 compatible, so we do this: */
bSplitHere = bSplit
&& bRmod(std::floor(frout.time + 0.5),
- std::floor(tzero + 0.5), std::floor(split_t + 0.5));
+ std::floor(tzero + 0.5),
+ std::floor(split_t + 0.5));
}
if (bSeparate || bSplitHere)
{
switch (ftp)
{
case efGRO:
- write_hconf_p(out, title.c_str(), &useatoms, frout.x,
- frout.bV ? frout.v : nullptr, frout.box);
+ write_hconf_p(out,
+ title.c_str(),
+ &useatoms,
+ frout.x,
+ frout.bV ? frout.v : nullptr,
+ frout.box);
break;
case efPDB:
fprintf(out, "REMARK GENERATED BY TRJCONV\n");
{
model_nr++;
}
- write_pdbfile(out, title.c_str(), &useatoms, frout.x,
- frout.pbcType, frout.box, ' ', model_nr, gc);
+ write_pdbfile(out,
+ title.c_str(),
+ &useatoms,
+ frout.x,
+ frout.pbcType,
+ frout.box,
+ ' ',
+ model_nr,
+ gc);
break;
case efG96:
const char* outputTitle = "";
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2009-2018, The GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
fprintf(stderr,
"WARNING: Time step counters were reset at step %s,\n"
" though they were supposed to be reset at step %s!\n",
- dumstring, dumstring2);
+ dumstring,
+ dumstring2);
}
}
}
/* Look for domain decomp grid and separate PME nodes: */
if (str_starts(line, matchstrdd))
{
- sscanf(line, "Domain decomposition grid %d x %d x %d, separate PME ranks %d",
- &(perfdata->nx), &(perfdata->ny), &(perfdata->nz), &npme);
+ sscanf(line,
+ "Domain decomposition grid %d x %d x %d, separate PME ranks %d",
+ &(perfdata->nx),
+ &(perfdata->ny),
+ &(perfdata->nz),
+ &npme);
if (perfdata->nPMEnodes == -1)
{
perfdata->guessPME = npme;
s /= (nrepeats - 1);
s = std::sqrt(s);
- fprintf(fp, "%4d %3d %4d%s %12.3f %12.3f %12.3f %s", line, k, pd->nPMEnodes,
- strbuf, pd->Gcycles_Av, s, pd->ns_per_day_Av, str_PME_f_load);
+ fprintf(fp,
+ "%4d %3d %4d%s %12.3f %12.3f %12.3f %s",
+ line,
+ k,
+ pd->nPMEnodes,
+ strbuf,
+ pd->Gcycles_Av,
+ s,
+ pd->ns_per_day_Av,
+ str_PME_f_load);
if (nnodes > 1)
{
fprintf(fp, " %3d %3d %3d", pd->nx, pd->ny, pd->nz);
if (bRefinedCoul)
{
- fprintf(fp, " New Coulomb radius: %f nm (was %f nm)\n", info->rcoulomb[k_win],
- info->rcoulomb[0]);
+ fprintf(fp, " New Coulomb radius: %f nm (was %f nm)\n", info->rcoulomb[k_win], info->rcoulomb[0]);
}
if (bRefinedVdW)
if (bRefinedGrid)
{
- fprintf(fp, " New Fourier grid xyz: %d %d %d (was %d %d %d)\n", info->nkx[k_win],
- info->nky[k_win], info->nkz[k_win], info->nkx[0], info->nky[0], info->nkz[0]);
+ fprintf(fp,
+ " New Fourier grid xyz: %d %d %d (was %d %d %d)\n",
+ info->nkx[k_win],
+ info->nky[k_win],
+ info->nkz[k_win],
+ info->nkx[0],
+ info->nky[0],
+ info->nkz[0]);
}
if (bCanUseOrigTPR && ntprs > 1)
}
else
{
- snew(command, std::strlen(cmd_mpirun) + std::strlen(cmd_np) + std::strlen(cmd_mdrun)
- + std::strlen(filename) + 50);
+ snew(command,
+ std::strlen(cmd_mpirun) + std::strlen(cmd_np) + std::strlen(cmd_mdrun)
+ + std::strlen(filename) + 50);
sprintf(command, "%s%s%s -version -maxh 0.001 1> %s 2>&1", cmd_mpirun, cmd_np, cmd_mdrun, filename);
}
fprintf(stdout, "Trying '%s' ... ", command);
/* Make enough space for the system call command,
* (200 extra chars for -npme ... etc. options should suffice): */
- snew(command, std::strlen(cmd_mpirun) + std::strlen(cmd_mdrun) + std::strlen(cmd_np)
- + std::strlen(args_for_mdrun) + std::strlen(simulation_tpr) + 200);
+ snew(command,
+ std::strlen(cmd_mpirun) + std::strlen(cmd_mdrun) + std::strlen(cmd_np)
+ + std::strlen(args_for_mdrun) + std::strlen(simulation_tpr) + 200);
auto cmd_gpu_ids = make_gpu_id_command_line(eligible_gpu_ids);
* of the command line string */
if (bThreads)
{
- sprintf(command, "%s%s-npme %d -s %s %s %s", cmd_mdrun, cmd_np, nPMEnodes, simulation_tpr,
- args_for_mdrun, cmd_gpu_ids.c_str());
+ sprintf(command,
+ "%s%s-npme %d -s %s %s %s",
+ cmd_mdrun,
+ cmd_np,
+ nPMEnodes,
+ simulation_tpr,
+ args_for_mdrun,
+ cmd_gpu_ids.c_str());
}
else
{
- sprintf(command, "%s%s%s -npme %d -s %s %s %s", cmd_mpirun, cmd_np, cmd_mdrun, nPMEnodes,
- simulation_tpr, args_for_mdrun, cmd_gpu_ids.c_str());
+ sprintf(command,
+ "%s%s%s -npme %d -s %s %s %s",
+ cmd_mpirun,
+ cmd_np,
+ cmd_mdrun,
+ nPMEnodes,
+ simulation_tpr,
+ args_for_mdrun,
+ cmd_gpu_ids.c_str());
}
- fprintf(fp, "%s this command line to launch the simulation:\n\n%s",
- bLaunch ? "Using" : "Please use", command);
+ fprintf(fp, "%s this command line to launch the simulation:\n\n%s", bLaunch ? "Using" : "Please use", command);
sep_line(fp);
fflush(fp);
real fourierspacing; /* Basic fourierspacing from tpr */
- sprintf(buf, "Making benchmark tpr file%s with %s time step%s", *ntprs > 1 ? "s" : "",
- "%" PRId64, benchsteps > 1 ? "s" : "");
+ sprintf(buf,
+ "Making benchmark tpr file%s with %s time step%s",
+ *ntprs > 1 ? "s" : "",
+ "%" PRId64,
+ benchsteps > 1 ? "s" : "");
fprintf(stdout, buf, benchsteps);
if (statesteps > 0)
{
/* Check if some kind of PME was chosen */
if (EEL_PME(ir->coulombtype) == FALSE)
{
- gmx_fatal(FARGS, "Can only do optimizations for simulations with %s electrostatics.",
- EELTYPE(eelPME));
+ gmx_fatal(FARGS, "Can only do optimizations for simulations with %s electrostatics.", EELTYPE(eelPME));
}
/* Check if rcoulomb == rlist, which is necessary for plain PME. */
if ((ir->cutoff_scheme != ecutsVERLET) && (eelPME == ir->coulombtype) && !(ir->rcoulomb == ir->rlist))
{
- gmx_fatal(FARGS, "%s requires rcoulomb (%f) to be equal to rlist (%f).", EELTYPE(eelPME),
- ir->rcoulomb, ir->rlist);
+ gmx_fatal(FARGS,
+ "%s requires rcoulomb (%f) to be equal to rlist (%f).",
+ EELTYPE(eelPME),
+ ir->rcoulomb,
+ ir->rlist);
}
/* For other PME types, rcoulomb is allowed to be smaller than rlist */
else if (ir->rcoulomb > ir->rlist)
{
- gmx_fatal(FARGS, "%s requires rcoulomb (%f) to be equal to or smaller than rlist (%f)",
- EELTYPE(ir->coulombtype), ir->rcoulomb, ir->rlist);
+ gmx_fatal(FARGS,
+ "%s requires rcoulomb (%f) to be equal to or smaller than rlist (%f)",
+ EELTYPE(ir->coulombtype),
+ ir->rcoulomb,
+ ir->rlist);
}
if (bScaleRvdw && ir->rvdw != ir->rcoulomb)
fourierspacing = std::max(std::max(info->fsx[0], info->fsy[0]), info->fsz[0]);
}
- fprintf(stdout, "Calculating PME grid points on the basis of a fourierspacing of %f nm\n",
- fourierspacing);
+ fprintf(stdout, "Calculating PME grid points on the basis of a fourierspacing of %f nm\n", fourierspacing);
/* For performance comparisons the number of particles is useful to have */
fprintf(fp, " Number of particles : %d\n", mtop.natoms);
/* Print information about settings of which some are potentially modified: */
fprintf(fp, " Coulomb type : %s\n", EELTYPE(ir->coulombtype));
- fprintf(fp, " Grid spacing x y z : %f %f %f\n", box_size[XX] / ir->nkx,
- box_size[YY] / ir->nky, box_size[ZZ] / ir->nkz);
+ fprintf(fp,
+ " Grid spacing x y z : %f %f %f\n",
+ box_size[XX] / ir->nkx,
+ box_size[YY] / ir->nky,
+ box_size[ZZ] / ir->nkz);
fprintf(fp, " Van der Waals type : %s\n", EVDWTYPE(ir->vdwtype));
if (ir_vdw_switched(ir))
{
/* Scale the Fourier grid spacing */
ir->nkx = ir->nky = ir->nkz = 0;
- calcFftGrid(nullptr, state.box, fourierspacing * fac, minimalPmeGridSize(ir->pme_order),
- &ir->nkx, &ir->nky, &ir->nkz);
+ calcFftGrid(nullptr,
+ state.box,
+ fourierspacing * fac,
+ minimalPmeGridSize(ir->pme_order),
+ &ir->nkx,
+ &ir->nky,
+ &ir->nkz);
/* Adjust other radii since various conditions need to be fulfilled */
if (eelPME == ir->coulombtype)
* the -passall (if set) options requires cmd_args_bench to be
* at the end of the command line string */
snew(pd->mdrun_cmd_line, cmdline_length);
- sprintf(pd->mdrun_cmd_line, "%s-npme %d -s %s %s %s", cmd_stub, pd->nPMEnodes,
- tpr_names[k], cmd_args_bench, cmd_gpu_ids.c_str());
+ sprintf(pd->mdrun_cmd_line,
+ "%s-npme %d -s %s %s %s",
+ cmd_stub,
+ pd->nPMEnodes,
+ tpr_names[k],
+ cmd_args_bench,
+ cmd_gpu_ids.c_str());
/* To prevent that all benchmarks fail due to a show-stopper argument
* on the mdrun command line, we make a quick check first.
do for this check, but it'll be easier to
implement that after some refactoring of how
the number of MPI ranks is managed. */
- sprintf(temporary_cmd_line, "%s-npme 0 -nb cpu -s %s %s", cmd_stub,
- tpr_names[k], cmd_args_bench);
+ sprintf(temporary_cmd_line, "%s-npme 0 -nb cpu -s %s %s", cmd_stub, tpr_names[k], cmd_args_bench);
make_sure_it_runs(temporary_cmd_line, cmdline_length, fp, fnm, nfile);
}
bFirst = FALSE;
{
buf[0] = '\0';
}
- fprintf(stdout, "\n=== Progress %2.0f%%, tpr %d/%d, run %d/%d%s:\n",
- (100.0 * count) / totaltests, k + 1, nr_tprs, i + 1, *pmeentries, buf);
+ fprintf(stdout,
+ "\n=== Progress %2.0f%%, tpr %d/%d, run %d/%d%s:\n",
+ (100.0 * count) / totaltests,
+ k + 1,
+ nr_tprs,
+ i + 1,
+ *pmeentries,
+ buf);
make_backup(opt2fn("-err", nfile, fnm));
sprintf(command, "%s 1> /dev/null 2>%s", pd->mdrun_cmd_line, opt2fn("-err", nfile, fnm));
fprintf(stdout, "%s\n", pd->mdrun_cmd_line);
/* Collect the performance data from the log file; also check stderr
* for fatal errors */
- ret = parse_logfile(opt2fn("-bg", nfile, fnm), opt2fn("-err", nfile, fnm), pd, nr,
- presteps, cpt_steps, nnodes);
+ ret = parse_logfile(
+ opt2fn("-bg", nfile, fnm), opt2fn("-err", nfile, fnm), pd, nr, presteps, cpt_steps, nnodes);
if ((presteps > 0) && (ret == eParselogResetProblem))
{
bResetProblem = TRUE;
}
/* Write the data we got to disk */
- fprintf(fp, "%4d%s %12.3f %12.3f %s %s", pd->nPMEnodes, buf, pd->Gcycles[nr],
- pd->ns_per_day[nr], str_PME_f_load, ParseLog[ret]);
+ fprintf(fp,
+ "%4d%s %12.3f %12.3f %s %s",
+ pd->nPMEnodes,
+ buf,
+ pd->Gcycles[nr],
+ pd->ns_per_day[nr],
+ str_PME_f_load,
+ ParseLog[ret]);
if (!(ret == eParselogOK || ret == eParselogNoDDGrid || ret == eParselogNotFound))
{
fprintf(fp, " Check %s file for problems.", ret == eParselogFatal ? "err" : "log");
gmx_fatal(FARGS,
"Please choose the Coulomb radii such that rmin <= rmax.\n"
"rmin = %g, rmax = %g, actual rcoul from .tpr file = %g\n",
- *rmin, *rmax, rcoulomb);
+ *rmin,
+ *rmax,
+ rcoulomb);
}
/* Add test scenarios if rmin or rmax were set */
if (*ntprs <= 2)
{
fprintf(stderr, "WARNING: steps=");
fprintf(stderr, "%" PRId64, bench_nsteps);
- fprintf(stderr, ". Are you sure you want to perform so %s steps for each benchmark?\n",
+ fprintf(stderr,
+ ". Are you sure you want to perform so %s steps for each benchmark?\n",
(bench_nsteps < 100) ? "few" : "many");
}
gmx_fatal(FARGS,
"Cannot have more than %d PME-only ranks for a total of %d ranks (you chose "
"%d).\n",
- nnodes / 2, nnodes, npme_fixed);
+ nnodes / 2,
+ nnodes,
+ npme_fixed);
}
if ((npme_fixed > 0) && (5 * npme_fixed < nnodes))
{
"[THISMODULE] needs to call [gmx-mdrun] and so requires that you",
"specify how to call mdrun with the argument to the [TT]-mdrun[tt]",
"parameter. Depending how you have built GROMACS, values such as",
- "'gmx mdrun', 'gmx_d mdrun', or 'mdrun_mpi' might be needed.[PAR]",
+ "'gmx mdrun', 'gmx_d mdrun', or 'gmx_mpi mdrun' might be needed.[PAR]",
"The program that runs MPI programs can be set in the environment variable",
"MPIRUN (defaults to 'mpirun'). Note that for certain MPI frameworks,",
"you need to provide a machine- or hostfile. This can also be passed",
FALSE,
etSTR,
{ &cmd_mdrun },
- "Command line to run a simulation, e.g. 'gmx mdrun' or 'mdrun_mpi'" },
+ "Command line to run a simulation, e.g. 'gmx mdrun' or 'gmx_mpi mdrun'" },
{ "-np",
FALSE,
etINT,
seconds = gmx_gettime();
- if (!parse_common_args(&argc, argv, PCA_NOEXIT_ON_ARGS, NFILE, fnm, asize(pa), pa, asize(desc),
- desc, 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_NOEXIT_ON_ARGS, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
cmd_np = bbuf;
- create_command_line_snippets(bAppendFiles, bKeepAndNumCPT, bResetCountersHalfWay, presteps,
- NFILE, fnm, &cmd_args_bench, &cmd_args_launch, ExtraArgs, deffnm);
+ create_command_line_snippets(bAppendFiles,
+ bKeepAndNumCPT,
+ bResetCountersHalfWay,
+ presteps,
+ NFILE,
+ fnm,
+ &cmd_args_bench,
+ &cmd_args_launch,
+ ExtraArgs,
+ deffnm);
/* Prepare to use checkpoint file if requested */
sim_part = 1;
fp = gmx_ffopen(opt2fn("-p", NFILE, fnm), "w");
/* Make a quick consistency check of command line parameters */
- check_input(nnodes, repeats, &ntprs, &rmin, rcoulomb, &rmax, maxPMEfraction, minPMEfraction,
- npme_fixed, bench_nsteps, fnm, NFILE, sim_part, presteps, asize(pa), pa);
+ check_input(nnodes,
+ repeats,
+ &ntprs,
+ &rmin,
+ rcoulomb,
+ &rmax,
+ maxPMEfraction,
+ minPMEfraction,
+ npme_fixed,
+ bench_nsteps,
+ fnm,
+ NFILE,
+ sim_part,
+ presteps,
+ asize(pa),
+ pa);
/* Determine the maximum and minimum number of PME nodes to test,
* the actual list of settings is build in do_the_tests(). */
/* It can be that ntprs is reduced by make_benchmark_tprs if not enough
* different grids could be found. */
- make_benchmark_tprs(opt2fn("-s", NFILE, fnm), tpr_names, bench_nsteps + presteps, cpt_steps,
- rmin, rmax, bScaleRvdw, &ntprs, info, fp);
+ make_benchmark_tprs(opt2fn("-s", NFILE, fnm),
+ tpr_names,
+ bench_nsteps + presteps,
+ cpt_steps,
+ rmin,
+ rmax,
+ bScaleRvdw,
+ &ntprs,
+ info,
+ fp);
/********************************************************************************/
/* Main loop over all scenarios we need to test: tpr files, PME nodes, repeats */
{
GMX_RELEASE_ASSERT(npmevalues_opt[0] != nullptr,
"Options inconsistency; npmevalues_opt[0] is NULL");
- do_the_tests(fp, tpr_names, maxPMEnodes, minPMEnodes, npme_fixed, npmevalues_opt[0], perfdata,
- &pmeentries, repeats, nnodes, ntprs, bThreads, cmd_mpirun, cmd_np, cmd_mdrun,
- cmd_args_bench, fnm, NFILE, presteps, cpt_steps, bCheck, eligible_gpu_ids);
+ do_the_tests(fp,
+ tpr_names,
+ maxPMEnodes,
+ minPMEnodes,
+ npme_fixed,
+ npmevalues_opt[0],
+ perfdata,
+ &pmeentries,
+ repeats,
+ nnodes,
+ ntprs,
+ bThreads,
+ cmd_mpirun,
+ cmd_np,
+ cmd_mdrun,
+ cmd_args_bench,
+ fnm,
+ NFILE,
+ presteps,
+ cpt_steps,
+ bCheck,
+ eligible_gpu_ids);
fprintf(fp, "\nTuning took%8.1f minutes.\n", (gmx_gettime() - seconds) / 60.0);
/* Analyse the results and give a suggestion for optimal settings: */
- bKeepTPR = analyze_data(fp, opt2fn("-p", NFILE, fnm), perfdata, nnodes, ntprs, pmeentries,
- repeats, info, &best_tpr, &best_npme);
+ bKeepTPR = analyze_data(
+ fp, opt2fn("-p", NFILE, fnm), perfdata, nnodes, ntprs, pmeentries, repeats, info, &best_tpr, &best_npme);
/* Take the best-performing tpr file and enlarge nsteps to original value */
if (bKeepTPR && !bOverwrite)
{
simulation_tpr = opt2fn("-so", NFILE, fnm);
modify_PMEsettings(bOverwrite ? (new_sim_nsteps + cpt_steps) : info->orig_sim_steps,
- info->orig_init_step, tpr_names[best_tpr], simulation_tpr);
+ info->orig_init_step,
+ tpr_names[best_tpr],
+ simulation_tpr);
}
/* Let's get rid of the temporary benchmark input files */
}
/* Now start the real simulation if the user requested it ... */
- launch_simulation(bLaunch, fp, bThreads, cmd_mpirun, cmd_np, cmd_mdrun, cmd_args_launch,
- simulation_tpr, best_npme, eligible_gpu_ids);
+ launch_simulation(
+ bLaunch, fp, bThreads, cmd_mpirun, cmd_np, cmd_mdrun, cmd_args_launch, simulation_tpr, best_npme, eligible_gpu_ids);
}
gmx_ffclose(fp);
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+# Set up the module library
+add_library(topology INTERFACE)
+
file(GLOB TOPOLOGY_SOURCES *.cpp)
set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${TOPOLOGY_SOURCES} PARENT_SCOPE)
-if (BUILD_TESTING)
- add_subdirectory(tests)
-endif()
-
if(GMX_INSTALL_LEGACY_API)
install(FILES
atomprop.h
- atoms.h
- block.h
- forcefieldparameters.h
- idef.h
- ifunc.h
+ atoms.h
+ block.h
+ forcefieldparameters.h
+ idef.h
+ ifunc.h
index.h
- symtab.h
- topology.h
- DESTINATION include/gromacs/topology)
+ symtab.h
+ topology.h
+ DESTINATION include/gromacs/topology)
endif()
+
+# Source files have the following private module dependencies.
+target_link_libraries(options PRIVATE
+ )
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(topology PUBLIC
+target_include_directories(topology INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(topology PUBLIC
+target_link_libraries(topology INTERFACE
+ legacy_api
+ )
+
+# TODO: when topology is an OBJECT target
+#target_link_libraries(topology PUBLIC legacy_api)
+#target_link_libraries(topology PRIVATE common)
+
+# Module dependencies
+# topology interfaces convey transitive dependence on these modules.
+#target_link_libraries(topology PUBLIC
+target_link_libraries(topology INTERFACE
+ utility
+ )
+
+if (BUILD_TESTING)
+ add_subdirectory(tests)
+endif()
\ No newline at end of file
}
else
{
- fprintf(debug, " match: %4s %4s\n", ap->entry[j].residueName.c_str(),
+ fprintf(debug,
+ " match: %4s %4s\n",
+ ap->entry[j].residueName.c_str(),
ap->entry[j].atomName.c_str());
}
}
{
if (ap->entry[j].value == propValue)
{
- fprintf(stderr, "Warning double identical entries for %s %s %g on line %d in file %s\n",
- residueName.c_str(), atomName.c_str(), propValue, line, ap->db.c_str());
+ fprintf(stderr,
+ "Warning double identical entries for %s %s %g on line %d in file %s\n",
+ residueName.c_str(),
+ atomName.c_str(),
+ propValue,
+ line,
+ ap->db.c_str());
}
else
{
fprintf(stderr,
"Warning double different entries %s %s %g and %g on line %d in file %s\n"
"Using last entry (%g)\n",
- residueName.c_str(), atomName.c_str(), propValue, ap->entry[j].value, line,
- ap->db.c_str(), propValue);
+ residueName.c_str(),
+ atomName.c_str(),
+ propValue,
+ ap->entry[j].value,
+ line,
+ ap->db.c_str(),
+ propValue);
ap->entry[j].value = propValue;
}
}
*/
static bool setProperties(AtomProperty* ap, ResidueType* restype, int eprop, bool haveBeenWarned)
{
- const char* fns[epropNR] = { "atommass.dat", "vdwradii.dat", "dgsolv.dat", "electroneg.dat",
- "elements.dat" };
- double fac[epropNR] = { 1.0, 1.0, 418.4, 1.0, 1.0 };
- double def[epropNR] = { 12.011, 0.14, 0.0, 2.2, -1 };
+ const char* fns[epropNR] = {
+ "atommass.dat", "vdwradii.dat", "dgsolv.dat", "electroneg.dat", "elements.dat"
+ };
+ double fac[epropNR] = { 1.0, 1.0, 418.4, 1.0, 1.0 };
+ double def[epropNR] = { 12.011, 0.14, 0.0, 2.2, -1 };
bool printWarning = false;
if (!ap->isSet)
{
if (nullptr != fp)
{
- fprintf(fp, "NOTE: From version 5.0 %s uses the Van der Waals radii\n",
+ fprintf(fp,
+ "NOTE: From version 5.0 %s uses the Van der Waals radii\n",
gmx::getProgramContext().displayName());
fprintf(fp, "from the source below. This means the results may be different\n");
fprintf(fp, "compared to previous GROMACS versions.\n");
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2010,2014,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2010,2014,2018,2019,2021, 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.
#ifndef GMX_TOPOLOGY_ATOMPROP_H
#define GMX_TOPOLOGY_ATOMPROP_H
+#include <memory>
#include <string>
#include "gromacs/utility/basedefinitions.h"
-#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/real.h"
enum
//! Implementation pointer.
class Impl;
- gmx::PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
#endif
fprintf(fp,
"%s[%6d]={type=%3hu, typeB=%3hu, ptype=%8s, m=%12.5e, "
"q=%12.5e, mB=%12.5e, qB=%12.5e, resind=%5d, atomnumber=%3d}\n",
- title, i, atom[i].type, atom[i].typeB, ptype_str[atom[i].ptype], atom[i].m,
- atom[i].q, atom[i].mB, atom[i].qB, atom[i].resind, atom[i].atomnumber);
+ title,
+ i,
+ atom[i].type,
+ atom[i].typeB,
+ ptype_str[atom[i].ptype],
+ atom[i].m,
+ atom[i].q,
+ atom[i].mB,
+ atom[i].qB,
+ atom[i].resind,
+ atom[i].atomnumber);
}
}
}
for (i = 0; i < n; i++)
{
pr_indent(fp, indent);
- fprintf(fp, "%s[%d]={name=\"%s\",nameB=\"%s\"}\n", title, bShowNumbers ? i : -1,
- *(nm[i]), *(nmB[i]));
+ fprintf(fp, "%s[%d]={name=\"%s\",nameB=\"%s\"}\n", title, bShowNumbers ? i : -1, *(nm[i]), *(nmB[i]));
}
}
}
for (i = 0; i < n; i++)
{
pr_indent(fp, indent);
- fprintf(fp, "%s[%d]={name=\"%s\", nr=%d, ic='%c'}\n", title, bShowNumbers ? i : -1,
- *(resinfo[i].name), resinfo[i].nr, (resinfo[i].ic == '\0') ? ' ' : resinfo[i].ic);
+ fprintf(fp,
+ "%s[%d]={name=\"%s\", nr=%d, ic='%c'}\n",
+ title,
+ bShowNumbers ? i : -1,
+ *(resinfo[i].name),
+ resinfo[i].nr,
+ (resinfo[i].ic == '\0') ? ' ' : resinfo[i].ic);
}
}
}
for (i = 0; i < atomtypes->nr; i++)
{
pr_indent(fp, indent);
- fprintf(fp, "atomtype[%3d]={atomnumber=%4d}\n", bShowNumbers ? i : -1,
- atomtypes->atomnumber[i]);
+ fprintf(fp, "atomtype[%3d]={atomnumber=%4d}\n", bShowNumbers ? i : -1, atomtypes->atomnumber[i]);
}
}
}
bool haveMass = true;
for (int i = 0; i < atoms->nr; i++)
{
- if (!aps.setAtomProperty(epropMass, *atoms->resinfo[atoms->atom[i].resind].name,
- *atoms->atomname[i], &atoms->atom[i].m))
+ if (!aps.setAtomProperty(epropMass,
+ *atoms->resinfo[atoms->atom[i].resind].name,
+ *atoms->atomname[i],
+ &atoms->atom[i].m))
{
haveMass = false;
if (numWarn < maxWarn)
{
- fprintf(stderr, "Can not find mass in database for atom %s in residue %d %s\n",
- *atoms->atomname[i], atoms->resinfo[atoms->atom[i].resind].nr,
+ fprintf(stderr,
+ "Can not find mass in database for atom %s in residue %d %s\n",
+ *atoms->atomname[i],
+ atoms->resinfo[atoms->atom[i].resind].nr,
*atoms->resinfo[atoms->atom[i].resind].name);
numWarn++;
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014,2015,2016,2019, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015,2016,2019,2021, 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.
#ifndef GMX_TOPOLOGY_ATOMSBUILDER_H
#define GMX_TOPOLOGY_ATOMSBUILDER_H
+#include <memory>
#include <vector>
#include "gromacs/math/vectypes.h"
+
#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/real.h"
}
else
{
- fprintf(fp, "%s[%d]={%d..%d}\n", title, bShowNumbers ? i : -1,
- bShowNumbers ? start : -1, bShowNumbers ? end - 1 : -1);
+ fprintf(fp,
+ "%s[%d]={%d..%d}\n",
+ title,
+ bShowNumbers ? i : -1,
+ bShowNumbers ? start : -1,
+ bShowNumbers ? end - 1 : -1);
}
start = end;
}
}
else
{
- size += fprintf(fp, "%s[%d][%d..%d]={", title, bShowNumbers ? i : -1,
- bShowNumbers ? start : -1, bShowNumbers ? end - 1 : -1);
+ size += fprintf(fp,
+ "%s[%d][%d..%d]={",
+ title,
+ bShowNumbers ? i : -1,
+ bShowNumbers ? start : -1,
+ bShowNumbers ? end - 1 : -1);
}
for (j = start; j < end; j++)
{
for (i = 0; i < ffparams->numTypes(); i++)
{
pr_indent(fp, indent + INDENT);
- fprintf(fp, "functype[%d]=%s, ", bShowNumbers ? i : -1,
+ fprintf(fp,
+ "functype[%d]=%s, ",
+ bShowNumbers ? i : -1,
interaction_function[ffparams->functype[i]].name);
pr_iparams(fp, ffparams->functype[i], ffparams->iparams[i]);
}
const char* r,
const char* kr)
{
- writer->writeLineFormatted("%sA=%12.5e, %sA=%12.5e, %sB=%12.5e, %sB=%12.5e", r,
- iparams.harmonic.rA, kr, iparams.harmonic.krA, r,
- iparams.harmonic.rB, kr, iparams.harmonic.krB);
+ writer->writeLineFormatted("%sA=%12.5e, %sA=%12.5e, %sB=%12.5e, %sB=%12.5e",
+ r,
+ iparams.harmonic.rA,
+ kr,
+ iparams.harmonic.krA,
+ r,
+ iparams.harmonic.rB,
+ kr,
+ iparams.harmonic.krB);
}
void pr_iparams(FILE* fp, t_functype ftype, const t_iparams& iparams)
case F_ANGLES:
case F_G96ANGLES: printHarmonicInteraction(writer, iparams, "th", "ct"); break;
case F_CROSS_BOND_BONDS:
- writer->writeLineFormatted("r1e=%15.8e, r2e=%15.8e, krr=%15.8e", iparams.cross_bb.r1e,
- iparams.cross_bb.r2e, iparams.cross_bb.krr);
+ writer->writeLineFormatted("r1e=%15.8e, r2e=%15.8e, krr=%15.8e",
+ iparams.cross_bb.r1e,
+ iparams.cross_bb.r2e,
+ iparams.cross_bb.krr);
break;
case F_CROSS_BOND_ANGLES:
writer->writeLineFormatted("r1e=%15.8e, r1e=%15.8e, r3e=%15.8e, krt=%15.8e",
- iparams.cross_ba.r1e, iparams.cross_ba.r2e,
- iparams.cross_ba.r3e, iparams.cross_ba.krt);
+ iparams.cross_ba.r1e,
+ iparams.cross_ba.r2e,
+ iparams.cross_ba.r3e,
+ iparams.cross_ba.krt);
break;
case F_LINEAR_ANGLES:
writer->writeLineFormatted("klinA=%15.8e, aA=%15.8e, klinB=%15.8e, aB=%15.8e",
- iparams.linangle.klinA, iparams.linangle.aA,
- iparams.linangle.klinB, iparams.linangle.aB);
+ iparams.linangle.klinA,
+ iparams.linangle.aA,
+ iparams.linangle.klinB,
+ iparams.linangle.aB);
break;
case F_UREY_BRADLEY:
writer->writeLineFormatted(
"thetaA=%15.8e, kthetaA=%15.8e, r13A=%15.8e, kUBA=%15.8e, thetaB=%15.8e, "
"kthetaB=%15.8e, r13B=%15.8e, kUBB=%15.8e",
- iparams.u_b.thetaA, iparams.u_b.kthetaA, iparams.u_b.r13A, iparams.u_b.kUBA,
- iparams.u_b.thetaB, iparams.u_b.kthetaB, iparams.u_b.r13B, iparams.u_b.kUBB);
+ iparams.u_b.thetaA,
+ iparams.u_b.kthetaA,
+ iparams.u_b.r13A,
+ iparams.u_b.kUBA,
+ iparams.u_b.thetaB,
+ iparams.u_b.kthetaB,
+ iparams.u_b.r13B,
+ iparams.u_b.kUBB);
break;
case F_QUARTIC_ANGLES:
writer->writeStringFormatted("theta=%15.8e", iparams.qangle.theta);
writer->ensureLineBreak();
break;
case F_BHAM:
- writer->writeLineFormatted("a=%15.8e, b=%15.8e, c=%15.8e", iparams.bham.a,
- iparams.bham.b, iparams.bham.c);
+ writer->writeLineFormatted(
+ "a=%15.8e, b=%15.8e, c=%15.8e", iparams.bham.a, iparams.bham.b, iparams.bham.c);
break;
case F_BONDS:
case F_G96BONDS:
case F_MORSE:
writer->writeLineFormatted(
"b0A=%15.8e, cbA=%15.8e, betaA=%15.8e, b0B=%15.8e, cbB=%15.8e, betaB=%15.8e",
- iparams.morse.b0A, iparams.morse.cbA, iparams.morse.betaA, iparams.morse.b0B,
- iparams.morse.cbB, iparams.morse.betaB);
+ iparams.morse.b0A,
+ iparams.morse.cbA,
+ iparams.morse.betaA,
+ iparams.morse.b0B,
+ iparams.morse.cbB,
+ iparams.morse.betaB);
break;
case F_CUBICBONDS:
- writer->writeLineFormatted("b0=%15.8e, kb=%15.8e, kcub=%15.8e", iparams.cubic.b0,
- iparams.cubic.kb, iparams.cubic.kcub);
+ writer->writeLineFormatted("b0=%15.8e, kb=%15.8e, kcub=%15.8e",
+ iparams.cubic.b0,
+ iparams.cubic.kb,
+ iparams.cubic.kcub);
break;
case F_CONNBONDS: writer->ensureEmptyLine(); break;
case F_FENEBONDS:
writer->writeLineFormatted(
"lowA=%15.8e, up1A=%15.8e, up2A=%15.8e, kA=%15.8e, lowB=%15.8e, up1B=%15.8e, "
"up2B=%15.8e, kB=%15.8e,",
- iparams.restraint.lowA, iparams.restraint.up1A, iparams.restraint.up2A,
- iparams.restraint.kA, iparams.restraint.lowB, iparams.restraint.up1B,
- iparams.restraint.up2B, iparams.restraint.kB);
+ iparams.restraint.lowA,
+ iparams.restraint.up1A,
+ iparams.restraint.up2A,
+ iparams.restraint.kA,
+ iparams.restraint.lowB,
+ iparams.restraint.up1B,
+ iparams.restraint.up2B,
+ iparams.restraint.kB);
break;
case F_TABBONDS:
case F_TABBONDSNC:
case F_TABANGLES:
case F_TABDIHS:
- writer->writeLineFormatted("tab=%d, kA=%15.8e, kB=%15.8e", iparams.tab.table,
- iparams.tab.kA, iparams.tab.kB);
+ writer->writeLineFormatted(
+ "tab=%d, kA=%15.8e, kB=%15.8e", iparams.tab.table, iparams.tab.kA, iparams.tab.kB);
break;
case F_POLARIZATION:
writer->writeLineFormatted("alpha=%15.8e", iparams.polarize.alpha);
break;
case F_ANHARM_POL:
writer->writeLineFormatted("alpha=%15.8e drcut=%15.8e khyp=%15.8e",
- iparams.anharm_polarize.alpha, iparams.anharm_polarize.drcut,
+ iparams.anharm_polarize.alpha,
+ iparams.anharm_polarize.drcut,
iparams.anharm_polarize.khyp);
break;
case F_THOLE_POL:
writer->writeLineFormatted("a=%15.8e, alpha1=%15.8e, alpha2=%15.8e, rfac=%15.8e",
- iparams.thole.a, iparams.thole.alpha1, iparams.thole.alpha2,
+ iparams.thole.a,
+ iparams.thole.alpha1,
+ iparams.thole.alpha2,
iparams.thole.rfac);
break;
case F_WATER_POL:
writer->writeLineFormatted(
"al_x=%15.8e, al_y=%15.8e, al_z=%15.8e, rOH=%9.6f, rHH=%9.6f, rOD=%9.6f",
- iparams.wpol.al_x, iparams.wpol.al_y, iparams.wpol.al_z, iparams.wpol.rOH,
- iparams.wpol.rHH, iparams.wpol.rOD);
+ iparams.wpol.al_x,
+ iparams.wpol.al_y,
+ iparams.wpol.al_z,
+ iparams.wpol.rOH,
+ iparams.wpol.rHH,
+ iparams.wpol.rOD);
break;
case F_LJ:
writer->writeLineFormatted("c6=%15.8e, c12=%15.8e", iparams.lj.c6, iparams.lj.c12);
break;
case F_LJ14:
writer->writeLineFormatted("c6A=%15.8e, c12A=%15.8e, c6B=%15.8e, c12B=%15.8e",
- iparams.lj14.c6A, iparams.lj14.c12A, iparams.lj14.c6B,
+ iparams.lj14.c6A,
+ iparams.lj14.c12A,
+ iparams.lj14.c6B,
iparams.lj14.c12B);
break;
case F_LJC14_Q:
writer->writeLineFormatted("fqq=%15.8e, qi=%15.8e, qj=%15.8e, c6=%15.8e, c12=%15.8e",
- iparams.ljc14.fqq, iparams.ljc14.qi, iparams.ljc14.qj,
- iparams.ljc14.c6, iparams.ljc14.c12);
+ iparams.ljc14.fqq,
+ iparams.ljc14.qi,
+ iparams.ljc14.qj,
+ iparams.ljc14.c6,
+ iparams.ljc14.c12);
break;
case F_LJC_PAIRS_NB:
- writer->writeLineFormatted("qi=%15.8e, qj=%15.8e, c6=%15.8e, c12=%15.8e", iparams.ljcnb.qi,
- iparams.ljcnb.qj, iparams.ljcnb.c6, iparams.ljcnb.c12);
+ writer->writeLineFormatted("qi=%15.8e, qj=%15.8e, c6=%15.8e, c12=%15.8e",
+ iparams.ljcnb.qi,
+ iparams.ljcnb.qj,
+ iparams.ljcnb.c6,
+ iparams.ljcnb.c12);
break;
case F_PDIHS:
case F_PIDIHS:
case F_ANGRES:
case F_ANGRESZ:
writer->writeLineFormatted("phiA=%15.8e, cpA=%15.8e, phiB=%15.8e, cpB=%15.8e, mult=%d",
- iparams.pdihs.phiA, iparams.pdihs.cpA, iparams.pdihs.phiB,
- iparams.pdihs.cpB, iparams.pdihs.mult);
+ iparams.pdihs.phiA,
+ iparams.pdihs.cpA,
+ iparams.pdihs.phiB,
+ iparams.pdihs.cpB,
+ iparams.pdihs.mult);
break;
case F_DISRES:
writer->writeLineFormatted(
"label=%4d, type=%1d, low=%15.8e, up1=%15.8e, up2=%15.8e, fac=%15.8e)",
- iparams.disres.label, iparams.disres.type, iparams.disres.low,
- iparams.disres.up1, iparams.disres.up2, iparams.disres.kfac);
+ iparams.disres.label,
+ iparams.disres.type,
+ iparams.disres.low,
+ iparams.disres.up1,
+ iparams.disres.up2,
+ iparams.disres.kfac);
break;
case F_ORIRES:
writer->writeLineFormatted(
"ex=%4d, label=%d, power=%4d, c=%15.8e, obs=%15.8e, kfac=%15.8e)",
- iparams.orires.ex, iparams.orires.label, iparams.orires.power, iparams.orires.c,
- iparams.orires.obs, iparams.orires.kfac);
+ iparams.orires.ex,
+ iparams.orires.label,
+ iparams.orires.power,
+ iparams.orires.c,
+ iparams.orires.obs,
+ iparams.orires.kfac);
break;
case F_DIHRES:
writer->writeLineFormatted(
"phiA=%15.8e, dphiA=%15.8e, kfacA=%15.8e, phiB=%15.8e, dphiB=%15.8e, "
"kfacB=%15.8e",
- iparams.dihres.phiA, iparams.dihres.dphiA, iparams.dihres.kfacA,
- iparams.dihres.phiB, iparams.dihres.dphiB, iparams.dihres.kfacB);
+ iparams.dihres.phiA,
+ iparams.dihres.dphiA,
+ iparams.dihres.kfacA,
+ iparams.dihres.phiB,
+ iparams.dihres.dphiB,
+ iparams.dihres.kfacB);
break;
case F_POSRES:
writer->writeLineFormatted(
"pos0A=(%15.8e,%15.8e,%15.8e), fcA=(%15.8e,%15.8e,%15.8e), "
"pos0B=(%15.8e,%15.8e,%15.8e), fcB=(%15.8e,%15.8e,%15.8e)",
- iparams.posres.pos0A[XX], iparams.posres.pos0A[YY], iparams.posres.pos0A[ZZ],
- iparams.posres.fcA[XX], iparams.posres.fcA[YY], iparams.posres.fcA[ZZ],
- iparams.posres.pos0B[XX], iparams.posres.pos0B[YY], iparams.posres.pos0B[ZZ],
- iparams.posres.fcB[XX], iparams.posres.fcB[YY], iparams.posres.fcB[ZZ]);
+ iparams.posres.pos0A[XX],
+ iparams.posres.pos0A[YY],
+ iparams.posres.pos0A[ZZ],
+ iparams.posres.fcA[XX],
+ iparams.posres.fcA[YY],
+ iparams.posres.fcA[ZZ],
+ iparams.posres.pos0B[XX],
+ iparams.posres.pos0B[YY],
+ iparams.posres.pos0B[ZZ],
+ iparams.posres.fcB[XX],
+ iparams.posres.fcB[YY],
+ iparams.posres.fcB[ZZ]);
break;
case F_FBPOSRES:
writer->writeLineFormatted(
"pos0=(%15.8e,%15.8e,%15.8e), geometry=%d, r=%15.8e, k=%15.8e",
- iparams.fbposres.pos0[XX], iparams.fbposres.pos0[YY], iparams.fbposres.pos0[ZZ],
- iparams.fbposres.geom, iparams.fbposres.r, iparams.fbposres.k);
+ iparams.fbposres.pos0[XX],
+ iparams.fbposres.pos0[YY],
+ iparams.fbposres.pos0[ZZ],
+ iparams.fbposres.geom,
+ iparams.fbposres.r,
+ iparams.fbposres.k);
break;
case F_RBDIHS:
for (int i = 0; i < NR_RBDIHS; i++)
{
- writer->writeStringFormatted("%srbcA[%d]=%15.8e", i == 0 ? "" : ", ", i,
- iparams.rbdihs.rbcA[i]);
+ writer->writeStringFormatted(
+ "%srbcA[%d]=%15.8e", i == 0 ? "" : ", ", i, iparams.rbdihs.rbcA[i]);
}
writer->ensureLineBreak();
for (int i = 0; i < NR_RBDIHS; i++)
{
- writer->writeStringFormatted("%srbcB[%d]=%15.8e", i == 0 ? "" : ", ", i,
- iparams.rbdihs.rbcB[i]);
+ writer->writeStringFormatted(
+ "%srbcB[%d]=%15.8e", i == 0 ? "" : ", ", i, iparams.rbdihs.rbcB[i]);
}
writer->ensureLineBreak();
break;
case F_VSITE3OUT:
case F_VSITE4FD:
case F_VSITE4FDN:
- writer->writeLineFormatted("a=%15.8e, b=%15.8e, c=%15.8e", iparams.vsite.a,
- iparams.vsite.b, iparams.vsite.c);
+ writer->writeLineFormatted(
+ "a=%15.8e, b=%15.8e, c=%15.8e", iparams.vsite.a, iparams.vsite.b, iparams.vsite.c);
break;
case F_VSITEN:
writer->writeLineFormatted("n=%2d, a=%15.8e", iparams.vsiten.n, iparams.vsiten.a);
writer->ensureLineBreak();
break;
default:
- gmx_fatal(FARGS, "unknown function type %d (%s) in %s line %d", ftype,
- interaction_function[ftype].name, __FILE__, __LINE__);
+ gmx_fatal(FARGS,
+ "unknown function type %d (%s) in %s line %d",
+ ftype,
+ interaction_function[ftype].name,
+ __FILE__,
+ __LINE__);
}
}
for (i = 0; i < idef->ntypes; i++)
{
pr_indent(fp, indent + INDENT);
- fprintf(fp, "functype[%d]=%s, ", bShowNumbers ? i : -1,
+ fprintf(fp,
+ "functype[%d]=%s, ",
+ bShowNumbers ? i : -1,
interaction_function[idef->functype[i]].name);
pr_iparams(fp, idef->functype[i], idef->iparams[i]);
}
for (j = 0; (j < F_NRE); j++)
{
- printIlist(fp, indent, interaction_function[j].longname, idef->functype, idef->il[j],
- bShowNumbers, bShowParameters, idef->iparams);
+ printIlist(fp,
+ indent,
+ interaction_function[j].longname,
+ idef->functype,
+ idef->il[j],
+ bShowNumbers,
+ bShowParameters,
+ idef->iparams);
}
}
}
/* this MUST correspond to the enum in src/gromacs/topology/ifunc.h */
const t_interaction_function interaction_function[F_NRE] = {
- def_bond("BONDS", "Bond", 2, 2, 2), def_bond("G96BONDS", "G96Bond", 2, 2, 2),
- def_bond("MORSE", "Morse", 2, 3, 3), def_bond("CUBICBONDS", "Cubic Bonds", 2, 3, 0),
+ def_bond("BONDS", "Bond", 2, 2, 2),
+ def_bond("G96BONDS", "G96Bond", 2, 2, 2),
+ def_bond("MORSE", "Morse", 2, 3, 3),
+ def_bond("CUBICBONDS", "Cubic Bonds", 2, 3, 0),
def_bondnb("CONNBONDS", "Connect Bonds", 2, 0, 0),
- def_bonded("HARMONIC", "Harmonic Pot.", 2, 2, 2), def_bondnb("FENEBONDS", "FENE Bonds", 2, 2, 0),
- def_bondt("TABBONDS", "Tab. Bonds", 2, 2, 2), def_bondedtz("TABBONDSNC", "Tab. Bonds NC", 2, 2, 2),
- def_bonded("RESTRAINTPOT", "Restraint Pot.", 2, 4, 4), def_angle("ANGLES", "Angle", 3, 2, 2),
- def_angle("G96ANGLES", "G96Angle", 3, 2, 2), def_angle("RESTRANGLES", "Restricted Angles", 3, 2, 2),
+ def_bonded("HARMONIC", "Harmonic Pot.", 2, 2, 2),
+ def_bondnb("FENEBONDS", "FENE Bonds", 2, 2, 0),
+ def_bondt("TABBONDS", "Tab. Bonds", 2, 2, 2),
+ def_bondedtz("TABBONDSNC", "Tab. Bonds NC", 2, 2, 2),
+ def_bonded("RESTRAINTPOT", "Restraint Pot.", 2, 4, 4),
+ def_angle("ANGLES", "Angle", 3, 2, 2),
+ def_angle("G96ANGLES", "G96Angle", 3, 2, 2),
+ def_angle("RESTRANGLES", "Restricted Angles", 3, 2, 2),
def_angle("LINEAR_ANGLES", "Lin. Angle", 3, 2, 2),
def_bonded("CROSS_BOND_BOND", "Bond-Cross", 3, 3, 0),
- def_bonded("CROSS_BOND_ANGLE", "BA-Cross", 3, 4, 0), def_angle("UREY_BRADLEY", "U-B", 3, 4, 4),
- def_angle("QANGLES", "Quartic Angles", 3, 6, 0), def_bondedt("TABANGLES", "Tab. Angles", 3, 2, 2),
- def_dihedral("PDIHS", "Proper Dih.", 4, 3, 3), def_dihedral("RBDIHS", "Ryckaert-Bell.", 4, 6, 6),
+ def_bonded("CROSS_BOND_ANGLE", "BA-Cross", 3, 4, 0),
+ def_angle("UREY_BRADLEY", "U-B", 3, 4, 4),
+ def_angle("QANGLES", "Quartic Angles", 3, 6, 0),
+ def_bondedt("TABANGLES", "Tab. Angles", 3, 2, 2),
+ def_dihedral("PDIHS", "Proper Dih.", 4, 3, 3),
+ def_dihedral("RBDIHS", "Ryckaert-Bell.", 4, 6, 6),
def_dihedral("RESTRDIHS", "Restricted Dih.", 4, 2, 2),
- def_dihedral("CBTDIHS", "CBT Dih.", 4, 6, 6), def_dihedral("FOURDIHS", "Fourier Dih.", 4, 4, 4),
- def_dihedral("IDIHS", "Improper Dih.", 4, 2, 2), def_dihedral("PIDIHS", "Improper Dih.", 4, 3, 3),
+ def_dihedral("CBTDIHS", "CBT Dih.", 4, 6, 6),
+ def_dihedral("FOURDIHS", "Fourier Dih.", 4, 4, 4),
+ def_dihedral("IDIHS", "Improper Dih.", 4, 2, 2),
+ def_dihedral("PIDIHS", "Improper Dih.", 4, 3, 3),
def_dihedral_tabulated("TABDIHS", "Tab. Dih.", 4, 2, 2),
- def_dihedral("CMAP", "CMAP Dih.", 5, -1, -1), def_nofc("GB12", "GB 1-2 Pol. (unused)"),
- def_nofc("GB13", "GB 1-3 Pol. (unused)"), def_nofc("GB14", "GB 1-4 Pol. (unused)"),
- def_nofc("GBPOL", "GB Polarization (unused)"), def_nofc("NPSOLVATION", "Nonpolar Sol. (unused)"),
- def_pair("LJ14", "LJ-14", 2, 2, 2), def_nofc("COUL14", "Coulomb-14"),
- def_pair("LJC14_Q", "LJC-14 q", 2, 5, 0), def_pair("LJC_NB", "LJC Pairs NB", 2, 4, 0),
- def_nb("LJ_SR", "LJ (SR)", 2, 2), def_nb("BHAM", "Buck.ham (SR)", 2, 3),
- def_nofc("LJ_LR", "LJ (unused)"), def_nofc("BHAM_LR", "B.ham (unused)"),
- def_nofc("DISPCORR", "Disper. corr."), def_nofc("COUL_SR", "Coulomb (SR)"),
- def_nofc("COUL_LR", "Coul (unused)"), def_nofc("RF_EXCL", "RF excl."),
- def_nofc("COUL_RECIP", "Coul. recip."), def_nofc("LJ_RECIP", "LJ recip."),
- def_nofc("DPD", "DPD"), def_bondnb("POLARIZATION", "Polarization", 2, 1, 0),
- def_bonded("WATERPOL", "Water Pol.", 5, 6, 0), def_bonded("THOLE", "Thole Pol.", 4, 3, 0),
- def_bondnb("ANHARM_POL", "Anharm. Pol.", 2, 3, 0), def_bonded("POSRES", "Position Rest.", 1, 3, 3),
- def_bonded("FBPOSRES", "Flat-bottom posres", 1, 3, 0), def_bonded("DISRES", "Dis. Rest.", 2, 6, 0),
- def_nofc("DISRESVIOL", "D.R.Viol. (nm)"), def_bonded("ORIRES", "Orient. Rest.", 2, 6, 0),
- def_nofc("ORDEV", "Ori. R. RMSD"), def_bonded("ANGRES", "Angle Rest.", 4, 3, 3),
- def_bonded("ANGRESZ", "Angle Rest. Z", 2, 3, 3), def_bonded("DIHRES", "Dih. Rest.", 4, 3, 3),
+ def_dihedral("CMAP", "CMAP Dih.", 5, -1, -1),
+ def_nofc("GB12", "GB 1-2 Pol. (unused)"),
+ def_nofc("GB13", "GB 1-3 Pol. (unused)"),
+ def_nofc("GB14", "GB 1-4 Pol. (unused)"),
+ def_nofc("GBPOL", "GB Polarization (unused)"),
+ def_nofc("NPSOLVATION", "Nonpolar Sol. (unused)"),
+ def_pair("LJ14", "LJ-14", 2, 2, 2),
+ def_nofc("COUL14", "Coulomb-14"),
+ def_pair("LJC14_Q", "LJC-14 q", 2, 5, 0),
+ def_pair("LJC_NB", "LJC Pairs NB", 2, 4, 0),
+ def_nb("LJ_SR", "LJ (SR)", 2, 2),
+ def_nb("BHAM", "Buck.ham (SR)", 2, 3),
+ def_nofc("LJ_LR", "LJ (unused)"),
+ def_nofc("BHAM_LR", "B.ham (unused)"),
+ def_nofc("DISPCORR", "Disper. corr."),
+ def_nofc("COUL_SR", "Coulomb (SR)"),
+ def_nofc("COUL_LR", "Coul (unused)"),
+ def_nofc("RF_EXCL", "RF excl."),
+ def_nofc("COUL_RECIP", "Coul. recip."),
+ def_nofc("LJ_RECIP", "LJ recip."),
+ def_nofc("DPD", "DPD"),
+ def_bondnb("POLARIZATION", "Polarization", 2, 1, 0),
+ def_bonded("WATERPOL", "Water Pol.", 5, 6, 0),
+ def_bonded("THOLE", "Thole Pol.", 4, 3, 0),
+ def_bondnb("ANHARM_POL", "Anharm. Pol.", 2, 3, 0),
+ def_bonded("POSRES", "Position Rest.", 1, 3, 3),
+ def_bonded("FBPOSRES", "Flat-bottom posres", 1, 3, 0),
+ def_bonded("DISRES", "Dis. Rest.", 2, 6, 0),
+ def_nofc("DISRESVIOL", "D.R.Viol. (nm)"),
+ def_bonded("ORIRES", "Orient. Rest.", 2, 6, 0),
+ def_nofc("ORDEV", "Ori. R. RMSD"),
+ def_bonded("ANGRES", "Angle Rest.", 4, 3, 3),
+ def_bonded("ANGRESZ", "Angle Rest. Z", 2, 3, 3),
+ def_bonded("DIHRES", "Dih. Rest.", 4, 3, 3),
def_nofc("DIHRESVIOL", "Dih. Rest. Viol."), /* obsolete */
- def_shkcb("CONSTR", "Constraint", 2, 1, 1), def_shk("CONSTRNC", "Constr. No Conn.", 2, 1, 1),
- def_shkcb("SETTLE", "Settle", 3, 2, 0), def_vsite("VSITE1", "Virtual site 1", 2, 0),
- def_vsite("VSITE2", "Virtual site 2", 3, 1), def_vsite("VSITE2FD", "Virtual site 2fd", 3, 1),
- def_vsite("VSITE3", "Virtual site 3", 4, 2), def_vsite("VSITE3FD", "Virtual site 3fd", 4, 2),
+ def_shkcb("CONSTR", "Constraint", 2, 1, 1),
+ def_shk("CONSTRNC", "Constr. No Conn.", 2, 1, 1),
+ def_shkcb("SETTLE", "Settle", 3, 2, 0),
+ def_vsite("VSITE1", "Virtual site 1", 2, 0),
+ def_vsite("VSITE2", "Virtual site 2", 3, 1),
+ def_vsite("VSITE2FD", "Virtual site 2fd", 3, 1),
+ def_vsite("VSITE3", "Virtual site 3", 4, 2),
+ def_vsite("VSITE3FD", "Virtual site 3fd", 4, 2),
def_vsite("VSITE3FAD", "Virtual site 3fad", 4, 2),
- def_vsite("VSITE3OUT", "Virtual site 3out", 4, 3), def_vsite("VSITE4FD", "Virtual site 4fd", 5, 3),
- def_vsite("VSITE4FDN", "Virtual site 4fdn", 5, 3), def_vsite("VSITEN", "Virtual site N", 2, 2),
- def_nofc("COM_PULL", "COM Pull En."), def_nofc("DENSITYFIT", "Density fitting"),
- def_nofc("EQM", "Quantum En."), def_nofc("EPOT", "Potential"), def_nofc("EKIN", "Kinetic En."),
- def_nofc("ETOT", "Total Energy"), def_nofc("ECONS", "Conserved En."),
- def_nofc("TEMP", "Temperature"), def_nofc("VTEMP", "Vir. Temp. (not used)"),
+ def_vsite("VSITE3OUT", "Virtual site 3out", 4, 3),
+ def_vsite("VSITE4FD", "Virtual site 4fd", 5, 3),
+ def_vsite("VSITE4FDN", "Virtual site 4fdn", 5, 3),
+ def_vsite("VSITEN", "Virtual site N", 2, 2),
+ def_nofc("COM_PULL", "COM Pull En."),
+ def_nofc("DENSITYFIT", "Density fitting"),
+ def_nofc("EQM", "Quantum En."),
+ def_nofc("EPOT", "Potential"),
+ def_nofc("EKIN", "Kinetic En."),
+ def_nofc("ETOT", "Total Energy"),
+ def_nofc("ECONS", "Conserved En."),
+ def_nofc("TEMP", "Temperature"),
+ def_nofc("VTEMP", "Vir. Temp. (not used)"),
/* Note that pressure names can not be more than 8 char's,
* because " (bar)" is appended to them.
*/
- def_nofc("PDISPCORR", "Pres. DC"), def_nofc("PRES", "Pressure"),
+ def_nofc("PDISPCORR", "Pres. DC"),
+ def_nofc("PRES", "Pressure"),
def_nofc("DH/DL_CON", "dH/dl constr."), /* obsolete */
- def_nofc("DV/DL", "dVremain/dl"), def_nofc("DK/DL", "dEkin/dl"), def_nofc("DVC/DL", "dVcoul/dl"),
- def_nofc("DVV/DL", "dVvdw/dl"), def_nofc("DVB/DL", "dVbonded/dl"),
- def_nofc("DVR/DL", "dVrestraint/dl"), def_nofc("DVT/DL", "dVtemperature/dl")
+ def_nofc("DV/DL", "dVremain/dl"),
+ def_nofc("DK/DL", "dEkin/dl"),
+ def_nofc("DVC/DL", "dVcoul/dl"),
+ def_nofc("DVV/DL", "dVvdw/dl"),
+ def_nofc("DVB/DL", "dVbonded/dl"),
+ def_nofc("DVR/DL", "dVrestraint/dl"),
+ def_nofc("DVT/DL", "dVtemperature/dl")
};
else
{
if (0
- == gmx_strncasecmp(constructing_data[i].defining_atomnames[j], atnm,
+ == gmx_strncasecmp(constructing_data[i].defining_atomnames[j],
+ atnm,
strlen(constructing_data[i].defining_atomnames[j])))
{
match = TRUE;
{
t_resinfo* ri;
ri = &atoms->resinfo[resind];
- sprintf(ndx_name, "%s_%s%d%c", constructing_data[i].group_name, *ri->name,
- ri->nr, ri->ic == ' ' ? '\0' : ri->ic);
+ sprintf(ndx_name,
+ "%s_%s%d%c",
+ constructing_data[i].group_name,
+ *ri->name,
+ ri->nr,
+ ri->ic == ' ' ? '\0' : ri->ic);
add_grp(gb, gn, aid, ndx_name);
aid.clear();
}
{
gmx_fatal(FARGS,
"%s atom number (index[%d]=%d) is larger than the number of atoms in %s (%d)",
- gname ? gname : "Index", i + 1, index[i] + 1, traj ? traj : "the trajectory",
+ gname ? gname : "Index",
+ i + 1,
+ index[i] + 1,
+ traj ? traj : "the trajectory",
natoms);
}
else if (index[i] < 0)
{
- gmx_fatal(FARGS, "%s atom number (index[%d]=%d) is less than zero",
- gname ? gname : "Index", i + 1, index[i] + 1);
+ gmx_fatal(FARGS,
+ "%s atom number (index[%d]=%d) is less than zero",
+ gname ? gname : "Index",
+ i + 1,
+ index[i] + 1);
}
}
}
}
for (i = 0; (i < grps->nr); i++)
{
- fprintf(stderr, "Group %5d (%15s) has %5d elements\n", i, grpname[i],
- grps->index[i + 1] - grps->index[i]);
+ fprintf(stderr, "Group %5d (%15s) has %5d elements\n", i, grpname[i], grps->index[i + 1] - grps->index[i]);
}
for (i = 0; (i < ngrps); i++)
{
c->maxframe = std::max(c->maxframe, c->clust->a[i]);
}
fprintf(fplog ? fplog : stdout,
- "There are %d clusters containing %d structures, highest framenr is %d\n", c->clust->nr,
- c->clust->nra, c->maxframe);
+ "There are %d clusters containing %d structures, highest framenr is %d\n",
+ c->clust->nr,
+ c->clust->nra,
+ c->maxframe);
if (debug)
{
pr_blocka(debug, 0, "clust", c->clust, TRUE);
gmx_fatal(FARGS,
"Range check error for c->clust->a[%d] = %d\n"
"should be within 0 and %d",
- i, c->clust->a[i], c->maxframe + 1);
+ i,
+ c->clust->a[i],
+ c->maxframe + 1);
}
}
}
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2010,2014,2015,2019, by the GROMACS development team, led by
+ * Copyright (c) 2010,2014,2015,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.
gmx_fatal(FARGS,
"Double entries in block structure. Item %d is in blocks %d and %d\n"
" Cannot make an unambiguous inverse block.",
- j, i, invblock[j]);
+ j,
+ i,
+ invblock[j]);
}
}
}
gmx_fatal(FARGS,
"Double entries in block structure. Item %d is in blocks %d and %d\n"
" Cannot make an unambiguous inverse block.",
- j, i, invblock[block->a[j]]);
+ j,
+ i,
+ invblock[block->a[j]]);
}
}
}
const char** residueName,
int* globalResidueIndex)
{
- mtopGetAtomAndResidueName(&mtop, globalAtomIndex, moleculeBlock, atomName, residueNumber,
- residueName, globalResidueIndex);
+ mtopGetAtomAndResidueName(
+ &mtop, globalAtomIndex, moleculeBlock, atomName, residueNumber, residueName, globalResidueIndex);
}
/*! \brief Returns residue information for an atom based on global atom index
/* residue information */
for (l = dest->nres, j = 0; (j < copies); j++, l += src->nres)
{
- memcpy(reinterpret_cast<char*>(&(dest->resinfo[l])), reinterpret_cast<char*>(&(src->resinfo[0])),
+ memcpy(reinterpret_cast<char*>(&(dest->resinfo[l])),
+ reinterpret_cast<char*>(&(src->resinfo[0])),
static_cast<size_t>(src->nres * sizeof(src->resinfo[0])));
}
for (l = destnr, j = 0; (j < copies); j++, l += srcnr)
{
- memcpy(reinterpret_cast<char*>(&(dest->atom[l])), reinterpret_cast<char*>(&(src->atom[0])),
+ memcpy(reinterpret_cast<char*>(&(dest->atom[l])),
+ reinterpret_cast<char*>(&(src->atom[0])),
static_cast<size_t>(srcnr * sizeof(src->atom[0])));
memcpy(reinterpret_cast<char*>(&(dest->atomname[l])),
reinterpret_cast<char*>(&(src->atomname[0])),
int maxresnr = mtop->maxResNumberNotRenumbered();
for (const gmx_molblock_t& molb : mtop->molblock)
{
- atomcat(&atoms, &mtop->moltype[molb.type].atoms, molb.nmol,
- mtop->maxResiduesPerMoleculeToTriggerRenumber(), &maxresnr);
+ atomcat(&atoms,
+ &mtop->moltype[molb.type].atoms,
+ molb.nmol,
+ mtop->maxResiduesPerMoleculeToTriggerRenumber(),
+ &maxresnr);
}
return atoms;
*/
for (int mol = 0; mol < molb.nmol; mol++)
{
- ilistcat(ftype, &idef->il[F_CONSTR], molt.ilist[F_CONSTR], 1,
- destnr + mol * srcnr, srcnr);
- ilistcat(ftype, &idef->il[F_CONSTR], molt.ilist[F_CONSTRNC], 1,
- destnr + mol * srcnr, srcnr);
+ ilistcat(ftype, &idef->il[F_CONSTR], molt.ilist[F_CONSTR], 1, destnr + mol * srcnr, srcnr);
+ ilistcat(ftype, &idef->il[F_CONSTR], molt.ilist[F_CONSTRNC], 1, destnr + mol * srcnr, srcnr);
}
}
else if (!(mergeConstr && ftype == F_CONSTRNC))
if (mtop.atomtypes.atomnumber)
{
snew(atomtypes->atomnumber, mtop.atomtypes.nr);
- std::copy(mtop.atomtypes.atomnumber, mtop.atomtypes.atomnumber + mtop.atomtypes.nr,
+ std::copy(mtop.atomtypes.atomnumber,
+ mtop.atomtypes.atomnumber + mtop.atomtypes.nr,
atomtypes->atomnumber);
}
else
fprintf(stderr,
"Warning: Residue '%s' already present with type '%s' in database, ignoring "
"new type '%s'.\n",
- residueName.c_str(), (*foundIt)->residueType.c_str(), residueType.c_str());
+ residueName.c_str(),
+ (*foundIt)->residueType.c_str(),
+ residueType.c_str());
}
}
else
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2014,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2010,2014,2018,2019,2020,2021, 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.
#ifndef GMX_TOPOLOGY_RESIDUETYPES_H
#define GMX_TOPOLOGY_RESIDUETYPES_H
+#include <memory>
#include <optional>
#include <string>
#include "gromacs/utility/basedefinitions.h"
-#include "gromacs/utility/classhelpers.h"
struct ResidueTypeEntry;
//! Implementation pointer.
class Impl;
- gmx::PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
#endif
StringTable::StringTable(gmx::ISerializer* serializer)
{
- GMX_RELEASE_ASSERT(serializer->reading(),
- "Can not use writing serializer to read string table");
+ GMX_RELEASE_ASSERT(serializer->reading(), "Can not use writing serializer to read string table");
int nr = 0;
serializer->doInt(&nr);
table_.resize(nr);
StringTableEntry readStringTableEntry(gmx::ISerializer* serializer, const StringTable& table)
{
- GMX_RELEASE_ASSERT(serializer->reading(),
- "Can not use writing serializer to read string index");
+ GMX_RELEASE_ASSERT(serializer->reading(), "Can not use writing serializer to read string index");
int entry = 0;
serializer->doInt(&entry);
return table.at(entry);
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/utility/txtdump.h"
static gmx::EnumerationArray<SimulationAtomGroupType, const char*> c_simulationAtomGroupTypeShortNames = {
- { "T-Coupling", "Energy Mon.", "Acceleration", "Freeze", "User1", "User2", "VCM",
- "Compressed X", "Or. Res. Fit", "QMMM" }
+ { "T-Coupling",
+ "Energy Mon.",
+ "Acc. not used",
+ "Freeze",
+ "User1",
+ "User2",
+ "VCM",
+ "Compressed X",
+ "Or. Res. Fit",
+ "QMMM" }
};
const char* shortName(SimulationAtomGroupType type)
int index = 0;
for (const auto& group : grps)
{
- fprintf(fp, "%s[%-12s] nr=%zu, name=[", title, c_simulationAtomGroupTypeShortNames[index],
- group.size());
+ fprintf(fp, "%s[%-12s] nr=%zu, name=[", title, c_simulationAtomGroupTypeShortNames[index], group.size());
for (const auto& entry : group)
{
fprintf(fp, " %s", *(grpname[entry]));
static void pr_groups(FILE* fp, int indent, const SimulationGroups& groups, gmx_bool bShowNumbers)
{
pr_grps(fp, "grp", groups.groups, const_cast<char***>(groups.groupNames.data()));
- pr_strings(fp, indent, "grpname", const_cast<char***>(groups.groupNames.data()),
- groups.groupNames.size(), bShowNumbers);
+ pr_strings(fp,
+ indent,
+ "grpname",
+ const_cast<char***>(groups.groupNames.data()),
+ groups.groupNames.size(),
+ bShowNumbers);
pr_indent(fp, indent);
fprintf(fp, "groups ");
fprintf(fp, "groupnr[%5d] =", i);
for (auto group : keysOf(groups.groups))
{
- fprintf(fp, " %3d ",
+ fprintf(fp,
+ " %3d ",
!groups.groupNumbers[group].empty() ? groups.groupNumbers[group][i] : 0);
}
fprintf(fp, "\n");
pr_listoflists(fp, indent, "excls", &molt->excls, bShowNumbers);
for (j = 0; (j < F_NRE); j++)
{
- pr_ilist(fp, indent, interaction_function[j].longname, ffparams->functype.data(),
- molt->ilist[j], bShowNumbers, bShowParameters, ffparams->iparams.data());
+ pr_ilist(fp,
+ indent,
+ interaction_function[j].longname,
+ ffparams->functype.data(),
+ molt->ilist[j],
+ bShowNumbers,
+ bShowParameters,
+ ffparams->iparams.data());
}
}
{
pr_molblock(fp, indent, "molblock", &mtop->molblock[mb], mb, mtop->moltype);
}
- pr_str(fp, indent, "bIntermolecularInteractions",
- gmx::boolToString(mtop->bIntermolecularInteractions));
+ pr_str(fp, indent, "bIntermolecularInteractions", gmx::boolToString(mtop->bIntermolecularInteractions));
if (mtop->bIntermolecularInteractions)
{
for (int j = 0; j < F_NRE; j++)
{
- pr_ilist(fp, indent, interaction_function[j].longname,
- mtop->ffparams.functype.data(), (*mtop->intermolecular_ilist)[j],
- bShowNumbers, bShowParameters, mtop->ffparams.iparams.data());
+ pr_ilist(fp,
+ indent,
+ interaction_function[j].longname,
+ mtop->ffparams.functype.data(),
+ (*mtop->intermolecular_ilist)[j],
+ bShowNumbers,
+ bShowParameters,
+ mtop->ffparams.iparams.data());
}
}
pr_ffparams(fp, indent, "ffparams", &(mtop->ffparams), bShowNumbers);
pr_atomtypes(fp, indent, "atomtypes", &(mtop->atomtypes), bShowNumbers);
for (size_t mt = 0; mt < mtop->moltype.size(); mt++)
{
- pr_moltype(fp, indent, "moltype", &mtop->moltype[mt], mt, &mtop->ffparams, bShowNumbers,
- bShowParameters);
+ pr_moltype(fp, indent, "moltype", &mtop->moltype[mt], mt, &mtop->ffparams, bShowNumbers, bShowParameters);
}
pr_groups(fp, indent, mtop->groups, bShowNumbers);
}
pr_atoms(fp, indent, "atoms", &(top->atoms), bShowNumbers);
pr_atomtypes(fp, indent, "atomtypes", &(top->atomtypes), bShowNumbers);
pr_block(fp, indent, "mols", &top->mols, bShowNumbers);
- pr_str(fp, indent, "bIntermolecularInteractions",
- gmx::boolToString(top->bIntermolecularInteractions));
+ pr_str(fp, indent, "bIntermolecularInteractions", gmx::boolToString(top->bIntermolecularInteractions));
pr_idef(fp, indent, "idef", &top->idef, bShowNumbers, bShowParameters);
}
}
bDiff = FALSE;
for (i = 0; i < nrfpB && !bDiff; i++)
{
- bDiff = !equal_real(ip1.generic.buf[p0 + i], ip1.generic.buf[nrfpA + i], relativeTolerance,
- absoluteTolerance);
+ bDiff = !equal_real(
+ ip1.generic.buf[p0 + i], ip1.generic.buf[nrfpA + i], relativeTolerance, absoluteTolerance);
}
if (bDiff)
{
for (i = 0; i < 4 * cmap1->grid_spacing * cmap1->grid_spacing; i++)
{
- cmp_real(fp, "", i, cmap1->cmapdata[g].cmap[i], cmap2->cmapdata[g].cmap[i],
- relativeTolerance, absoluteTolerance);
+ cmp_real(fp, "", i, cmap1->cmapdata[g].cmap[i], cmap2->cmapdata[g].cmap[i], relativeTolerance, absoluteTolerance);
}
}
}
std::string buf = gmx::formatString("ffparams->functype[%d]", i);
cmp_int(fp, buf.c_str(), i, ff1.functype[i], ff2.functype[i]);
buf = gmx::formatString("ffparams->iparams[%d]", i);
- cmp_iparm(fp, buf.c_str(), ff1.functype[i], ff1.iparams[i], ff2.iparams[i],
- relativeTolerance, absoluteTolerance);
+ cmp_iparm(fp, buf.c_str(), ff1.functype[i], ff1.iparams[i], ff2.iparams[i], relativeTolerance, absoluteTolerance);
}
}
fprintf(fp, "comparing mtop topology\n");
cmp_str(fp, "Name", -1, *mtop1.name, *mtop2.name);
cmp_int(fp, "natoms", -1, mtop1.natoms, mtop2.natoms);
- cmp_int(fp, "maxres_renum", -1, mtop1.maxResiduesPerMoleculeToTriggerRenumber(),
+ cmp_int(fp,
+ "maxres_renum",
+ -1,
+ mtop1.maxResiduesPerMoleculeToTriggerRenumber(),
mtop2.maxResiduesPerMoleculeToTriggerRenumber());
cmp_int(fp, "maxresnr", -1, mtop1.maxResNumberNotRenumbered(), mtop2.maxResNumberNotRenumbered());
- cmp_bool(fp, "bIntermolecularInteractions", -1, mtop1.bIntermolecularInteractions,
- mtop2.bIntermolecularInteractions);
+ cmp_bool(fp, "bIntermolecularInteractions", -1, mtop1.bIntermolecularInteractions, mtop2.bIntermolecularInteractions);
cmp_bool(fp, "haveMoleculeIndices", -1, mtop1.haveMoleculeIndices, mtop2.haveMoleculeIndices);
compareFfparams(fp, mtop1.ffparams, mtop2.ffparams, relativeTolerance, absoluteTolerance);
compareInteractionLists(fp, mtop1.intermolecular_ilist.get(), mtop2.intermolecular_ilist.get());
compareAtomtypes(fp, mtop1.atomtypes, mtop2.atomtypes);
compareAtomGroups(fp, mtop1.groups, mtop2.groups, mtop1.natoms, mtop2.natoms);
- compareIntermolecularExclusions(fp, mtop1.intermolecularExclusionGroup,
- mtop2.intermolecularExclusionGroup);
+ compareIntermolecularExclusions(
+ fp, mtop1.intermolecularExclusionGroup, mtop2.intermolecularExclusionGroup);
compareBlockIndices(fp, mtop1.moleculeBlockIndices, mtop2.moleculeBlockIndices);
}
for (gmx::index j = 0; j < gmx::ssize(g0.groups[group]); j++)
{
buf = gmx::formatString("grps[%d].name[%zd]", static_cast<int>(group), j);
- cmp_str(fp, buf.c_str(), -1, *g0.groupNames[g0.groups[group][j]],
+ cmp_str(fp,
+ buf.c_str(),
+ -1,
+ *g0.groupNames[g0.groups[group][j]],
*g1.groupNames[g1.groups[group][j]]);
}
}
- cmp_int(fp, "ngrpnr", static_cast<int>(group), g0.numberOfGroupNumbers(group),
+ cmp_int(fp,
+ "ngrpnr",
+ static_cast<int>(group),
+ g0.numberOfGroupNumbers(group),
g1.numberOfGroupNumbers(group));
if (g0.numberOfGroupNumbers(group) == g1.numberOfGroupNumbers(group) && natoms0 == natoms1
&& (!g0.groupNumbers[group].empty() || !g1.groupNumbers[group].empty()))
{
for (int j = 0; j < natoms0; j++)
{
- cmp_int(fp, c_simulationAtomGroupTypeShortNames[group], j,
- getGroupType(g0, group, j), getGroupType(g1, group, j));
+ cmp_int(fp,
+ c_simulationAtomGroupTypeShortNames[group],
+ j,
+ getGroupType(g0, group, j),
+ getGroupType(g1, group, j));
}
}
}
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2011,2014,2015,2016,2018, The GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
{
TemperatureCoupling,
EnergyOutput,
- Acceleration,
+ AccelerationUnused,
Freeze,
User1,
User2,
case F_RESTRANGLES:
case F_RESTRDIHS:
case F_CBTDIHS:
- gmx_fatal(FARGS, "Function type %s does not support currentely free energy calculations",
+ gmx_fatal(FARGS,
+ "Function type %s does not support currentely free energy calculations",
interaction_function[ftype].longname);
default:
- gmx_fatal(FARGS, "Function type %s not implemented in ip_pert",
+ gmx_fatal(FARGS,
+ "Function type %s not implemented in ip_pert",
interaction_function[ftype].longname);
}
if (debug)
{
const int numNonperturbed = idef->numNonperturbedInteractions[ftype];
- fprintf(debug, "%s non-pert %d pert %d\n", interaction_function[ftype].longname,
- numNonperturbed, ilist->size() - numNonperturbed);
+ fprintf(debug,
+ "%s non-pert %d pert %d\n",
+ interaction_function[ftype].longname,
+ numNonperturbed,
+ ilist->size() - numNonperturbed);
}
}
}
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2015,2016,2018,2019, by the GROMACS development team, led by
+# Copyright (c) 2015,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.
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
-gmx_add_libgromacs_sources(
- energyframe.cpp
- trajectoryframe.cpp
- )
+# Set up the module library
+add_library(trajectory INTERFACE)
+file(GLOB TRAJECTORY_SOURCES *.cpp)
+set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${TRAJECTORY_SOURCES} PARENT_SCOPE)
+
+# Source files have the following dependencies on library infrastructure.
+#target_link_libraries(trajectory PRIVATE
+# common
+# legacy_modules
+#)
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(trajectory PUBLIC
+target_include_directories(trajectory INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(trajectory PUBLIC
+target_link_libraries(trajectory INTERFACE
+ legacy_api
+ )
+
+# TODO: when trajectory is an OBJECT target
+#target_link_libraries(trajectory PUBLIC legacy_api)
+#target_link_libraries(trajectory PRIVATE common)
+
+# Module dependencies
+# trajectory interfaces convey transitive dependence on these modules.
+#target_link_libraries(trajectory PUBLIC
+target_link_libraries(trajectory INTERFACE
+ utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(trajectory PRIVATE NOTHING)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(trajectory PRIVATE legacy_modules)
if(GMX_INSTALL_LEGACY_API)
install(FILES trajectoryframe.h
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
{
GMX_THROW(InternalError(formatString(
"Index %d for energy %s not present in energy frame with %d energies",
- index.second, index.first.c_str(), enxframe.nre)));
+ index.second,
+ index.first.c_str(),
+ enxframe.nre)));
}
values_[index.first] = enxframe.ener[index.second].e;
}
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+# Set up the module library
+add_library(trajectoryanalysis INTERFACE)
file(GLOB TRAJECTORYANALYSIS_SOURCES *.cpp modules/*.cpp)
set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${TRAJECTORYANALYSIS_SOURCES} PARENT_SCOPE)
+# Source files have the following dependencies on library infrastructure.
+#target_link_libraries(trajectoryanalysis PRIVATE
+# common
+# legacy_modules
+#)
+
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(trajectoryanalysis PUBLIC
+target_include_directories(trajectoryanalysis INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(trajectoryanalysis PUBLIC
+target_link_libraries(trajectoryanalysis INTERFACE
+ legacy_api
+ )
+
+# TODO: when trajectoryanalysis is an OBJECT target
+#target_link_libraries(trajectoryanalysis PUBLIC legacy_api)
+#target_link_libraries(trajectoryanalysis PRIVATE common)
+
+# Module dependencies
+# trajectoryanalysis interfaces convey transitive dependence on these modules.
+#target_link_libraries(trajectoryanalysis PUBLIC
+target_link_libraries(trajectoryanalysis INTERFACE
+ utility
+ )
+# Source files have the following private module dependencies.
+#target_link_libraries(trajectoryanalysis PRIVATE NOTHING)
+# TODO: Explicitly link specific modules.
+#target_link_libraries(trajectoryanalysis PRIVATE legacy_modules)
+
if(GMX_INSTALL_LEGACY_API)
install(FILES
analysismodule.h
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2010,2011,2012,2013,2014 by the GROMACS development team.
- * Copyright (c) 2015,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2015,2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <vector>
#include "gromacs/selection/selection.h" // For gmx::SelectionList
-#include "gromacs/utility/classhelpers.h"
struct t_pbc;
struct t_trxframe;
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
//! Smart pointer to manage a TrajectoryAnalysisModuleData object.
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
/*! \brief
* Needed to access the registered analysis data sets.
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2010-2018, The GROMACS development team.
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 2019,2021, 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.
#ifndef GMX_TRAJECTORYANALYSIS_ANALYSISSETTINGS_H
#define GMX_TRAJECTORYANALYSIS_ANALYSISSETTINGS_H
+#include <memory>
#include <string>
#include "gromacs/options/timeunitmanager.h"
-#include "gromacs/utility/classhelpers.h"
namespace gmx
{
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
friend class TrajectoryAnalysisRunnerCommon;
};
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2011-2018, The GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/trajectory/trajectoryframe.h"
#include "gromacs/trajectoryanalysis/analysissettings.h"
#include "gromacs/utility/arrayref.h"
+#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/enumerationhelpers.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/gmxassert.h"
Count
};
//! String values corresponding to Group1Type.
-const EnumerationArray<Group1Type, const char*> c_group1TypeEnumNames = { { "angle", "dihedral",
- "vector", "plane" } };
+const EnumerationArray<Group1Type, const char*> c_group1TypeEnumNames = {
+ { "angle", "dihedral", "vector", "plane" }
+};
//! String values corresponding to Group2Type.
const EnumerationArray<Group2Type, const char*> c_group2TypeEnumNames = {
{ "none", "vector", "plane", "t0", "z", "sphnorm" }
{
GMX_THROW(InconsistentInputError(formatString(
"Number of positions in selection %d in the first group not divisible by %d",
- static_cast<int>(g + 1), natoms1_)));
+ static_cast<int>(g + 1),
+ natoms1_)));
}
const int angleCount1 = posCount1 / natoms1_;
int angleCount = angleCount1;
GMX_THROW(InconsistentInputError(
formatString("Number of positions in selection %d in the second group not "
"divisible by %d",
- static_cast<int>(g + 1), natoms2_)));
+ static_cast<int>(g + 1),
+ natoms2_)));
}
if (g2type_ == Group2Type::SphereNormal && posCount2 != 1)
{
// read), but unsurprisingly the static analyzer chokes a bit on that.
clear_rvecs(4, x);
- real angle;
+ real angle = 0;
// checkSelections() ensures that this reflects all the involved
// positions.
const bool bPresent = iter1.currentValuesSelected() && iter2.currentValuesSelected();
void ConvertTrj::initAnalysis(const TrajectoryAnalysisSettings& /*settings*/, const TopologyInformation& top)
{
- output_ = createTrajectoryFrameWriter(top.mtop(), sel_, name_,
+ output_ = createTrajectoryFrameWriter(top.mtop(),
+ sel_,
+ name_,
top.hasTopology() ? top.copyAtoms() : nullptr,
requirementsBuilder_.process());
}
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2010-2018, The GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
std::string message = formatString(
"Selection '%s' does not evaluate into an even number of positions "
"(there are %d positions)",
- sel[g].name(), sel[g].posCount());
+ sel[g].name(),
+ sel[g].posCount());
GMX_THROW(InconsistentInputError(message));
}
if (sel[g].isDynamic())
void Distance::writeOutput()
{
SelectionList::const_iterator sel;
- int index;
- for (sel = sel_.begin(), index = 0; sel != sel_.end(); ++sel, ++index)
+ int index = 0;
+ for (sel = sel_.begin(); sel != sel_.end(); ++sel, ++index)
{
printf("%s:\n", sel->name());
printf(" Number of samples: %d\n", summaryStatsModule_->sampleCount(index, 0));
{
std::string outputName = Path::concatenateBeforeExtension(
outputNamePrefix_, formatString("_%s", clusterIndex_->grpname[i]));
- writers_.emplace_back(createTrajectoryFrameWriter(top.mtop(), sel_, outputName,
+ writers_.emplace_back(createTrajectoryFrameWriter(top.mtop(),
+ sel_,
+ outputName,
top.hasTopology() ? top.copyAtoms() : nullptr,
requirementsBuilder_.process()));
}
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
for (ArrayRef<const int>::iterator ai = atomind.begin(); (ai < atomind.end()); ++ai)
{
// Dereference the iterator to obtain an atom number
- int i = *ai;
- real value;
+ int i = *ai;
+ real value = 0;
// Lookup the Van der Waals radius of this atom
int resnr = atoms->atom[i].resind;
nnovdw++;
if (nnovdw < maxnovdw)
{
- fprintf(stderr, "Could not determine VDW radius for %s-%s. Set to zero.\n",
- *(atoms->resinfo[resnr].name), *(atoms->atomname[i]));
+ fprintf(stderr,
+ "Could not determine VDW radius for %s-%s. Set to zero.\n",
+ *(atoms->resinfo[resnr].name),
+ *(atoms->atomname[i]));
}
vdw_radius_.push_back(0.0);
}
//! Strings corresponding to DistanceType.
const EnumerationArray<DistanceType, const char*> c_distanceTypeNames = { { "min", "max" } };
//! Strings corresponding to GroupType.
-const EnumerationArray<GroupType, const char*> c_groupTypeNames = { { "all", "res", "mol",
- "none" } };
+const EnumerationArray<GroupType, const char*> c_groupTypeNames = {
+ { "all", "res", "mol", "none" }
+};
/*! \brief
* Implements `gmx pairdist` trajectory analysis module.
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2018 by the GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
real prevSphereVolume = 0.0;
for (int i = 0; i < nbin; ++i)
{
- const real r = (i + 0.5) * binwidth_;
- real sphereVolume;
- if (bXY_)
- {
- sphereVolume = M_PI * r * r;
- }
- else
- {
- sphereVolume = (4.0 / 3.0) * M_PI * r * r * r;
- }
- const real binVolume = sphereVolume - prevSphereVolume;
- invBinVolume[i] = 1.0 / binVolume;
- prevSphereVolume = sphereVolume;
+ const real r = (i + 0.5) * binwidth_;
+ const real sphereVolume = (bXY_) ? M_PI * r * r : (4.0 / 3.0) * M_PI * r * r * r;
+ const real binVolume = sphereVolume - prevSphereVolume;
+ invBinVolume[i] = 1.0 / binVolume;
+ prevSphereVolume = sphereVolume;
}
finalRdf->scaleAllByVector(invBinVolume.data());
* Copyright (c) 2001-2006, The GROMACS development team.
* Copyright (c) 2008,2009,2010,2011,2012 by the GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
*/
void do_conect(const char* fn, int n, rvec x[])
{
- FILE* fp;
- int i, j;
- t_conect* c;
- rvec dx;
- real d2;
+ t_conect* c = nullptr;
fprintf(stderr, "Building CONECT records\n");
snew(c, n);
- for (i = 0; (i < n); i++)
+ for (int i = 0; (i < n); i++)
{
c[i].aa = c[i].ab = -1;
}
- for (i = 0; (i < n); i++)
+ for (int i = 0; (i < n); i++)
{
- for (j = i + 1; (j < n); j++)
+ for (int j = i + 1; (j < n); j++)
{
+ rvec dx;
rvec_sub(x[i], x[j], dx);
- d2 = iprod(dx, dx);
+ const real d2 = iprod(dx, dx);
add_rec(c, i, j, d2);
add_rec(c, j, i, d2);
}
}
- fp = gmx_ffopen(fn, "a");
- for (i = 0; (i < n); i++)
+ FILE* fp = gmx_ffopen(fn, "a");
+ for (int i = 0; (i < n); i++)
{
if ((c[i].aa == -1) || (c[i].ab == -1))
{
const char* const resnm = "DOT";
const char* const title = "Connolly Dot Surface Generated by gmx sasa";
- int i, i0, r0, ii0, k;
- rvec* xnew;
- t_atoms aaa;
+ rvec* xnew = nullptr;
if (bIncludeSolute)
{
- i0 = atoms->nr;
- r0 = atoms->nres;
+ int i0 = atoms->nr;
+ int r0 = atoms->nres;
srenew(atoms->atom, atoms->nr + ndots);
memset(&atoms->atom[i0], 0, sizeof(*atoms->atom) * ndots);
srenew(atoms->atomname, atoms->nr + ndots);
srenew(atoms->pdbinfo, atoms->nr + ndots);
}
snew(xnew, atoms->nr + ndots);
- for (i = 0; (i < atoms->nr); i++)
+ for (int i = 0; (i < atoms->nr); i++)
{
copy_rvec(x[i], xnew[i]);
}
- for (i = k = 0; (i < ndots); i++)
+ int k = 0;
+ for (int i = 0; (i < ndots); i++)
{
- ii0 = i0 + i;
+ int ii0 = i0 + i;
atoms->atomname[ii0] = put_symtab(symtab, atomnm);
atoms->atom[ii0].resind = r0;
xnew[ii0][XX] = dots[k++];
}
else
{
+ t_atoms aaa;
init_t_atoms(&aaa, ndots, TRUE);
aaa.atom[0].resind = 0;
t_atoms_set_resinfo(&aaa, 0, symtab, resnm, 1, ' ', 0, ' ');
snew(xnew, ndots);
- for (i = k = 0; (i < ndots); i++)
+ int k = 0;
+ for (int i = 0; (i < ndots); i++)
{
- ii0 = i;
+ int ii0 = i;
aaa.atomname[ii0] = put_symtab(symtab, atomnm);
aaa.pdbinfo[ii0].type = epdbATOM;
aaa.pdbinfo[ii0].atomnr = ii0;
"from the full surface.[PAR]",
"The average and standard deviation of the area over the trajectory",
- "can be calculated per residue and atom (options [TT]-or[tt] and", "[TT]-oa[tt]).[PAR]",
+ "can be calculated per residue and atom (options [TT]-or[tt] and",
+ "[TT]-oa[tt]).[PAR]",
//"In combination with the latter option an [REF].itp[ref] file can be",
//"generated (option [TT]-i[tt])",
//"which can be used to restrain surface atoms.[PAR]",
{
const int ii = atomIndices[i];
const int resind = atoms_->atom[ii].resind;
- real radius;
+ real radius = 0;
if (!aps.setAtomProperty(epropVDW, *(atoms_->resinfo[resind].name), *(atoms_->atomname[ii]), &radius))
{
ndefault++;
radii_.push_back(radius + solsize_);
if (bDGsol)
{
- real dgsFactor;
- if (!aps.setAtomProperty(epropDGsol, *(atoms_->resinfo[resind].name),
- *(atoms_->atomtype[ii]), &dgsFactor))
+ real dgsFactor = 0;
+ if (!aps.setAtomProperty(
+ epropDGsol, *(atoms_->resinfo[resind].name), *(atoms_->atomtype[ii]), &dgsFactor))
{
dgsFactor = dgsDefault_;
}
"Output selection '%s' is not a subset of "
"the surface selection (atom %d is the first "
"atom not in the surface selection)",
- outputSel_[g].name(), outputIndices[i] + 1);
+ outputSel_[g].name(),
+ outputIndices[i] + 1);
GMX_THROW(InconsistentInputError(message));
}
outputSel_[g].setOriginalId(i, j);
// area array contains the per-atom areas for the selected positions.
// surfacedots contains nsurfacedots entries, and contains the actual
// points.
- real totarea, totvolume;
+ real totarea = 0;
+ real totvolume = 0;
real *area = nullptr, *surfacedots = nullptr;
- int nsurfacedots;
- calculator_.calculate(surfaceSel.coordinates().data(), pbc, frameData.index_.size(),
- frameData.index_.data(), flag, &totarea, &totvolume, &area, &surfacedots,
+ int nsurfacedots = 0;
+ calculator_.calculate(surfaceSel.coordinates().data(),
+ pbc,
+ frameData.index_.size(),
+ frameData.index_.data(),
+ flag,
+ &totarea,
+ &totvolume,
+ &area,
+ &surfacedots,
&nsurfacedots);
// Unpack the atomwise areas into the frameData.atomAreas_ array for easier
// indexing in the case of dynamic surfaceSel.
// structures. But since it is only used in the first frame, and no
// one else uses the topology after initialization, it may just work
// even with future parallelization.
- connolly_plot(fnConnolly_.c_str(), nsurfacedots, surfacedots, fr.x, atoms_.get(),
- &mtop_->symtab, fr.pbcType, fr.box, bIncludeSolute_);
+ connolly_plot(fnConnolly_.c_str(),
+ nsurfacedots,
+ surfacedots,
+ fr.x,
+ atoms_.get(),
+ &mtop_->symtab,
+ fr.pbcType,
+ fr.box,
+ bIncludeSolute_);
}
ah.startFrame(frnr, fr.time);
ah.setPoint(0, totarea);
- real totalArea, dgsolv;
+ real totalArea = 0;
+ real dgsolv = 0;
if (bResAt || bDGsol)
{
- computeAreas(surfaceSel, surfaceSel, frameData.atomAreas_, dgsFactor_, &totalArea, &dgsolv,
- aah, rah, &frameData.res_a_);
+ computeAreas(surfaceSel,
+ surfaceSel,
+ frameData.atomAreas_,
+ dgsFactor_,
+ &totalArea,
+ &dgsolv,
+ aah,
+ rah,
+ &frameData.res_a_);
if (bDGsol)
{
dgh.setPoint(0, dgsolv);
aah.selectDataSet(g + 1);
rah.selectDataSet(g + 1);
}
- computeAreas(surfaceSel, outputSel[g], frameData.atomAreas_, dgsFactor_, &totalArea,
- &dgsolv, aah, rah, &frameData.res_a_);
+ computeAreas(surfaceSel,
+ outputSel[g],
+ frameData.atomAreas_,
+ dgsFactor_,
+ &totalArea,
+ &dgsolv,
+ aah,
+ rah,
+ &frameData.res_a_);
ah.setPoint(g + 1, totalArea);
if (bDGsol)
{
const EnumerationArray<ResidueNumbering, const char*> c_residueNumberingTypeNames = { { "number",
"index" } };
//! String values corresponding to PdbAtomsSelection.
-const EnumerationArray<PdbAtomsSelection, const char*> c_pdbAtomsTypeNames = { { "all", "maxsel",
- "selected" } };
+const EnumerationArray<PdbAtomsSelection, const char*> c_pdbAtomsTypeNames = {
+ { "all", "maxsel", "selected" }
+};
class Select : public TrajectoryAnalysisModule
{
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2007, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2017,2018 by the GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
divarc(real x1, real y1, real z1, real x2, real y2, real z2, int div1, int div2, real* xr, real* yr, real* zr)
{
- real xd, yd, zd, dd, d1, d2, s, x, y, z;
- real phi, sphi, cphi;
-
- xd = y1 * z2 - y2 * z1;
- yd = z1 * x2 - z2 * x1;
- zd = x1 * y2 - x2 * y1;
- dd = std::sqrt(xd * xd + yd * yd + zd * zd);
+ const real xd = y1 * z2 - y2 * z1;
+ const real yd = z1 * x2 - z2 * x1;
+ const real zd = x1 * y2 - x2 * y1;
+ const real dd = std::sqrt(xd * xd + yd * yd + zd * zd);
GMX_ASSERT(dd >= DP_TOL, "Rotation axis vector too short");
- d1 = x1 * x1 + y1 * y1 + z1 * z1;
- d2 = x2 * x2 + y2 * y2 + z2 * z2;
+ const real d1 = x1 * x1 + y1 * y1 + z1 * z1;
+ const real d2 = x2 * x2 + y2 * y2 + z2 * z2;
GMX_ASSERT(d1 >= 0.5, "Vector 1 too short");
GMX_ASSERT(d2 >= 0.5, "Vector 2 too short");
- phi = safe_asin(dd / std::sqrt(d1 * d2));
- phi = phi * (static_cast<real>(div1)) / (static_cast<real>(div2));
- sphi = sin(phi);
- cphi = cos(phi);
- s = (x1 * xd + y1 * yd + z1 * zd) / dd;
-
- x = xd * s * (1. - cphi) / dd + x1 * cphi + (yd * z1 - y1 * zd) * sphi / dd;
- y = yd * s * (1. - cphi) / dd + y1 * cphi + (zd * x1 - z1 * xd) * sphi / dd;
- z = zd * s * (1. - cphi) / dd + z1 * cphi + (xd * y1 - x1 * yd) * sphi / dd;
- dd = std::sqrt(x * x + y * y + z * z);
- *xr = x / dd;
- *yr = y / dd;
- *zr = z / dd;
+ real phi = safe_asin(dd / std::sqrt(d1 * d2));
+ phi = phi * (static_cast<real>(div1)) / (static_cast<real>(div2));
+ const real sphi = sin(phi);
+ const real cphi = cos(phi);
+ const real s = (x1 * xd + y1 * yd + z1 * zd) / dd;
+
+ const real x = xd * s * (1. - cphi) / dd + x1 * cphi + (yd * z1 - y1 * zd) * sphi / dd;
+ const real y = yd * s * (1. - cphi) / dd + y1 * cphi + (zd * x1 - z1 * xd) * sphi / dd;
+ const real z = zd * s * (1. - cphi) / dd + z1 * cphi + (xd * y1 - x1 * yd) * sphi / dd;
+ const real dd2 = std::sqrt(x * x + y * y + z * z);
+ *xr = x / dd2;
+ *yr = y / dd2;
+ *zr = z / dd2;
}
/* densit...required dots per unit sphere */
/* dot distribution on a unit sphere based on an icosaeder *
* great circle average refining of icosahedral face */
- int i, j, k, tl, tl2, tn;
- real a, d, x, y, z, x2, y2, z2, x3, y3, z3;
- real xij, yij, zij, xji, yji, zji, xik, yik, zik, xki, yki, zki, xjk, yjk, zjk, xkj, ykj, zkj;
+ real x2 = NAN, y2 = NAN, z2 = NAN, x3 = NAN, y3 = NAN, z3 = NAN;
+ real xij = NAN, yij = NAN, zij = NAN, xji = NAN, yji = NAN, zji = NAN, xik = NAN, yik = NAN,
+ zik = NAN, xki = NAN, yki = NAN, zki = NAN, xjk = NAN, yjk = NAN, zjk = NAN, xkj = NAN,
+ ykj = NAN, zkj = NAN;
/* calculate tessalation level */
- a = std::sqrt(((static_cast<real>(densit)) - 2.) / 10.);
- const int tess = static_cast<int>(ceil(a));
- const int ndot = 10 * tess * tess + 2;
+ const real a = std::sqrt(((static_cast<real>(densit)) - 2.) / 10.);
+ const int tess = static_cast<int>(ceil(a));
+ const int ndot = 10 * tess * tess + 2;
GMX_RELEASE_ASSERT(ndot >= densit, "Inconsistent surface dot formula");
std::vector<real> xus(3 * ndot);
if (tess > 1)
{
- tn = 12;
- a = rh * rh * 2. * (1. - cos(TORAD(72.)));
+ int tn = 12;
+ const real a = rh * rh * 2. * (1. - cos(TORAD(72.)));
/* calculate tessalation of icosaeder edges */
- for (i = 0; i < 11; i++)
+ for (int i = 0; i < 11; i++)
{
- for (j = i + 1; j < 12; j++)
+ for (int j = i + 1; j < 12; j++)
{
- x = xus[3 * i] - xus[3 * j];
- y = xus[1 + 3 * i] - xus[1 + 3 * j];
- z = xus[2 + 3 * i] - xus[2 + 3 * j];
- d = x * x + y * y + z * z;
+ const real x = xus[3 * i] - xus[3 * j];
+ const real y = xus[1 + 3 * i] - xus[1 + 3 * j];
+ const real z = xus[2 + 3 * i] - xus[2 + 3 * j];
+ const real d = x * x + y * y + z * z;
if (std::fabs(a - d) > DP_TOL)
{
continue;
}
- for (tl = 1; tl < tess; tl++)
+ for (int tl = 1; tl < tess; tl++)
{
GMX_ASSERT(tn < ndot, "Inconsistent precomputed surface dot count");
- divarc(xus[3 * i], xus[1 + 3 * i], xus[2 + 3 * i], xus[3 * j], xus[1 + 3 * j],
- xus[2 + 3 * j], tl, tess, &xus[3 * tn], &xus[1 + 3 * tn], &xus[2 + 3 * tn]);
+ divarc(xus[3 * i],
+ xus[1 + 3 * i],
+ xus[2 + 3 * i],
+ xus[3 * j],
+ xus[1 + 3 * j],
+ xus[2 + 3 * j],
+ tl,
+ tess,
+ &xus[3 * tn],
+ &xus[1 + 3 * tn],
+ &xus[2 + 3 * tn]);
tn++;
}
}
}
/* calculate tessalation of icosaeder faces */
- for (i = 0; i < 10; i++)
+ for (int i = 0; i < 10; i++)
{
- for (j = i + 1; j < 11; j++)
+ for (int j = i + 1; j < 11; j++)
{
- x = xus[3 * i] - xus[3 * j];
- y = xus[1 + 3 * i] - xus[1 + 3 * j];
- z = xus[2 + 3 * i] - xus[2 + 3 * j];
- d = x * x + y * y + z * z;
+ real x = xus[3 * i] - xus[3 * j];
+ real y = xus[1 + 3 * i] - xus[1 + 3 * j];
+ real z = xus[2 + 3 * i] - xus[2 + 3 * j];
+ real d = x * x + y * y + z * z;
if (std::fabs(a - d) > DP_TOL)
{
continue;
}
- for (k = j + 1; k < 12; k++)
+ for (int k = j + 1; k < 12; k++)
{
x = xus[3 * i] - xus[3 * k];
y = xus[1 + 3 * i] - xus[1 + 3 * k];
{
continue;
}
- for (tl = 1; tl < tess - 1; tl++)
+ for (int tl = 1; tl < tess - 1; tl++)
{
- divarc(xus[3 * j], xus[1 + 3 * j], xus[2 + 3 * j], xus[3 * i],
- xus[1 + 3 * i], xus[2 + 3 * i], tl, tess, &xji, &yji, &zji);
- divarc(xus[3 * k], xus[1 + 3 * k], xus[2 + 3 * k], xus[3 * i],
- xus[1 + 3 * i], xus[2 + 3 * i], tl, tess, &xki, &yki, &zki);
-
- for (tl2 = 1; tl2 < tess - tl; tl2++)
+ divarc(xus[3 * j],
+ xus[1 + 3 * j],
+ xus[2 + 3 * j],
+ xus[3 * i],
+ xus[1 + 3 * i],
+ xus[2 + 3 * i],
+ tl,
+ tess,
+ &xji,
+ &yji,
+ &zji);
+ divarc(xus[3 * k],
+ xus[1 + 3 * k],
+ xus[2 + 3 * k],
+ xus[3 * i],
+ xus[1 + 3 * i],
+ xus[2 + 3 * i],
+ tl,
+ tess,
+ &xki,
+ &yki,
+ &zki);
+
+ for (int tl2 = 1; tl2 < tess - tl; tl2++)
{
- divarc(xus[3 * i], xus[1 + 3 * i], xus[2 + 3 * i], xus[3 * j],
- xus[1 + 3 * j], xus[2 + 3 * j], tl2, tess, &xij, &yij, &zij);
- divarc(xus[3 * k], xus[1 + 3 * k], xus[2 + 3 * k], xus[3 * j],
- xus[1 + 3 * j], xus[2 + 3 * j], tl2, tess, &xkj, &ykj, &zkj);
- divarc(xus[3 * i], xus[1 + 3 * i], xus[2 + 3 * i], xus[3 * k], xus[1 + 3 * k],
- xus[2 + 3 * k], tess - tl - tl2, tess, &xik, &yik, &zik);
- divarc(xus[3 * j], xus[1 + 3 * j], xus[2 + 3 * j], xus[3 * k], xus[1 + 3 * k],
- xus[2 + 3 * k], tess - tl - tl2, tess, &xjk, &yjk, &zjk);
+ divarc(xus[3 * i],
+ xus[1 + 3 * i],
+ xus[2 + 3 * i],
+ xus[3 * j],
+ xus[1 + 3 * j],
+ xus[2 + 3 * j],
+ tl2,
+ tess,
+ &xij,
+ &yij,
+ &zij);
+ divarc(xus[3 * k],
+ xus[1 + 3 * k],
+ xus[2 + 3 * k],
+ xus[3 * j],
+ xus[1 + 3 * j],
+ xus[2 + 3 * j],
+ tl2,
+ tess,
+ &xkj,
+ &ykj,
+ &zkj);
+ divarc(xus[3 * i],
+ xus[1 + 3 * i],
+ xus[2 + 3 * i],
+ xus[3 * k],
+ xus[1 + 3 * k],
+ xus[2 + 3 * k],
+ tess - tl - tl2,
+ tess,
+ &xik,
+ &yik,
+ &zik);
+ divarc(xus[3 * j],
+ xus[1 + 3 * j],
+ xus[2 + 3 * j],
+ xus[3 * k],
+ xus[1 + 3 * k],
+ xus[2 + 3 * k],
+ tess - tl - tl2,
+ tess,
+ &xjk,
+ &yjk,
+ &zjk);
divarc(xki, yki, zki, xji, yji, zji, tl2, tess - tl, &x, &y, &z);
divarc(xkj, ykj, zkj, xij, yij, zij, tl, tess - tl2, &x2, &y2, &z2);
divarc(xjk, yjk, zjk, xik, yik, zik, tl, tl + tl2, &x3, &y3, &z3);
/* dot distribution on a unit sphere based on an icosaeder *
* great circle average refining of icosahedral face */
- int i, j, k, tl, tl2, tn, tess, j1, j2;
- real a, d, x, y, z, x2, y2, z2, x3, y3, z3, ai_d, adod;
- real xij, yij, zij, xji, yji, zji, xik, yik, zik, xki, yki, zki, xjk, yjk, zjk, xkj, ykj, zkj;
+ real x2 = NAN, y2 = NAN, z2 = NAN, x3 = NAN, y3 = NAN, z3 = NAN;
+ real xij = NAN, yij = NAN, zij = NAN, xji = NAN, yji = NAN, zji = NAN, xik = NAN, yik = NAN,
+ zik = NAN, xki = NAN, yki = NAN, zki = NAN, xjk = NAN, yjk = NAN, zjk = NAN, xkj = NAN,
+ ykj = NAN, zkj = NAN;
/* calculate tesselation level */
- a = std::sqrt(((static_cast<real>(densit)) - 2.) / 30.);
- tess = std::max(static_cast<int>(ceil(a)), 1);
+ real a = std::sqrt(((static_cast<real>(densit)) - 2.) / 30.);
+ const int tess = std::max(static_cast<int>(ceil(a)), 1);
const int ndot = 30 * tess * tess + 2;
GMX_RELEASE_ASSERT(ndot >= densit, "Inconsistent surface dot formula");
std::vector<real> xus(3 * ndot);
const real rh = icosaeder_vertices(xus.data());
- tn = 12;
+ int tn = 12;
/* square of the edge of an icosaeder */
a = rh * rh * 2. * (1. - cos(TORAD(72.)));
/* dodecaeder vertices */
- for (i = 0; i < 10; i++)
+ for (int i = 0; i < 10; i++)
{
- for (j = i + 1; j < 11; j++)
+ for (int j = i + 1; j < 11; j++)
{
- x = xus[3 * i] - xus[3 * j];
- y = xus[1 + 3 * i] - xus[1 + 3 * j];
- z = xus[2 + 3 * i] - xus[2 + 3 * j];
- d = x * x + y * y + z * z;
+ const real x = xus[3 * i] - xus[3 * j];
+ const real y = xus[1 + 3 * i] - xus[1 + 3 * j];
+ const real z = xus[2 + 3 * i] - xus[2 + 3 * j];
+ const real d = x * x + y * y + z * z;
if (std::fabs(a - d) > DP_TOL)
{
continue;
}
- for (k = j + 1; k < 12; k++)
+ for (int k = j + 1; k < 12; k++)
{
- x = xus[3 * i] - xus[3 * k];
- y = xus[1 + 3 * i] - xus[1 + 3 * k];
- z = xus[2 + 3 * i] - xus[2 + 3 * k];
- d = x * x + y * y + z * z;
- if (std::fabs(a - d) > DP_TOL)
{
- continue;
+ const real x = xus[3 * i] - xus[3 * k];
+ const real y = xus[1 + 3 * i] - xus[1 + 3 * k];
+ const real z = xus[2 + 3 * i] - xus[2 + 3 * k];
+ const real d = x * x + y * y + z * z;
+ if (std::fabs(a - d) > DP_TOL)
+ {
+ continue;
+ }
}
- x = xus[3 * j] - xus[3 * k];
- y = xus[1 + 3 * j] - xus[1 + 3 * k];
- z = xus[2 + 3 * j] - xus[2 + 3 * k];
- d = x * x + y * y + z * z;
- if (std::fabs(a - d) > DP_TOL)
{
- continue;
+ const real x = xus[3 * j] - xus[3 * k];
+ const real y = xus[1 + 3 * j] - xus[1 + 3 * k];
+ const real z = xus[2 + 3 * j] - xus[2 + 3 * k];
+ const real d = x * x + y * y + z * z;
+ if (std::fabs(a - d) > DP_TOL)
+ {
+ continue;
+ }
}
- x = xus[3 * i] + xus[3 * j] + xus[3 * k];
- y = xus[1 + 3 * i] + xus[1 + 3 * j] + xus[1 + 3 * k];
- z = xus[2 + 3 * i] + xus[2 + 3 * j] + xus[2 + 3 * k];
- d = std::sqrt(x * x + y * y + z * z);
+ const real x = xus[3 * i] + xus[3 * j] + xus[3 * k];
+ const real y = xus[1 + 3 * i] + xus[1 + 3 * j] + xus[1 + 3 * k];
+ const real z = xus[2 + 3 * i] + xus[2 + 3 * j] + xus[2 + 3 * k];
+ const real d = std::sqrt(x * x + y * y + z * z);
xus[3 * tn] = x / d;
xus[1 + 3 * tn] = y / d;
xus[2 + 3 * tn] = z / d;
if (tess > 1)
{
- tn = 32;
+ int tn = 32;
/* square of the edge of an dodecaeder */
- adod = 4. * (cos(TORAD(108.)) - cos(TORAD(120.))) / (1. - cos(TORAD(120.)));
+ const real adod = 4. * (cos(TORAD(108.)) - cos(TORAD(120.))) / (1. - cos(TORAD(120.)));
/* square of the distance of two adjacent vertices of ico- and dodecaeder */
- ai_d = 2. * (1. - std::sqrt(1. - a / 3.));
+ const real ai_d = 2. * (1. - std::sqrt(1. - a / 3.));
/* calculate tessalation of mixed edges */
- for (i = 0; i < 31; i++)
+ for (int i = 0; i < 31; i++)
{
- j1 = 12;
- j2 = 32;
- a = ai_d;
+ int j1 = 12;
+ int j2 = 32;
+ a = ai_d;
if (i >= 12)
{
j1 = i + 1;
a = adod;
}
- for (j = j1; j < j2; j++)
+ for (int j = j1; j < j2; j++)
{
- x = xus[3 * i] - xus[3 * j];
- y = xus[1 + 3 * i] - xus[1 + 3 * j];
- z = xus[2 + 3 * i] - xus[2 + 3 * j];
- d = x * x + y * y + z * z;
+ const real x = xus[3 * i] - xus[3 * j];
+ const real y = xus[1 + 3 * i] - xus[1 + 3 * j];
+ const real z = xus[2 + 3 * i] - xus[2 + 3 * j];
+ const real d = x * x + y * y + z * z;
if (std::fabs(a - d) > DP_TOL)
{
continue;
}
- for (tl = 1; tl < tess; tl++)
+ for (int tl = 1; tl < tess; tl++)
{
GMX_ASSERT(tn < ndot, "Inconsistent precomputed surface dot count");
- divarc(xus[3 * i], xus[1 + 3 * i], xus[2 + 3 * i], xus[3 * j], xus[1 + 3 * j],
- xus[2 + 3 * j], tl, tess, &xus[3 * tn], &xus[1 + 3 * tn], &xus[2 + 3 * tn]);
+ divarc(xus[3 * i],
+ xus[1 + 3 * i],
+ xus[2 + 3 * i],
+ xus[3 * j],
+ xus[1 + 3 * j],
+ xus[2 + 3 * j],
+ tl,
+ tess,
+ &xus[3 * tn],
+ &xus[1 + 3 * tn],
+ &xus[2 + 3 * tn]);
tn++;
}
}
}
/* calculate tessalation of pentakisdodecahedron faces */
- for (i = 0; i < 12; i++)
+ for (int i = 0; i < 12; i++)
{
- for (j = 12; j < 31; j++)
+ for (int j = 12; j < 31; j++)
{
- x = xus[3 * i] - xus[3 * j];
- y = xus[1 + 3 * i] - xus[1 + 3 * j];
- z = xus[2 + 3 * i] - xus[2 + 3 * j];
- d = x * x + y * y + z * z;
+ const real x = xus[3 * i] - xus[3 * j];
+ const real y = xus[1 + 3 * i] - xus[1 + 3 * j];
+ const real z = xus[2 + 3 * i] - xus[2 + 3 * j];
+ const real d = x * x + y * y + z * z;
if (std::fabs(ai_d - d) > DP_TOL)
{
continue;
}
- for (k = j + 1; k < 32; k++)
+ for (int k = j + 1; k < 32; k++)
{
- x = xus[3 * i] - xus[3 * k];
- y = xus[1 + 3 * i] - xus[1 + 3 * k];
- z = xus[2 + 3 * i] - xus[2 + 3 * k];
- d = x * x + y * y + z * z;
+ real x = xus[3 * i] - xus[3 * k];
+ real y = xus[1 + 3 * i] - xus[1 + 3 * k];
+ real z = xus[2 + 3 * i] - xus[2 + 3 * k];
+ real d = x * x + y * y + z * z;
if (std::fabs(ai_d - d) > DP_TOL)
{
continue;
{
continue;
}
- for (tl = 1; tl < tess - 1; tl++)
+ for (int tl = 1; tl < tess - 1; tl++)
{
- divarc(xus[3 * j], xus[1 + 3 * j], xus[2 + 3 * j], xus[3 * i],
- xus[1 + 3 * i], xus[2 + 3 * i], tl, tess, &xji, &yji, &zji);
- divarc(xus[3 * k], xus[1 + 3 * k], xus[2 + 3 * k], xus[3 * i],
- xus[1 + 3 * i], xus[2 + 3 * i], tl, tess, &xki, &yki, &zki);
-
- for (tl2 = 1; tl2 < tess - tl; tl2++)
+ divarc(xus[3 * j],
+ xus[1 + 3 * j],
+ xus[2 + 3 * j],
+ xus[3 * i],
+ xus[1 + 3 * i],
+ xus[2 + 3 * i],
+ tl,
+ tess,
+ &xji,
+ &yji,
+ &zji);
+ divarc(xus[3 * k],
+ xus[1 + 3 * k],
+ xus[2 + 3 * k],
+ xus[3 * i],
+ xus[1 + 3 * i],
+ xus[2 + 3 * i],
+ tl,
+ tess,
+ &xki,
+ &yki,
+ &zki);
+
+ for (int tl2 = 1; tl2 < tess - tl; tl2++)
{
- divarc(xus[3 * i], xus[1 + 3 * i], xus[2 + 3 * i], xus[3 * j],
- xus[1 + 3 * j], xus[2 + 3 * j], tl2, tess, &xij, &yij, &zij);
- divarc(xus[3 * k], xus[1 + 3 * k], xus[2 + 3 * k], xus[3 * j],
- xus[1 + 3 * j], xus[2 + 3 * j], tl2, tess, &xkj, &ykj, &zkj);
- divarc(xus[3 * i], xus[1 + 3 * i], xus[2 + 3 * i], xus[3 * k], xus[1 + 3 * k],
- xus[2 + 3 * k], tess - tl - tl2, tess, &xik, &yik, &zik);
- divarc(xus[3 * j], xus[1 + 3 * j], xus[2 + 3 * j], xus[3 * k], xus[1 + 3 * k],
- xus[2 + 3 * k], tess - tl - tl2, tess, &xjk, &yjk, &zjk);
+ divarc(xus[3 * i],
+ xus[1 + 3 * i],
+ xus[2 + 3 * i],
+ xus[3 * j],
+ xus[1 + 3 * j],
+ xus[2 + 3 * j],
+ tl2,
+ tess,
+ &xij,
+ &yij,
+ &zij);
+ divarc(xus[3 * k],
+ xus[1 + 3 * k],
+ xus[2 + 3 * k],
+ xus[3 * j],
+ xus[1 + 3 * j],
+ xus[2 + 3 * j],
+ tl2,
+ tess,
+ &xkj,
+ &ykj,
+ &zkj);
+ divarc(xus[3 * i],
+ xus[1 + 3 * i],
+ xus[2 + 3 * i],
+ xus[3 * k],
+ xus[1 + 3 * k],
+ xus[2 + 3 * k],
+ tess - tl - tl2,
+ tess,
+ &xik,
+ &yik,
+ &zik);
+ divarc(xus[3 * j],
+ xus[1 + 3 * j],
+ xus[2 + 3 * j],
+ xus[3 * k],
+ xus[1 + 3 * k],
+ xus[2 + 3 * k],
+ tess - tl - tl2,
+ tess,
+ &xjk,
+ &yjk,
+ &zjk);
divarc(xki, yki, zki, xji, yji, zji, tl2, tess - tl, &x, &y, &z);
divarc(xkj, ykj, zkj, xij, yij, zij, tl, tess - tl2, &x2, &y2, &z2);
divarc(xjk, yjk, zjk, xik, yik, zik, tl, tl + tl2, &x3, &y3, &z3);
static int unsp_type(int densit)
{
- int i1, i2;
- i1 = 1;
+ int i1 = 1;
while (10 * i1 * i1 + 2 < densit)
{
i1++;
}
- i2 = 1;
+ int i2 = 1;
while (30 * i2 * i2 + 2 < densit)
{
i2++;
static std::vector<real> make_unsp(int densit, int cubus)
{
- int *ico_wk, *ico_pt;
- int ico_cube, ico_cube_cb, i, j, k, l, ijk, tn, tl, tl2;
- int* work;
- real x, y, z;
+ int ico_cube = 0;
int mode = unsp_type(densit);
std::vector<real> xus;
}
else
{
- i = 1;
+ int i = 1;
while (i * i * i * 2 < ndot)
{
i++;
}
ico_cube = std::max(i - 1, 0);
}
- ico_cube_cb = ico_cube * ico_cube * ico_cube;
- const real del_cube = 2. / (static_cast<real>(ico_cube));
- snew(work, ndot);
- for (l = 0; l < ndot; l++)
+ int ico_cube_cb = ico_cube * ico_cube * ico_cube;
+ const real del_cube = 2. / (static_cast<real>(ico_cube));
+ std::vector<int> work;
+ for (int l = 0; l < ndot; l++)
{
- i = std::max(static_cast<int>(floor((1. + xus[3 * l]) / del_cube)), 0);
+ int i = std::max(static_cast<int>(floor((1. + xus[3 * l]) / del_cube)), 0);
if (i >= ico_cube)
{
i = ico_cube - 1;
}
- j = std::max(static_cast<int>(floor((1. + xus[1 + 3 * l]) / del_cube)), 0);
+ int j = std::max(static_cast<int>(floor((1. + xus[1 + 3 * l]) / del_cube)), 0);
if (j >= ico_cube)
{
j = ico_cube - 1;
}
- k = std::max(static_cast<int>(floor((1. + xus[2 + 3 * l]) / del_cube)), 0);
+ int k = std::max(static_cast<int>(floor((1. + xus[2 + 3 * l]) / del_cube)), 0);
if (k >= ico_cube)
{
k = ico_cube - 1;
}
- ijk = i + j * ico_cube + k * ico_cube * ico_cube;
- work[l] = ijk;
+ int ijk = i + j * ico_cube + k * ico_cube * ico_cube;
+ work.emplace_back(ijk);
}
- snew(ico_wk, 2 * ico_cube_cb + 1);
+ std::vector<int> ico_wk(2 * ico_cube_cb + 1);
- ico_pt = ico_wk + ico_cube_cb;
- for (l = 0; l < ndot; l++)
+ int* ico_pt = ico_wk.data() + ico_cube_cb;
+ for (int l = 0; l < ndot; l++)
{
ico_wk[work[l]]++; /* dots per elementary cube */
}
/* reordering of the coordinate array in accordance with box number */
- tn = 0;
- for (i = 0; i < ico_cube; i++)
+ int tn = 0;
+ for (int i = 0; i < ico_cube; i++)
{
- for (j = 0; j < ico_cube; j++)
+ for (int j = 0; j < ico_cube; j++)
{
- for (k = 0; k < ico_cube; k++)
+ for (int k = 0; k < ico_cube; k++)
{
- tl = 0;
- tl2 = tn;
- ijk = i + ico_cube * j + ico_cube * ico_cube * k;
+ int tl = 0;
+ int tl2 = tn;
+ int ijk = i + ico_cube * j + ico_cube * ico_cube * k;
*(ico_pt + ijk) = tn;
- for (l = tl2; l < ndot; l++)
+ for (int l = tl2; l < ndot; l++)
{
if (ijk == work[l])
{
- x = xus[3 * l];
- y = xus[1 + 3 * l];
- z = xus[2 + 3 * l];
+ const real x = xus[3 * l];
+ const real y = xus[1 + 3 * l];
+ const real z = xus[2 + 3 * l];
xus[3 * l] = xus[3 * tn];
xus[1 + 3 * l] = xus[1 + 3 * tn];
xus[2 + 3 * l] = xus[2 + 3 * tn];
tl++;
}
}
- *(ico_wk + ijk) = tl;
+ *(ico_wk.data() + ijk) = tl;
} /* cycle k */
} /* cycle j */
} /* cycle i */
- sfree(ico_wk);
- sfree(work);
return xus;
}
{
*n_dots = 0;
}
- nsc_dclm_pbc(x, impl_->radius_, nat, &impl_->unitSphereDots_[0], impl_->unitSphereDots_.size() / 3,
- flags, area, at_area, volume, lidots, n_dots, index, &impl_->nb_, pbc);
+ nsc_dclm_pbc(x,
+ impl_->radius_,
+ nat,
+ &impl_->unitSphereDots_[0],
+ impl_->unitSphereDots_.size() / 3,
+ flags,
+ area,
+ at_area,
+ volume,
+ lidots,
+ n_dots,
+ index,
+ &impl_->nb_,
+ pbc);
}
} // namespace gmx
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2017,2019, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2017,2019,2021, 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.
#ifndef GMX_TRAJECTORYANALYSIS_SURFACEAREA_H
#define GMX_TRAJECTORYANALYSIS_SURFACEAREA_H
+#include <memory>
+
#include "gromacs/math/vectypes.h"
#include "gromacs/utility/arrayref.h"
-#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/real.h"
struct t_pbc;
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
{
const std::string message =
formatString("Trajectory (%d atoms) does not match topology (%d atoms)",
- fr->natoms, topologyAtomCount);
+ fr->natoms,
+ topologyAtomCount);
GMX_THROW(InconsistentInputError(message));
}
}
const std::string message = formatString(
"Selection specified with -fgroup has %d atoms, but "
"the trajectory (-f) has %d atoms.",
- trajectoryGroup_.atomCount(), fr->natoms);
+ trajectoryGroup_.atomCount(),
+ fr->natoms);
GMX_THROW(InconsistentInputError(message));
}
fr->bIndex = TRUE;
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2010,2011,2012,2013,2014 by the GROMACS development team.
- * Copyright (c) 2015,2016,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,2019,2020,2021, 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.
#ifndef GMX_TRAJECTORYANALYSIS_RUNNERCOMMON_H
#define GMX_TRAJECTORYANALYSIS_RUNNERCOMMON_H
-#include "gromacs/utility/classhelpers.h"
+#include <memory>
struct t_trxframe;
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
)
gmx_register_gtest_test(TrajectoryAnalysisUnitTests trajectoryanalysis-test SLOW_TEST)
target_link_libraries(trajectoryanalysis-test PRIVATE analysisdata-test-shared)
+target_link_libraries(trajectoryanalysis-test PRIVATE common)
add_executable(test_selection ${UNITTEST_TARGET_OPTIONS} test_selection.cpp)
-target_link_libraries(test_selection PRIVATE libgromacs ${GMX_EXE_LINKER_FLAGS})
+target_link_libraries(test_selection PRIVATE
+ common
+ libgromacs
+ ${GMX_EXE_LINKER_FLAGS})
+# TODO: Explicitly link to module dependencies.
+target_link_libraries(test_selection PRIVATE legacy_modules)
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
TEST_F(ConvertTrjModuleTest, WorksWithAtomsAndSelection)
{
- const char* const cmdline[] = { "convert-trj", "-atoms", "always-from-structure", "-select",
- "not resname = CO2" };
+ const char* const cmdline[] = {
+ "convert-trj", "-atoms", "always-from-structure", "-select", "not resname = CO2"
+ };
// TODO check output structures once this is supported.
setTopology("clustsize.tpr");
setInputFile("-f", "clustsize.pdb");
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
TEST_F(ExtractClusterModuleTest, WorksWithAtomSubset)
{
std::string realFileName = TestFileManager::getTestSpecificFileName("test.g96");
- const char* const cmdline[] = { "extract-cluster", "-o", realFileName.c_str(), "-select",
- "atomnr 1 2" };
+ const char* const cmdline[] = {
+ "extract-cluster", "-o", realFileName.c_str(), "-select", "atomnr 1 2"
+ };
runTest(CommandLine(cmdline));
compareFiles();
{
const char* const name = dataset->first.c_str();
AbstractAnalysisData& data = module.datasetFromName(name);
- AnalysisDataTestFixture::addReferenceCheckerModule(dataChecker, name, &data,
- dataset->second.tolerance);
+ AnalysisDataTestFixture::addReferenceCheckerModule(
+ dataChecker, name, &data, dataset->second.tolerance);
}
}
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2013,2014,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2018,2019,2021, 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.
#ifndef GMX_TRAJECTORYANALYSIS_TESTS_MODULETEST_H
#define GMX_TRAJECTORYANALYSIS_TESTS_MODULETEST_H
+#include <memory>
+
#include <gtest/gtest.h>
#include "gromacs/trajectoryanalysis/analysismodule.h"
-#include "gromacs/utility/classhelpers.h"
#include "testutils/cmdlinetest.h"
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
/*! \internal \brief
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015,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.
TEST_F(RdfModuleTest, SelectionsSolelyFromIndexFileWork)
{
- const char* const cmdline[] = { "rdf", "-bin", "0.05",
+ const char* const cmdline[] = { "rdf",
+ "-bin",
+ "0.05",
// Use selection that names a group in the index file
- "-ref", "name_OW",
+ "-ref",
+ "name_OW",
// Use selections that name groups in the index file
- "-sel", "name_OW", "not_name_OW" };
+ "-sel",
+ "name_OW",
+ "not_name_OW" };
// Note not supplying a topology file to -s
setTrajectory("spc216.gro");
setInputFile("-n", "index.ndx");
TEST_F(RdfModuleTest, SelectionsFromBothTopologyFileAndIndexFileWork)
{
- const char* const cmdline[] = { "rdf", "-bin", "0.05",
+ const char* const cmdline[] = { "rdf",
+ "-bin",
+ "0.05",
// Use selection whose parsing requires topology file
- "-ref", "name OW",
+ "-ref",
+ "name OW",
// Use selections that name groups in the index file
- "-sel", "name_OW", "not_name_OW" };
+ "-sel",
+ "name_OW",
+ "not_name_OW" };
// Note supplying a topology file to -s
setTopology("spc216.gro");
setInputFile("-n", "index.ndx");
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2013,2014,2015,2019, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015,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.
TEST_F(SelectModuleTest, WritesResidueIndices)
{
- const char* const cmdline[] = { "select", "-select", "res_com of resname RA RD", "-resnr",
- "index" };
+ const char* const cmdline[] = {
+ "select", "-select", "res_com of resname RA RD", "-resnr", "index"
+ };
setTopology("simple.gro");
includeDataset("index");
runTest(CommandLine(cmdline));
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2014,2015,2016,2017,2018 by the GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
for (int i = 0; i < count; ++i)
{
rvec x;
- real radius;
+ real radius = 0;
generateRandomPosition(x, &radius);
addSphere(x[XX], x[YY], x[ZZ], radius);
}
gmx::SurfaceAreaCalculator calculator;
calculator.setDotCount(ndots);
calculator.setRadii(radius_);
- calculator.calculate(as_rvec_array(x_.data()), bPBC ? &pbc : nullptr, index_.size(),
- index_.data(), flags, &area_, &volume_, &atomArea_, &dots_, &dotCount_);
+ calculator.calculate(as_rvec_array(x_.data()),
+ bPBC ? &pbc : nullptr,
+ index_.size(),
+ index_.data(),
+ flags,
+ &area_,
+ &volume_,
+ &atomArea_,
+ &dots_,
+ &dotCount_);
}
real resultArea() const { return area_; }
real resultVolume() const { return volume_; }
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2010-2018, The GROMACS development team.
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
for (size_t g = 0; g < selections_.size(); ++g)
{
const Selection& sel = selections_[g];
- int n;
fprintf(stderr, " Atoms (%d pcs):", sel.atomCount());
- n = sel.atomCount();
+ int n = sel.atomCount();
if (nmaxind_ >= 0 && n > nmaxind_)
{
n = nmaxind_;
for (int i = 0; i < n; ++i)
{
const SelectionPosition& p = sel.position(i);
- fprintf(stderr, " (%.2f,%.2f,%.2f) r=%d, m=%d, n=%d\n", p.x()[XX], p.x()[YY],
- p.x()[ZZ], p.refId(), p.mappedId(), p.atomCount());
+ fprintf(stderr,
+ " (%.2f,%.2f,%.2f) r=%d, m=%d, n=%d\n",
+ p.x()[XX],
+ p.x()[YY],
+ p.x()[ZZ],
+ p.refId(),
+ p.mappedId(),
+ p.atomCount());
}
if (n < sel.posCount())
{
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
EXPECT_TRUE(atoms2);
// Must be different pointer to a deep copy.
EXPECT_NE(atoms1.get(), atoms2.get());
- auto atoms = topInfo.atoms();
+ const auto* atoms = topInfo.atoms();
// Must be a pointer to a different instance.
EXPECT_NE(atoms1.get(), atoms);
EXPECT_NE(atoms2.get(), atoms);
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
// t_atoms that we'd keep, which we currently can't do.
// TODO Once there are fewer callers of the file-reading
// functionality, make them read directly into std::vector.
- rvec *x, *v;
+ rvec *x = nullptr, *v = nullptr;
readConfAndTopology(filename.c_str(), &bTop_, mtop_.get(), &pbcType_, &x, &v, boxtop_);
xtop_.assign(x, x + mtop_->natoms);
vtop_.assign(v, v + mtop_->natoms);
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2010-2018, The GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
* compiler-specific attributes, and ::GMX_UNUSED_VALUE and ::GMX_IGNORE_RETURN_VALUE
* for handling warnings about unused values.
*
- * The header classhelpers.h implements a gmx::PrivateImplPointer template for easily
- * writing classes that use the private implementation idiom. This header also
- * declares ::GMX_DISALLOW_COPY_AND_ASSIGN and ::GMX_DISALLOW_ASSIGN macros for
- * class declarations.
+ * The header classhelpers.h declares ::GMX_DISALLOW_COPY_AND_ASSIGN,
+ * ::GMX_DISALLOW_COPY_MOVE_AND_ASSIGN, ::GMX_DISALLOW_ASSIGN, and
+ * ::GMX_DEFAULT_CONSTRUCTORS macros for class declarations.
*
* The header flags.h implements a gmx::FlagsTemplate template for better type
* safety when using bit flag fields.
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+add_library(utility INTERFACE)
+
file(GLOB UTILITY_SOURCES *.cpp)
if (GMX_GPU_CUDA)
gmx_add_libgromacs_sources(cuda_version_information.cu)
endif()
set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${UTILITY_SOURCES} PARENT_SCOPE)
-# TODO: (https://gitlab.com/gromacs/gromacs/-/issues/988) Find a new convention for defining public API.
-install(FILES
- basedefinitions.h
- current_function.h
- gmxassert.h
- real.h
- DESTINATION include/gromacs/utility)
-
if(GMX_INSTALL_LEGACY_API)
install(FILES
- arrayref.h
baseversion.h
classhelpers.h
enumerationhelpers.h
- exceptions.h
- listoflists.h
fileptr.h
futil.h
flags.h
DESTINATION include/gromacs/utility)
endif()
+# Public interface for modules, including dependencies and interfaces
+#target_include_directories(utility PUBLIC
+target_include_directories(utility INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+#target_link_libraries(utility PUBLIC
+target_link_libraries(utility INTERFACE
+ legacy_api
+ )
+
+# TODO: when utility is an OBJECT target
+#target_link_libraries(utility PUBLIC legacy_api)
+#target_link_libraries(utility PRIVATE common)
+
+# Source files have the following private module dependencies.
+# TODO: Explicitly link specific modules.
+#target_link_libraries(utility PRIVATE legacy_modules)
+
if (BUILD_TESTING)
add_subdirectory(tests)
endif()
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2015,2017,2018,2019,2021, 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.
//! Implement malloc of \c bytes of memory, aligned to \c alignment.
void* mallocImpl(std::size_t bytes, std::size_t alignment)
{
- void* p;
+ void* p = nullptr;
#if HAVE__MM_MALLOC
p = _mm_malloc(bytes, alignment);
//! \todo Move this function into sysinfo.cpp where other OS-specific code/includes live
static std::size_t getPageSize()
{
- long pageSize;
+ long pageSize = 0;
#if GMX_NATIVE_WINDOWS
SYSTEM_INFO si;
GetNativeSystemInfo(&si);
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#if !GMX_MPI
return false;
#else
- int n;
+ int n = 0;
MPI_Initialized(&n);
return n != 0;
return 1;
}
# endif
- int i;
+ int i = 0;
(void)MPI_Comm_size(MPI_COMM_WORLD, &i);
return i;
#endif
return 0;
}
# endif
- int i;
+ int i = 0;
(void)MPI_Comm_rank(MPI_COMM_WORLD, &i);
return i;
#endif
static int mpi_hostname_hash()
{
- int hash_int;
+ int hash_int = 0;
#if GMX_LIB_MPI
int resultlen;
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2010,2012,2014,2015,2018 by the GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
*/
#include "gromacs/utility/baseversion_gen.h"
-const char _gmx_ver_string[] = "@GMX_VERSION_STRING_FULL@";
-const char _gmx_full_git_hash[] = "@GMX_VERSION_FULL_HASH@";
-const char _gmx_central_base_hash[] = "@GMX_VERSION_CENTRAL_BASE_HASH@";
+const char gmx_ver_string[] = "@GMX_VERSION_STRING_FULL@";
+const char gmx_full_git_hash[] = "@GMX_VERSION_FULL_HASH@";
+const char gmx_central_base_hash[] = "@GMX_VERSION_CENTRAL_BASE_HASH@";
const char gmxSourceDoiString[] = "@GMX_SOURCE_DOI@";
const char gmxReleaseSourceFileChecksum[] = "@GMX_RELEASE_SOURCE_FILE_CHECKSUM@";
const char gmxCurrentSourceFileChecksum[] = "@GMX_CURRENT_SOURCE_FILE_CHECKSUM@";
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014,2015,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015,2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
const char* gmx_version()
{
- return _gmx_ver_string;
+ return gmx_ver_string;
}
const char* gmx_version_git_full_hash()
{
- return _gmx_full_git_hash;
+ return gmx_full_git_hash;
}
const char* gmx_version_git_central_base_hash()
{
- return _gmx_central_base_hash;
+ return gmx_central_base_hash;
}
const char* gmxDOI()
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2010,2012,2013,2014,2015 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
//! \{
//! Version string, containing the version, date, and abbreviated hash.
-extern const char _gmx_ver_string[];
+extern const char gmx_ver_string[];
//! Full git hash of the latest commit.
-extern const char _gmx_full_git_hash[];
+extern const char gmx_full_git_hash[];
//! Full git hash of the latest commit in a central \Gromacs repository.
-extern const char _gmx_central_base_hash[];
+extern const char gmx_central_base_hash[];
/*! \brief
* DOI string for the \Gromacs source code populated by CMake.
*
static const char* const CopyrightText[] = {
"Copyright (c) 1991-2000, University of Groningen, The Netherlands.",
"Copyright (c) 2001-2019, The GROMACS development team at",
- "Uppsala University, Stockholm University and", "the Royal Institute of Technology, Sweden.",
+ "Uppsala University, Stockholm University and",
+ "the Royal Institute of Technology, Sweden.",
"check out http://www.gromacs.org for more information."
};
#if HAVE_EXTRAE
unsigned major, minor, revision;
Extrae_get_version(&major, &minor, &revision);
- writer->writeLine(formatString("Tracing support: enabled. Using Extrae-%d.%d.%d", major,
- minor, revision));
+ writer->writeLine(formatString(
+ "Tracing support: enabled. Using Extrae-%d.%d.%d", major, minor, revision));
#else
writer->writeLine("Tracing support: disabled");
#endif
* them. Can wait for later, as the master branch has ready code to do all
* that. */
writer->writeLine(formatString("C compiler: %s", BUILD_C_COMPILER));
- writer->writeLine(formatString("C compiler flags: %s %s", BUILD_CFLAGS,
- CMAKE_BUILD_CONFIGURATION_C_FLAGS));
+ writer->writeLine(formatString(
+ "C compiler flags: %s %s", BUILD_CFLAGS, CMAKE_BUILD_CONFIGURATION_C_FLAGS));
writer->writeLine(formatString("C++ compiler: %s", BUILD_CXX_COMPILER));
- writer->writeLine(formatString("C++ compiler flags: %s %s", BUILD_CXXFLAGS,
- CMAKE_BUILD_CONFIGURATION_CXX_FLAGS));
+ writer->writeLine(formatString(
+ "C++ compiler flags: %s %s", BUILD_CXXFLAGS, CMAKE_BUILD_CONFIGURATION_CXX_FLAGS));
#ifdef HAVE_LIBMKL
/* MKL might be used for LAPACK/BLAS even if FFTs use FFTW, so keep it separate */
- writer->writeLine(formatString("Linked with Intel MKL version %d.%d.%d.", __INTEL_MKL__,
- __INTEL_MKL_MINOR__, __INTEL_MKL_UPDATE__));
+ writer->writeLine(formatString(
+ "Linked with Intel MKL version %d.%d.%d.", __INTEL_MKL__, __INTEL_MKL_MINOR__, __INTEL_MKL_UPDATE__));
#endif
#if GMX_GPU_OPENCL
writer->writeLine(formatString("OpenCL include dir: %s", OPENCL_INCLUDE_DIR));
#endif
#if GMX_GPU_CUDA
writer->writeLine(formatString("CUDA compiler: %s", CUDA_COMPILER_INFO));
- writer->writeLine(formatString("CUDA compiler flags:%s %s", CUDA_COMPILER_FLAGS,
- CMAKE_BUILD_CONFIGURATION_CXX_FLAGS));
+ writer->writeLine(formatString(
+ "CUDA compiler flags:%s %s", CUDA_COMPILER_FLAGS, CMAKE_BUILD_CONFIGURATION_CXX_FLAGS));
writer->writeLine("CUDA driver: " + gmx::getCudaDriverVersionString());
writer->writeLine("CUDA runtime: " + gmx::getCudaRuntimeVersionString());
#endif
// necessary to read stuff above the copyright notice.
// The line above the copyright notice puts the copyright notice is
// context, though.
- writer->writeLine(formatString("%sGROMACS: %s, version %s%s%s", prefix, name,
- gmx_version(), precisionString, suffix));
+ writer->writeLine(formatString(
+ "%sGROMACS: %s, version %s%s%s", prefix, name, gmx_version(), precisionString, suffix));
}
const char* const binaryPath = programContext.fullBinaryPath();
if (!gmx::isNullOrEmpty(binaryPath))
const gmx::InstallationPrefixInfo installPrefix = programContext.installationPrefix();
if (!gmx::isNullOrEmpty(installPrefix.path))
{
- writer->writeLine(formatString("%sData prefix: %s%s%s", prefix, installPrefix.path,
- installPrefix.bSourceLayout ? " (source tree)" : "", suffix));
+ writer->writeLine(formatString("%sData prefix: %s%s%s",
+ prefix,
+ installPrefix.path,
+ installPrefix.bSourceLayout ? " (source tree)" : "",
+ suffix));
}
const std::string workingDir = Path::getWorkingDirectory();
if (!workingDir.empty())
const char* const commandLine = programContext.commandLine();
if (!gmx::isNullOrEmpty(commandLine))
{
- writer->writeLine(formatString("%sCommand line:%s\n%s %s%s", prefix, suffix, prefix,
- commandLine, suffix));
+ writer->writeLine(formatString(
+ "%sCommand line:%s\n%s %s%s", prefix, suffix, prefix, commandLine, suffix));
}
if (settings.bExtendedInfo_)
{
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2014,2018,2019,2021, 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.
inline static bool bitmask_is_disjoint(gmx_bitmask_t a, gmx_bitmask_t b)
{
- int i;
bool r = true;
- for (i = 0; i < BITMASK_ALEN; i++)
+ for (int i = 0; i < BITMASK_ALEN; i++)
{
r = r && ((a[i] & b[i]) == 0U);
}
inline static bool bitmask_is_equal(gmx_bitmask_t a, gmx_bitmask_t b)
{
- int i;
bool r = true;
- for (i = 0; i < BITMASK_ALEN; i++)
+ for (int i = 0; i < BITMASK_ALEN; i++)
{
r = r && (a[i] == b[i]);
}
inline static bool bitmask_is_zero(gmx_bitmask_t m)
{
- int i;
bool r = true;
- for (i = 0; i < BITMASK_ALEN; i++)
+ for (int i = 0; i < BITMASK_ALEN; i++)
{
r = r && (m[i] == 0U);
}
inline static void bitmask_union(gmx_bitmask_t* a, gmx_bitmask_t b)
{
- int i;
- for (i = 0; i < BITMASK_ALEN; i++)
+ for (int i = 0; i < BITMASK_ALEN; i++)
{
(*a)[i] |= b[i];
}
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
#ifndef GMX_UTILITY_CLASSHELPERS_H
#define GMX_UTILITY_CLASSHELPERS_H
-#include <memory>
-
namespace gmx
{
#endif
//clang-format on
-/*! \brief
- * Helper class to manage a pointer to a private implementation class.
- *
- * This helper provides the following benefits (all but the last could also be
- * achieved with std::unique_ptr):
- * - Automatic memory management: the implementation pointer is freed in
- * the destructor automatically. If the destructor is not declared or is
- * defined inline in the header file, a compilation error occurs instead
- * of a memory leak or undefined behavior.
- * - Exception safety in constructors: the implementation pointer is freed
- * correctly even if the constructor of the containing class throws after
- * the implementation class is constructed.
- * - Copy and/or assignment is automatically disallowed if explicit copy
- * constructor and/or assignment operator is not provided.
- * - Compiler helps to manage const-correctness: in const methods, it is not
- * possible to change the implementation class.
- *
- * Move construction and assignment are also disallowed, but can be enabled by
- * providing explicit move constructor and/or assignment.
- *
- * Intended use:
- * \code
- // In exampleclass.h
- class ExampleClass
- {
- public:
- ExampleClass();
- ~ExampleClass(); // Must be defined, must not be defined inline
-
- // <...>
-
- private:
- class Impl;
-
- PrivateImplPointer<Impl> impl_;
- };
-
- // In exampleclass.cpp
-
- // <definition of ExampleClass::Impl>
-
- ExampleClass::ExampleClass()
- : impl_(new Impl)
- {
- }
-
- ExampleClass::~ExampleClass()
- {
- }
- \endcode
- *
- * Note that ExampleClass::~ExampleClass cannot be declared inline (or
- * generated by the compiler) because the implementation of impl_
- * requires that ExampleClass::Impl be known in size, whereas it has
- * only been forward declared. Only the translation unit where
- * ExampleClass::Impl is declared can define the destructor for
- * ExampleClass (which may be defaulted).
- *
- * \inlibraryapi
- * \ingroup module_utility
- */
-template<class Impl>
-class PrivateImplPointer
-{
-public:
- //! Allow implicit initialization from nullptr to support comparison.
- PrivateImplPointer(std::nullptr_t) : ptr_(nullptr) {}
- //! Initialize with the given implementation class.
- explicit PrivateImplPointer(Impl* ptr) : ptr_(ptr) {}
- //! \cond
- // Explicitly declared to work around MSVC problems.
- PrivateImplPointer(PrivateImplPointer&& other) noexcept : ptr_(std::move(other.ptr_)) {}
- PrivateImplPointer& operator=(PrivateImplPointer&& other) noexcept
- {
- ptr_ = std::move(other.ptr_);
- return *this;
- }
- //! \endcond
-
- /*! \brief
- * Sets a new implementation class and destructs the previous one.
- *
- * Needed, e.g., to implement lazily initializable or copy-assignable
- * classes.
- */
- void reset(Impl* ptr) { ptr_.reset(ptr); }
- //! Access the raw pointer.
- Impl* get() { return ptr_.get(); }
- //! Access the implementation class as with a raw pointer.
- Impl* operator->() { return ptr_.get(); }
- //! Access the implementation class as with a raw pointer.
- Impl& operator*() { return *ptr_; }
- //! Access the implementation class as with a raw pointer.
- const Impl* operator->() const { return ptr_.get(); }
- //! Access the implementation class as with a raw pointer.
- const Impl& operator*() const { return *ptr_; }
-
- //! Allows testing whether the implementation is initialized.
- explicit operator bool() const { return ptr_ != nullptr; }
-
- //! Tests for equality (mainly useful against nullptr).
- bool operator==(const PrivateImplPointer& other) const { return ptr_ == other.ptr_; }
- //! Tests for inequality (mainly useful against nullptr).
- bool operator!=(const PrivateImplPointer& other) const { return ptr_ != other.ptr_; }
-
-private:
- std::unique_ptr<Impl> ptr_;
-
- // Copy construction and assignment disabled by the unique_ptr member.
-};
-
} // namespace gmx
#endif
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <cstdio>
+#include "gromacs/mdtypes/md_enums.h"
#include "gromacs/utility/basedefinitions.h"
#include "gromacs/utility/real.h"
//! Compares two doubles and prints differences.
void cmp_double(FILE* fp, const char* s, int index, double i1, double i2, double ftol, double abstol);
+//! Compare two enums of generic type and print differences.
+template<typename EnumType>
+void cmpEnum(FILE* fp, const char* s, EnumType value1, EnumType value2)
+{
+ if (value1 != value2)
+ {
+ fprintf(fp, "%s (", s);
+ fprintf(fp, "%s", enumValueToString(value1));
+ fprintf(fp, " - ");
+ fprintf(fp, "%s", enumValueToString(value2));
+ fprintf(fp, ")\n");
+ }
+}
+
#endif
{ "Disturb the Peace of a John Q Citizen", "Urban Dance Squad" },
{ "Wicky-wicky Wa-wild West", "Will Smith" },
{ "This is Tense !", "Star Wars Episode I The Phantom Menace" },
- { "Fly to the Court of England and Unfold",
- "Macbeth, Act 3, Scene 6, William Shakespeare" },
+ { "Fly to the Court of England and Unfold", "Macbeth, Act 3, Scene 6, William Shakespeare" },
{ "Why, how now, Claudio ! Whence Comes this Restraint ?",
"Lucio in Measure for measure, Act 1, Scene 4, William Shakespeare" },
{ "In the End Science Comes Down to Praying", "P. v.d. Berg" },
{ "Nobody Never Learnt No-Nothing from No History", "Gogol Bordello" },
{ "I'd be Safe and Warm if I was in L.A.", "The Mamas and the Papas" },
{ "It's Unacceptable That Chocolate Makes You Fat", "MI 3" },
- { "My Brothers are Protons (Protons!), My Sisters are Neurons (Neurons)",
- "Gogol Bordello" },
+ { "My Brothers are Protons (Protons!), My Sisters are Neurons (Neurons)", "Gogol Bordello" },
{ "Put Me Inside SSC, Let's Test Superstring Theory, Oh Yoi Yoi Accelerate the Protons",
"Gogol Bordello" },
{ "Do You Have Sex Maniacs or Schizophrenics or Astrophysicists in Your Family?",
{ "The scientific method is an integral part of human intelligence, and when it has once "
"been set at work it can only be dismissed by dismissing the intelligence itself",
"George H. Mead" },
- { "Der Ball ist rund, das Spiel dauert 90 minuten, alles andere ist Theorie",
- "Lola rennt" },
+ { "Der Ball ist rund, das Spiel dauert 90 minuten, alles andere ist Theorie", "Lola rennt" },
{ "Life in the streets is not easy", "Marky Mark" },
{ "How will I know it's working right?", "MGMT" },
{ "There was no preconception on what to do", "Daft Punk" },
{ "All sorts of things can happen when you're open to new ideas and playing around with "
"things.",
"Stephanie Kwolek, inventor of Kevlar" },
- { "As always in life, people want a simple answer... and it's always wrong.",
- "Marie Daly" },
+ { "As always in life, people want a simple answer... and it's always wrong.", "Marie Daly" },
{ "For a research worker the unforgotten moments of his life are those rare ones which "
"come after years of plodding work, when the veil over natures secret seems suddenly to "
"lift & when what was dark & chaotic appears in a clear & beautiful light & pattern.",
"3-phosphoshikimate-carboxyvinyl transferase?' Shopkeeper: 'You mean Roundup?' "
"Scientist: 'Yeah, that's it. I can never remember that dang name!'",
"John Pickett" },
- { "It is not clear that intelligence has any long-term survival value.",
- "Stephen Hawking" },
+ { "It is not clear that intelligence has any long-term survival value.", "Stephen Hawking" },
{ "The greatest shortcoming of the human race is our inability to understand the "
"exponential function.",
"Albert Bartlett" },
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
int continuing(char* s)
{
- int sl;
assert(s);
rtrim(s);
- sl = strlen(s);
+ int sl = strlen(s);
if ((sl > 0) && (s[sl - 1] == CONTINUE))
{
s[sl - 1] = 0;
char* fgets2(char* line, int n, FILE* stream)
{
- char* c;
+ char* c = nullptr;
if (fgets(line, n, stream) == nullptr)
{
return nullptr;
gmx_fatal(FARGS,
"An input file contains a line longer than %d characters, while the buffer "
"passed to fgets2 has size %d. The line starts with: '%20.20s'",
- n, n, line);
+ n,
+ n,
+ line);
}
}
if ((c = strchr(line, '\r')) != nullptr)
void strip_comment(char* line)
{
- char* c;
+ char* c = nullptr;
if (!line)
{
void upstring(char* str)
{
- int i;
-
- for (i = 0; (i < static_cast<int>(strlen(str))); i++)
+ for (int i = 0; (i < static_cast<int>(strlen(str))); i++)
{
str[i] = toupper(str[i]);
}
void ltrim(char* str)
{
- int i, c;
-
if (nullptr == str)
{
return;
}
- c = 0;
+ int c = 0;
while (('\0' != str[c]) && isspace(str[c]))
{
c++;
}
if (c > 0)
{
- for (i = c; ('\0' != str[i]); i++)
+ int i = c;
+ for (; ('\0' != str[i]); i++)
{
str[i - c] = str[i];
}
void rtrim(char* str)
{
- int nul;
-
if (nullptr == str)
{
return;
}
- nul = strlen(str) - 1;
+ int nul = strlen(str) - 1;
while ((nul > 0) && ((str[nul] == ' ') || (str[nul] == '\t')))
{
str[nul] = '\0';
int gmx_strcasecmp_min(const char* str1, const char* str2)
{
- char ch1, ch2;
+ char ch1 = 0, ch2 = 0;
do
{
int gmx_strncasecmp_min(const char* str1, const char* str2, int n)
{
- char ch1, ch2;
- char *stri1, *stri2;
+ char ch1 = 0, ch2 = 0;
- stri1 = const_cast<char*>(str1);
- stri2 = const_cast<char*>(str2);
+ const char* stri1 = str1;
+ const char* stri2 = str2;
do
{
do
int gmx_strcasecmp(const char* str1, const char* str2)
{
- char ch1, ch2;
+ char ch1 = 0, ch2 = 0;
do
{
int gmx_strncasecmp(const char* str1, const char* str2, int n)
{
- char ch1, ch2;
+ char ch1 = 0, ch2 = 0;
if (n == 0)
{
char* gmx_strdup(const char* src)
{
- char* dest;
+ char* dest = nullptr;
auto length = strlen(src) + 1;
snew(dest, length);
char* gmx_strndup(const char* src, int n)
{
- int len;
- char* dest;
+ char* dest = nullptr;
- len = strlen(src);
+ int len = strlen(src);
if (len > n)
{
len = n;
unsigned int gmx_string_fullhash_func(const char* s, unsigned int hash_init)
{
- int c;
+ int c = 0;
while ((c = (*s++)) != '\0')
{
unsigned int gmx_string_hash_func(const char* s, unsigned int hash_init)
{
- int c;
+ int c = 0;
while ((c = toupper(*s++)) != '\0')
{
* since we have processed them above. */
if (*pattern == *str)
{
- int rc;
/* Match the suffix, and return if a match or an error */
- rc = gmx_wcmatch(pattern, str);
+ int rc = gmx_wcmatch(pattern, str);
if (rc != GMX_NO_WCMATCH)
{
return rc;
char* wrap_lines(const char* buf, int line_width, int indent, gmx_bool bIndentFirst)
{
- char* b2;
- int i, i0, i2, j, b2len, lspace = 0, l2space = 0;
- gmx_bool bFirst, bFitsOnLine;
+ int i = 0;
/* characters are copied from buf to b2 with possible spaces changed
* into newlines and extra space added for indentation.
* the current line (where it also won't fit, but looks better)
*/
- b2 = nullptr;
- b2len = strlen(buf) + 1 + indent;
+ char* b2 = nullptr;
+ int b2len = strlen(buf) + 1 + indent;
snew(b2, b2len);
- i0 = i2 = 0;
+ int i0 = 0;
+ int i2 = 0;
if (bIndentFirst)
{
for (i2 = 0; (i2 < indent); i2++)
b2[i2] = ' ';
}
}
- bFirst = TRUE;
+ bool bFirst = true;
do
{
- l2space = -1;
+ int lspace = 0;
+ int l2space = -1;
/* find the last space before end of line */
for (i = i0; ((i - i0 < line_width) || (l2space == -1)) && (buf[i]); i++)
{
b2len += indent;
srenew(b2, b2len);
/* add indentation after the newline */
- for (j = 0; (j < indent); j++)
+ for (int j = 0; (j < indent); j++)
{
b2[i2++] = ' ';
}
if (buf[i])
{
/* check if one word does not fit on the line */
- bFitsOnLine = (i - i0 <= line_width);
+ bool bFitsOnLine = (i - i0 <= line_width);
/* reset line counters to just after the space */
i0 = lspace + 1;
i2 = l2space + 1;
}
b2len += indent;
srenew(b2, b2len);
- for (j = 0; (j < indent); j++)
+ for (int j = 0; (j < indent); j++)
{
b2[i2++] = ' ';
}
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2014,2015,2016,2017,2018 by the GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
{
if (!impl_)
{
- impl_.reset(new Impl());
+ impl_ = std::make_unique<Impl>();
}
impl_->envName_ = envVarName;
const char* const lib = getenv(envVarName);
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014,2015,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015,2018,2019,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <cstdio>
+#include <memory>
#include <string>
#include <vector>
-#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/fileptr.h"
namespace gmx
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
}
else
{
- GMX_THROW_WITH_ERRNO(FileIOError("Failed to list files in a directory"),
- "_findnext", errno);
+ GMX_THROW_WITH_ERRNO(
+ FileIOError("Failed to list files in a directory"), "_findnext", errno);
}
}
*filename = finddata.name;
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2016,2019, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,2019,2021, 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.
#ifndef GMX_UTILITY_DIRECTORYENUMERATOR_H
#define GMX_UTILITY_DIRECTORYENUMERATOR_H
+#include <memory>
#include <string>
#include <vector>
-#include "gromacs/utility/classhelpers.h"
-
namespace gmx
{
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2011-2018, The GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
*/
#include "gmxpre.h"
-#include "exceptions.h"
+#include "gromacs/utility/exceptions.h"
#include <cstring>
#include <stdexcept>
#include <typeinfo>
-#include "thread_mpi/system_error.h"
-
#include "gromacs/utility/basenetwork.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/gmxassert.h"
std::fprintf(fp_, "%*sReason: %s\n", indent, "", std::strerror(errorNumber));
if (funcName != nullptr)
{
- std::fprintf(fp_, "%*s(call to %s() returned error code %d)\n", indent, "", funcName,
- errorNumber);
+ std::fprintf(fp_, "%*s(call to %s() returned error code %d)\n", indent, "", funcName, errorNumber);
}
}
if (errorNumber != nullptr && *errorNumber != 0)
{
const char* const* funcName = gmxEx->getInfo<ExceptionInfoApiFunction>();
- writer->writeErrNoInfo(*errorNumber, funcName != nullptr ? *funcName : nullptr,
- (indent + 1) * 2);
+ writer->writeErrNoInfo(
+ *errorNumber, funcName != nullptr ? *funcName : nullptr, (indent + 1) * 2);
bAnythingWritten = true;
}
{
title = getErrorCodeString(gmxEx->errorCode());
}
- else if (dynamic_cast<const tMPI::system_error*>(&ex) != nullptr)
- {
- title = "System error in thread synchronization";
- }
else if (dynamic_cast<const std::bad_alloc*>(&ex) != nullptr)
{
title = "Memory allocation failed";
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017, The GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <cstring>
#include <exception>
+#include <mutex>
#include "gromacs/utility/basedefinitions.h"
#include "gromacs/utility/baseversion.h"
#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/futil.h"
-#include "gromacs/utility/mutex.h"
#include "gromacs/utility/programcontext.h"
#include "gromacs/utility/stringutil.h"
gmx_bool gmx_debug_at = FALSE;
static FILE* log_file = nullptr;
-static gmx::Mutex error_mutex;
+static std::mutex error_mutex;
-using Lock = gmx::lock_guard<gmx::Mutex>;
+using Lock = std::lock_guard<std::mutex>;
void gmx_init_debug(const int dbglevel, const char* dbgfile)
{
va_end(ap);
}
-void _gmx_error(const char* key, const std::string& msg, const char* file, int line)
+void gmx_error_function(const char* key, const std::string& msg, const char* file, int line)
{
call_error_handler(key, file, line, msg);
gmx_exit_on_fatal_error(ExitType_Abort, 1);
}
-void _range_check(int n, int n_min, int n_max, const char* warn_str, const char* var, const char* file, int line)
+void range_check_function(int n, int n_min, int n_max, const char* warn_str, const char* var, const char* file, int line)
{
if ((n < n_min) || (n >= n_max))
{
buf += gmx::formatString(
"Variable %s has value %d. It should have been "
"within [ %d .. %d ]\n",
- var, n, n_min, n_max);
+ var,
+ n,
+ n_min,
+ n_max);
- _gmx_error("range", buf, file, line);
+ gmx_error_function("range", buf, file, line);
}
}
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2012,2014,2015,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2012,2014,2015,2018,2019,2021, 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.
}
\endcode
*/
-extern FILE* debug;
+extern FILE* debug; //NOLINT(cppcoreguidelines-avoid-non-const-global-variables,-warnings-as-errors)
/** Whether extra debugging is enabled. */
-extern gmx_bool gmx_debug_at;
+extern gmx_bool gmx_debug_at; //NOLINT(cppcoreguidelines-avoid-non-const-global-variables,-warnings-as-errors)
/*! \brief
* Initializes debugging variables.
#define FARGS 0, __FILE__, __LINE__
/** Implementation for gmx_error(). */
-[[noreturn]] void _gmx_error(const char* key, const std::string& msg, const char* file, int line);
+[[noreturn]] void gmx_error_function(const char* key, const std::string& msg, const char* file, int line);
/*! \brief
* Alternative fatal error routine with canned messages.
*
* based on a string key, and printf-style formatting is not supported.
* Should not typically be called directly, but through gmx_call() etc.
*/
-#define gmx_error(key, msg) _gmx_error(key, msg, __FILE__, __LINE__)
+#define gmx_error(key, msg) gmx_error_function(key, msg, __FILE__, __LINE__)
/*! \name Fatal error routines for certain types of errors
*
*
* \p warn_str can be NULL.
*/
-void _range_check(int n, int n_min, int n_max, const char* warn_str, const char* var, const char* file, int line);
+void range_check_function(int n, int n_min, int n_max, const char* warn_str, const char* var, const char* file, int line);
/*! \brief
* Checks that a variable is within a range.
* \p n_min is inclusive, but \p n_max is not.
*/
#define range_check_mesg(n, n_min, n_max, str) \
- _range_check(n, n_min, n_max, str, #n, __FILE__, __LINE__)
+ range_check_function(n, n_min, n_max, str, #n, __FILE__, __LINE__)
/*! \brief
* Checks that a variable is within a range.
*
* This works as range_check_mesg(), but with a default error message.
*/
-#define range_check(n, n_min, n_max) _range_check(n, n_min, n_max, NULL, #n, __FILE__, __LINE__)
+#define range_check(n, n_min, n_max) \
+ range_check_function(n, n_min, n_max, NULL, #n, __FILE__, __LINE__)
/*! \brief
* Prints a warning message to stderr.
fp_ = std::fopen(filename, mode);
if (fp_ == nullptr)
{
- GMX_THROW_WITH_ERRNO(FileIOError(formatString("Could not open file '%s'", filename)),
- "fopen", errno);
+ GMX_THROW_WITH_ERRNO(
+ FileIOError(formatString("Could not open file '%s'", filename)), "fopen", errno);
}
}
~FileStreamImpl()
FilePtr fp(fopen(filename, "r"));
if (fp == nullptr)
{
- GMX_THROW_WITH_ERRNO(FileIOError(formatString("Could not open file '%s'", filename)),
- "fopen", errno);
+ GMX_THROW_WITH_ERRNO(
+ FileIOError(formatString("Could not open file '%s'", filename)), "fopen", errno);
}
return fp;
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2015,2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <cstdio>
+#include <memory>
#include <string>
-#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/fileptr.h"
#include "gromacs/utility/textstream.h"
void close() override;
private:
- PrivateImplPointer<internal::FileStreamImpl> impl_;
+ std::unique_ptr<internal::FileStreamImpl> impl_;
};
/*! \libinternal \brief
static TextOutputFile& standardError();
private:
- PrivateImplPointer<internal::FileStreamImpl> impl_;
+ std::unique_ptr<internal::FileStreamImpl> impl_;
};
} // namespace gmx
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017, The GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <cstdlib>
#include <cstring>
+#include <mutex>
#include <tuple>
#include <fcntl.h>
#include "gromacs/utility/dir_separator.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/fatalerror.h"
-#include "gromacs/utility/mutex.h"
#include "gromacs/utility/path.h"
#include "gromacs/utility/programcontext.h"
#include "gromacs/utility/smalloc.h"
/* this linked list is an intrinsically globally shared object, so we have
to protect it with mutexes */
-static gmx::Mutex pstack_mutex;
+static std::mutex pstack_mutex;
-using Lock = gmx::lock_guard<gmx::Mutex>;
+using Lock = std::lock_guard<std::mutex>;
namespace gmx
{
static void push_ps(FILE* fp)
{
- t_pstack* ps;
+ t_pstack* ps = nullptr;
Lock pstackLock(pstack_mutex);
int gmx_ffclose(FILE* fp)
{
- t_pstack *ps, *tmp;
- int ret = 0;
+ int ret = 0;
Lock pstackLock(pstack_mutex);
- ps = pstack;
+ t_pstack* ps = pstack;
if (ps == nullptr)
{
if (fp != nullptr)
{
ret = pclose(ps->prev->fp);
}
- tmp = ps->prev;
- ps->prev = ps->prev->prev;
+ t_pstack* tmp = ps->prev;
+ ps->prev = ps->prev->prev;
sfree(tmp);
}
else
static FILE* uncompress(const std::string& fn, const char* mode)
{
- FILE* fp;
+ FILE* fp = nullptr;
std::string buf = "uncompress -c < " + fn;
fprintf(stderr, "Going to execute '%s'\n", buf.c_str());
if ((fp = popen(buf.c_str(), mode)) == nullptr)
static FILE* gunzip(const std::string& fn, const char* mode)
{
- FILE* fp;
+ FILE* fp = nullptr;
std::string buf = "gunzip -c < ";
buf += fn;
fprintf(stderr, "Going to execute '%s'\n", buf.c_str());
gmx_bool gmx_fexist(const std::string& fname)
{
- FILE* test;
-
if (fname.empty())
{
return FALSE;
}
- test = fopen(fname.c_str(), "r");
+ FILE* test = fopen(fname.c_str(), "r");
if (test == nullptr)
{
/*Windows doesn't allow fopen of directory - so we need to check this seperately */
gmx_fatal(FARGS,
"Won't make more than %d backups of %s for you.\n"
"The env.var. GMX_MAXBACKUP controls this maximum, -1 disables backups.",
- s_maxBackupCount, fn.c_str());
+ s_maxBackupCount,
+ fn.c_str());
}
return buf;
FILE* gmx_ffopen(const std::string& file, const char* mode)
{
- FILE* ff = nullptr;
- gmx_bool bRead;
- int bs;
+ FILE* ff = nullptr;
if (file.empty())
{
make_backup(file);
}
- bRead = (mode[0] == 'r' && mode[1] != '+');
+ bool bRead = (mode[0] == 'r' && mode[1] != '+');
if (!bRead || gmx_fexist(file))
{
if ((ff = fopen(file.c_str(), mode)) == nullptr)
if (bUnbuffered || ((bufsize = getenv("GMX_LOG_BUFFER")) != nullptr))
{
/* Check whether to use completely unbuffered */
- if (bUnbuffered)
- {
- bs = 0;
- }
- else
- {
- bs = strtol(bufsize, nullptr, 10);
- }
+ const int bs = bUnbuffered ? 0 : strtol(bufsize, nullptr, 10);
if (bs <= 0)
{
setbuf(ff, nullptr);
}
else
{
- char* ptr;
+ char* ptr = nullptr;
snew(ptr, bs + 8);
if (setvbuf(ff, ptr, _IOFBF, bs) != 0)
{
* \todo Use std::string and std::vector<char>. */
static int makeTemporaryFilename(char* buf)
{
- int len;
+ int len = 0;
if ((len = strlen(buf)) < 7)
{
* since windows doesnt support it we have to separate the cases.
* 20090307: mktemp deprecated, use iso c++ _mktemp instead.
*/
- int fd;
#if GMX_NATIVE_WINDOWS
_mktemp(buf);
if (buf == NULL)
{
gmx_fatal(FARGS, "Error creating temporary file %s: %s", buf, strerror(errno));
}
- fd = 0;
+ int fd = 0;
#else
- fd = mkstemp(buf);
+ int fd = mkstemp(buf);
if (fd < 0)
{
while (!feof(in.get()))
{
- size_t nread;
-
- nread = fread(buf.data(), sizeof(char), FILECOPY_BUFSIZE, in.get());
+ size_t nread = fread(buf.data(), sizeof(char), FILECOPY_BUFSIZE, in.get());
if (nread > 0)
{
- size_t ret;
+ size_t ret = 0;
if (!out)
{
/* so this is where we open when copy_if_empty is false:
int rc = 0;
{
- int fn;
-
/* get the file number */
#if HAVE_FILENO
- fn = fileno(fp);
+ int fn = fileno(fp);
#elif HAVE__FILENO
- fn = _fileno(fp);
+ int fn = _fileno(fp);
#else
GMX_UNUSED_VALUE(fp);
- fn = -1;
+ int fn = -1;
#endif
/* do the actual fsync */
#endif
if (rc != 0)
{
- auto message = gmx::formatString("Cannot change directory to '%s'. Reason: %s", directory,
- strerror(errno));
+ auto message = gmx::formatString(
+ "Cannot change directory to '%s'. Reason: %s", directory, strerror(errno));
GMX_THROW(gmx::FileIOError(message));
}
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2011,2012,2014,2015,2019, by the GROMACS development team, led by
+ * Copyright (c) 2011,2012,2014,2015,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.
*/
#include "gmxpre.h"
-#include "gmxassert.h"
+#include "gromacs/utility/gmxassert.h"
#include <cstdio>
#include <cstdlib>
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012,2013,2014,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
/* We assume that the affinity setting is available on all platforms
* gcc supports. Even if this is not the case (e.g. Mac OS) the user
* will only get a warning. */
-# if defined(__GNUC__) || defined(__INTEL_COMPILER)
+# if defined(__GNUC__)
const char* programName;
try
{
" setting as the two can conflict and cause performance degradation.\n"
" To keep using the %s internal affinity setting, unset the\n"
" GOMP_CPU_AFFINITY environment variable.",
- programName, programName);
+ programName,
+ programName);
*message = gmx_strdup(buf.c_str());
}
GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
shouldSetAffinity = false;
}
-# endif /* __GNUC__ || __INTEL_COMPILER */
-
-# if defined(__INTEL_COMPILER)
- const char* const kmp_env = getenv("KMP_AFFINITY");
- const bool bKmpAffinitySet = (kmp_env != NULL);
-
- // turn off internal pinning if KMP_AFFINITY is set but does not contain
- // the settings 'disabled' or 'none'.
- if (bKmpAffinitySet && (strstr(kmp_env, "disabled") == NULL) && (strstr(kmp_env, "none") == NULL))
- {
- try
- {
- std::string buf = gmx::formatString(
- "NOTE: KMP_AFFINITY set, will turn off %s internal affinity\n"
- " setting as the two can conflict and cause performance degradation.\n"
- " To keep using the %s internal affinity setting, unset the\n"
- " KMP_AFFINITY environment variable or set it to 'none' or 'disabled'.",
- programName, programName);
- *message = gmx_strdup(buf.c_str());
- }
- GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
- shouldSetAffinity = false;
- }
-# endif /* __INTEL_COMPILER */
+# endif /* __GNUC__ */
#endif /* GMX_OPENMP */
return shouldSetAffinity;
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
YieldProcessor();
#elif HAVE_XMMINTRIN_H
_mm_pause();
-#elif defined __MIC__
- _mm_delay_32(32);
#else
// No wait for unknown architecture
#endif
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2016,2017,2018,2019,2020,2021, 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.
}
void doString(std::string* value)
{
- uint64_t size;
+ uint64_t size = 0;
doValue<uint64_t>(&size);
*value = std::string(&buffer_[pos_], size);
pos_ += size;
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2016,2017,2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <cstddef>
+#include <memory>
#include <vector>
#include "gromacs/utility/arrayref.h"
-#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/iserializer.h"
namespace gmx
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
class InMemoryDeserializer : public ISerializer
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2015,2017,2018,2019,2021, 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.
int int64_to_int(int64_t step, const char* warn)
{
- int i;
-
- i = static_cast<int>(step);
+ int i = static_cast<int>(step);
if (warn != nullptr && (static_cast<int64_t>(i) != step))
{
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2016,2017,2018,2019,2020,2021, 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.
}
}
///@}
+
+ //! Serialize enum value with underlying type int
+ template<typename EnumType>
+ void doEnumAsInt(EnumType* enumValue)
+ {
+ static_assert(std::is_same<std::underlying_type_t<EnumType>, int>::value,
+ "Only enums with underlying type int are supported.");
+ auto castedValue = static_cast<int>(*enumValue);
+ doInt(&castedValue);
+ *enumValue = static_cast<EnumType>(castedValue);
+ }
};
} // namespace gmx
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2016,2017,2018,2019,2020,2021, 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.
writer->wrapperSettings().setIndent(oldIndent);
}
else if (value.isArray()
- && std::all_of(value.asArray().values().begin(), value.asArray().values().end(),
+ && std::all_of(value.asArray().values().begin(),
+ value.asArray().values().end(),
[](const auto& elem) { return elem.isObject(); }))
{
// Array containing only objects
else if (!areSimpleValuesOfSameTypeEqual(value1, value2))
{
writer_->writeString(currentPath_.toString());
- writer_->writeLine(formatString(" (%s - %s)", simpleValueToString(value1).c_str(),
+ writer_->writeLine(formatString(" (%s - %s)",
+ simpleValueToString(value1).c_str(),
simpleValueToString(value2).c_str()));
}
}
}
}
- bool areSimpleValuesOfSameTypeEqual(const KeyValueTreeValue& value1, const KeyValueTreeValue& value2)
+ bool areSimpleValuesOfSameTypeEqual(const KeyValueTreeValue& value1, const KeyValueTreeValue& value2) const
{
GMX_ASSERT(value1.type() == value2.type(), "Caller should ensure that types are equal");
if (value1.isType<bool>())
void handleMissingKeyInFirstObject(const KeyValueTreeValue& value)
{
- const std::string message = formatString("%s (missing - %s)", currentPath_.toString().c_str(),
+ const std::string message = formatString("%s (missing - %s)",
+ currentPath_.toString().c_str(),
formatValueForMissingMessage(value).c_str());
writer_->writeLine(message);
}
void handleMissingKeyInSecondObject(const KeyValueTreeValue& value)
{
- const std::string message = formatString("%s (%s - missing)", currentPath_.toString().c_str(),
+ const std::string message = formatString("%s (%s - missing)",
+ currentPath_.toString().c_str(),
formatValueForMissingMessage(value).c_str());
writer_->writeLine(message);
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2016,2017,2018,2019,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "keyvaluetreeserializer.h"
+#include <mutex>
+
#include "gromacs/utility/iserializer.h"
#include "gromacs/utility/keyvaluetree.h"
#include "gromacs/utility/keyvaluetreebuilder.h"
-#include "gromacs/utility/mutex.h"
namespace gmx
{
DeserializerFunction deserialize;
};
- static Mutex s_initMutex;
+ static std::mutex s_initMutex;
static std::map<std::type_index, Serializer> s_serializers;
static std::map<unsigned char, DeserializerFunction> s_deserializers;
};
-Mutex ValueSerializer::s_initMutex;
+std::mutex ValueSerializer::s_initMutex;
std::map<std::type_index, ValueSerializer::Serializer> ValueSerializer::s_serializers;
std::map<unsigned char, ValueSerializer::DeserializerFunction> ValueSerializer::s_deserializers;
}
static void deserializeObject(KeyValueTreeObjectBuilder* builder, ISerializer* serializer)
{
- int count;
+ int count = 0;
std::string key;
serializer->doInt(&count);
for (int i = 0; i < count; ++i)
static void deserialize(KeyValueTreeValueBuilder* value, ISerializer* serializer)
{
KeyValueTreeArrayBuilder builder(value->createArray());
- int count;
+ int count = 0;
serializer->doInt(&count);
for (int i = 0; i < count; ++i)
{
static void serialize(bool value, ISerializer* serializer) { serializer->doBool(&value); }
static void deserialize(KeyValueTreeValueBuilder* builder, ISerializer* serializer)
{
- bool value;
+ bool value = false;
serializer->doBool(&value);
builder->setValue<bool>(value);
}
static void serialize(int value, ISerializer* serializer) { serializer->doInt(&value); }
static void deserialize(KeyValueTreeValueBuilder* builder, ISerializer* serializer)
{
- int value;
+ int value = 0;
serializer->doInt(&value);
builder->setValue<int>(value);
}
static void serialize(int64_t value, ISerializer* serializer) { serializer->doInt64(&value); }
static void deserialize(KeyValueTreeValueBuilder* builder, ISerializer* serializer)
{
- int64_t value;
+ int64_t value = 0;
serializer->doInt64(&value);
builder->setValue<int64_t>(value);
}
static void serialize(float value, ISerializer* serializer) { serializer->doFloat(&value); }
static void deserialize(KeyValueTreeValueBuilder* builder, ISerializer* serializer)
{
- float value;
+ float value = 0;
serializer->doFloat(&value);
builder->setValue<float>(value);
}
static void serialize(double value, ISerializer* serializer) { serializer->doDouble(&value); }
static void deserialize(KeyValueTreeValueBuilder* builder, ISerializer* serializer)
{
- double value;
+ double value = 0;
serializer->doDouble(&value);
builder->setValue<double>(value);
}
// static
void ValueSerializer::initSerializers()
{
- lock_guard<Mutex> lock(s_initMutex);
+ std::lock_guard<std::mutex> lock(s_initMutex);
if (!s_serializers.empty())
{
return;
KeyValueTreeValue ValueSerializer::deserialize(ISerializer* serializer)
{
- unsigned char typeTag;
+ unsigned char typeTag = 0;
serializer->doUChar(&typeTag);
auto iter = s_deserializers.find(typeTag);
GMX_RELEASE_ASSERT(iter != s_deserializers.end(), "Unknown type tag for deserializization");
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2016,2017,2018,2019,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#define GMX_UTILITY_KEYVALUETREETRANSFORM_H
#include <functional>
+#include <memory>
#include <string>
#include <typeindex>
#include <vector>
#include "gromacs/utility/any.h"
-#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/keyvaluetree.h"
namespace gmx
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
/*! \libinternal \brief
IKeyValueTreeErrorHandler* errorHandler) const;
private:
- PrivateImplPointer<internal::KeyValueTreeTransformerImpl> impl_;
+ std::unique_ptr<internal::KeyValueTreeTransformerImpl> impl_;
};
class IKeyValueTreeBackMapping
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2016,2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <memory>
#include <string>
-#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/logger.h"
namespace gmx
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
/*! \libinternal \brief
LoggerOwner(std::unique_ptr<Impl> impl);
- PrivateImplPointer<Impl> impl_;
- const MDLogger* logger_;
+ std::unique_ptr<Impl> impl_;
+ const MDLogger* logger_;
friend class LoggerBuilder;
};
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/utility/mdmodulenotification-impl.h"
struct t_commrec;
+struct gmx_mtop_t;
enum class PbcType : int;
namespace gmx
class KeyValueTreeObjectBuilder;
class LocalAtomSetManager;
class IndexGroupsAndNames;
+class SeparatePmeRanksPermitted;
struct MdModulesCheckpointReadingDataOnMaster;
struct MdModulesCheckpointReadingBroadcast;
struct MdModulesWriteCheckpointData;
* wrote to .tpr files
* LocalAtomSetManager* enables modules to add atom indices to local atom sets
* to be managed
+ * const gmx_mtop_t& provides the topology of the system to the modules
* MdModulesEnergyOutputToDensityFittingRequestChecker* enables modules to
* report if they want to write their energy output
* to the density fitting field in the energy files
+ * SeparatePmeRanksPermitted* enables modules to report if they want
+ * to disable dedicated PME ranks
* const PbcType& provides modules with the periodic boundary condition type
* that is used during the simulation
* const SimulationTimeStep& provides modules with the simulation time-step
*/
registerMdModuleNotification<const KeyValueTreeObject&,
LocalAtomSetManager*,
+ const gmx_mtop_t&,
MdModulesEnergyOutputToDensityFittingRequestChecker*,
+ SeparatePmeRanksPermitted*,
const PbcType&,
const SimulationTimeStep&,
const t_commrec&>::type simulationSetupNotifications_;
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2011,2012,2013,2014,2019, by the GROMACS development team, led by
+ * Copyright (c) 2011,2012,2013,2014,2019,2021, 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.
#ifndef GMX_UTILITY_MESSAGESTRINGCOLLECTOR_H
#define GMX_UTILITY_MESSAGESTRINGCOLLECTOR_H
+#include <memory>
#include <string>
#include "gromacs/utility/classhelpers.h"
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
/*! \libinternal \brief
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 2015, by the GROMACS development team, led by
- * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
- * and including many others, as listed in the AUTHORS file in the
- * top-level source directory and at http://www.gromacs.org.
- *
- * GROMACS is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * GROMACS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with GROMACS; if not, see
- * http://www.gnu.org/licenses, or write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * If you want to redistribute modifications to GROMACS, please
- * consider that scientific software is very special. Version
- * control is crucial - bugs must be traceable. We will be happy to
- * consider code for inclusion in the official distribution, but
- * derived work must not be called official GROMACS. Details are found
- * in the README & COPYING files - if they are missing, get the
- * official version at http://www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org.
- */
-/*! \libinternal \file
- * \brief
- * Declares C++11-style basic threading primitives
- * (gmx::Mutex, gmx::lock_guard).
- *
- * For now, the implementation is imported from thread-MPI.
- *
- * \author Teemu Murtola <teemu.murtola@gmail.com>
- * \inlibraryapi
- * \ingroup module_utility
- */
-#ifndef GMX_THREADING_MUTEX_H
-#define GMX_THREADING_MUTEX_H
-
-#include "thread_mpi/mutex.h"
-
-namespace gmx
-{
-
-//! \cond libapi
-/*! \libinternal \brief
- * C++11-compatible basic mutex.
- */
-typedef tMPI::mutex Mutex;
-//! \endcond
-using tMPI::lock_guard;
-
-} // namespace gmx
-
-#endif
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2021, 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.
void niceHeader(TextWriter* writer, const char* fn, char commentChar)
{
- int uid;
char userbuf[256];
char hostbuf[256];
writer->writeLine(formatString("%c", commentChar));
writer->writeLine(formatString("%c\tFile '%s' was generated", commentChar, fn ? fn : "unknown"));
- uid = gmx_getuid();
+ int uid = gmx_getuid();
gmx_getusername(userbuf, 256);
gmx_gethostname(hostbuf, 256);
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2011-2018, The GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
// p2 is done first, so any error reported is for p1
// FixME: #1635
- handle_wrapper h2(CreateFile(path2.c_str(), 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
- 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0));
-
- handle_wrapper h1(CreateFile(path1.c_str(), 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
- 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0));
+ handle_wrapper h2(CreateFile(path2.c_str(),
+ 0,
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+ 0,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ 0));
+
+ handle_wrapper h1(CreateFile(path1.c_str(),
+ 0,
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+ 0,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ 0));
if (h1.handle == INVALID_HANDLE_VALUE || h2.handle == INVALID_HANDLE_VALUE)
{
// but if both are invalid then it is an error.
if (e1 != 0 && e2 != 0)
{
- GMX_THROW_WITH_ERRNO(FileIOError("Path::isEquivalent called with two invalid files"),
- "stat", errno);
+ GMX_THROW_WITH_ERRNO(
+ FileIOError("Path::isEquivalent called with two invalid files"), "stat", errno);
}
return false;
}
void Path::splitPathEnvironment(const std::string& pathEnv, std::vector<std::string>* result)
{
- size_t prevPos = 0;
- size_t separator;
+ size_t prevPos = 0;
+ size_t separator = 0;
do
{
separator = pathEnv.find(cPathSeparator, prevPos);
std::string result(path);
#if !GMX_NATIVE_WINDOWS
char buf[GMX_PATH_MAX];
- int length;
+ int length = 0;
while ((length = readlink(result.c_str(), buf, sizeof(buf) - 1)) > 0)
{
buf[length] = '\0';
void File::throwOnNotFound(const NotFoundInfo& info)
{
throwOnError(info);
- const std::string message = formatString("File '%s' does not exist or is not accessible.\n%s",
- info.filename, info.message);
+ const std::string message = formatString(
+ "File '%s' does not exist or is not accessible.\n%s", info.filename, info.message);
GMX_THROW_WITH_ERRNO(InvalidInputError(message), info.call, info.err);
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2021, 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.
PhysicalNodeCommunicator::PhysicalNodeCommunicator(MPI_Comm world, int physicalNodeId)
{
#if GMX_MPI
- int isInitialized;
+ int isInitialized = 0;
MPI_Initialized(&isInitialized);
if (isInitialized)
{
- int sizeOfWorld;
+ int sizeOfWorld = 0;
MPI_Comm_size(world, &sizeOfWorld);
if (sizeOfWorld > 1)
{
- int rankWithinWorld;
+ int rankWithinWorld = 0;
MPI_Comm_rank(world, &rankWithinWorld);
MPI_Comm_split(world, physicalNodeId, rankWithinWorld, &comm_);
auto ptr = MPI_Comm_ptr(&comm_);
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
const char* pages;
} t_citerec;
+static constexpr int sc_lineWidth = 79;
+
void please_cite(FILE* fp, const char* key)
{
static const t_citerec citedb[] = {
- { "Allen1987a", "M. P. Allen and D. J. Tildesley", "Computer simulation of liquids",
- "Oxford Science Publications", 1, 1987, "1" },
- { "Berendsen95a", "H. J. C. Berendsen, D. van der Spoel and R. van Drunen",
+ { "Allen1987a",
+ "M. P. Allen and D. J. Tildesley",
+ "Computer simulation of liquids",
+ "Oxford Science Publications",
+ 1,
+ 1987,
+ "1" },
+ { "Berendsen95a",
+ "H. J. C. Berendsen, D. van der Spoel and R. van Drunen",
"GROMACS: A message-passing parallel molecular dynamics implementation",
- "Comp. Phys. Comm.", 91, 1995, "43-56" },
- { "Berendsen84a", "H. J. C. Berendsen, J. P. M. Postma, A. DiNola and J. R. Haak",
- "Molecular dynamics with coupling to an external bath", "J. Chem. Phys.", 81, 1984,
+ "Comp. Phys. Comm.",
+ 91,
+ 1995,
+ "43-56" },
+ { "Berendsen84a",
+ "H. J. C. Berendsen, J. P. M. Postma, A. DiNola and J. R. Haak",
+ "Molecular dynamics with coupling to an external bath",
+ "J. Chem. Phys.",
+ 81,
+ 1984,
"3684-3690" },
- { "Ryckaert77a", "J. P. Ryckaert and G. Ciccotti and H. J. C. Berendsen",
+ { "Ryckaert77a",
+ "J. P. Ryckaert and G. Ciccotti and H. J. C. Berendsen",
"Numerical Integration of the Cartesian Equations of Motion of a System with "
"Constraints; Molecular Dynamics of n-Alkanes",
- "J. Comp. Phys.", 23, 1977, "327-341" },
- { "Miyamoto92a", "S. Miyamoto and P. A. Kollman",
+ "J. Comp. Phys.",
+ 23,
+ 1977,
+ "327-341" },
+ { "Miyamoto92a",
+ "S. Miyamoto and P. A. Kollman",
"SETTLE: An Analytical Version of the SHAKE and RATTLE Algorithms for Rigid Water Models",
- "J. Comp. Chem.", 13, 1992, "952-962" },
- { "Cromer1968a", "D. T. Cromer & J. B. Mann",
+ "J. Comp. Chem.",
+ 13,
+ 1992,
+ "952-962" },
+ { "Cromer1968a",
+ "D. T. Cromer & J. B. Mann",
"X-ray scattering factors computed from numerical Hartree-Fock wave functions",
- "Acta Cryst. A", 24, 1968, "321" },
- { "Barth95a", "E. Barth and K. Kuczera and B. Leimkuhler and R. D. Skeel",
- "Algorithms for Constrained Molecular Dynamics", "J. Comp. Chem.", 16, 1995, "1192-1209" },
+ "Acta Cryst. A",
+ 24,
+ 1968,
+ "321" },
+ { "Barth95a",
+ "E. Barth and K. Kuczera and B. Leimkuhler and R. D. Skeel",
+ "Algorithms for Constrained Molecular Dynamics",
+ "J. Comp. Chem.",
+ 16,
+ 1995,
+ "1192-1209" },
{ "Essmann95a",
"U. Essmann, L. Perera, M. L. Berkowitz, T. Darden, H. Lee and L. G. Pedersen ",
- "A smooth particle mesh Ewald method", "J. Chem. Phys.", 103, 1995, "8577-8592" },
- { "Torda89a", "A. E. Torda and R. M. Scheek and W. F. van Gunsteren",
+ "A smooth particle mesh Ewald method",
+ "J. Chem. Phys.",
+ 103,
+ 1995,
+ "8577-8592" },
+ { "Torda89a",
+ "A. E. Torda and R. M. Scheek and W. F. van Gunsteren",
"Time-dependent distance restraints in molecular dynamics simulations",
- "Chem. Phys. Lett.", 157, 1989, "289-294" },
- { "Tironi95a", "I. G. Tironi and R. Sperb and P. E. Smith and W. F. van Gunsteren",
- "Generalized reaction field method for molecular dynamics simulations", "J. Chem. Phys",
- 102, 1995, "5451-5459" },
- { "Hess97a", "B. Hess and H. Bekker and H. J. C. Berendsen and J. G. E. M. Fraaije",
- "LINCS: A Linear Constraint Solver for molecular simulations", "J. Comp. Chem.", 18, 1997,
+ "Chem. Phys. Lett.",
+ 157,
+ 1989,
+ "289-294" },
+ { "Tironi95a",
+ "I. G. Tironi and R. Sperb and P. E. Smith and W. F. van Gunsteren",
+ "Generalized reaction field method for molecular dynamics simulations",
+ "J. Chem. Phys",
+ 102,
+ 1995,
+ "5451-5459" },
+ { "Hess97a",
+ "B. Hess and H. Bekker and H. J. C. Berendsen and J. G. E. M. Fraaije",
+ "LINCS: A Linear Constraint Solver for molecular simulations",
+ "J. Comp. Chem.",
+ 18,
+ 1997,
"1463-1472" },
- { "Hess2008a", "B. Hess",
+ { "Hess2008a",
+ "B. Hess",
"P-LINCS: A Parallel Linear Constraint Solver for molecular simulation",
- "J. Chem. Theory Comput.", 4, 2008, "116-122" },
- { "Hess2008b", "B. Hess and C. Kutzner and D. van der Spoel and E. Lindahl",
+ "J. Chem. Theory Comput.",
+ 4,
+ 2008,
+ "116-122" },
+ { "Hess2008b",
+ "B. Hess and C. Kutzner and D. van der Spoel and E. Lindahl",
"GROMACS 4: Algorithms for highly efficient, load-balanced, and scalable molecular "
"simulation",
- "J. Chem. Theory Comput.", 4, 2008, "435-447" },
- { "Hub2010", "J. S. Hub, B. L. de Groot and D. van der Spoel",
+ "J. Chem. Theory Comput.",
+ 4,
+ 2008,
+ "435-447" },
+ { "Hub2010",
+ "J. S. Hub, B. L. de Groot and D. van der Spoel",
"g_wham - A free weighted histogram analysis implementation including robust error and "
"autocorrelation estimates",
- "J. Chem. Theory Comput.", 6, 2010, "3713-3720" },
- { "In-Chul99a", "Y. In-Chul and M. L. Berkowitz",
- "Ewald summation for systems with slab geometry", "J. Chem. Phys.", 111, 1999,
+ "J. Chem. Theory Comput.",
+ 6,
+ 2010,
+ "3713-3720" },
+ { "In-Chul99a",
+ "Y. In-Chul and M. L. Berkowitz",
+ "Ewald summation for systems with slab geometry",
+ "J. Chem. Phys.",
+ 111,
+ 1999,
"3155-3162" },
{ "DeGroot97a",
"B. L. de Groot and D. M. F. van Aalten and R. M. Scheek and A. Amadei and G. Vriend and "
"H. J. C. Berendsen",
- "Prediction of Protein Conformational Freedom From Distance Constrains", "Proteins", 29,
- 1997, "240-251" },
- { "Spoel98a", "D. van der Spoel and P. J. van Maaren and H. J. C. Berendsen",
+ "Prediction of Protein Conformational Freedom From Distance Constrains",
+ "Proteins",
+ 29,
+ 1997,
+ "240-251" },
+ { "Spoel98a",
+ "D. van der Spoel and P. J. van Maaren and H. J. C. Berendsen",
"A systematic study of water models for molecular simulation. Derivation of models "
"optimized for use with a reaction-field.",
- "J. Chem. Phys.", 108, 1998, "10220-10230" },
- { "Wishart98a", "D. S. Wishart and A. M. Nip",
- "Protein Chemical Shift Analysis: A Practical Guide", "Biochem. Cell Biol.", 76, 1998,
+ "J. Chem. Phys.",
+ 108,
+ 1998,
+ "10220-10230" },
+ { "Wishart98a",
+ "D. S. Wishart and A. M. Nip",
+ "Protein Chemical Shift Analysis: A Practical Guide",
+ "Biochem. Cell Biol.",
+ 76,
+ 1998,
"153-163" },
- { "Maiorov95", "V. N. Maiorov and G. M. Crippen",
+ { "Maiorov95",
+ "V. N. Maiorov and G. M. Crippen",
"Size-Independent Comparison of Protein Three-Dimensional Structures",
- "PROTEINS: Struct. Funct. Gen.", 22, 1995, "273-283" },
- { "Feenstra99", "K. A. Feenstra and B. Hess and H. J. C. Berendsen",
+ "PROTEINS: Struct. Funct. Gen.",
+ 22,
+ 1995,
+ "273-283" },
+ { "Feenstra99",
+ "K. A. Feenstra and B. Hess and H. J. C. Berendsen",
"Improving Efficiency of Large Time-scale Molecular Dynamics Simulations of "
"Hydrogen-rich Systems",
- "J. Comput. Chem.", 20, 1999, "786-798" },
+ "J. Comput. Chem.",
+ 20,
+ 1999,
+ "786-798" },
{ "Lourenco2013a",
"Tuanan C. Lourenco and Mariny F. C. Coelho and Teodorico C. Ramalho and David van der "
"Spoel and Luciano T. Costa",
"Insights on the Solubility of CO2 in 1-Ethyl-3-methylimidazolium "
"Bis(trifluoromethylsulfonyl)imide from the Microscopic Point of View",
- "Environ. Sci. Technol.", 47, 2013, "7421-7429" },
- { "Timneanu2004a", "N. Timneanu and C. Caleman and J. Hajdu and D. van der Spoel",
- "Auger Electron Cascades in Water and Ice", "Chem. Phys.", 299, 2004, "277-283" },
- { "Pascal2011a", "T. A. Pascal and S. T. Lin and W. A. Goddard III",
+ "Environ. Sci. Technol.",
+ 47,
+ 2013,
+ "7421-7429" },
+ { "Timneanu2004a",
+ "N. Timneanu and C. Caleman and J. Hajdu and D. van der Spoel",
+ "Auger Electron Cascades in Water and Ice",
+ "Chem. Phys.",
+ 299,
+ 2004,
+ "277-283" },
+ { "Pascal2011a",
+ "T. A. Pascal and S. T. Lin and W. A. Goddard III",
"Thermodynamics of liquids: standard molar entropies and heat capacities of common "
"solvents from 2PT molecular dynamics",
- "Phys. Chem. Chem. Phys.", 13, 2011, "169-181" },
- { "Caleman2008a", "C. Caleman and D. van der Spoel",
+ "Phys. Chem. Chem. Phys.",
+ 13,
+ 2011,
+ "169-181" },
+ { "Caleman2008a",
+ "C. Caleman and D. van der Spoel",
"Picosecond Melting of Ice by an Infrared Laser Pulse: A Simulation Study",
- "Angew. Chem. Int. Ed", 47, 2008, "1417-1420" },
+ "Angew. Chem. Int. Ed",
+ 47,
+ 2008,
+ "1417-1420" },
{ "Caleman2011b",
"C. Caleman and P. J. van Maaren and M. Hong and J. S. Hub and L. T. da Costa and D. van "
"der Spoel",
"Force Field Benchmark of Organic Liquids: Density, Enthalpy of Vaporization, Heat "
"Capacities, Surface Tension, Isothermal Compressibility, Volumetric Expansion "
"Coefficient, and Dielectric Constant",
- "J. Chem. Theo. Comp.", 8, 2012, "61" },
- { "Lindahl2001a", "E. Lindahl and B. Hess and D. van der Spoel",
- "GROMACS 3.0: A package for molecular simulation and trajectory analysis", "J. Mol. Mod.",
- 7, 2001, "306-317" },
- { "Wang2001a", "J. Wang and W. Wang and S. Huo and M. Lee and P. A. Kollman",
- "Solvation model based on weighted solvent accessible surface area", "J. Phys. Chem. B",
- 105, 2001, "5055-5067" },
- { "Eisenberg86a", "D. Eisenberg and A. D. McLachlan",
- "Solvation energy in protein folding and binding", "Nature", 319, 1986, "199-203" },
- { "Bondi1964a", "A. Bondi", "van der Waals Volumes and Radii", "J. Phys. Chem.", 68, 1964,
+ "J. Chem. Theo. Comp.",
+ 8,
+ 2012,
+ "61" },
+ { "Lindahl2001a",
+ "E. Lindahl and B. Hess and D. van der Spoel",
+ "GROMACS 3.0: A package for molecular simulation and trajectory analysis",
+ "J. Mol. Mod.",
+ 7,
+ 2001,
+ "306-317" },
+ { "Wang2001a",
+ "J. Wang and W. Wang and S. Huo and M. Lee and P. A. Kollman",
+ "Solvation model based on weighted solvent accessible surface area",
+ "J. Phys. Chem. B",
+ 105,
+ 2001,
+ "5055-5067" },
+ { "Eisenberg86a",
+ "D. Eisenberg and A. D. McLachlan",
+ "Solvation energy in protein folding and binding",
+ "Nature",
+ 319,
+ 1986,
+ "199-203" },
+ { "Bondi1964a",
+ "A. Bondi",
+ "van der Waals Volumes and Radii",
+ "J. Phys. Chem.",
+ 68,
+ 1964,
"441-451" },
{ "Eisenhaber95",
"Frank Eisenhaber and Philip Lijnzaad and Patrick Argos and Chris Sander and Michael "
"Scharf",
"The Double Cube Lattice Method: Efficient Approaches to Numerical Integration of "
"Surface Area and Volume and to Dot Surface Contouring of Molecular Assemblies",
- "J. Comp. Chem.", 16, 1995, "273-284" },
- { "Hess2002", "B. Hess, H. Saint-Martin and H.J.C. Berendsen",
+ "J. Comp. Chem.",
+ 16,
+ 1995,
+ "273-284" },
+ { "Hess2002",
+ "B. Hess, H. Saint-Martin and H.J.C. Berendsen",
"Flexible constraints: an adiabatic treatment of quantum degrees of freedom, with "
"application to the flexible and polarizable MCDHO model for water",
- "J. Chem. Phys.", 116, 2002, "9602-9610" },
- { "Hess2003", "B. Hess and R.M. Scheek",
+ "J. Chem. Phys.",
+ 116,
+ 2002,
+ "9602-9610" },
+ { "Hess2003",
+ "B. Hess and R.M. Scheek",
"Orientation restraints in molecular dynamics simulations using time and ensemble "
"averaging",
- "J. Magn. Res.", 164, 2003, "19-27" },
- { "Rappe1991a", "A. K. Rappe and W. A. Goddard III",
- "Charge Equillibration for Molecular Dynamics Simulations", "J. Phys. Chem.", 95, 1991,
+ "J. Magn. Res.",
+ 164,
+ 2003,
+ "19-27" },
+ { "Rappe1991a",
+ "A. K. Rappe and W. A. Goddard III",
+ "Charge Equillibration for Molecular Dynamics Simulations",
+ "J. Phys. Chem.",
+ 95,
+ 1991,
"3358-3363" },
- { "Mu2005a", "Y. Mu, P. H. Nguyen and G. Stock",
+ { "Mu2005a",
+ "Y. Mu, P. H. Nguyen and G. Stock",
"Energy landscape of a small peptide revelaed by dihedral angle principal component "
"analysis",
- "Prot. Struct. Funct. Bioinf.", 58, 2005, "45-52" },
- { "Okabe2001a", "T. Okabe and M. Kawata and Y. Okamoto and M. Mikami",
+ "Prot. Struct. Funct. Bioinf.",
+ 58,
+ 2005,
+ "45-52" },
+ { "Okabe2001a",
+ "T. Okabe and M. Kawata and Y. Okamoto and M. Mikami",
"Replica-exchange {M}onte {C}arlo method for the isobaric-isothermal ensemble",
- "Chem. Phys. Lett.", 335, 2001, "435-439" },
- { "Hukushima96a", "K. Hukushima and K. Nemoto",
+ "Chem. Phys. Lett.",
+ 335,
+ 2001,
+ "435-439" },
+ { "Hukushima96a",
+ "K. Hukushima and K. Nemoto",
"Exchange Monte Carlo Method and Application to Spin Glass Simulations",
- "J. Phys. Soc. Jpn.", 65, 1996, "1604-1608" },
- { "Tropp80a", "J. Tropp",
+ "J. Phys. Soc. Jpn.",
+ 65,
+ 1996,
+ "1604-1608" },
+ { "Tropp80a",
+ "J. Tropp",
"Dipolar Relaxation and Nuclear Overhauser effects in nonrigid molecules: The effect of "
"fluctuating internuclear distances",
- "J. Chem. Phys.", 72, 1980, "6035-6043" },
+ "J. Chem. Phys.",
+ 72,
+ 1980,
+ "6035-6043" },
{ "Bultinck2002a",
"P. Bultinck and W. Langenaeker and P. Lahorte and F. De Proft and P. Geerlings and M. "
"Waroquier and J. P. Tollenaere",
"The electronegativity equalization method I: Parametrization and validation for atomic "
"charge calculations",
- "J. Phys. Chem. A", 106, 2002, "7887-7894" },
- { "Yang2006b", "Q. Y. Yang and K. A. Sharp",
+ "J. Phys. Chem. A",
+ 106,
+ 2002,
+ "7887-7894" },
+ { "Yang2006b",
+ "Q. Y. Yang and K. A. Sharp",
"Atomic charge parameters for the finite difference Poisson-Boltzmann method using "
"electronegativity neutralization",
- "J. Chem. Theory Comput.", 2, 2006, "1152-1167" },
+ "J. Chem. Theory Comput.",
+ 2,
+ 2006,
+ "1152-1167" },
{ "Spoel2005a",
"D. van der Spoel, E. Lindahl, B. Hess, G. Groenhof, A. E. Mark and H. J. C. Berendsen",
- "GROMACS: Fast, Flexible and Free", "J. Comp. Chem.", 26, 2005, "1701-1719" },
- { "Spoel2006b", "D. van der Spoel, P. J. van Maaren, P. Larsson and N. Timneanu",
+ "GROMACS: Fast, Flexible and Free",
+ "J. Comp. Chem.",
+ 26,
+ 2005,
+ "1701-1719" },
+ { "Spoel2006b",
+ "D. van der Spoel, P. J. van Maaren, P. Larsson and N. Timneanu",
"Thermodynamics of hydrogen bonding in hydrophilic and hydrophobic media",
- "J. Phys. Chem. B", 110, 2006, "4393-4398" },
- { "Spoel2006d", "D. van der Spoel and M. M. Seibert",
+ "J. Phys. Chem. B",
+ 110,
+ 2006,
+ "4393-4398" },
+ { "Spoel2006d",
+ "D. van der Spoel and M. M. Seibert",
"Protein folding kinetics and thermodynamics from atomistic simulations",
- "Phys. Rev. Letters", 96, 2006, "238102" },
- { "Palmer94a", "B. J. Palmer",
+ "Phys. Rev. Letters",
+ 96,
+ 2006,
+ "238102" },
+ { "Palmer94a",
+ "B. J. Palmer",
"Transverse-current autocorrelation-function calculations of the shear viscosity for "
"molecular liquids",
- "Phys. Rev. E", 49, 1994, "359-366" },
- { "Bussi2007a", "G. Bussi, D. Donadio and M. Parrinello",
- "Canonical sampling through velocity rescaling", "J. Chem. Phys.", 126, 2007, "014101" },
- { "Hub2006", "J. S. Hub and B. L. de Groot", "Does CO2 permeate through Aquaporin-1?",
- "Biophys. J.", 91, 2006, "842-848" },
- { "Hub2008", "J. S. Hub and B. L. de Groot",
- "Mechanism of selectivity in aquaporins and aquaglyceroporins", "PNAS", 105, 2008,
+ "Phys. Rev. E",
+ 49,
+ 1994,
+ "359-366" },
+ { "Bussi2007a",
+ "G. Bussi, D. Donadio and M. Parrinello",
+ "Canonical sampling through velocity rescaling",
+ "J. Chem. Phys.",
+ 126,
+ 2007,
+ "014101" },
+ { "Hub2006",
+ "J. S. Hub and B. L. de Groot",
+ "Does CO2 permeate through Aquaporin-1?",
+ "Biophys. J.",
+ 91,
+ 2006,
+ "842-848" },
+ { "Hub2008",
+ "J. S. Hub and B. L. de Groot",
+ "Mechanism of selectivity in aquaporins and aquaglyceroporins",
+ "PNAS",
+ 105,
+ 2008,
"1198-1203" },
{ "Friedrich2009",
"M. S. Friedrichs, P. Eastman, V. Vaidyanathan, M. Houston, S. LeGrand, A. L. Beberg, D. "
"L. Ensign, C. M. Bruns, and V. S. Pande",
"Accelerating Molecular Dynamic Simulation on Graphics Processing Units",
- "J. Comp. Chem.", 30, 2009, "864-872" },
- { "Engin2010", "O. Engin, A. Villa, M. Sayar and B. Hess",
+ "J. Comp. Chem.",
+ 30,
+ 2009,
+ "864-872" },
+ { "Engin2010",
+ "O. Engin, A. Villa, M. Sayar and B. Hess",
"Driving Forces for Adsorption of Amphiphilic Peptides to Air-Water Interface",
- "J. Phys. Chem. B", 114, 2010, "11093" },
- { "Wang2010", "H. Wang, F. Dommert, C.Holm",
+ "J. Phys. Chem. B",
+ 114,
+ 2010,
+ "11093" },
+ { "Wang2010",
+ "H. Wang, F. Dommert, C.Holm",
"Optimizing working parameters of the smooth particle mesh Ewald algorithm in terms of "
"accuracy and efficiency",
- "J. Chem. Phys. B", 133, 2010, "034117" },
- { "Sugita1999a", "Y. Sugita, Y. Okamoto",
- "Replica-exchange molecular dynamics method for protein folding", "Chem. Phys. Lett.",
- 314, 1999, "141-151" },
- { "Kutzner2011", "C. Kutzner and J. Czub and H. Grubmuller",
+ "J. Chem. Phys. B",
+ 133,
+ 2010,
+ "034117" },
+ { "Sugita1999a",
+ "Y. Sugita, Y. Okamoto",
+ "Replica-exchange molecular dynamics method for protein folding",
+ "Chem. Phys. Lett.",
+ 314,
+ 1999,
+ "141-151" },
+ { "Kutzner2011",
+ "C. Kutzner and J. Czub and H. Grubmuller",
"Keep it Flexible: Driving Macromolecular Rotary Motions in Atomistic Simulations with "
"GROMACS",
- "J. Chem. Theory Comput.", 7, 2011, "1381-1393" },
+ "J. Chem. Theory Comput.",
+ 7,
+ 2011,
+ "1381-1393" },
{ "Hoefling2011",
"M. Hoefling, N. Lima, D. Haenni, C.A.M. Seidel, B. Schuler, H. Grubmuller",
"Structural Heterogeneity and Quantitative FRET Efficiency Distributions of Polyprolines "
"through a Hybrid Atomistic Simulation and Monte Carlo Approach",
- "PLoS ONE", 6, 2011, "e19791" },
- { "Hockney1988", "R. W. Hockney and J. W. Eastwood", "Computer simulation using particles",
- "IOP, Bristol", 1, 1988, "1" },
- { "Ballenegger2012", "V. Ballenegger, J.J. Cerda, and C. Holm",
+ "PLoS ONE",
+ 6,
+ 2011,
+ "e19791" },
+ { "Hockney1988",
+ "R. W. Hockney and J. W. Eastwood",
+ "Computer simulation using particles",
+ "IOP, Bristol",
+ 1,
+ 1988,
+ "1" },
+ { "Ballenegger2012",
+ "V. Ballenegger, J.J. Cerda, and C. Holm",
"How to Convert SPME to P3M: Influence Functions and Error Estimates",
- "J. Chem. Theory Comput.", 8, 2012, "936-947" },
+ "J. Chem. Theory Comput.",
+ 8,
+ 2012,
+ "936-947" },
{ "Garmay2012",
"Garmay Yu, Shvetsov A, Karelov D, Lebedev D, Radulescu A, Petukhov M, Isaev-Ivanov V",
"Correlated motion of protein subdomains and large-scale conformational flexibility of "
"RecA protein filament",
- "Journal of Physics: Conference Series", 340, 2012, "012094" },
- { "Kutzner2011b", "C. Kutzner, H. Grubmuller, B. L. de Groot, and U. Zachariae",
+ "Journal of Physics: Conference Series",
+ 340,
+ 2012,
+ "012094" },
+ { "Kutzner2011b",
+ "C. Kutzner, H. Grubmuller, B. L. de Groot, and U. Zachariae",
"Computational Electrophysiology: The Molecular Dynamics of Ion Channel Permeation and "
"Selectivity in Atomistic Detail",
- "Biophys. J.", 101, 2011, "809-817" },
+ "Biophys. J.",
+ 101,
+ 2011,
+ "809-817" },
{ "Lundborg2014",
"M. Lundborg, R. Apostolov, D. Spangberg, A. Gardenas, D. van der Spoel and E. Lindahl",
"An efficient and extensible format, library, and API for binary trajectory data from "
"molecular simulations",
- "J. Comput. Chem.", 35, 2014, "260-269" },
+ "J. Comput. Chem.",
+ 35,
+ 2014,
+ "260-269" },
{ "Goga2012",
"N. Goga and A. J. Rzepiela and A. H. de Vries and S. J. Marrink and H. J. C. Berendsen",
- "Efficient Algorithms for Langevin and DPD Dynamics", "J. Chem. Theory Comput.", 8, 2012,
+ "Efficient Algorithms for Langevin and DPD Dynamics",
+ "J. Chem. Theory Comput.",
+ 8,
+ 2012,
"3637--3649" },
{ "Pronk2013",
"S. Pronk, S. Páll, R. Schulz, P. Larsson, P. Bjelkmar, R. Apostolov, M. R. Shirts, J. "
"C. Smith, P. M. Kasson, D. van der Spoel, B. Hess, and E. Lindahl",
"GROMACS 4.5: a high-throughput and highly parallel open source molecular simulation "
"toolkit",
- "Bioinformatics", 29, 2013, "845-54" },
- { "Pall2015", "S. Páll, M. J. Abraham, C. Kutzner, B. Hess, E. Lindahl",
+ "Bioinformatics",
+ 29,
+ 2013,
+ "845-54" },
+ { "Pall2015",
+ "S. Páll, M. J. Abraham, C. Kutzner, B. Hess, E. Lindahl",
"Tackling Exascale Software Challenges in Molecular Dynamics Simulations with GROMACS",
- "In S. Markidis & E. Laure (Eds.), Solving Software Challenges for Exascale", 8759, 2015,
+ "In S. Markidis & E. Laure (Eds.), Solving Software Challenges for Exascale",
+ 8759,
+ 2015,
"3-27" },
{ "Abraham2015",
"M. J. Abraham, T. Murtola, R. Schulz, S. Páll, J. C. Smith, B. Hess, E. Lindahl",
"GROMACS: High performance molecular simulations through multi-level parallelism from "
"laptops to supercomputers",
- "SoftwareX", 1, 2015, "19-25" },
- { "Ballenegger2009", "V. Ballenegger, A. Arnold, J. J. Cerdà",
+ "SoftwareX",
+ 1,
+ 2015,
+ "19-25" },
+ { "Ballenegger2009",
+ "V. Ballenegger, A. Arnold, J. J. Cerdà",
"Simulations of non-neutral slab systems with long-range electrostatic interactions in "
"two-dimensional periodic boundary conditions",
- "J. Chem. Phys", 131, 2009, "094107" },
- { "Hub2014a", "J. S. Hub, B. L. de Groot, H. Grubmueller, G. Groenhof",
+ "J. Chem. Phys",
+ 131,
+ 2009,
+ "094107" },
+ { "Hub2014a",
+ "J. S. Hub, B. L. de Groot, H. Grubmueller, G. Groenhof",
"Quantifying Artifacts in Ewald Simulations of Inhomogeneous Systems with a Net Charge",
- "J. Chem. Theory Comput.", 10, 2014, "381-393" },
- { "Spoel2018a", "D. van der Spoel, M. M. Ghahremanpour, J. Lemkul",
+ "J. Chem. Theory Comput.",
+ 10,
+ 2014,
+ "381-393" },
+ { "Spoel2018a",
+ "D. van der Spoel, M. M. Ghahremanpour, J. Lemkul",
"Small Molecule Thermochemistry: A Tool For Empirical Force Field Development",
- "J. Phys. Chem. A", 122, 2018, "8982-8988" },
- { "Lindahl2014", "V. Lindahl, J. Lidmar, B. Hess",
+ "J. Phys. Chem. A",
+ 122,
+ 2018,
+ "8982-8988" },
+ { "Lindahl2014",
+ "V. Lindahl, J. Lidmar, B. Hess",
"Accelerated weight histogram method for exploring free energy landscapes",
- "J. Chem. Phys.", 141, 2014, "044110" },
- { "Bernetti2020", "M. Bernetti, G. Bussi",
- "Pressure control using stochastic cell rescaling", "J. Chem. Phys.", 153, 2020,
+ "J. Chem. Phys.",
+ 141,
+ 2014,
+ "044110" },
+ { "Bernetti2020",
+ "M. Bernetti, G. Bussi",
+ "Pressure control using stochastic cell rescaling",
+ "J. Chem. Phys.",
+ 153,
+ 2020,
"114107" },
};
#define NSTR static_cast<int>(asize(citedb))
- int index;
- char* author;
- char* title;
-#define LINE_WIDTH 79
-
if (fp == nullptr)
{
return;
}
- for (index = 0; index < NSTR && (strcmp(citedb[index].key, key) != 0); index++) {}
+ int index = 0;
+ for (; index < NSTR && (strcmp(citedb[index].key, key) != 0); index++) {}
fprintf(fp, "\n++++ PLEASE READ AND CITE THE FOLLOWING REFERENCE ++++\n");
if (index < NSTR)
{
/* Insert newlines */
- author = wrap_lines(citedb[index].author, LINE_WIDTH, 0, FALSE);
- title = wrap_lines(citedb[index].title, LINE_WIDTH, 0, FALSE);
- fprintf(fp, "%s\n%s\n%s %d (%d) pp. %s\n", author, title, citedb[index].journal,
- citedb[index].volume, citedb[index].year, citedb[index].pages);
+ char* author = wrap_lines(citedb[index].author, sc_lineWidth, 0, FALSE);
+ char* title = wrap_lines(citedb[index].title, sc_lineWidth, 0, FALSE);
+ fprintf(fp,
+ "%s\n%s\n%s %d (%d) pp. %s\n",
+ author,
+ title,
+ citedb[index].journal,
+ citedb[index].volume,
+ citedb[index].year,
+ citedb[index].pages);
sfree(author);
sfree(title);
}
return;
}
gmx::TextLineWrapper wrapper;
- wrapper.settings().setLineLength(LINE_WIDTH);
+ wrapper.settings().setLineLength(sc_lineWidth);
wrapper.settings().setFirstLineIndent(0);
const std::string doiString = wrapper.wrapToString(gmxDOI());
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <cstdio>
#include <cstdlib>
+#include <mutex>
+
#ifdef WITH_DMALLOC
# include <dmalloc.h>
#endif
#include <cstring>
-#include "thread_mpi/threads.h"
-
#include "gromacs/utility/alignedallocator.h"
#include "gromacs/utility/dir_separator.h"
#include "gromacs/utility/fatalerror.h"
# include "gromacs/utility/gmxmpi.h"
#endif
-static gmx_bool g_bOverAllocDD = FALSE;
-static tMPI_Thread_mutex_t g_over_alloc_mutex = TMPI_THREAD_MUTEX_INITIALIZER;
+static bool g_bOverAllocDD = false;
+static std::mutex g_overAllocMutex;
void* save_malloc(const char* name, const char* file, int line, size_t size)
{
- void* p;
+ void* p = nullptr;
- p = nullptr;
if (size == 0)
{
p = nullptr;
{
if ((p = malloc(size)) == nullptr)
{
- gmx_fatal(errno, __FILE__, __LINE__,
+ gmx_fatal(errno,
+ __FILE__,
+ __LINE__,
"Not enough memory. Failed to malloc %" PRId64
" bytes for %s\n"
"(called from file %s, line %d)",
- static_cast<int64_t>(size), name, file, line);
+ static_cast<int64_t>(size),
+ name,
+ file,
+ line);
}
(void)memset(p, 0, size);
}
void* save_calloc(const char* name, const char* file, int line, size_t nelem, size_t elsize)
{
- void* p;
+ void* p = nullptr;
- p = nullptr;
if ((nelem == 0) || (elsize == 0))
{
p = nullptr;
{
int rank = gmx_node_rank();
printf("Allocating %.1f MB for %s (called from file %s, line %d on %d)\n",
- nelem * elsize / 1048576.0, name, file, line, rank);
+ nelem * elsize / 1048576.0,
+ name,
+ file,
+ line,
+ rank);
}
#endif
#if GMX_BROKEN_CALLOC
a broken calloc, e.g. in -lgmalloc on cray xt3. */
if ((p = malloc((size_t)nelem * (size_t)elsize)) == NULL)
{
- gmx_fatal(errno, __FILE__, __LINE__,
+ gmx_fatal(errno,
+ __FILE__,
+ __LINE__,
"Not enough memory. Failed to calloc %" PRId64 " elements of size %" PRId64
" for %s\n(called from file %s, line %d)",
- (int64_t)nelem, (int64_t)elsize, name, file, line);
+ (int64_t)nelem,
+ (int64_t)elsize,
+ name,
+ file,
+ line);
}
memset(p, 0, (size_t)(nelem * elsize));
#else
if ((p = calloc(nelem, elsize)) == nullptr)
{
- gmx_fatal(errno, __FILE__, __LINE__,
+ gmx_fatal(errno,
+ __FILE__,
+ __LINE__,
"Not enough memory. Failed to calloc %" PRId64 " elements of size %" PRId64
" for %s\n(called from file %s, line %d)",
- static_cast<int64_t>(nelem), static_cast<int64_t>(elsize), name, file, line);
+ static_cast<int64_t>(nelem),
+ static_cast<int64_t>(elsize),
+ name,
+ file,
+ line);
}
#endif
}
void* save_realloc(const char* name, const char* file, int line, void* ptr, size_t nelem, size_t elsize)
{
- void* p;
+ void* p = nullptr;
size_t size = nelem * elsize;
- p = nullptr;
if (size == 0)
{
save_free(name, file, line, ptr);
{
int rank = gmx_node_rank();
printf("Reallocating %.1f MB for %s (called from file %s, line %d on %d)\n",
- size / 1048576.0, name, file, line, rank);
+ size / 1048576.0,
+ name,
+ file,
+ line,
+ rank);
}
#endif
if (ptr == nullptr)
}
if (p == nullptr)
{
- gmx_fatal(errno, __FILE__, __LINE__,
+ gmx_fatal(errno,
+ __FILE__,
+ __LINE__,
"Not enough memory. Failed to realloc %zu bytes for %s, %s=%p\n"
"(called from file %s, line %d)",
- size, name, name, ptr, file, line);
+ size,
+ name,
+ name,
+ ptr,
+ file,
+ line);
}
}
return p;
* the necessary alignment. */
void* save_malloc_aligned(const char* name, const char* file, int line, size_t nelem, size_t elsize, size_t alignment)
{
- void* p;
+ void* p = nullptr;
if (alignment == 0)
{
- gmx_fatal(errno, __FILE__, __LINE__,
+ gmx_fatal(errno,
+ __FILE__,
+ __LINE__,
"Cannot allocate aligned memory with alignment of zero!\n(called from file %s, "
"line %d)",
- file, line);
+ file,
+ line);
}
size_t alignmentSize = gmx::AlignedAllocationPolicy::alignment();
if (alignment > alignmentSize)
{
- gmx_fatal(errno, __FILE__, __LINE__,
+ gmx_fatal(errno,
+ __FILE__,
+ __LINE__,
"Cannot allocate aligned memory with alignment > %zu bytes\n(called from file "
"%s, line %d)",
- alignmentSize, file, line);
+ alignmentSize,
+ file,
+ line);
}
{
int rank = gmx_node_rank();
printf("Allocating %.1f MB for %s (called from file %s, line %d on %d)\n",
- nelem * elsize / 1048576.0, name, file, line, rank);
+ nelem * elsize / 1048576.0,
+ name,
+ file,
+ line,
+ rank);
}
#endif
if (p == nullptr)
{
- gmx_fatal(errno, __FILE__, __LINE__,
+ gmx_fatal(errno,
+ __FILE__,
+ __LINE__,
"Not enough memory. Failed to allocate %zu aligned elements of size %zu for "
"%s\n(called from file %s, line %d)",
- nelem, elsize, name, file, line);
+ nelem,
+ elsize,
+ name,
+ file,
+ line);
}
}
return p;
gmx::AlignedAllocationPolicy::free(ptr);
}
-void set_over_alloc_dd(gmx_bool set)
+void set_over_alloc_dd(bool set)
{
- tMPI_Thread_mutex_lock(&g_over_alloc_mutex);
+ std::lock_guard<std::mutex> lock(g_overAllocMutex);
/* we just make sure that we don't set this at the same time.
We don't worry too much about reading this rarely-set variable */
g_bOverAllocDD = set;
- tMPI_Thread_mutex_unlock(&g_over_alloc_mutex);
}
int over_alloc_dd(int n)
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2018,2019,2020, by the GROMACS development team.
+ * Copyright (c) 2021, 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.
* This is mdrun-specific, so it might be better to put this and
* over_alloc_dd() much higher up.
*/
-void set_over_alloc_dd(gmx_bool set);
+void set_over_alloc_dd(bool set);
/*! \brief
* Returns new allocation count for domain decomposition allocations.
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2016,2018,2019,2021, 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.
int intFromString(const char* str)
{
- errno = 0;
- char* endptr;
- const long int value = std::strtol(str, &endptr, 10);
+ errno = 0;
+ char* endptr = nullptr;
+ const long int value = std::strtol(str, &endptr, 10);
if (errno == ERANGE || value < std::numeric_limits<int>::min()
|| value > std::numeric_limits<int>::max())
{
int64_t int64FromString(const char* str)
{
- errno = 0;
- char* endptr;
- const int64_t value = str_to_int64_t(str, &endptr);
+ errno = 0;
+ char* endptr = nullptr;
+ const int64_t value = str_to_int64_t(str, &endptr);
if (errno == ERANGE)
{
GMX_THROW(InvalidInputError("Invalid value: '" + std::string(str)
float floatFromString(const char* str)
{
- errno = 0;
- char* endptr;
- const double value = std::strtod(str, &endptr);
+ errno = 0;
+ char* endptr = nullptr;
+ const double value = std::strtod(str, &endptr);
if (errno == ERANGE || value < -std::numeric_limits<float>::max()
|| value > std::numeric_limits<float>::max())
{
double doubleFromString(const char* str)
{
- errno = 0;
- char* endptr;
- const double value = std::strtod(str, &endptr);
+ errno = 0;
+ char* endptr = nullptr;
+ const double value = std::strtod(str, &endptr);
if (errno == ERANGE)
{
GMX_THROW(InvalidInputError("Invalid value: '" + std::string(str)
// will throw if any conversion from string to value fails
std::array<ValueType, NumExpectedValues> valuesAsArray;
- std::transform(std::begin(valuesAsStrings), std::end(valuesAsStrings), std::begin(valuesAsArray),
+ std::transform(std::begin(valuesAsStrings),
+ std::end(valuesAsStrings),
+ std::begin(valuesAsArray),
[](const std::string& split) { return fromString<ValueType>(split); });
return { valuesAsArray };
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
gmx_bool get_a_line(FILE* fp, char line[], int n)
{
- char* line0;
- char* dum;
+ char* line0 = nullptr;
+ char* dum = nullptr;
snew(line0, n + 1);
else if (static_cast<int>(std::strlen(line0)) == n)
{
fprintf(stderr,
- "Warning: line length exceeds buffer length (%d), data might be corrupted\n", n);
+ "Warning: line length exceeds buffer length (%d), data might be corrupted\n",
+ n);
line0[n - 1] = '\0';
}
else
int search_str(int nstr, char** str, char* key)
{
- int i;
-
/* Linear search */
- for (i = 0; (i < nstr); i++)
+ for (int i = 0; (i < nstr); i++)
{
if (gmx_strcasecmp(str[i], key) == 0)
{
static int fget_lines(FILE* in, const char* db, char*** strings)
{
- char** ptr;
+ char** ptr = nullptr;
char buf[STRLEN];
- int i, nstr;
- char* pret;
+ int nstr = 0;
- pret = fgets(buf, STRLEN, in);
+ char* pret = fgets(buf, STRLEN, in);
if (pret == nullptr || sscanf(buf, "%d", &nstr) != 1)
{
gmx_warning("File is empty");
return 0;
}
snew(ptr, nstr);
- for (i = 0; (i < nstr); i++)
+ for (int i = 0; (i < nstr); i++)
{
if (fgets2(buf, STRLEN, in) == nullptr)
{
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2011-2018, The GROMACS development team.
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
std::vector<std::string> splitDelimitedString(const std::string& str, char delim)
{
std::vector<std::string> result;
- size_t currPos = 0;
- const size_t len = str.length();
+ const size_t len = str.length();
if (len > 0)
{
- size_t nextDelim;
+ size_t nextDelim = 0;
+ size_t currPos = 0;
do
{
nextDelim = str.find(delim, currPos);
}
comparisonEnd = source.begin() + maxLengthOfComparison;
}
- return std::equal(source.begin(), comparisonEnd, target.begin(),
- [](const char& s, const char& t) { return std::tolower(s) == std::tolower(t); });
+ return std::equal(source.begin(), comparisonEnd, target.begin(), [](const char& s, const char& t) {
+ return std::tolower(s) == std::tolower(t);
+ });
}
/********************************************************************
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2020, by the GROMACS development team, led by
+ * Copyright (c) 2020,2021, 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.
/** \internal \brief Helper function to select appropriate template based on runtime values.
*
- * Can only use enums for template parameters.
+ * Can use enums or booleans for template parameters.
* These enums must have a member \c Count indicating the total number of valid values.
*
* Example usage:
Count = 2
};
- template<Options p1, Options p2>
+ template<bool p0, Options p1, Options p2>
bool foo(int i);
- bool bar(Options p1, Options p2, int i) {
+ bool bar(bool p0, Options p1, Options p2, int i) {
return dispatchTemplatedFunction(
- [=](auto p1, auto p2) {
- return foo<p1, p2>(i);
+ [=](auto p0, auto p1, auto p2) {
+ return foo<p0, p1, p2>(i);
},
- p1, p2);
+ p0, p1, p2);
}
* \endcode
*/
es...);
}
+template<class Function, class... Enums>
+auto dispatchTemplatedFunction(Function&& f, bool e, Enums... es)
+{
+ return dispatchTemplatedFunction(
+ [&](auto... es_) {
+ return compat::mp_with_index<2>(size_t(e), [&](auto e_) {
+ return std::forward<Function>(f)(std::bool_constant<static_cast<bool>(e_)>(), es_...);
+ });
+ },
+ es...);
+}
+
} // namespace gmx
#endif // GMX_UTILITY_TEMPLATE_MP_H
# This file is part of the GROMACS molecular simulation package.
#
# Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team.
-# Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
+# Copyright (c) 2017,2018,2019,2020,2021, 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.
listoflists.cpp
logger.cpp
mdmodulenotification-impl.cpp
- mutex.cpp
path.cpp
physicalnodecommunicator.cpp
range.cpp
textwriter.cpp
typetraits.cpp
)
+# TODO: Explicitly link specific modules.
+target_link_libraries(utility-test PRIVATE legacy_modules)
gmx_add_mpi_unit_test(UtilityMpiUnitTests utility-mpi-test 4
CPP_SOURCE_FILES
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2014,2018,2019,2021, 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.
BITMASK_TEST_P(SetAndClear) //NOLINT(misc-definitions-in-headers)
{
- gmx_bitmask_t m;
+ gmx_bitmask_t m; //NOLINT(cppcoreguidelines-init-variables)
int i = GetParam();
bitmask_clear(&m);
EXPECT_TRUE(bitmask_is_zero(m));
BITMASK_TEST_P(InitBit) //NOLINT(misc-definitions-in-headers)
{
- gmx_bitmask_t m1, m2;
+ gmx_bitmask_t m1, m2; //NOLINT(cppcoreguidelines-init-variables)
int i = GetParam();
bitmask_init_bit(&m1, i);
bitmask_clear(&m2);
BITMASK_TEST_P(InitLowBits) //NOLINT(misc-definitions-in-headers)
{
- gmx_bitmask_t m;
+ gmx_bitmask_t m; //NOLINT(cppcoreguidelines-init-variables)
int i = GetParam();
bitmask_init_low_bits(&m, i);
for (int j = 0; j < BITMASK_SIZE; j++)
BITMASK_TEST_P(Disjoint) //NOLINT(misc-definitions-in-headers)
{
- gmx_bitmask_t m1, m2;
+ gmx_bitmask_t m1, m2; //NOLINT(cppcoreguidelines-init-variables)
int i = GetParam();
bitmask_init_bit(&m1, i);
bitmask_init_bit(&m2, i);
BITMASK_TEST_P(Union) //NOLINT(misc-definitions-in-headers)
{
- gmx_bitmask_t m1, m2;
+ gmx_bitmask_t m1, m2; //NOLINT(cppcoreguidelines-init-variables)
int i = GetParam();
int j = (i + BITMASK_SIZE / 2) % BITMASK_SIZE;
bitmask_init_bit(&m1, i);
}
BITMASK_TEST_P(ToHex) //NOLINT(misc-definitions-in-headers)
{
- gmx_bitmask_t m;
+ gmx_bitmask_t m; //NOLINT(cppcoreguidelines-init-variables)
bitmask_clear(&m);
bitmask_set_bit(&m, BITMASK_SIZE - 1);
EXPECT_EQ(to_hex_string(m), "8" + std::string(BITMASK_SIZE / 4 - 1, '0'));
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
}
// Incrementing iterators works
- auto x = std::begin(fooStrings);
+ const auto* x = std::begin(fooStrings);
EXPECT_EQ(*x, "Bar");
++x;
EXPECT_EQ(*x, "Baz");
auto buffer = serializerWithSwap.finishAndGetBuffer();
- InMemoryDeserializer deserializerWithSwap(buffer, std::is_same_v<real, double>,
- EndianSwapBehavior::Swap);
+ InMemoryDeserializer deserializerWithSwap(
+ buffer, std::is_same_v<real, double>, EndianSwapBehavior::Swap);
SerializerValues deserialisedValues = deserialize(&deserializerWithSwap);
auto buffer = serializer.finishAndGetBuffer();
- InMemoryDeserializer deserializerWithSwap(buffer, std::is_same_v<real, double>,
- EndianSwapBehavior::Swap);
+ InMemoryDeserializer deserializerWithSwap(
+ buffer, std::is_same_v<real, double>, EndianSwapBehavior::Swap);
SerializerValues deserialisedValues = deserialize(&deserializerWithSwap);
checkSerializerValuesforEquality(endianessSwappedValues_, deserialisedValues);
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2017,2019, by the GROMACS development team, led by
+ * Copyright (c) 2016,2017,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.
gmx::test::TestReferenceChecker checker(data.rootChecker());
checker.checkKeyValueTreeObject(input, "Input");
auto mappedPaths = transform.mappedPaths();
- checker.checkSequence(mappedPaths.begin(), mappedPaths.end(), "MappedPaths",
- &TreeValueTransformTest::checkMappedPath);
+ checker.checkSequence(
+ mappedPaths.begin(), mappedPaths.end(), "MappedPaths", &TreeValueTransformTest::checkMappedPath);
checker.checkKeyValueTreeObject(object, "Tree");
checkBackMapping(&checker, object, result.backMapping());
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
public:
void callback(EventA /*a*/) { notifiedEventA_ = true; }
- bool notifiedEventA() { return notifiedEventA_; }
+ bool notifiedEventA() const { return notifiedEventA_; }
private:
bool notifiedEventA_ = false;
public:
void callback(EventB* /* bPointer */) { notifiedEventB_ = true; }
- bool notifiedEventB() { return notifiedEventB_; }
+ bool notifiedEventB() const { return notifiedEventB_; }
private:
bool notifiedEventB_ = false;
void callback(EventA /* a */) { notifiedEventA_ = true; }
- bool notifiedEventB() { return notifiedEventB_; }
- bool notifiedEventA() { return notifiedEventA_; }
+ bool notifiedEventB() const { return notifiedEventB_; }
+ bool notifiedEventA() const { return notifiedEventA_; }
private:
bool notifiedEventB_ = false;
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
- * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
- * and including many others, as listed in the AUTHORS file in the
- * top-level source directory and at http://www.gromacs.org.
- *
- * 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 gmx::Mutex
- *
- * These tests ensure that basic mutual-exclusion properties hold.
- * Note that no testing can prove there isn't a bug, but if one
- * exists, then these tests might expose one.
- *
- * In particular, try_lock can be implemented differently on different
- * platforms, or with different default mutex types, so we should
- * check that the behaviour continues to conform with the thread-MPI
- * documentation.
- *
- * \author Mark Abraham <mark.j.abraham@gmail.com>
- * \ingroup module_utility
- */
-
-#include "gmxpre.h"
-
-#include "gromacs/utility/mutex.h"
-
-#include "config.h"
-
-#include <future>
-
-#include <gtest/gtest.h>
-
-
-namespace gmx
-{
-namespace test
-{
-namespace
-{
-
-//! Convenience definition.
-using Lock = gmx::lock_guard<Mutex>;
-
-TEST(MutexBasicTest, CanBeMade)
-{
- Mutex m;
-}
-
-TEST(MutexBasicTest, CanBeLocked)
-{
- Mutex m;
- ASSERT_NO_THROW(m.lock());
- m.unlock();
-}
-
-TEST(MutexBasicTest, CanBeTryLocked)
-{
- Mutex m;
- ASSERT_TRUE(m.try_lock());
- m.unlock();
-}
-
-TEST(MutexBasicTest, CanBeUsedInLockGuard)
-{
- Mutex m;
- Lock g(m);
-}
-
-//! A shared value for a mutex to protect
-int g_sharedValue;
-//! A mutex to protect a shared value
-Mutex g_sharedValueMutex;
-
-//! Function type for asynchronous tasks.
-using TaskType = std::function<int(void)>;
-
-//! A task that just does work.
-int updateSharedValue()
-{
- return ++g_sharedValue;
-}
-
-//! A task that does work after it gets the mutex.
-int updateSharedValueWithLock()
-{
- Lock guard(g_sharedValueMutex);
- return updateSharedValue();
-}
-
-//! A task that does work only if it can get the mutex immediately.
-int updateSharedValueWithTryLock()
-{
- // Special return value to signal when work was not done because
- // the lock was not acquired.
- int result = -1;
- if (g_sharedValueMutex.try_lock())
- {
- result = updateSharedValue();
- g_sharedValueMutex.unlock();
- }
- return result;
-}
-
-/*! \brief Parameterized test fixture.
- *
- * Checks that different launch policies work. In further tests of
- * mutual exclusion, we need to specify std::thread::async, to require
- * that a thread actually launched. The default policy permits the
- * std:: implementation to avoid launching a thread, and at least the
- * behaviour of thread-MPI try_lock also varies with the threading
- * implementation underlying it. */
-class DifferentTasksTest : public ::testing::TestWithParam<TaskType>
-{
-public:
- DifferentTasksTest() { g_sharedValue = 0; }
- //! Check the results
- void checkResults()
- {
- int result = 0;
- EXPECT_NO_THROW(result = futureResult_.get()) << "Future should not contain an exception";
- EXPECT_EQ(1, result) << "Task should have run";
- EXPECT_EQ(1, g_sharedValue) << "Shared value should be updated";
- }
- //! Contains the result the task returns.
- std::future<int> futureResult_;
-};
-
-TEST_P(DifferentTasksTest, StdAsyncWorksWithDefaultPolicy)
-{
- auto task = GetParam();
- EXPECT_NO_THROW(futureResult_ = std::async(task)) << "Async should succeed";
- checkResults();
-}
-
-TEST_P(DifferentTasksTest, StdAsyncWorksWithAsyncLaunchPolicy)
-{
- auto task = GetParam();
- EXPECT_NO_THROW(futureResult_ = std::async(std::launch::async, task)) << "Async should succeed";
- checkResults();
-}
-
-TEST_P(DifferentTasksTest, StdAsyncWorksWithDeferredLaunchPolicy)
-{
- auto task = GetParam();
- EXPECT_NO_THROW(futureResult_ = std::async(std::launch::deferred, task))
- << "Async should succeed";
- checkResults();
-}
-
-// Test that the different launch policies work with the different tasks
-INSTANTIATE_TEST_CASE_P(WithAndWithoutMutex,
- DifferentTasksTest,
- ::testing::Values(updateSharedValue,
- updateSharedValueWithLock,
- updateSharedValueWithTryLock));
-
-TEST(MutexTaskTest, MutualExclusionWorksWithLock)
-{
- g_sharedValue = 0;
- std::future<int> result;
- {
- // Hold the mutex, launch a lock attempt on another
- // thread, check that the shared value isn't changed, then
- // release the mutex by leaving the scope, after which the
- // other thread's lock can get the mutex.
- Lock guard(g_sharedValueMutex);
- result = std::async(std::launch::async, updateSharedValueWithLock);
- EXPECT_EQ(0, g_sharedValue) << "Task should not have run yet";
- }
- EXPECT_EQ(1, result.get()) << "Task should have run";
- EXPECT_EQ(1, g_sharedValue) << "Shared value should be updated";
-}
-
-TEST(MutexTaskTest, MutualExclusionWorksWithTryLockOnOtherThread)
-{
- g_sharedValue = 0;
- {
- // Hold the mutex, launch a try_lock attempt on another
- // thread, check that the shared value isn't changed, then
- // make sure the try_lock attempt has returned, double check
- // that the shared value isn't changed, and release the mutex
- // by leaving the scope.
- Lock guard(g_sharedValueMutex);
- auto result = std::async(std::launch::async, updateSharedValueWithTryLock);
- EXPECT_EQ(0, g_sharedValue) << "Data race detected";
- EXPECT_EQ(-1, result.get()) << "The try_lock should fail";
- EXPECT_EQ(0, g_sharedValue) << "Task should not have run";
- }
- EXPECT_EQ(0, g_sharedValue) << "Mutex release can't affect the protected value";
-}
-
-TEST(MutexTaskTest, MutualExclusionWorksWithTryLockOnSameThread)
-{
- g_sharedValue = 0;
- int finalSharedValue = GMX_NATIVE_WINDOWS ? 1 : 0;
- {
- // Hold the mutex and launch a try_lock attempt on this
- // thread. Behaviour then varies with the implementation
- // underlying thread-MPI.
- Lock guard(g_sharedValueMutex);
- int result = updateSharedValueWithTryLock();
- if (GMX_NATIVE_WINDOWS)
- {
- EXPECT_EQ(1, result) << "The try_lock should succeed";
- EXPECT_EQ(finalSharedValue, g_sharedValue) << "Task should have run";
- }
- else
- {
- EXPECT_EQ(-1, result) << "The try_lock should fail";
- EXPECT_EQ(finalSharedValue, g_sharedValue) << "Task should not have run";
- }
- }
- EXPECT_EQ(finalSharedValue, g_sharedValue) << "Mutex release can't affect the protected value";
-}
-
-} // namespace
-} // namespace test
-} // namespace gmx
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
{
gmx::test::TestReferenceData data;
gmx::test::TestReferenceChecker rootChecker(data.rootChecker());
- for (const std::string& input :
- { "", "md.log", "md", "/tmp/absolute.txt", "simpledir/traj.tng", "simpledir/traj",
- "windowsdir\\traj.tng", "complex.dir/traj.tng", "complex.dir/traj",
- "nested/dir/conf.pdb", "/tmp/absolutedir/conf.pdb" })
+ for (const std::string& input : { "",
+ "md.log",
+ "md",
+ "/tmp/absolute.txt",
+ "simpledir/traj.tng",
+ "simpledir/traj",
+ "windowsdir\\traj.tng",
+ "complex.dir/traj.tng",
+ "complex.dir/traj",
+ "nested/dir/conf.pdb",
+ "/tmp/absolutedir/conf.pdb" })
{
SCOPED_TRACE(std::string("for input '") + input + "'");
auto checker = rootChecker.checkCompound("PathToTest", input);
{
const char* const words[] = { "The", "quick", "brown", "fox" };
EXPECT_EQ("The .quick .brown .fox ",
- gmx::formatAndJoin(gmx::ArrayRef<const char* const>(words), ".",
- gmx::StringFormatter("%-10s")));
+ gmx::formatAndJoin(
+ gmx::ArrayRef<const char* const>(words), ".", gmx::StringFormatter("%-10s")));
const int values[] = { 0, 1, 4 };
EXPECT_EQ("0,1,4",
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2020, by the GROMACS development team, led by
+ * Copyright (c) 2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
return 2 * int(i) + int(j) + k;
}
-TEST(TemplateMPTest, DispatchTemplatedFunction)
+template<bool doDoubling, Options i, Options j>
+static int testBoolEnumTwoIPlusJPlusK(int k)
+{
+ return (doDoubling ? 2 : 1) * int(i) + int(j) + k;
+}
+
+template<bool doDoubling>
+static int testBoolDoubleOrNot(int k)
+{
+ return (doDoubling ? 2 : 1) * k;
+}
+
+
+TEST(TemplateMPTest, DispatchTemplatedFunctionEnum)
+{
+ int five = 5;
+ int two1plus2plus5 = dispatchTemplatedFunction(
+ [=](auto p1, auto p2) { return testEnumTwoIPlusJPlusK<p1, p2>(five); }, Options::Op1, Options::Op2);
+ EXPECT_EQ(two1plus2plus5, 9);
+}
+
+TEST(TemplateMPTest, DispatchTemplatedFunctionBool)
+{
+ int five = 5;
+ int double5 = dispatchTemplatedFunction([=](auto p1) { return testBoolDoubleOrNot<p1>(five); }, true);
+ EXPECT_EQ(double5, 10);
+ int just5 = dispatchTemplatedFunction([=](auto p1) { return testBoolDoubleOrNot<p1>(five); }, false);
+ EXPECT_EQ(just5, 5);
+}
+
+TEST(TemplateMPTest, DispatchTemplatedFunctionEnumBool)
{
int five = 5;
int two1plus2plus5 = dispatchTemplatedFunction(
- [=](auto p1, auto p2) { return testEnumTwoIPlusJPlusK<p1, p2>(five); }, Options::Op1,
+ [=](auto p1, auto p2, auto p3) { return testBoolEnumTwoIPlusJPlusK<p1, p2, p3>(five); },
+ true,
+ Options::Op1,
Options::Op2);
EXPECT_EQ(two1plus2plus5, 9);
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2017,2019, by the GROMACS development team, led by
+ * Copyright (c) 2015,2017,2019,2021, 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.
#ifndef GMX_UTILITY_TEXTREADER_H
#define GMX_UTILITY_TEXTREADER_H
+#include <memory>
#include <string>
-#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/textstream.h"
namespace gmx
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2015,2018,2019,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <cstdio>
+#include <memory>
#include <string>
-#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/textstream.h"
namespace gmx
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace gmx
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2017,2018 by the GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
int pr_indent(FILE* fp, int n)
{
- int i;
-
- for (i = 0; i < n; i++)
+ for (int i = 0; i < n; i++)
{
fprintf(fp, " ");
}
void pr_reals(FILE* fp, int indent, const char* title, const real* vec, int n)
{
- int i;
-
if (available(fp, vec, indent, title))
{
pr_indent(fp, indent);
fprintf(fp, "%s:\t", title);
- for (i = 0; i < n; i++)
+ for (int i = 0; i < n; i++)
{
fprintf(fp, " %10g", vec[i]);
}
void pr_doubles(FILE* fp, int indent, const char* title, const double* vec, int n)
{
- int i;
-
if (available(fp, vec, indent, title))
{
pr_indent(fp, indent);
fprintf(fp, "%s:\t", title);
- for (i = 0; i < n; i++)
+ for (int i = 0; i < n; i++)
{
fprintf(fp, " %10g", vec[i]);
}
void pr_reals_of_dim(FILE* fp, int indent, const char* title, const real* vec, int n, int dim)
{
- int i, j;
const char* fshort = "%12.5e";
const char* flong = "%15.8e";
- const char* format;
-
- if (getenv("GMX_PRINT_LONGFORMAT") != nullptr)
- {
- format = flong;
- }
- else
- {
- format = fshort;
- }
+ const char* format = (getenv("GMX_PRINT_LONGFORMAT") != nullptr) ? flong : fshort;
if (available(fp, vec, indent, title))
{
indent = pr_title_nxn(fp, indent, title, n, dim);
- for (i = 0; i < n; i++)
+ for (int i = 0; i < n; i++)
{
pr_indent(fp, indent);
fprintf(fp, "%s[%5d]={", title, i);
- for (j = 0; j < dim; j++)
+ for (int j = 0; j < dim; j++)
{
if (j != 0)
{
void pr_strings(FILE* fp, int indent, const char* title, char*** nm, int n, gmx_bool bShowNumbers)
{
- int i;
-
if (available(fp, nm, indent, title))
{
indent = pr_title_n(fp, indent, title, n);
- for (i = 0; i < n; i++)
+ for (int i = 0; i < n; i++)
{
pr_indent(fp, indent);
fprintf(fp, "%s[%d]={name=\"%s\"}\n", title, bShowNumbers ? i : -1, *(nm[i]));
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2014,2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
# define _GNU_SOURCE 1
#endif
-/* Some C++(?) compilers require these to be defined to get the integer limits
- * and format specifier macros from stdint.h and inttypes.h, respectively.
- * The macros are in C99 and C++11, but not in C++98...
- * As with _GNU_SOURCE, these need to be defined before these headers get first
- * included. Unlike _GNU_SOURCE, these headers are included indirectly in most
- * header and source files (even though the macros are not used that often), so
- * there is no easy alternative to defining them here, either.
- * If someone happens to use such a compiler to compile against the installed
- * Gromacs headers, they need for now take care to define the macros themselves
- * (as there is no way Gromacs can do that consistently).
- */
-#define __STDC_LIMIT_MACROS
-#define __STDC_FORMAT_MACROS
-
#if GMX_FAHCORE
# define FULLINDIRECT 1
# define USE_FAH_XDR 1
# This file is part of the GROMACS molecular simulation package.
#
# Copyright (c) 2010,2011,2012,2013,2014 by the GROMACS development team.
-# Copyright (c) 2015,2016,2018,2019,2020, by the GROMACS development team, led by
+# Copyright (c) 2015,2016,2018,2019,2020,2021, by the GROMACS development team, led by
# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
# and including many others, as listed in the AUTHORS file in the
# top-level source directory and at http://www.gromacs.org.
target_include_directories(mdrun_objlib SYSTEM BEFORE PRIVATE ${PROJECT_SOURCE_DIR}/src/external/thread_mpi/include)
# Should be possible to remove this when resolving #3290
target_include_directories(mdrun_objlib SYSTEM PRIVATE ${PROJECT_SOURCE_DIR}/src/external)
+target_link_libraries(mdrun_objlib PRIVATE common)
+target_link_libraries(mdrun_objlib PRIVATE legacy_api)
+# TODO: Explicitly link specific modules.
+target_link_libraries(mdrun_objlib PRIVATE legacy_modules)
if(GMX_FAHCORE)
# The lack of a real source file here alongside the object library
# may break some generators, according to CMake documentation. If
# so, we can consider adding some dummy file to make it work.
add_library(fahcore $<TARGET_OBJECTS:mdrun_objlib>)
- target_link_libraries(fahcore PRIVATE ${GMX_COMMON_LIBRARIES})
-elseif(GMX_BUILD_MDRUN_ONLY)
- message(STATUS "The mdrun-only build is deprecated")
- add_executable(mdrun $<TARGET_OBJECTS:mdrun_objlib> mdrun_main.cpp)
- gmx_target_compile_options(mdrun)
- target_include_directories(mdrun SYSTEM BEFORE PRIVATE ${PROJECT_SOURCE_DIR}/src/external/thread_mpi/include)
- target_compile_definitions(mdrun PRIVATE HAVE_CONFIG_H)
- target_link_libraries(mdrun libgromacs
- ${GMX_COMMON_LIBRARIES}
- ${GMX_EXE_LINKER_FLAGS})
- set(BINARY_NAME "mdrun${GMX_BINARY_SUFFIX}")
- set_target_properties(mdrun PROPERTIES
- OUTPUT_NAME "${BINARY_NAME}")
- install(TARGETS mdrun DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT mdrun)
- file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/gmx-completion-${BINARY_NAME}.bash
- "complete -o nospace -F _gmx_mdrun_compl ${BINARY_NAME}")
- install(FILES ${CMAKE_CURRENT_BINARY_DIR}/gmx-completion-${BINARY_NAME}.bash
- DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime)
+ target_link_libraries(fahcore PRIVATE ${GMX_COMMON_LIBRARIES} legacy_api)
else()
file(GLOB GMX_MAIN_SOURCES gmx.cpp legacymodules.cpp)
if(GMX_X11)
gmx_target_compile_options(view_objlib)
target_compile_definitions(view_objlib PRIVATE HAVE_CONFIG_H)
target_include_directories(view_objlib SYSTEM PRIVATE ${PROJECT_SOURCE_DIR}/src/external)
+ target_link_libraries(view_objlib PRIVATE common legacy_api)
+ # TODO: Explicitly link specific modules.
+ target_link_libraries(view_objlib PRIVATE legacy_modules)
add_library(gmx_objlib OBJECT ${GMX_MAIN_SOURCES})
+ target_link_libraries(gmx_objlib PRIVATE common legacy_api)
+ # TODO: Explicitly link specific modules.
+ target_link_libraries(gmx_objlib PRIVATE legacy_modules)
target_include_directories(gmx_objlib SYSTEM PRIVATE ${PROJECT_SOURCE_DIR}/src/external)
target_include_directories(gmx_objlib SYSTEM BEFORE PRIVATE ${PROJECT_SOURCE_DIR}/src/external/thread_mpi/include)
add_executable(gmx
add_executable(Gromacs::gmx ALIAS gmx)
gmx_target_compile_options(gmx)
target_compile_definitions(gmx PRIVATE HAVE_CONFIG_H)
- target_link_libraries(gmx libgromacs
- ${GMX_COMMON_LIBRARIES}
- ${GMX_EXE_LINKER_FLAGS})
+ target_link_libraries(gmx PRIVATE
+ common
+ libgromacs
+ ${GMX_COMMON_LIBRARIES}
+ ${GMX_EXE_LINKER_FLAGS})
if(GMX_X11)
target_link_libraries(gmx ${X11_LIBRARIES})
endif()
gmx::ICommandLineOptionsModule::registerModuleFactory(
manager, gmx::DumpInfo::name, gmx::DumpInfo::shortDescription, &gmx::DumpInfo::create);
registerModule(manager, &gmx_grompp, "grompp", "Make a run input file");
- gmx::ICommandLineOptionsModule::registerModuleFactory(manager, gmx::ConvertTprInfo::name,
+ gmx::ICommandLineOptionsModule::registerModuleFactory(manager,
+ gmx::ConvertTprInfo::name,
gmx::ConvertTprInfo::shortDescription,
&gmx::ConvertTprInfo::create);
registerObsoleteTool(manager, "tpbconv");
registerModule(manager, &gmx_x2top, "x2top", "Generate a primitive topology from coordinates");
registerModuleNoNice(
- manager, &gmx::gmx_mdrun, "mdrun",
+ manager,
+ &gmx::gmx_mdrun,
+ "mdrun",
"Perform a simulation, do a normal mode analysis or an energy minimization");
- gmx::ICommandLineOptionsModule::registerModuleFactory(
- manager, gmx::NonbondedBenchmarkInfo::name,
- gmx::NonbondedBenchmarkInfo::shortDescription, &gmx::NonbondedBenchmarkInfo::create);
+ gmx::ICommandLineOptionsModule::registerModuleFactory(manager,
+ gmx::NonbondedBenchmarkInfo::name,
+ gmx::NonbondedBenchmarkInfo::shortDescription,
+ &gmx::NonbondedBenchmarkInfo::create);
- gmx::ICommandLineOptionsModule::registerModuleFactory(manager, gmx::InsertMoleculesInfo::name(),
+ gmx::ICommandLineOptionsModule::registerModuleFactory(manager,
+ gmx::InsertMoleculesInfo::name(),
gmx::InsertMoleculesInfo::shortDescription(),
&gmx::InsertMoleculesInfo::create);
- gmx::ICommandLineOptionsModule::registerModuleFactory(manager, gmx::ReportMethodsInfo::name,
+ gmx::ICommandLineOptionsModule::registerModuleFactory(manager,
+ gmx::ReportMethodsInfo::name,
gmx::ReportMethodsInfo::shortDescription,
&gmx::ReportMethodsInfo::create);
- gmx::ICommandLineOptionsModule::registerModuleFactory(manager, gmx::pdb2gmxInfo::name,
- gmx::pdb2gmxInfo::shortDescription,
- &gmx::pdb2gmxInfo::create);
+ gmx::ICommandLineOptionsModule::registerModuleFactory(
+ manager, gmx::pdb2gmxInfo::name, gmx::pdb2gmxInfo::shortDescription, &gmx::pdb2gmxInfo::create);
// Modules from gmx_ana.h.
- registerModule(manager, &gmx_do_dssp, "do_dssp",
+ registerModule(manager,
+ &gmx_do_dssp,
+ "do_dssp",
"Assign secondary structure and calculate solvent accessible surface area");
registerModule(manager, &gmx_editconf, "editconf", "Convert and manipulates structure files");
registerModule(manager, &gmx_eneconv, "eneconv", "Convert energy files");
registerModule(manager, &gmx_solvate, "solvate", "Solvate a system");
registerObsoleteTool(manager, "genbox");
- registerModule(manager, &gmx_genconf, "genconf",
- "Multiply a conformation in 'random' orientations");
- registerModule(manager, &gmx_genion, "genion",
+ registerModule(
+ manager, &gmx_genconf, "genconf", "Multiply a conformation in 'random' orientations");
+ registerModule(manager,
+ &gmx_genion,
+ "genion",
"Generate monoatomic ions on energetically favorable positions");
- registerModule(manager, &gmx_genrestr, "genrestr",
+ registerModule(manager,
+ &gmx_genrestr,
+ "genrestr",
"Generate position restraints or distance restraints for index groups");
- registerModule(manager, &gmx_make_edi, "make_edi",
+ registerModule(manager,
+ &gmx_make_edi,
+ "make_edi",
"Generate input files for essential dynamics sampling");
registerModule(manager, &gmx_make_ndx, "make_ndx", "Make index files");
registerModule(manager, &gmx_mk_angndx, "mk_angndx", "Generate index files for 'gmx angle'");
registerModule(manager, &gmx_trjcat, "trjcat", "Concatenate trajectory files");
registerModule(manager, &gmx_trjconv, "trjconv", "Convert and manipulates trajectory files");
- registerModule(manager, &gmx_trjorder, "trjorder",
+ registerModule(manager,
+ &gmx_trjorder,
+ "trjorder",
"Order molecules according to their distance to a group");
- registerModule(manager, &gmx_xpm2ps, "xpm2ps",
- "Convert XPM (XPixelMap) matrices to postscript or XPM");
+ registerModule(
+ manager, &gmx_xpm2ps, "xpm2ps", "Convert XPM (XPixelMap) matrices to postscript or XPM");
registerModule(manager, &gmx_anaeig, "anaeig", "Analyze eigenvectors/normal modes");
registerModule(manager, &gmx_analyze, "analyze", "Analyze data sets");
- registerModule(manager, &gmx_g_angle, "angle",
+ registerModule(manager,
+ &gmx_g_angle,
+ "angle",
"Calculate distributions and correlations for angles and dihedrals");
- registerModule(manager, &gmx_awh, "awh",
- "Extract data from an accelerated weight histogram (AWH) run");
- registerModule(manager, &gmx_bar, "bar",
+ registerModule(
+ manager, &gmx_awh, "awh", "Extract data from an accelerated weight histogram (AWH) run");
+ registerModule(manager,
+ &gmx_bar,
+ "bar",
"Calculate free energy difference estimates through Bennett's acceptance ratio");
registerObsoleteTool(manager, "bond");
registerObsoleteTool(manager, "dist");
registerObsoleteTool(manager, "sgangle");
registerModule(manager, &gmx_bundle, "bundle", "Analyze bundles of axes, e.g., helices");
- registerModule(manager, &gmx_chi, "chi",
+ registerModule(manager,
+ &gmx_chi,
+ "chi",
"Calculate everything you want to know about chi and other dihedrals");
registerModule(manager, &gmx_cluster, "cluster", "Cluster structures");
- registerModule(manager, &gmx_clustsize, "clustsize",
- "Calculate size distributions of atomic clusters");
+ registerModule(
+ manager, &gmx_clustsize, "clustsize", "Calculate size distributions of atomic clusters");
registerModule(manager, &gmx_confrms, "confrms", "Fit two structures and calculates the RMSD");
registerModule(manager, &gmx_covar, "covar", "Calculate and diagonalize the covariance matrix");
- registerModule(manager, &gmx_current, "current",
+ registerModule(manager,
+ &gmx_current,
+ "current",
"Calculate dielectric constants and current autocorrelation function");
registerModule(manager, &gmx_density, "density", "Calculate the density of the system");
- registerModule(manager, &gmx_densmap, "densmap",
- "Calculate 2D planar or axial-radial density maps");
+ registerModule(
+ manager, &gmx_densmap, "densmap", "Calculate 2D planar or axial-radial density maps");
registerModule(manager, &gmx_densorder, "densorder", "Calculate surface fluctuations");
- registerModule(manager, &gmx_dielectric, "dielectric",
+ registerModule(manager,
+ &gmx_dielectric,
+ "dielectric",
"Calculate frequency dependent dielectric constants");
registerModule(manager, &gmx_dipoles, "dipoles", "Compute the total dipole plus fluctuations");
registerModule(manager, &gmx_disre, "disre", "Analyze distance restraints");
- registerModule(manager, &gmx_dos, "dos",
- "Analyze density of states and properties based on that");
+ registerModule(
+ manager, &gmx_dos, "dos", "Analyze density of states and properties based on that");
registerModule(manager, &gmx_dyecoupl, "dyecoupl", "Extract dye dynamics from trajectories");
registerModule(manager, &gmx_enemat, "enemat", "Extract an energy matrix from an energy file");
- registerModule(manager, &gmx_energy, "energy",
- "Writes energies to xvg files and display averages");
- registerModule(manager, &gmx_filter, "filter",
+ registerModule(
+ manager, &gmx_energy, "energy", "Writes energies to xvg files and display averages");
+ registerModule(manager,
+ &gmx_filter,
+ "filter",
"Frequency filter trajectories, useful for making smooth movies");
registerModule(manager, &gmx_gyrate, "gyrate", "Calculate the radius of gyration");
registerModule(manager, &gmx_h2order, "h2order", "Compute the orientation of water molecules");
registerModule(manager, &gmx_hbond, "hbond", "Compute and analyze hydrogen bonds");
registerModule(manager, &gmx_helix, "helix", "Calculate basic properties of alpha helices");
- registerModule(manager, &gmx_helixorient, "helixorient",
+ registerModule(manager,
+ &gmx_helixorient,
+ "helixorient",
"Calculate local pitch/bending/rotation/orientation inside helices");
- registerModule(manager, &gmx_hydorder, "hydorder",
+ registerModule(manager,
+ &gmx_hydorder,
+ "hydorder",
"Compute tetrahedrality parameters around a given atom");
registerModule(manager, &gmx_lie, "lie", "Estimate free energy from linear combinations");
registerModule(manager, &gmx_mdmat, "mdmat", "Calculate residue contact maps");
- registerModule(manager, &gmx_mindist, "mindist",
- "Calculate the minimum distance between two groups");
+ registerModule(
+ manager, &gmx_mindist, "mindist", "Calculate the minimum distance between two groups");
registerModule(manager, &gmx_msd, "msd", "Calculates mean square displacements");
registerModule(manager, &gmx_nmeig, "nmeig", "Diagonalize the Hessian for normal mode analysis");
- registerModule(manager, &gmx_nmens, "nmens",
+ registerModule(manager,
+ &gmx_nmens,
+ "nmens",
"Generate an ensemble of structures from the normal modes");
- registerModule(manager, &gmx_nmr, "nmr",
+ registerModule(manager,
+ &gmx_nmr,
+ "nmr",
"Analyze nuclear magnetic resonance properties from an energy file");
- registerModule(manager, &gmx_nmtraj, "nmtraj",
+ registerModule(manager,
+ &gmx_nmtraj,
+ "nmtraj",
"Generate a virtual oscillating trajectory from an eigenvector");
- registerModule(manager, &gmx_order, "order",
- "Compute the order parameter per atom for carbon tails");
- registerModule(manager, &gmx_pme_error, "pme_error",
+ registerModule(
+ manager, &gmx_order, "order", "Compute the order parameter per atom for carbon tails");
+ registerModule(manager,
+ &gmx_pme_error,
+ "pme_error",
"Estimate the error of using PME with a given input file");
registerModule(manager, &gmx_polystat, "polystat", "Calculate static properties of polymers");
- registerModule(manager, &gmx_potential, "potential",
+ registerModule(manager,
+ &gmx_potential,
+ "potential",
"Calculate the electrostatic potential across the box");
- registerModule(manager, &gmx_principal, "principal",
+ registerModule(manager,
+ &gmx_principal,
+ "principal",
"Calculate principal axes of inertia for a group of atoms");
registerModule(manager, &gmx_rama, "rama", "Compute Ramachandran plots");
- registerModule(manager, &gmx_rms, "rms",
+ registerModule(manager,
+ &gmx_rms,
+ "rms",
"Calculate RMSDs with a reference structure and RMSD matrices");
- registerModule(manager, &gmx_rmsdist, "rmsdist",
+ registerModule(manager,
+ &gmx_rmsdist,
+ "rmsdist",
"Calculate atom pair distances averaged with power -2, -3 or -6");
registerModule(manager, &gmx_rmsf, "rmsf", "Calculate atomic fluctuations");
- registerModule(manager, &gmx_rotacf, "rotacf",
+ registerModule(manager,
+ &gmx_rotacf,
+ "rotacf",
"Calculate the rotational correlation function for molecules");
- registerModule(manager, &gmx_rotmat, "rotmat",
+ registerModule(manager,
+ &gmx_rotmat,
+ "rotmat",
"Plot the rotation matrix for fitting to a reference structure");
registerModule(manager, &gmx_saltbr, "saltbr", "Compute salt bridges");
registerModule(manager, &gmx_sans, "sans", "Compute small angle neutron scattering spectra");
registerModule(manager, &gmx_saxs, "saxs", "Compute small angle X-ray scattering spectra");
- registerModule(manager, &gmx_sham, "sham",
- "Compute free energies or other histograms from histograms");
- registerModule(manager, &gmx_sigeps, "sigeps",
+ registerModule(
+ manager, &gmx_sham, "sham", "Compute free energies or other histograms from histograms");
+ registerModule(manager,
+ &gmx_sigeps,
+ "sigeps",
"Convert c6/12 or c6/cn combinations to and from sigma/epsilon");
registerModule(manager, &gmx_sorient, "sorient", "Analyze solvent orientation around solutes");
registerModule(manager, &gmx_spatial, "spatial", "Calculate the spatial distribution function");
- registerModule(manager, &gmx_spol, "spol",
+ registerModule(manager,
+ &gmx_spol,
+ "spol",
"Analyze solvent dipole orientation and polarization around solutes");
registerModule(manager, &gmx_tcaf, "tcaf", "Calculate viscosities of liquids");
- registerModule(manager, &gmx_traj, "traj",
+ registerModule(manager,
+ &gmx_traj,
+ "traj",
"Plot x, v, f, box, temperature and rotational energy from trajectories");
- registerModule(manager, &gmx_tune_pme, "tune_pme",
+ registerModule(manager,
+ &gmx_tune_pme,
+ "tune_pme",
"Time mdrun as a function of PME ranks to optimize settings");
- registerModule(manager, &gmx_vanhove, "vanhove",
+ registerModule(manager,
+ &gmx_vanhove,
+ "vanhove",
"Compute Van Hove displacement and correlation functions");
registerModule(manager, &gmx_velacc, "velacc", "Calculate velocity autocorrelation functions");
- registerModule(manager, &gmx_wham, "wham",
+ registerModule(manager,
+ &gmx_wham,
+ "wham",
"Perform weighted histogram analysis after umbrella sampling");
registerModule(manager, &gmx_wheel, "wheel", "Plot helical wheels");
registerModuleNoNice(manager, &gmx_view, "view", "View a trajectory on an X-Windows terminal");
StartingBehavior startingBehavior = StartingBehavior::NewSimulation;
LogFilePtr logFileGuard = nullptr;
gmx_multisim_t* ms = simulationContext.multiSimulation_.get();
- std::tie(startingBehavior, logFileGuard) = handleRestart(
- findIsSimulationMasterRank(ms, communicator), communicator, ms,
- options.mdrunOptions.appendingBehavior, ssize(options.filenames), options.filenames.data());
+ std::tie(startingBehavior, logFileGuard) = handleRestart(findIsSimulationMasterRank(ms, communicator),
+ communicator,
+ ms,
+ options.mdrunOptions.appendingBehavior,
+ ssize(options.filenames),
+ options.filenames.data());
/* The named components for the builder exposed here are descriptive of the
* state of mdrun at implementation and are not intended to be prescriptive
$<TARGET_OBJECTS:mdrun_objlib>
)
target_include_directories(mdrun_test_infrastructure SYSTEM PRIVATE ${PROJECT_SOURCE_DIR}/src/external)
+target_link_libraries(mdrun_test_infrastructure PUBLIC legacy_api)
# To avoid running into test timeouts, some end-to-end tests of mdrun
# functionality are split off. This can be rearranged in future as we
$<TARGET_OBJECTS:mdrun_objlib>
)
target_link_libraries(${exename} PRIVATE mdrun_test_infrastructure)
+# 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
// 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 TrajectoryTolerances trajectoryTolerances{
+ defaultRealTolerance(), defaultRealTolerance(), defaultRealTolerance(), defaultRealTolerance()
+ };
const auto mdpFieldValues =
prepareMdpFieldValues(simulationName, integrator, temperatureCoupling, pressureCoupling);
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(),
+ simulationName.c_str(),
+ integrator.c_str(),
+ temperatureCoupling.c_str(),
pressureCoupling.c_str()));
SCOPED_TRACE("End of trajectory sanity");
{
auto& energyValueInReference = referenceIt->second;
auto& energyValueInTest = testIt->second;
- EXPECT_REAL_EQ_TOL(energyValueInReference, energyValueInTest,
- energyTermsToCompare_.at(energyName));
+ EXPECT_REAL_EQ_TOL(
+ energyValueInReference, energyValueInTest, energyTermsToCompare_.at(energyName));
}
else
{
const EnergyTermsToCompare& energyTermsToCompare,
TestReferenceChecker* checker)
{
- checkEnergiesAgainstReferenceData(energyFilename, energyTermsToCompare, checker,
- MaxNumFrames::compareAllFrames());
+ checkEnergiesAgainstReferenceData(
+ energyFilename, energyTermsToCompare, checker, MaxNumFrames::compareAllFrames());
}
} // namespace test
fprintf(stdout,
"Test system '%s' cannot run with %d ranks.\n"
"The supported numbers are %s 1.\n",
- simulationName.c_str(), numRanksAvailable, numRanksAvailable == 1 ? ">" : "=");
+ simulationName.c_str(),
+ numRanksAvailable,
+ numRanksAvailable == 1 ? ">" : "=");
return;
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
fprintf(stdout,
"Test system '%s' cannot run with %d ranks.\n"
"The supported numbers are: %s\n",
- simulationName.c_str(), numRanksAvailable,
+ simulationName.c_str(),
+ numRanksAvailable,
reportNumbersOfPpRanksSupported(simulationName).c_str());
return;
}
SCOPED_TRACE(
formatString("Comparing normal and two-part run of simulation '%s' "
"with integrator '%s'",
- simulationName.c_str(), integrator.c_str()));
+ simulationName.c_str(),
+ integrator.c_str()));
- auto mdpFieldValues = prepareMdpFieldValues(simulationName.c_str(), integrator.c_str(),
- temperatureCoupling.c_str(), pressureCoupling.c_str());
+ auto mdpFieldValues = prepareMdpFieldValues(simulationName.c_str(),
+ integrator.c_str(),
+ temperatureCoupling.c_str(),
+ pressureCoupling.c_str());
// The exact lambda state choice is unimportant, so long as there
// is one when using an FEP input.
- mdpFieldValues["other"] += formatString("\ninit-lambda-state = %d", 3);
- mdpFieldValues["nsteps"] = "16";
+ mdpFieldValues["init-lambda-state"] = "3";
+ mdpFieldValues["nsteps"] = "16";
// Forces on GPUs are generally not reproducible enough for a tight
// tolerance. Similarly, the propagation of sd and bd are not as
if (pressureCoupling == "parrinello-rahman")
{
- energyTermsToCompare.insert(
- { "Box-Vel-XX", relativeToleranceAsPrecisionDependentUlp(1e-12, ulpToleranceInMixed,
- ulpToleranceInDouble) });
- energyTermsToCompare.insert(
- { "Box-Vel-YY", relativeToleranceAsPrecisionDependentUlp(1e-12, ulpToleranceInMixed,
- ulpToleranceInDouble) });
- energyTermsToCompare.insert(
- { "Box-Vel-ZZ", relativeToleranceAsPrecisionDependentUlp(1e-12, ulpToleranceInMixed,
- ulpToleranceInDouble) });
+ energyTermsToCompare.insert({ "Box-Vel-XX",
+ relativeToleranceAsPrecisionDependentUlp(
+ 1e-12, ulpToleranceInMixed, ulpToleranceInDouble) });
+ energyTermsToCompare.insert({ "Box-Vel-YY",
+ relativeToleranceAsPrecisionDependentUlp(
+ 1e-12, ulpToleranceInMixed, ulpToleranceInDouble) });
+ energyTermsToCompare.insert({ "Box-Vel-ZZ",
+ relativeToleranceAsPrecisionDependentUlp(
+ 1e-12, ulpToleranceInMixed, ulpToleranceInDouble) });
}
int numWarningsToTolerate = 1;
- runTest(&fileManager_, &runner_, simulationName, numWarningsToTolerate, mdpFieldValues,
- energyTermsToCompare);
+ runTest(&fileManager_, &runner_, simulationName, numWarningsToTolerate, mdpFieldValues, energyTermsToCompare);
}
// TODO The time for OpenCL kernel compilation means these tests time
fprintf(stdout,
"The FEP tests cannot run with %d ranks.\n"
"The maximum number of ranks supported is %d.",
- numRanksAvailable, maxNumRanks);
+ numRanksAvailable,
+ maxNumRanks);
return;
}
// Check that the trajectories agree with the refdata within tolerance.
if (testTwoTrajectoryFrames)
{
- checkTrajectoryAgainstReferenceData(simulationTrajectoryFileName, trajectoryComparison,
- &rootChecker, MaxNumFrames(2));
+ checkTrajectoryAgainstReferenceData(
+ simulationTrajectoryFileName, trajectoryComparison, &rootChecker, MaxNumFrames(2));
}
else if (testOneTrajectoryFrame)
{
- checkTrajectoryAgainstReferenceData(simulationTrajectoryFileName, trajectoryComparison,
- &rootChecker, MaxNumFrames(1));
+ checkTrajectoryAgainstReferenceData(
+ simulationTrajectoryFileName, trajectoryComparison, &rootChecker, MaxNumFrames(1));
}
else
{
- checkTrajectoryAgainstReferenceData(simulationTrajectoryFileName, trajectoryComparison,
- &rootChecker, MaxNumFrames(0));
+ checkTrajectoryAgainstReferenceData(
+ simulationTrajectoryFileName, trajectoryComparison, &rootChecker, MaxNumFrames(0));
}
if (File::exists(simulationDhdlFileName, File::returnFalseOnError))
{
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
"integrator = %s\n"
"nsteps = %d\n"
"dt = %f\n",
- integratorName.c_str(), nsteps, timestep);
+ integratorName.c_str(),
+ nsteps,
+ timestep);
runner_.useStringAsMdpFile(theMdpFile);
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
auto simulationName = std::get<0>(params);
auto minimizer = std::get<1>(params);
SCOPED_TRACE(formatString("Comparing '%s' energy minimization for simulation '%s'",
- minimizer.c_str(), simulationName.c_str()));
+ minimizer.c_str(),
+ simulationName.c_str()));
// TODO At some point we should also test PME-only ranks.
int numRanksAvailable = getNumberOfTestMpiRanks();
fprintf(stdout,
"Test system '%s' cannot run with %d ranks.\n"
"The supported numbers are: %s\n",
- simulationName.c_str(), numRanksAvailable,
+ simulationName.c_str(),
+ numRanksAvailable,
reportNumbersOfPpRanksSupported(simulationName).c_str());
return;
}
"glycine_no_constraints_vacuo" };
std::vector<std::string> minimizersToTest_g = { "steep", "cg", "l-bfgs" };
-std::vector<std::string> constrainedSystemsToTest_g = { "tip3p5", "glycine_vacuo",
+std::vector<std::string> constrainedSystemsToTest_g = { "tip3p5",
+ "glycine_vacuo",
"alanine_vsite_vacuo" };
std::vector<std::string> minimizersToTestWithConstraints_g = { "steep", "cg" };
//! \}
caller.addOption("-ntomp", g_numOpenMPThreads);
#endif
- return gmx_mdrun(MdrunTestFixtureBase::communicator_, *MdrunTestFixtureBase::hwinfo_,
- caller.argc(), caller.argv());
+ return gmx_mdrun(MdrunTestFixtureBase::communicator_,
+ *MdrunTestFixtureBase::hwinfo_,
+ caller.argc(),
+ caller.argv());
}
int SimulationRunner::callMdrun()
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <gtest/gtest.h>
+#include <memory>
+
#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/gmxmpi.h"
auto mtsScheme = std::get<1>(params);
// Note that there should be no relevant limitation on MPI ranks and OpenMP threads
- SCOPED_TRACE(formatString("Comparing for '%s' no MTS with MTS scheme '%s'",
- simulationName.c_str(), mtsScheme.c_str()));
+ SCOPED_TRACE(formatString(
+ "Comparing for '%s' no MTS with MTS scheme '%s'", simulationName.c_str(), mtsScheme.c_str()));
const bool isPullTest = (mtsScheme.find("pull") != std::string::npos);
"rcoulomb = 0.9\n"
"rvdw = 0.9\n"
"constraints = h-bonds\n",
- numSteps, isPullTest ? "reaction-field" : "PME");
+ numSteps,
+ isPullTest ? "reaction-field" : "PME");
if (isPullTest)
{
"nstxout = 0\n"
"nstvout = 0\n"
"nstfout = %d\n",
- numSteps, numSteps, nstfout);
+ numSteps,
+ numSteps,
+ nstfout);
auto mtsMdpOptions = sharedMdpOptions
+ gmx::formatString(
"nstxout = 0\n"
"nstvout = 0\n"
"nstfout = %d\n",
- mtsScheme.c_str(), numSteps, numSteps, nstfout);
+ mtsScheme.c_str(),
+ numSteps,
+ numSteps,
+ nstfout);
// At step 0 the energy and virial should only differ due to rounding errors
EnergyTermsToCompare energyTermsToCompareStep0 = energyTermsToCompare(0.001, 0.01);
runMdrun(&runner_);
// Compare simulation results at step 0, which should be indentical
- compareEnergies(simulator1EdrFileName, simulator2EdrFileName, energyTermsToCompareStep0,
- MaxNumFrames(1));
+ compareEnergies(
+ simulator1EdrFileName, simulator2EdrFileName, energyTermsToCompareStep0, MaxNumFrames(1));
compareTrajectories(simulator1TrajectoryFileName, simulator2TrajectoryFileName, trajectoryComparison);
// Compare energies at the last step (and step 0 again) with lower tolerance
- compareEnergies(simulator1EdrFileName, simulator2EdrFileName, energyTermsToCompareAllSteps,
+ compareEnergies(simulator1EdrFileName,
+ simulator2EdrFileName,
+ energyTermsToCompareAllSteps,
MaxNumFrames::compareAllFrames());
}
"gen-temp = %f\n"
// control variable specification
"%s\n",
- numSteps, baseTemperature + 0.0001 * rank_, basePressure * std::pow(1.01, rank_),
+ numSteps,
+ baseTemperature + 0.0001 * rank_,
+ basePressure * std::pow(1.01, rank_),
/* Set things up so that the initial KE decreases with
increasing replica number, so that the (identical)
starting PE decreases on the first step more for the
replicas with higher number, which will tend to force
replica exchange to occur. */
- std::max(baseTemperature - 10 * rank_, real(0)), controlVariable);
+ std::max(baseTemperature - 10 * rank_, real(0)),
+ controlVariable);
runner->useStringAsMdpFile(mdpFileContents);
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
const char* const command[] = { "nonbonded-benchmark" };
CommandLine cmdline(command);
cmdline.addOption("-iter", 1);
- EXPECT_EQ(0, gmx::test::CommandLineTestHelper::runModuleFactory(
- &gmx::NonbondedBenchmarkInfo::create, &cmdline));
+ EXPECT_EQ(0,
+ gmx::test::CommandLineTestHelper::runModuleFactory(
+ &gmx::NonbondedBenchmarkInfo::create, &cmdline));
}
} // namespace
fprintf(stdout,
"Test system '%s' cannot run with %d ranks.\n"
"The supported numbers are: %s\n",
- simulationName.c_str(), numRanksAvailable,
+ simulationName.c_str(),
+ numRanksAvailable,
reportNumbersOfPpRanksSupported(simulationName).c_str());
return;
}
//! Containers of systems and integrators to test.
//! \{
-std::vector<std::string> systemsToTest_g = { "scaled-water", "villin", "spc-dimer", "one-tip5p",
+std::vector<std::string> systemsToTest_g = { "scaled-water",
+ "villin",
+ "spc-dimer",
+ "one-tip5p",
"sw-dimer" };
std::vector<std::string> integratorsToTest_g = { "nm" };
SCOPED_TRACE(
formatString("Checking for presence of expected output files using "
"simulation '%s' with integrator '%s'",
- simulationName.c_str(), integrator.c_str()));
+ simulationName.c_str(),
+ integrator.c_str()));
// Prepare the .tpr file
{
}
// Check if expected files are present
{
- for (const auto& file : { runner_.fullPrecisionTrajectoryFileName_, runner_.logFileName_,
- runner_.edrFileName_, fileManager_.getTemporaryFilePath("state.gro"),
+ for (const auto& file : { runner_.fullPrecisionTrajectoryFileName_,
+ runner_.logFileName_,
+ runner_.edrFileName_,
+ fileManager_.getTemporaryFilePath("state.gro"),
fileManager_.getTemporaryFilePath("state.cpt") })
{
EXPECT_TRUE(File::exists(file, File::returnFalseOnError))
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
auto propagation = std::get<0>(GetParam());
SCOPED_TRACE(
formatString("Doing %s simulation with %s integrator, %s tcoupling and %s pcoupling\n",
- propagation["simulationName"].c_str(), propagation["integrator"].c_str(),
- propagation["tcoupl"].c_str(), propagation["pcoupl"].c_str()));
- auto mdpFieldValues = prepareMdpFieldValues(propagation["simulationName"], propagation["integrator"],
- propagation["tcoupl"], propagation["pcoupl"]);
- mdpFieldValues.insert(propagation.begin(), propagation.end());
- mdpFieldValues.insert(output.begin(), output.end());
+ propagation["simulationName"].c_str(),
+ propagation["integrator"].c_str(),
+ propagation["tcoupl"].c_str(),
+ propagation["pcoupl"].c_str()));
+ auto mdpFieldValues = prepareMdpFieldValues(propagation["simulationName"],
+ propagation["integrator"],
+ propagation["tcoupl"],
+ propagation["pcoupl"]);
+
+ // This lambda writes all mdp options in `source` into `target`, overwriting options already
+ // present in `target`. It also filters out non-mdp option entries in the source maps
+ auto overWriteMdpMapValues = [](const MdpFieldValues& source, MdpFieldValues& target) {
+ for (auto const& [key, value] : source)
+ {
+ if (key == "simulationName" || key == "maxGromppWarningsTolerated" || key == "description")
+ {
+ // Remove non-mdp entries used in propagation and output
+ continue;
+ }
+ target[key] = value;
+ }
+ };
+ // Add options in propagation and output to the mdp options
+ overWriteMdpMapValues(propagation, mdpFieldValues);
+ overWriteMdpMapValues(output, mdpFieldValues);
// prepare the tpr file
{
{
auto propagation = std::get<0>(GetParam());
SCOPED_TRACE(formatString("Comparing two simulations of '%s' with integrator '%s'",
- propagation["simulationName"].c_str(), propagation["integrator"].c_str()));
+ propagation["simulationName"].c_str(),
+ propagation["integrator"].c_str()));
prepareReferenceData();
+ "' and test '" + runner_.edrFileName_ + "'");
shouldContinueComparing = shouldContinueComparing
&& compareFrames(referenceEnergyFrameReader.get(),
- testEnergyFrameReader.get(), energyComparison_);
+ testEnergyFrameReader.get(),
+ energyComparison_);
}
}
}
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "config.h"
#include "gromacs/topology/ifunc.h"
+#include "gromacs/utility/strconvert.h"
#include "gromacs/utility/stringutil.h"
#include "testutils/mpitest.h"
fprintf(stdout,
"Test system '%s' cannot run with %d ranks.\n"
"The supported numbers are: %s\n",
- simulationName.c_str(), numRanksAvailable,
+ simulationName.c_str(),
+ numRanksAvailable,
reportNumbersOfPpRanksSupported(simulationName).c_str());
return;
}
SCOPED_TRACE(
formatString("Comparing normal and rerun of simulation '%s' "
"with integrator '%s'",
- simulationName.c_str(), integrator.c_str()));
+ simulationName.c_str(),
+ integrator.c_str()));
auto mdpFieldValues =
prepareMdpFieldValues(simulationName.c_str(), integrator.c_str(), "no", "no");
const int toleranceScaleFactor = (integrator == "bd") ? 2 : 1;
EnergyTermsToCompare energyTermsToCompare{ {
{ interaction_function[F_EPOT].longname,
- relativeToleranceAsPrecisionDependentUlp(10.0, 24 * toleranceScaleFactor,
- 40 * toleranceScaleFactor) },
+ relativeToleranceAsPrecisionDependentUlp(
+ 10.0, 24 * toleranceScaleFactor, 40 * toleranceScaleFactor) },
} };
// Specify how trajectory frame matching must work
TrajectoryComparison::s_defaultTrajectoryTolerances };
int numWarningsToTolerate = 0;
- executeRerunTest(&fileManager_, &runner_, simulationName, numWarningsToTolerate, mdpFieldValues,
- energyTermsToCompare, trajectoryComparison);
+ executeRerunTest(&fileManager_,
+ &runner_,
+ simulationName,
+ numWarningsToTolerate,
+ mdpFieldValues,
+ energyTermsToCompare,
+ trajectoryComparison);
}
// TODO The time for OpenCL kernel compilation means these tests time
SCOPED_TRACE(
formatString("Comparing normal and rerun of simulation '%s' "
"with integrator '%s' for initial lambda state %d",
- simulationName.c_str(), integrator.c_str(), initLambdaState));
+ simulationName.c_str(),
+ integrator.c_str(),
+ initLambdaState));
auto mdpFieldValues =
prepareMdpFieldValues(simulationName.c_str(), integrator.c_str(), "no", "no");
- mdpFieldValues["other"] += formatString("\ninit-lambda-state = %d", initLambdaState);
+ mdpFieldValues["init-lambda-state"] = toString(initLambdaState);
EnergyTermsToCompare energyTermsToCompare{
{ { interaction_function[F_EPOT].longname, relativeToleranceAsPrecisionDependentUlp(10.0, 24, 32) },
// The md integrator triggers a warning for nearly decoupled
// states, which we need to suppress. TODO sometimes?
int numWarningsToTolerate = (integrator == "md") ? 1 : 0;
- executeRerunTest(&fileManager_, &runner_, simulationName, numWarningsToTolerate, mdpFieldValues,
- energyTermsToCompare, trajectoryComparison);
+ executeRerunTest(&fileManager_,
+ &runner_,
+ simulationName,
+ numWarningsToTolerate,
+ mdpFieldValues,
+ energyTermsToCompare,
+ trajectoryComparison);
}
// TODO The time for OpenCL kernel compilation means these tests time
fprintf(stdout,
"Test system '%s' cannot run with %d ranks.\n"
"The supported numbers are: %s\n",
- simulationName.c_str(), numRanksAvailable,
+ simulationName.c_str(),
+ numRanksAvailable,
reportNumbersOfPpRanksSupported(simulationName).c_str());
return;
}
fprintf(stdout,
"Test system '%s' cannot run with %d ranks.\n"
"The supported numbers are: %s\n",
- simulationName.c_str(), numRanksAvailable,
+ simulationName.c_str(),
+ numRanksAvailable,
reportNumbersOfPpRanksSupported(simulationName).c_str());
return;
}
"Comparing two simulations of '%s' "
"with integrator '%s', '%s' temperature coupling, and '%s' pressure coupling "
"switching environment variable '%s'",
- simulationName.c_str(), integrator.c_str(), tcoupling.c_str(), pcoupling.c_str(),
+ simulationName.c_str(),
+ integrator.c_str(),
+ tcoupling.c_str(),
+ pcoupling.c_str(),
environmentVariable.c_str()));
- const auto mdpFieldValues = prepareMdpFieldValues(simulationName.c_str(), integrator.c_str(),
- tcoupling.c_str(), pcoupling.c_str());
+ const auto mdpFieldValues = prepareMdpFieldValues(
+ simulationName.c_str(), integrator.c_str(), tcoupling.c_str(), pcoupling.c_str());
EnergyTermsToCompare energyTermsToCompare{ {
{ interaction_function[F_EPOT].longname, relativeToleranceAsPrecisionDependentUlp(60.0, 200, 160) },
ASSERT_EQ(0, runner_.callMdrun(secondPart));
auto logFileContents = TextReader::readFileToString(runner_.logFileName_);
- EXPECT_NE(
- std::string::npos,
- logFileContents.find("Restarting from checkpoint, appending to previous log file"))
+ EXPECT_NE(std::string::npos, logFileContents.find("Restarting from checkpoint, appending to previous log file"))
<< "appending was not detected";
}
}
ASSERT_EQ(0, runner_.callMdrun(secondPart));
auto logFileContents = TextReader::readFileToString(runner_.logFileName_);
- EXPECT_EQ(
- std::string::npos,
- logFileContents.find("Restarting from checkpoint, appending to previous log file"))
+ EXPECT_EQ(std::string::npos, logFileContents.find("Restarting from checkpoint, appending to previous log file"))
<< "appending was not detected";
}
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
ref_t = 298
nsteps = %d
)",
- randomSeed, nsteps);
+ randomSeed,
+ nsteps);
runner_.useStringAsMdpFile(mdpFileContents);
runTest();
const TrajectoryComparison& trajectoryComparison,
TestReferenceChecker* checker)
{
- checkTrajectoryAgainstReferenceData(trajectoryFilename, trajectoryComparison, checker,
- MaxNumFrames::compareAllFrames());
+ checkTrajectoryAgainstReferenceData(
+ trajectoryFilename, trajectoryComparison, checker, MaxNumFrames::compareAllFrames());
}
void checkTrajectoryAgainstReferenceData(const std::string& trajectoryFilename,
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2016,2017,2018,2019,2020, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
{
t_trxstatus* trajectoryFile;
int flags = TRX_READ_X | TRX_READ_V | TRX_READ_F;
- nextFrameExists_ = read_first_frame(oenvGuard_.get(), &trajectoryFile, filename_.c_str(),
- trxframeGuard_.get(), flags);
+ nextFrameExists_ = read_first_frame(
+ oenvGuard_.get(), &trajectoryFile, filename_.c_str(), trxframeGuard_.get(), flags);
if (!trajectoryFile)
{
GMX_THROW(FileIOError("Could not open trajectory file " + filename_ + " for reading"));
/*
* 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.
int main(int argc, char* argv[])
{
- return gmx::CommandLineModuleManager::runAsMainCMainWithSettings(argc, argv, &gmx::gmx_mdrun,
- &initSettingsNoNice);
+ return gmx::CommandLineModuleManager::runAsMainCMainWithSettings(
+ argc, argv, &gmx::gmx_mdrun, &initSettingsNoNice);
}
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2013, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2019, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,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.
/* VBox holder */
y0 = XTextHeight(x11->font) + 2 * AIR + 2;
- InitWin(&vb->wd, 0, 0, vb->nbut * (play_width + AIR) + AIR, y0 + play_height + 2 * AIR, 1,
+ InitWin(&vb->wd,
+ 0,
+ 0,
+ vb->nbut * (play_width + AIR) + AIR,
+ y0 + play_height + 2 * AIR,
+ 1,
"VCR - Control");
- vb->wd.self = XCreateSimpleWindow(x11->disp, Parent, vb->wd.x, vb->wd.y, vb->wd.width,
- vb->wd.height, vb->wd.bwidth, fg, bg);
+ vb->wd.self = XCreateSimpleWindow(
+ x11->disp, Parent, vb->wd.x, vb->wd.y, vb->wd.width, vb->wd.height, vb->wd.bwidth, fg, bg);
x11->RegisterCallback(x11, vb->wd.self, Parent, VBCallBack, vb);
x11->SetInputMask(x11, vb->wd.self, ExposureMask);
default: fprintf(stderr, "Invalid bitmap in init_vbox %d\n", ID); std::exit(1);
}
/* Rely on the fact that all bitmaps are equal size */
- pm = XCreatePixmapFromBitmapData(x11->disp, x11->root, (char*)data, play_width, play_height,
- BLACK, LIGHTGREY, x11->depth);
+ pm = XCreatePixmapFromBitmapData(
+ x11->disp, x11->root, (char*)data, play_width, play_height, BLACK, LIGHTGREY, x11->depth);
vb->b[i].ID = ID;
vb->b[i].wd.Parent = SendTo;
- vb->b[i].wd.self = XCreateSimpleWindow(x11->disp, vb->wd.self, x, y0 + AIR, play_width,
- play_height, 0, WHITE, BLACK);
+ vb->b[i].wd.self = XCreateSimpleWindow(
+ x11->disp, vb->wd.self, x, y0 + AIR, play_width, play_height, 0, WHITE, BLACK);
XSetWindowBackgroundPixmap(x11->disp, vb->b[i].wd.self, pm);
x11->RegisterCallback(x11, vb->b[i].wd.self, vb->wd.self, ButtonCallBack, &(vb->b[i]));
InitWin(&(bbox->wd), 0, 0, /*width,(y0+AIR)*IDBUTNR+AIR+2*BORDER,*/ 1, 1, 1, "Button Box");
width -= 2 * AIR + 2 * BORDER;
- bbox->wd.self = XCreateSimpleWindow(x11->disp, Parent, bbox->wd.x, bbox->wd.y, bbox->wd.width,
- bbox->wd.height, bbox->wd.bwidth, fg, bg);
+ bbox->wd.self = XCreateSimpleWindow(
+ x11->disp, Parent, bbox->wd.x, bbox->wd.y, bbox->wd.width, bbox->wd.height, bbox->wd.bwidth, fg, bg);
x11->RegisterCallback(x11, bbox->wd.self, Parent, BBCallBack, bbox);
x11->SetInputMask(x11, bbox->wd.self, StructureNotifyMask);
h0 += y0 + AIR;
but->wd.Parent = SendTo;
but->ID = i;
- but->wd.self = XCreateSimpleWindow(x11->disp, DrawOn, but->wd.x, but->wd.y, but->wd.width,
- but->wd.height, but->wd.bwidth, bg, bg);
+ but->wd.self = XCreateSimpleWindow(
+ x11->disp, DrawOn, but->wd.x, but->wd.y, but->wd.width, but->wd.height, but->wd.bwidth, bg, bg);
x11->RegisterCallback(x11, but->wd.self, DrawOn, ButtonCallBack, but);
x11->SetInputMask(x11, but->wd.self, ExposureMask | ButtonPressMask | EnterLeave);
}
static t_dlg* about_mb(t_x11* x11, t_gmx* gmx)
{
- const char* lines[] = { " G R O M A C S", " Machine for Simulating Chemistry",
+ const char* lines[] = { " G R O M A C S",
+ " Machine for Simulating Chemistry",
" Copyright (c) 1992-2013",
" Berk Hess, David van der Spoel, Erik Lindahl",
" and many collaborators!" };
- return MessageBox(x11, gmx->wd->self, gmx->wd->text, asize(lines), lines,
- MB_OK | MB_ICONGMX | MBFLAGS, MBCallback, gmx);
+ return MessageBox(
+ x11, gmx->wd->self, gmx->wd->text, asize(lines), lines, MB_OK | MB_ICONGMX | MBFLAGS, MBCallback, gmx);
}
static void QuitCB(t_x11* x11, int dlg_mess, int /*item_id*/, char* set, void* data)
{
const char* lines[] = { " Do you really want to Quit ?" };
- return MessageBox(x11, gmx->wd->self, gmx->wd->text, asize(lines), lines,
- MB_YESNO | MB_ICONSTOP | MBFLAGS, QuitCB, gmx);
+ return MessageBox(
+ x11, gmx->wd->self, gmx->wd->text, asize(lines), lines, MB_YESNO | MB_ICONSTOP | MBFLAGS, QuitCB, gmx);
}
static t_dlg* help_mb(t_x11* x11, t_gmx* gmx)
{
const char* lines[] = { " Help will soon be added" };
- return MessageBox(x11, gmx->wd->self, gmx->wd->text, asize(lines), lines,
- MB_OK | MB_ICONINFORMATION | MBFLAGS, MBCallback, gmx);
+ return MessageBox(
+ x11, gmx->wd->self, gmx->wd->text, asize(lines), lines, MB_OK | MB_ICONINFORMATION | MBFLAGS, MBCallback, gmx);
}
static t_dlg* ni_mb(t_x11* x11, t_gmx* gmx)
{
const char* lines[] = { " This feature has not been", " implemented yet." };
- return MessageBox(x11, gmx->wd->self, gmx->wd->text, asize(lines), lines,
- MB_OK | MB_ICONEXCLAMATION | MBFLAGS, MBCallback, gmx);
+ return MessageBox(
+ x11, gmx->wd->self, gmx->wd->text, asize(lines), lines, MB_OK | MB_ICONEXCLAMATION | MBFLAGS, MBCallback, gmx);
}
enum
snew(gmx->dlgs, edNR);
for (int i = 0; (i < asize(di)); i++)
{
- gmx->dlgs[i] = ReadDlg(x11, gmx->wd->self, di[i].dlgfile, di[i].dlgfile, 0, 0, true, false,
- di[i].cb, gmx);
+ gmx->dlgs[i] = ReadDlg(
+ x11, gmx->wd->self, di[i].dlgfile, di[i].dlgfile, 0, 0, true, false, di[i].cb, gmx);
}
gmx->dlgs[edFilter] = select_filter(x11, gmx);
{
int i;
- std::printf(" type: %s, set: '%s', get: '%s', def: '%s', help: '%s'\n {", type[fitem->edlg],
- fitem->set, fitem->get, fitem->def, fitem->help);
+ std::printf(" type: %s, set: '%s', get: '%s', def: '%s', help: '%s'\n {",
+ type[fitem->edlg],
+ fitem->set,
+ fitem->get,
+ fitem->def,
+ fitem->help);
for (i = 0; (i < fitem->nname); i++)
{
std::printf(" '%s'", fitem->name[i]);
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2013, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2017,2019, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2017,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.
{
if (!gmx->filter->bDisable[k])
{
- std::fprintf(tmp, "checkbox \"%s\" \"%d\" %s %s %s\n", gmx->filter->grpnames[k], k,
- dummy, dummy, dummy);
+ std::fprintf(
+ tmp, "checkbox \"%s\" \"%d\" %s %s %s\n", gmx->filter->grpnames[k], k, dummy, dummy, dummy);
}
else
{
- std::fprintf(tmp, "statictext { \" %s\" } \"%d\" %s %s %s\n",
- gmx->filter->grpnames[k], k, dummy, dummy, dummy);
+ std::fprintf(tmp,
+ "statictext { \" %s\" } \"%d\" %s %s %s\n",
+ gmx->filter->grpnames[k],
+ k,
+ dummy,
+ dummy,
+ dummy);
}
}
std::fprintf(tmp, "}\n\n");
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2013, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2017,2019, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2017,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.
XSetLineAttributes(x11->disp, x11->gc, 3, LineSolid, CapNotLast, JoinRound);
for (i = 0; (i < asize(lines)); i += 2)
{
- XDrawLine(x11->disp, wd->self, x11->gc, c[lines[i]].x, c[lines[i]].y,
- c[lines[i + 1]].x, c[lines[i + 1]].y);
+ XDrawLine(x11->disp,
+ wd->self,
+ x11->gc,
+ c[lines[i]].x,
+ c[lines[i]].y,
+ c[lines[i + 1]].x,
+ c[lines[i + 1]].y);
}
XSetLineAttributes(x11->disp, x11->gc, 1, LineSolid, CapNotLast, JoinRound);
for (i = 0; (i < asize(c)); i++)
XDrawRectangle(x11->disp, wd->self, x11->gc, 2, 2, wd->width - 5, wd->height - 5);
for (i = 0; (i < NMESS); i++)
{
- SpecialTextInRect(x11, Mess[i].fnt, wd->self, Mess[i].text, 0, Mess[i].y, wd->width,
- Mess[i].h, eXCenter, eYCenter);
+ SpecialTextInRect(
+ x11, Mess[i].fnt, wd->self, Mess[i].text, 0, Mess[i].y, wd->width, Mess[i].h, eXCenter, eYCenter);
}
XSetForeground(x11->disp, x11->gc, x11->fg);
break;
{
GetNamedColor(x11, newcol, &bg);
}
- logo->wd.self = XCreateSimpleWindow(x11->disp, parent, logo->wd.x, logo->wd.y, logo->wd.width,
- logo->wd.height, logo->wd.bwidth, WHITE, bg);
+ logo->wd.self = XCreateSimpleWindow(
+ x11->disp, parent, logo->wd.x, logo->wd.y, logo->wd.width, logo->wd.height, logo->wd.bwidth, WHITE, bg);
for (i = 0, logo->bigfont = nullptr; (i < NBF); i++)
{
if ((logo->bigfont = XLoadQueryFont(x11->disp, bfname[i])) != nullptr)
return;
}
XSetForeground(x11->disp, x11->gc, col);
- XDrawString(x11->disp, man->molw->wd.self, x11->gc, x + 2, y - 2, man->szLab[ai],
- std::strlen(man->szLab[ai]));
+ XDrawString(
+ x11->disp, man->molw->wd.self, x11->gc, x + 2, y - 2, man->szLab[ai], std::strlen(man->szLab[ai]));
XSetForeground(x11->disp, x11->gc, x11->fg);
}
}
gmx_fatal(FARGS,
"Topology %s (%d atoms) and trajectory %s (%d atoms) "
"do not match",
- status, man->top.atoms.nr, trajectory, man->natom);
+ status,
+ man->top.atoms.nr,
+ trajectory,
+ man->natom);
}
man->title.text =
man->bSort = true;
man->oenv = oenv;
InitWin(&(man->wd), x, y, width, height, 0, "Manager");
- man->wd.self = XCreateSimpleWindow(x11->disp, Parent, man->wd.x, man->wd.y, man->wd.width,
- man->wd.height, man->wd.bwidth, fg, bg);
+ man->wd.self = XCreateSimpleWindow(
+ x11->disp, Parent, man->wd.x, man->wd.y, man->wd.width, man->wd.height, man->wd.bwidth, fg, bg);
x11->RegisterCallback(x11, man->wd.self, Parent, ManCallBack, man);
x11->SetInputMask(x11, man->wd.self, StructureNotifyMask | ExposureMask | ButtonPressMask);
/* Title Window */
InitWin(&(man->title), 0, 0, 1, 1, 0, nullptr);
- man->title.self =
- XCreateSimpleWindow(x11->disp, man->molw->wd.self, man->title.x, man->title.y,
- man->title.width, man->title.height, man->title.bwidth, WHITE, BLUE);
+ man->title.self = XCreateSimpleWindow(x11->disp,
+ man->molw->wd.self,
+ man->title.x,
+ man->title.y,
+ man->title.width,
+ man->title.height,
+ man->title.bwidth,
+ WHITE,
+ BLUE);
x11->RegisterCallback(x11, man->title.self, man->molw->wd.self, TitleCallBack, &(man->title));
x11->SetInputMask(x11, man->title.self, ExposureMask | StructureNotifyMask);
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2013, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2017,2019, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2017,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.
ps_color(ps, 0, 0, 0.5);
for (i = 0; (i < 12); i++)
{
- ps_line(ps, vec2[bonds[i][0]][XX], vec2[bonds[i][0]][YY], vec2[bonds[i][1]][XX],
- vec2[bonds[i][1]][YY]);
+ ps_line(ps, vec2[bonds[i][0]][XX], vec2[bonds[i][0]][YY], vec2[bonds[i][1]][XX], vec2[bonds[i][1]][YY]);
}
}
}
/* Draw the objects */
- draw_objects(x11->disp, win->self, x11->gc, nvis, man->obj, man->ix, man->x, man->col,
- man->size, mw->bShowHydrogen, mw->bond_type, man->bPlus);
+ draw_objects(x11->disp,
+ win->self,
+ x11->gc,
+ nvis,
+ man->obj,
+ man->ix,
+ man->x,
+ man->col,
+ man->size,
+ mw->bShowHydrogen,
+ mw->bond_type,
+ man->bPlus);
/* Draw the labels */
XSetForeground(x11->disp, x11->gc, WHITE);
{
if (man->bLabel[i] && man->bVis[i])
{
- XDrawString(x11->disp, win->self, x11->gc, vec2[i][XX] + 2, vec2[i][YY] - 2,
- man->szLab[i], std::strlen(man->szLab[i]));
+ XDrawString(x11->disp,
+ win->self,
+ x11->gc,
+ vec2[i][XX] + 2,
+ vec2[i][YY] - 2,
+ man->szLab[i],
+ std::strlen(man->szLab[i]));
}
}
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2013, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2017,2019, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2017,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.
/* Nothing to be done */
if (m->bGrabbed)
{
- m->bGrabbed = GrabOK(stderr, XGrabPointer(x11->disp, m->wd.self, True, ButtonReleaseMask,
- GrabModeAsync, GrabModeAsync, m->wd.self,
- None, CurrentTime));
+ m->bGrabbed = GrabOK(stderr,
+ XGrabPointer(x11->disp,
+ m->wd.self,
+ True,
+ ButtonReleaseMask,
+ GrabModeAsync,
+ GrabModeAsync,
+ m->wd.self,
+ None,
+ CurrentTime));
}
break;
case ButtonRelease: hide_menu(x11, m); break;
}
InitWin(&(m->wd), 10, 10, fcol * mlen, frows * mht, 1, "Menu");
snew(m->item, nent);
- m->wd.self = XCreateSimpleWindow(x11->disp, Parent, m->wd.x, m->wd.y, m->wd.width, m->wd.height,
- m->wd.bwidth, fg, bg);
+ m->wd.self = XCreateSimpleWindow(
+ x11->disp, Parent, m->wd.x, m->wd.y, m->wd.width, m->wd.height, m->wd.bwidth, fg, bg);
x11->RegisterCallback(x11, m->wd.self, Parent, MenuCallBack, m);
x11->SetInputMask(x11, m->wd.self, ExposureMask | OwnerGrabButtonMask | ButtonReleaseMask);
kid->Parent = Parent;
w = &(kid->wd);
InitWin(w, j * mlen, k * mht, mlen - 2, mht - 2, 1, nullptr);
- w->self = XCreateSimpleWindow(x11->disp, m->wd.self, w->x, w->y, w->width, w->height,
- w->bwidth, bg, bg);
+ w->self = XCreateSimpleWindow(
+ x11->disp, m->wd.self, w->x, w->y, w->width, w->height, w->bwidth, bg, bg);
x11->RegisterCallback(x11, w->self, m->wd.self, ChildCallBack, kid);
- x11->SetInputMask(x11, w->self,
+ x11->SetInputMask(x11,
+ w->self,
ButtonPressMask | ButtonReleaseMask | OwnerGrabButtonMask
| ExposureMask | EnterWindowMask | LeaveWindowMask);
}
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2013, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2019, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,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.
XDrawLine(x11->disp, w, x11->gc, 0, y - 1, pd->wd.width, y - 1);
for (i = 0; (i < pd->nmenu); i++)
{
- XDrawString(x11->disp, pd->wd.self, x11->gc, pd->xpos[i], x11->font->ascent,
- pd->title[i], std::strlen(pd->title[i]));
+ XDrawString(x11->disp,
+ pd->wd.self,
+ x11->gc,
+ pd->xpos[i],
+ x11->font->ascent,
+ pd->title[i],
+ std::strlen(pd->title[i]));
}
break;
case ButtonPress:
}
InitWin(&(pd->wd), 0, 0, width, XTextHeight(x11->font) + 2, 0, "PullDown");
- pd->wd.self = XCreateSimpleWindow(x11->disp, Parent, pd->wd.x, pd->wd.y, pd->wd.width,
- pd->wd.height, pd->wd.bwidth, fg, bg);
+ pd->wd.self = XCreateSimpleWindow(
+ x11->disp, Parent, pd->wd.x, pd->wd.y, pd->wd.width, pd->wd.height, pd->wd.bwidth, fg, bg);
x11->RegisterCallback(x11, pd->wd.self, Parent, PDCallBack, pd);
- x11->SetInputMask(x11, pd->wd.self,
- ExposureMask | ButtonPressMask | OwnerGrabButtonMask | ButtonReleaseMask);
+ x11->SetInputMask(
+ x11, pd->wd.self, ExposureMask | ButtonPressMask | OwnerGrabButtonMask | ButtonReleaseMask);
XMapWindow(x11->disp, pd->wd.self);
for (i = 0; (i < nmenu); i++)
case IDIMPORT:
case IDEXPORT: ShowDlg(gmx->dlgs[edExport]); break;
case IDDOEXPORT:
- write_sto_conf(gmx->confout, *gmx->man->top.name, &(gmx->man->top.atoms), gmx->man->x,
- nullptr, gmx->man->molw->pbcType, gmx->man->box);
+ write_sto_conf(gmx->confout,
+ *gmx->man->top.name,
+ &(gmx->man->top.atoms),
+ gmx->man->x,
+ nullptr,
+ gmx->man->molw->pbcType,
+ gmx->man->box);
break;
case IDQUIT: show_mb(gmx, emQuit); break;
case IDTERM: done_gmx(x11, gmx); return true;
w0 = DisplayWidth(x11->disp, x11->screen) - 132;
h0 = DisplayHeight(x11->disp, x11->screen) - 140;
InitWin(gmx->wd, 0, 0, w0, h0, 3, gmx::bromacs().c_str());
- gmx->wd->self = XCreateSimpleWindow(x11->disp, x11->root, gmx->wd->x, gmx->wd->y, gmx->wd->width,
- gmx->wd->height, gmx->wd->bwidth, WHITE, BLACK);
- pm = XCreatePixmapFromBitmapData(x11->disp, x11->root, (char*)gromacs_bits, gromacs_width,
- gromacs_height, WHITE, BLACK, 1);
+ gmx->wd->self = XCreateSimpleWindow(
+ x11->disp, x11->root, gmx->wd->x, gmx->wd->y, gmx->wd->width, gmx->wd->height, gmx->wd->bwidth, WHITE, BLACK);
+ pm = XCreatePixmapFromBitmapData(
+ x11->disp, x11->root, (char*)gromacs_bits, gromacs_width, gromacs_height, WHITE, BLACK, 1);
hints.flags = PMinSize;
hints.min_width = 2 * EWIDTH + 40;
hints.min_height = EHEIGHT + LDHEIGHT + LEGHEIGHT + 40;
XSetStandardProperties(x11->disp, gmx->wd->self, gmx->wd->text, program, pm, nullptr, 0, &hints);
x11->RegisterCallback(x11, gmx->wd->self, x11->root, MainCallBack, gmx);
- x11->SetInputMask(x11, gmx->wd->self,
+ x11->SetInputMask(x11,
+ gmx->wd->self,
ButtonPressMask | ButtonReleaseMask | OwnerGrabButtonMask | ExposureMask
| StructureNotifyMask);
map_man(x11, gmx->man);
/* Pull Down menu */
- gmx->pd = init_pd(x11, gmx->wd->self, gmx->wd->width, x11->fg, x11->bg, MSIZE, gmx_pd_size,
- gmx_pd, MenuTitle);
+ gmx->pd = init_pd(
+ x11, gmx->wd->self, gmx->wd->width, x11->fg, x11->bg, MSIZE, gmx_pd_size, gmx_pd, MenuTitle);
/* Dialogs & Filters */
{ efNDX, nullptr, nullptr, ffOPTRD } };
#define NFILE asize(fnm)
- if (parse_common_args(&argc, argv, PCA_CAN_TIME, NFILE, fnm, 0, nullptr, asize(desc), desc,
- asize(bugs), bugs, &oenv))
+ if (parse_common_args(
+ &argc, argv, PCA_CAN_TIME, NFILE, fnm, 0, nullptr, asize(desc), desc, asize(bugs), bugs, &oenv))
{
#if !GMX_X11
std::fprintf(stderr, "Compiled without X-Windows - can not run viewer.\n");
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2013, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2017,2019, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2017,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.
else
{
/* We have real color! */
- std::fprintf(x11->console, "%s screen with depth %d.\n",
- (i == NCLASS) ? "Unknown" : v_name[i], x11->depth);
+ std::fprintf(x11->console,
+ "%s screen with depth %d.\n",
+ (i == NCLASS) ? "Unknown" : v_name[i],
+ x11->depth);
GetNamedColor(x11, "midnight blue", &BLUE);
GetNamedColor(x11, "DarkGreen", &GREEN);
GetNamedColor(x11, "SeaGreen", &CYAN);
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2017,2019, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2017,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.
dlgitem->win.height = h;
}
#ifdef DEBUG
- std::fprintf(dlg->x11->console, "Size window from: %dx%d to %dx%d\n", old_w, old_h,
- dlgitem->win.width, dlgitem->win.height);
+ std::fprintf(dlg->x11->console,
+ "Size window from: %dx%d to %dx%d\n",
+ old_w,
+ old_h,
+ dlgitem->win.width,
+ dlgitem->win.height);
dlg->x11->Flush(dlg->x11);
#endif
if (dlgitem->win.self)
void NoHelp(t_dlg* dlg)
{
const char* lines[2] = { "Error", "No help for this item" };
- MessageBox(dlg->x11, dlg->wDad, "No Help", 2, lines, MB_OK | MB_ICONSTOP | MB_APPLMODAL,
- nullptr, nullptr);
+ MessageBox(dlg->x11, dlg->wDad, "No Help", 2, lines, MB_OK | MB_ICONSTOP | MB_APPLMODAL, nullptr, nullptr);
}
void HelpDlg(t_dlg* dlg)
{
const char* lines[] = { "Place the cursor over one of the items",
- "and press the F1 key to get more help.", "First press the OK button." };
- MessageBox(dlg->x11, dlg->win.self, "Help Dialogbox", 3, lines,
- MB_OK | MB_ICONINFORMATION | MB_APPLMODAL, nullptr, nullptr);
+ "and press the F1 key to get more help.",
+ "First press the OK button." };
+ MessageBox(dlg->x11, dlg->win.self, "Help Dialogbox", 3, lines, MB_OK | MB_ICONINFORMATION | MB_APPLMODAL, nullptr, nullptr);
}
void HelpNow(t_dlg* dlg, t_dlgitem* dlgitem)
}
}
} while (bCont);
- MessageBox(dlg->x11, dlg->wDad, "Help", nlines, lines,
- MB_OK | MB_ICONINFORMATION | MB_APPLMODAL, nullptr, nullptr);
+ MessageBox(dlg->x11, dlg->wDad, "Help", nlines, lines, MB_OK | MB_ICONINFORMATION | MB_APPLMODAL, nullptr, nullptr);
for (i = 0; (i < nlines); i++)
{
sfree(lines[i]);
{
if (dlg->flags & DLG_APPLMODAL)
{
- dlg->bGrab = GrabOK(dlg->x11->console,
- XGrabPointer(dlg->x11->disp, dlg->win.self, True, 0, GrabModeAsync,
- GrabModeAsync, dlg->win.self, None, CurrentTime));
+ dlg->bGrab = GrabOK(
+ dlg->x11->console,
+ XGrabPointer(
+ dlg->x11->disp, dlg->win.self, True, 0, GrabModeAsync, GrabModeAsync, dlg->win.self, None, CurrentTime));
}
dlg->x11->Flush(dlg->x11);
}
{
if ((dlg->dlgitem[i]->type == edlgBN) && (dlg->dlgitem[i]->u.button.bDefault))
{
- PushMouse(x11->disp, dlg->dlgitem[i]->win.self,
- dlg->dlgitem[i]->win.width / 2, dlg->dlgitem[i]->win.height / 2);
+ PushMouse(x11->disp,
+ dlg->dlgitem[i]->win.self,
+ dlg->dlgitem[i]->win.width / 2,
+ dlg->dlgitem[i]->win.height / 2);
break;
}
}
attr.save_under = True;
attr.cursor = XCreateFontCursor(dlg->x11->disp, XC_hand2);
Val = CWBackPixel | CWBorderPixel | CWOverrideRedirect | CWSaveUnder | CWCursor;
- dlg->win.self = XCreateWindow(dlg->x11->disp, dlg->wDad, dlg->win.x, dlg->win.y, dlg->win.width,
- dlg->win.height, dlg->win.bwidth, CopyFromParent, InputOutput,
- CopyFromParent, Val, &attr);
+ dlg->win.self = XCreateWindow(dlg->x11->disp,
+ dlg->wDad,
+ dlg->win.x,
+ dlg->win.y,
+ dlg->win.width,
+ dlg->win.height,
+ dlg->win.bwidth,
+ CopyFromParent,
+ InputOutput,
+ CopyFromParent,
+ Val,
+ &attr);
dlg->x11->RegisterCallback(dlg->x11, dlg->win.self, dlg->wDad, DlgCB, dlg);
dlg->x11->SetInputMask(dlg->x11, dlg->win.self, ExposureMask | ButtonPressMask | KeyPressMask);
{
gmx_fatal(FARGS, "dlgitem not allocated");
}
- item->win.self = XCreateSimpleWindow(dlg->x11->disp, dlg->win.self, item->win.x, item->win.y,
- item->win.width, item->win.height, item->win.bwidth,
- dlg->x11->fg, dlg->x11->bg);
+ item->win.self = XCreateSimpleWindow(dlg->x11->disp,
+ dlg->win.self,
+ item->win.x,
+ item->win.y,
+ item->win.width,
+ item->win.height,
+ item->win.bwidth,
+ dlg->x11->fg,
+ dlg->x11->bg);
CheckWindow(item->win.self);
dlg->x11->RegisterCallback(dlg->x11, item->win.self, dlg->win.self, DlgCB, dlg);
dlg->win.height = h;
#ifdef DEBUG
- std::fprintf(dlg->x11->console, "SetDlgSize: Dialog is %dx%d, at %d,%d\n", dlg->win.width,
- dlg->win.height, dlg->win.x, dlg->win.y);
+ std::fprintf(dlg->x11->console,
+ "SetDlgSize: Dialog is %dx%d, at %d,%d\n",
+ dlg->win.width,
+ dlg->win.height,
+ dlg->win.x,
+ dlg->win.y);
dlg->x11->Flush(dlg->x11);
#endif
if (dlg->win.self)
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2013, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2017,2019, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2017,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.
switch (fitem->edlg)
{
case edlgBN:
- AddListItem(list, CreateButton(x11, fitem->name[0], fitem->bDef, (*ID)++, GroupID, x,
- (*y), 0, 0, 0));
+ AddListItem(list,
+ CreateButton(x11, fitem->name[0], fitem->bDef, (*ID)++, GroupID, x, (*y), 0, 0, 0));
break;
case edlgRB:
std::strcpy(buf, fitem->def);
for (i = 0; (i < fitem->nname); i++)
{
- AddListItem(list, CreateRadioButton(x11, fitem->name[i], (iSel == i), (*ID)++,
- GroupID, x, (*y), 0, 0, 0));
+ AddListItem(list,
+ CreateRadioButton(
+ x11, fitem->name[i], (iSel == i), (*ID)++, GroupID, x, (*y), 0, 0, 0));
(*y) += list->list[list->nitem - 1]->win.height + OFFS_Y;
(*w) = std::max((*w), list->list[list->nitem - 1]->win.width);
SetDlgitemOpts(list->list[list->nitem - 1], bUseMon, fitem->set, fitem->get, fitem->help);
bool bCheck;
bCheck = gmx_strcasecmp(fitem->def, "TRUE") == 0;
- AddListItem(list, CreateCheckBox(x11, fitem->name[0], bCheck, (*ID)++, GroupID, x, (*y),
- 0, 0, 0));
+ AddListItem(list,
+ CreateCheckBox(x11, fitem->name[0], bCheck, (*ID)++, GroupID, x, (*y), 0, 0, 0));
break;
}
case edlgST:
- AddListItem(list, CreateStaticText(x11, fitem->nname, fitem->name, (*ID)++, GroupID, x,
- (*y), 0, 0, 0));
+ AddListItem(list,
+ CreateStaticText(
+ x11, fitem->nname, fitem->name, (*ID)++, GroupID, x, (*y), 0, 0, 0));
break;
case edlgET:
slen = std::strlen(fitem->name[0]) + strlen(fitem->def);
- AddListItem(list, CreateEditText(x11, fitem->name[0], slen, fitem->def, (*ID)++,
- GroupID, x, (*y), 0, 0, 0));
+ AddListItem(list,
+ CreateEditText(
+ x11, fitem->name[0], slen, fitem->def, (*ID)++, GroupID, x, (*y), 0, 0, 0));
break;
case edlgPM:
case edlgGB:
{
ids[i] = GroupID + i + 1;
}
- item->list[0] = CreateGroupBox(x11, fgroup->name, GroupID, item->nitem - 1, ids, 2 * OFFS_X,
- 2 * OFFS_Y, w + 2 * OFFS_X, y, 0);
+ item->list[0] = CreateGroupBox(
+ x11, fgroup->name, GroupID, item->nitem - 1, ids, 2 * OFFS_X, 2 * OFFS_Y, w + 2 * OFFS_X, y, 0);
sfree(ids);
item->w = fgroup->w;
item->h = fgroup->h;
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2013, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2017,2019, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2017,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.
{
case Expose:
XSetForeground(x11->disp, x11->gc, x11->fg);
- XDrawRoundRect(x11->disp, win->self, x11->gc, 0, y / 2, win->width - 1,
- win->height - y / 2 - 1);
+ XDrawRoundRect(
+ x11->disp, win->self, x11->gc, 0, y / 2, win->width - 1, win->height - y / 2 - 1);
XClearArea(x11->disp, win->self, OFFS_X, 0, x + OFFS_X, y, False);
TextInRect(x11, win->self, win->text, 2 * OFFS_X, 0, x, y, eXCenter, eYCenter);
break;
dy = XTextHeight(x11->font) + OFFS_Y;
for (i = 0; (i < st->nlines); i++)
{
- TextInRect(x11, win->self, st->lines[i], 0, OFFS_Y + i * dy, win->width, dy, eXLeft,
- eYCenter);
+ TextInRect(x11, win->self, st->lines[i], 0, OFFS_Y + i * dy, win->width, dy, eXLeft, eYCenter);
}
break;
default: return DefWndProc(x11, dlgitem, event);
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2013, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2017,2019, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2017,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.
if (nicon > 0)
{
AddDlgItem(dlg,
- CreatePixmap(XCreatePixmapFromBitmapData(x11->disp, dlg->win.self, icon_bits, icon_width,
- icon_height, icon_fg, icon_bg, x11->depth),
- ID_ICON, ID_BOX, 2 * OFFS_X, 2 * OFFS_Y, icon_width, icon_height, 0));
+ CreatePixmap(
+ XCreatePixmapFromBitmapData(
+ x11->disp, dlg->win.self, icon_bits, icon_width, icon_height, icon_fg, icon_bg, x11->depth),
+ ID_ICON,
+ ID_BOX,
+ 2 * OFFS_X,
+ 2 * OFFS_Y,
+ icon_width,
+ icon_height,
+ 0));
x += QueryDlgItemW(dlg, ID_ICON) + 2 * OFFS_X;
}
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2013, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2017,2019, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2017,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.
{
XSetLineAttributes(disp, gc, 1, LineOnOffDash, CapButt, JoinRound);
XSetForeground(disp, gc, color);
- XDrawRoundRect(disp, win->self, gc, offsx, offsy, win->width - 2 * offsx - 1,
- win->height - 2 * offsy - 1);
+ XDrawRoundRect(
+ disp, win->self, gc, offsx, offsy, win->width - 2 * offsx - 1, win->height - 2 * offsy - 1);
XSetLineAttributes(disp, gc, 1, LineSolid, CapButt, JoinRound);
}
return()
endif()
-set(TESTUTILS_SOURCES
- cmdlinetest.cpp
- conftest.cpp
- filematchers.cpp
- interactivetest.cpp
- loggertest.cpp
- mpi_printer.cpp
- mpitest.cpp
- refdata.cpp
- refdata_xml.cpp
- simulationdatabase.cpp
- stdiohelper.cpp
- stringtest.cpp
- testasserts.cpp
- testfilemanager.cpp
- testfileredirector.cpp
- test_device.cpp
- test_hardware_environment.cpp
- testinit.cpp
- testmatchers.cpp
- testoptions.cpp
- textblockmatchers.cpp
- tprfilegenerator.cpp
- xvgtest.cpp
- )
-
-if(NOT HAVE_TINYXML2)
- list(APPEND TESTUTILS_SOURCES ../external/tinyxml2/tinyxml2.cpp)
-endif()
-
if (GMX_GPU_CUDA)
# Work around FindCUDA that prevents using target_link_libraries()
# with keywords otherwise...
set(CUDA_LIBRARIES PRIVATE ${CUDA_LIBRARIES})
if (NOT GMX_CLANG_CUDA)
- gmx_cuda_add_library(testutils ${TESTUTILS_SOURCES})
+ gmx_cuda_add_library(testutils)
else()
set_source_files_properties(test_device.cpp PROPERTIES CUDA_SOURCE_PROPERTY_FORMAT OBJ)
gmx_compile_cuda_file_with_clang(test_device.cpp)
endif()
target_link_libraries(testutils PRIVATE ${CUDA_CUFFT_LIBRARIES})
else()
- add_library(testutils STATIC ${UNITTEST_TARGET_OPTIONS} ${TESTUTILS_SOURCES})
+ add_library(testutils STATIC ${UNITTEST_TARGET_OPTIONS})
+endif()
+
+# Module interface / provided facilities
+target_include_directories(testutils PUBLIC include)
+
+# Executable targets for tests based on `testutils` acquire the source for
+# their entry point from unittest_main.cpp when linking to the `testutils` target.
+target_sources(testutils INTERFACE unittest_main.cpp)
+
+
+target_sources(testutils PRIVATE
+ cmdlinetest.cpp
+ conftest.cpp
+ filematchers.cpp
+ interactivetest.cpp
+ loggertest.cpp
+ mpi_printer.cpp
+ mpitest.cpp
+ refdata.cpp
+ refdata_xml.cpp
+ simulationdatabase.cpp
+ stdiohelper.cpp
+ stringtest.cpp
+ testasserts.cpp
+ testfilemanager.cpp
+ testfileredirector.cpp
+ test_device.cpp
+ test_hardware_environment.cpp
+ testinit.cpp
+ testmatchers.cpp
+ testoptions.cpp
+ textblockmatchers.cpp
+ tprfilegenerator.cpp
+ xvgtest.cpp
+ )
+
+
+if(HAVE_TINYXML2)
+ target_include_directories(testutils SYSTEM PRIVATE ${TinyXML2_INCLUDE_DIR})
+ target_link_libraries(testutils PRIVATE ${TinyXML2_LIBRARIES})
+else()
+ target_include_directories(testutils SYSTEM BEFORE PRIVATE ${CMAKE_SOURCE_DIR}/src/external/tinyxml2)
+ target_sources(testutils PRIVATE ${CMAKE_SOURCE_DIR}/src/external/tinyxml2/tinyxml2.cpp)
endif()
+target_include_directories(testutils PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
+
if (GMX_GPU_SYCL)
set_source_files_properties(test_device.cpp
PROPERTIES COMPILE_FLAGS "${SYCL_CXX_FLAGS}")
target_compile_definitions(testutils PRIVATE HAVE_CONFIG_H)
target_include_directories(testutils SYSTEM BEFORE PRIVATE ${PROJECT_SOURCE_DIR}/src/external/thread_mpi/include)
target_link_libraries(testutils PRIVATE libgromacs ${GMX_COMMON_LIBRARIES} gmock)
+target_link_libraries(testutils PUBLIC common)
-if(HAVE_TINYXML2)
- include_directories(SYSTEM ${TinyXML2_INCLUDE_DIR})
- target_link_libraries(testutils PRIVATE ${TinyXML2_LIBRARIES})
-else()
- include_directories(BEFORE SYSTEM "../external/tinyxml2")
-endif()
+# GROMACS module dependencies.
+# Note that testutils conveys transitive dependencies on some modules.
+# TODO: Explicitly link specific modules with minimal exposure.
+target_link_libraries(testutils PUBLIC legacy_modules)
# TODO Use gmx_add_missing_tests_notice() instead of the messages below.
set(GMX_CAN_RUN_MPI_TESTS 1)
set(GMX_CAN_RUN_MPI_TESTS 0)
endif()
-set(TESTUTILS_DIR ${CMAKE_CURRENT_SOURCE_DIR})
-set(TESTUTILS_DIR ${TESTUTILS_DIR} PARENT_SCOPE)
set(GMX_CAN_RUN_MPI_TESTS ${GMX_CAN_RUN_MPI_TESTS} PARENT_SCOPE)
add_subdirectory(tests)
cuda_add_executable(${EXENAME} ${UNITTEST_TARGET_OPTIONS}
${ARG_CPP_SOURCE_FILES}
${ARG_CUDA_CU_SOURCE_FILES}
- ${ARG_GPU_CPP_SOURCE_FILES}
- ${TESTUTILS_DIR}/unittest_main.cpp)
+ ${ARG_GPU_CPP_SOURCE_FILES})
else()
add_executable(${EXENAME} ${UNITTEST_TARGET_OPTIONS}
- ${ARG_CPP_SOURCE_FILES}
- ${TESTUTILS_DIR}/unittest_main.cpp)
+ ${ARG_CPP_SOURCE_FILES})
endif()
if (GMX_GPU_CUDA)
endif()
target_link_libraries(${EXENAME} PRIVATE
- testutils libgromacs gmock
+ testutils common libgromacs gmock
${GMX_COMMON_LIBRARIES} ${GMX_EXE_LINKER_FLAGS})
if(GMX_CLANG_TIDY)
*/
#include "gmxpre.h"
-#include "cmdlinetest.h"
+#include "testutils/cmdlinetest.h"
#include <cstdlib>
#include <cstring>
std::vector<const char*> convertFromStringArrayRef(const ArrayRef<const std::string>& cmdline)
{
std::vector<const char*> v(cmdline.size());
- std::transform(cmdline.begin(), cmdline.end(), v.begin(),
- [](const std::string& s) { return s.c_str(); });
+ std::transform(
+ cmdline.begin(), cmdline.end(), v.begin(), [](const std::string& s) { return s.c_str(); });
return v;
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2017,2018,2019,2021, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
*/
#include "gmxpre.h"
-#include "conftest.h"
+#include "testutils/conftest.h"
#include <cstdio>
#include <cstdlib>
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
*/
#include "gmxpre.h"
-#include "filematchers.h"
+#include "testutils/filematchers.h"
#include "gromacs/utility/filestream.h"
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team.
- * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2020,2021, 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.
// arrayref.h is not strictly necessary for this header, but nearly all
// callers will need it to use the constructor that takes ArrayRef.
#include "gromacs/utility/arrayref.h"
-#include "gromacs/utility/classhelpers.h"
namespace gmx
{
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
/*! \libinternal \brief
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
/*! \libinternal \brief
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace test
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2017,2018,2019,2021, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2020,2021, 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.
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2017,2019, by the GROMACS development team, led by
+ * Copyright (c) 2015,2017,2019,2020,2021, 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.
#ifndef GMX_TESTUTILS_INTERACTIVETEST_H
#define GMX_TESTUTILS_INTERACTIVETEST_H
+#include <memory>
+
#include "gromacs/utility/arrayref.h"
-#include "gromacs/utility/classhelpers.h"
namespace gmx
{
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace test
} // namespace gmx
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2017,2019, by the GROMACS development team, led by
+ * Copyright (c) 2016,2017,2019,2020,2021, 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.
#ifndef GMX_TESTUTILS_LOGGERTEST_H
#define GMX_TESTUTILS_LOGGERTEST_H
-#include "gromacs/utility/classhelpers.h"
+#include <memory>
+
#include "gromacs/utility/logger.h"
namespace gmx
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace test
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2019, by the GROMACS development team, led by
+ * Copyright (c) 2016,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.
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2011-2018, The GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
*/
explicit TestReferenceChecker(Impl* impl);
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
/*! \brief
* Needed to expose the constructor only to TestReferenceData.
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2013,2014,2017,2019, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2017,2019,2020,2021, 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.
#ifndef GMX_TESTUTILS_STDIOHELPER_H
#define GMX_TESTUTILS_STDIOHELPER_H
+#include <memory>
+
#include "gromacs/utility/classhelpers.h"
namespace gmx
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012,2013,2014,2015,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
#ifndef GMX_TESTUTILS_STRINGTEST_H
#define GMX_TESTUTILS_STRINGTEST_H
+#include <memory>
#include <string>
#include <gtest/gtest.h>
-#include "gromacs/utility/classhelpers.h"
-
namespace gmx
{
* \param[in] refFilename File with the expected contents.
* \param[in] testFilename File with the contents to be tested.
*/
- void testFilesEqual(const std::string& refFilename, const std::string& testFilename);
+ static void testFilesEqual(const std::string& refFilename, const std::string& testFilename);
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace test
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2020, by the GROMACS development team, led by
+ * Copyright (c) 2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
*/
#include <map>
+#include <memory>
#include <string>
#include <vector>
-#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/gmxassert.h"
class DeviceContext;
//! Implementation type.
class Impl;
//! Implementation object.
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace test
uint64_t doubleUlpDiff)
{
return FloatingPointTolerance(float(magnitude) * singleUlpDiff * GMX_FLOAT_EPS,
- magnitude * doubleUlpDiff * GMX_DOUBLE_EPS, 0.0, 0.0,
- singleUlpDiff, doubleUlpDiff, false);
+ magnitude * doubleUlpDiff * GMX_DOUBLE_EPS,
+ 0.0,
+ 0.0,
+ singleUlpDiff,
+ doubleUlpDiff,
+ false);
}
/*! \brief
static inline FloatingPointTolerance defaultFloatTolerance()
{
return relativeToleranceAsPrecisionDependentUlp(
- 1.0, detail::g_defaultUlpTolerance,
+ 1.0,
+ detail::g_defaultUlpTolerance,
static_cast<uint64_t>(detail::g_defaultUlpTolerance * (GMX_FLOAT_EPS / GMX_DOUBLE_EPS)));
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2011,2012,2015,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2011,2012,2015,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.
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012,2013,2014,2015,2018 by the GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
#ifndef GMX_TESTUTILS_TESTFILEMANAGER_H
#define GMX_TESTUTILS_TESTFILEMANAGER_H
+#include <memory>
#include <string>
-#include "gromacs/utility/classhelpers.h"
-
namespace gmx
{
/*! \libinternal \brief
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace test
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2015,2018,2019,2020,2021, 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.
#ifndef GMX_TESTUTILS_TESTFILEREDIRECTOR_H
#define GMX_TESTUTILS_TESTFILEREDIRECTOR_H
+#include <memory>
#include <set>
#include <string>
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
};
} // namespace test
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012,2013,2014,2015,2018 by the GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
* \param[in] name Name of the options provider (for ordering).
* \param[in] provider The provider to register.
* \throws std::bad_alloc if out of memory.
- * \throws tMPI::system_error on mutex failures.
*
* Typically not used directly in test code, but through the
* #GMX_TEST_OPTIONS macro.
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2015,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.
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2015,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.
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2016,2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,2017,2018,2019,2020, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
*/
#include "gmxpre.h"
-#include "interactivetest.h"
+#include "testutils/interactivetest.h"
#include <string>
#include <utility>
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2017,2019, by the GROMACS development team, led by
+ * Copyright (c) 2016,2017,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.
*/
#include "gmxpre.h"
-#include "loggertest.h"
+#include "testutils/loggertest.h"
#include <gmock/gmock.h>
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
*/
#include "gmxpre.h"
-#include "mpitest.h"
+#include "testutils/mpitest.h"
#include "config.h"
*/
#include "gmxpre.h"
-#include "refdata.h"
+#include "testutils/refdata.h"
#include <cctype>
#include <cstdlib>
#include "gromacs/utility/real.h"
#include "gromacs/utility/stringutil.h"
-#include "testutils/refdata_checkers.h"
-#include "testutils/refdata_impl.h"
-#include "testutils/refdata_xml.h"
#include "testutils/testasserts.h"
#include "testutils/testexceptions.h"
#include "testutils/testfilemanager.h"
+#include "refdata_checkers.h"
+#include "refdata_impl.h"
+#include "refdata_xml.h"
+
namespace gmx
{
namespace test
return TestReferenceChecker(new TestReferenceChecker::Impl(true));
}
impl_->compareRootEntry_->setChecked();
- return TestReferenceChecker(new TestReferenceChecker::Impl(
- "", impl_->compareRootEntry_.get(), impl_->outputRootEntry_.get(),
- impl_->updateMismatchingEntries_, impl_->bSelfTestMode_, defaultRealTolerance()));
+ return TestReferenceChecker(new TestReferenceChecker::Impl("",
+ impl_->compareRootEntry_.get(),
+ impl_->outputRootEntry_.get(),
+ impl_->updateMismatchingEntries_,
+ impl_->bSelfTestMode_,
+ defaultRealTolerance()));
}
{
impl_->outputRootEntry_->addChild(entry->cloneToOutputEntry());
}
- return TestReferenceChecker(new Impl(fullId, entry, entry->correspondingOutputEntry(),
- impl_->updateMismatchingEntries_, impl_->bSelfTestMode_,
+ return TestReferenceChecker(new Impl(fullId,
+ entry,
+ entry->correspondingOutputEntry(),
+ impl_->updateMismatchingEntries_,
+ impl_->bSelfTestMode_,
impl_->defaultTolerance_));
}
void TestReferenceChecker::checkBoolean(bool value, const char* id)
{
- EXPECT_PLAIN(impl_->processItem(Impl::cBooleanNodeName, id,
- ExactStringChecker(value ? "true" : "false")));
+ EXPECT_PLAIN(impl_->processItem(
+ Impl::cBooleanNodeName, id, ExactStringChecker(value ? "true" : "false")));
}
void TestReferenceChecker::checkUChar(unsigned char value, const char* id)
{
- EXPECT_PLAIN(impl_->processItem(Impl::cUCharNodeName, id,
- ExactStringChecker(formatString("%d", value))));
+ EXPECT_PLAIN(impl_->processItem(
+ Impl::cUCharNodeName, id, ExactStringChecker(formatString("%d", value))));
}
void TestReferenceChecker::checkInteger(int value, const char* id)
{
- EXPECT_PLAIN(impl_->processItem(Impl::cIntegerNodeName, id,
- ExactStringChecker(formatString("%d", value))));
+ EXPECT_PLAIN(impl_->processItem(
+ Impl::cIntegerNodeName, id, ExactStringChecker(formatString("%d", value))));
}
void TestReferenceChecker::checkInt32(int32_t value, const char* id)
{
- EXPECT_PLAIN(impl_->processItem(Impl::cInt32NodeName, id,
- ExactStringChecker(formatString("%" PRId32, value))));
+ EXPECT_PLAIN(impl_->processItem(
+ Impl::cInt32NodeName, id, ExactStringChecker(formatString("%" PRId32, value))));
}
void TestReferenceChecker::checkUInt32(uint32_t value, const char* id)
{
- EXPECT_PLAIN(impl_->processItem(Impl::cUInt32NodeName, id,
- ExactStringChecker(formatString("%" PRIu32, value))));
+ EXPECT_PLAIN(impl_->processItem(
+ Impl::cUInt32NodeName, id, ExactStringChecker(formatString("%" PRIu32, value))));
}
void TestReferenceChecker::checkInt64(int64_t value, const char* id)
{
- EXPECT_PLAIN(impl_->processItem(Impl::cInt64NodeName, id,
- ExactStringChecker(formatString("%" PRId64, value))));
+ EXPECT_PLAIN(impl_->processItem(
+ Impl::cInt64NodeName, id, ExactStringChecker(formatString("%" PRId64, value))));
}
void TestReferenceChecker::checkUInt64(uint64_t value, const char* id)
{
- EXPECT_PLAIN(impl_->processItem(Impl::cUInt64NodeName, id,
- ExactStringChecker(formatString("%" PRIu64, value))));
+ EXPECT_PLAIN(impl_->processItem(
+ Impl::cUInt64NodeName, id, ExactStringChecker(formatString("%" PRIu64, value))));
}
void TestReferenceChecker::checkDouble(double value, const char* id)
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2016,2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,2017,2018,2019,2020, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/utility/strconvert.h"
#include "gromacs/utility/stringutil.h"
-#include "testutils/refdata_impl.h"
#include "testutils/testasserts.h"
#include "testutils/testexceptions.h"
+#include "refdata_impl.h"
+
namespace gmx
{
namespace test
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2016,2017,2019, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,2017,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.
#include "gromacs/utility/exceptions.h"
-#include "testutils/refdata_impl.h"
#include "testutils/testexceptions.h"
+#include "refdata_impl.h"
+
namespace gmx
{
namespace test
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2016,2019, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,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.
#include <string>
-#include "testutils/refdata_impl.h"
+#include "refdata_impl.h"
namespace gmx
{
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2016,2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
*/
#include "gmxpre.h"
-#include "simulationdatabase.h"
+#include "testutils/simulationdatabase.h"
#include <algorithm>
#include <map>
{ { { "ref-t", "80" } },
{ // TODO This test case is not currently used, so we
// have not tested which rank counts work.
- 1, 2, 3, 4, 5, 6, 7, 8, 9 } } },
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9 } } },
// Simple system with 2 nearby water molecules
{ "spc2",
{ {},
{ // TODO This test case is not currently used, so we
// have not tested which rank counts work.
- 1, 2, 3, 4, 5, 6, 7, 8, 9 } } },
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9 } } },
// Simple system with 216 water molecules, condensed phase
{ "spc216",
{ {},
{
// TODO This test case is not currently used, so we
// have not tested which rank counts work.
- 1, 2, 3, 4, 5, 6, 7, 8, 9 // TODO tpi test
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9 // TODO tpi test
} } },
// Capped alanine peptide in vacuo with virtual sites
{ "alanine_vsite_vacuo",
{ { { "constraints", "all-bonds" }, { "compressibility", "5e-10" }, { "tau-p", "1000" } },
{ // TODO This test case is not currently used, so we
// have not tested which rank counts work.
- 1, 2, 3, 4, 5, 6, 7, 8, 9 } } },
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9 } } },
// Zwitterionic glycine in vacuo
{ "glycine_vacuo", { { { "constraints", "h-bonds" } }, { 1, 2, 3, 4, 5, 6, 7, 8, 9 } } },
// Zwitterionic glycine in vacuo, without constraints
{ "compressibility", "5e-10" },
{ "tau-p", "1000" },
{ "constraints", "h-bonds" },
- { "other",
- R"(free-energy = yes
- sc-alpha = 0.5
- sc-r-power = 6
- mass-lambdas = 0.0 0.5 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
- bonded-lambdas = 0.0 0.0 0.0 0.5 1.0 1.0 1.0 1.0 1.0 1.0 1.0
- restraint-lambdas = 0.0 0.0 0.0 0.0 0.0 0.5 1.0 1.0 1.0 1.0 1.0
- vdw-lambdas = 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.5 1.0 1.0 1.0
- coul-lambdas = 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.5 1.0
- ;couple-moltype = nonanol
- ;couple-lambda0 = none
- ;couple-lambda1 = vdw-q
- ;couple-intramol = yes)" } },
+ { "free-energy", "yes" },
+ { "sc-alpha", "0.5" },
+ { "sc-r-power", "6" },
+ { "mass-lambdas", "0.0 0.5 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0" },
+ { "bonded-lambdas", "0.0 0.0 0.0 0.5 1.0 1.0 1.0 1.0 1.0 1.0 1.0" },
+ { "restraint-lambdas", "0.0 0.0 0.0 0.0 0.0 0.5 1.0 1.0 1.0 1.0 1.0" },
+ { "vdw-lambdas", "0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.5 1.0 1.0 1.0" },
+ { "coul-lambdas", "0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.5 1.0" },
+ { ";couple-moltype", "nonanol" },
+ { ";couple-lambda0", "none" },
+ { ";couple-lambda1", "vdw-q" },
+ { ";couple-intramol", "yes" } },
{ 1, 2, 3, 4, 5, 6, 8, 9 } } }
};
*
* \throws std::bad_alloc if out of memory
* std::out_of_range if \c simulationName is not in the database
- *
- * Note: Any mdp options that are not added here cannot be used
*/
MdpFieldValues prepareDefaultMdpFieldValues(const std::string& simulationName)
{
mdpFieldValues.insert(MdpField("nstpcouple", "4"));
mdpFieldValues.insert(MdpField("compressibility", "5e-5"));
mdpFieldValues.insert(MdpField("constraints", "none"));
- mdpFieldValues.insert(MdpField("other", ""));
mdpFieldValues.insert(MdpField("coulombtype", "Cut-off"));
mdpFieldValues.insert(MdpField("rcoulomb", "0.7"));
mdpFieldValues.insert(MdpField("vdwtype", "Cut-off"));
mdpFieldValues.insert(MdpField("rvdw", "0.7"));
mdpFieldValues.insert(MdpField("nstcalcenergy", "100"));
+ mdpFieldValues.insert(MdpField("rlist", "-1"));
+ mdpFieldValues.insert(MdpField("bd-fric", "1000"));
+ mdpFieldValues.insert(MdpField("verlet-buffer-tolerance", "0.000001"));
+ mdpFieldValues.insert(MdpField("nstlist", "8"));
+ mdpFieldValues.insert(MdpField("ld-seed", "234262"));
+ mdpFieldValues.insert(MdpField("tau-t", "1"));
+ mdpFieldValues.insert(MdpField("tc-grps", "System"));
+ mdpFieldValues.insert(MdpField("pcoupltype", "isotropic"));
+ mdpFieldValues.insert(MdpField("ref-p", "1"));
+ mdpFieldValues.insert(MdpField("constraint-algorithm", "lincs"));
+ mdpFieldValues.insert(MdpField("lincs-order", "2"));
+ mdpFieldValues.insert(MdpField("lincs-iter", "5"));
return mdpFieldValues;
}
std::string reportNumbersOfPpRanksSupported(const std::string& simulationName)
{
const auto& possibleNumbers = mdpFileValueDatabase_g.at(simulationName).validPpRankCounts;
- return formatAndJoin(std::begin(possibleNumbers), std::end(possibleNumbers), ",",
- StringFormatter("%d"));
+ return formatAndJoin(
+ std::begin(possibleNumbers), std::end(possibleNumbers), ",", StringFormatter("%d"));
}
MdpFieldValues prepareMdpFieldValues(const std::string& simulationName,
* currently have a good way to compare forces at steps where
* energies were not computed with those from rerun on the same
* coordinates.
- *
- * Note: Any mdp options that are not printed here cannot be used
*/
- return formatString(
- R"(coulombtype = %s
- rcoulomb = %s
- vdwtype = %s
- rvdw = %s
- rlist = -1
- bd-fric = 1000
- verlet-buffer-tolerance = 0.000001
- nsteps = %s
- nstenergy = %s
- nstxout = %s
- nstvout = %s
- nstfout = %s
- nstxout-compressed = %s
- nstdhdl = %s
- nstlist = 8
- integrator = %s
- ld-seed = 234262
- tcoupl = %s
- nsttcouple = %s
- ref-t = %s
- tau-t = 1
- tc-grps = System
- pcoupl = %s
- nstpcouple = %s
- pcoupltype = isotropic
- ref-p = 1
- tau-p = %s
- compressibility = %s
- constraints = %s
- constraint-algorithm = lincs
- lincs-order = 2
- lincs-iter = 5
- nstcalcenergy = %s
- comm-mode = %s
- nstcomm = %s
- %s)",
- mdpFieldValues.at("coulombtype").c_str(), mdpFieldValues.at("rcoulomb").c_str(),
- mdpFieldValues.at("vdwtype").c_str(), mdpFieldValues.at("rvdw").c_str(),
- mdpFieldValues.at("nsteps").c_str(), mdpFieldValues.at("nstenergy").c_str(),
- mdpFieldValues.at("nstxout").c_str(), mdpFieldValues.at("nstvout").c_str(),
- mdpFieldValues.at("nstfout").c_str(), mdpFieldValues.at("nstxout-compressed").c_str(),
- mdpFieldValues.at("nstdhdl").c_str(), mdpFieldValues.at("integrator").c_str(),
- mdpFieldValues.at("tcoupl").c_str(), mdpFieldValues.at("nsttcouple").c_str(),
- mdpFieldValues.at("ref-t").c_str(), mdpFieldValues.at("pcoupl").c_str(),
- mdpFieldValues.at("nstpcouple").c_str(), mdpFieldValues.at("tau-p").c_str(),
- mdpFieldValues.at("compressibility").c_str(), mdpFieldValues.at("constraints").c_str(),
- mdpFieldValues.at("nstcalcenergy").c_str(), mdpFieldValues.at("comm-mode").c_str(),
- mdpFieldValues.at("nstcomm").c_str(), mdpFieldValues.at("other").c_str());
+ std::string optionString;
+ for (auto const& [key, value] : mdpFieldValues)
+ {
+ optionString += formatString("%-24s = %s\n", key.c_str(), value.c_str());
+ }
+ return optionString;
}
} // namespace test
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2013,2014,2015,2017,2019, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2017,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.
*/
#include "gmxpre.h"
-#include "stdiohelper.h"
+#include "testutils/stdiohelper.h"
#include <cerrno>
#include <cstdio>
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2013,2014,2015,2019, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015,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.
*/
#include "gmxpre.h"
-#include "stringtest.h"
+#include "testutils/stringtest.h"
#include <string>
*/
#include "gmxpre.h"
-#include "test_device.h"
+#include "testutils/test_device.h"
#include <memory>
#include "gmxpre.h"
-#include "test_hardware_environment.h"
+#include "testutils/test_hardware_environment.h"
#include <memory>
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014,2015,2016,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015,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.
*/
#include "gmxpre.h"
-#include "testasserts.h"
+#include "testutils/testasserts.h"
#include <cmath>
#include <cstdio>
relDiffStr = formatString("Inf");
}
- return formatString("%g (%" PRIu64 " %s-prec. ULPs, rel. %s)%s", absoluteDifference_,
- ulpDifference_, isDouble() ? "double" : "single", relDiffStr.c_str(),
+ return formatString("%g (%" PRIu64 " %s-prec. ULPs, rel. %s)%s",
+ absoluteDifference_,
+ ulpDifference_,
+ isDouble() ? "double" : "single",
+ relDiffStr.c_str(),
bSignDifference_ ? ", signs differ" : "");
}
*/
#include "gmxpre.h"
-#include "testfilemanager.h"
+#include "testutils/testfilemanager.h"
#include <cstdio>
// Assume file is in global directory for simulation input files.
return Path::join(getTestSimulationDatabaseDirectory(), filename);
}
- else
- {
- // Assume file is present locally without full name (e.g. extension).
- return Path::join(getInputDataDirectory(), filename);
- }
+ // Assume file is present locally without full name (e.g. extension).
+ return Path::join(getInputDataDirectory(), filename);
}
std::string TestFileManager::getInputFilePath(const std::string& filename)
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2016,2017,2019, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,2017,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.
*/
#include "gmxpre.h"
-#include "testfileredirector.h"
+#include "testutils/testfileredirector.h"
#include <memory>
#include <set>
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team.
- * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
*/
#include "gmxpre.h"
-#include "testinit.h"
+#include "testutils/testinit.h"
#include <cstdio>
#include <cstdlib>
#include "gromacs/utility/programcontext.h"
#include "gromacs/utility/textwriter.h"
-#include "testutils/mpi_printer.h"
#include "testutils/refdata.h"
#include "testutils/test_hardware_environment.h"
#include "testutils/testfilemanager.h"
#include "testutils/testoptions.h"
+#include "mpi_printer.h"
+
namespace gmx
{
namespace test
int* argc,
char*** argv)
{
-#if !defined NDEBUG \
- && !((defined __clang__ || (defined(__GNUC__) && !defined(__ICC) && __GNUC__ == 7)) \
- && defined __OPTIMIZE__)
- gmx_feenableexcept();
-#endif
+ if (gmxShouldEnableFPExceptions())
+ {
+ gmx_feenableexcept();
+ }
const CommandLineProgramContext& context = initForCommandLine(argc, argv);
try
{
"NOTE: You are running %s on %d MPI ranks, "
"but it is does not contain MPI-enabled tests. "
"The test will now exit.\n",
- context.programName(), gmx_node_num());
+ context.programName(),
+ gmx_node_num());
}
finalizeForCommandLine();
std::exit(1);
*/
#include "gmxpre.h"
-#include "testmatchers.h"
+#include "testutils/testmatchers.h"
#include <memory>
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2013,2014,2015,2019, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
*/
#include "gmxpre.h"
-#include "testoptions.h"
+#include "testutils/testoptions.h"
#include <list>
+#include <mutex>
+#include <memory>
#include "gromacs/utility/classhelpers.h"
-#include "gromacs/utility/mutex.h"
namespace gmx
{
//! Adds a provider into the registry.
void add(const char* /*name*/, TestOptionsProvider* provider)
{
- lock_guard<Mutex> lock(listMutex_);
+ std::lock_guard<std::mutex> lock(listMutex_);
providerList_.push_back(provider);
}
typedef std::list<TestOptionsProvider*> ProviderList;
- Mutex listMutex_;
+ std::mutex listMutex_;
ProviderList providerList_;
GMX_DISALLOW_COPY_AND_ASSIGN(TestOptionsRegistry);
{
// TODO: Have some deterministic order for the options; now it depends on
// the order in which the global initializers are run.
- lock_guard<Mutex> lock(listMutex_);
+ std::lock_guard<std::mutex> lock(listMutex_);
ProviderList::const_iterator i;
for (i = providerList_.begin(); i != providerList_.end(); ++i)
{
testasserts_tests.cpp
xvgtest_tests.cpp
)
+target_link_libraries(testutils-test PRIVATE testutils)
gmx_add_mpi_unit_test(TestUtilsMpiUnitTests testutils-mpi-test 2
CPP_SOURCE_FILES
mpitest.cpp
)
+target_link_libraries(testutils-test PRIVATE testutils)
checkXvgFile(&sis, &checker, XvgMatchSettings());
}
{
- const char* const input[] = { "0 2905.86 -410.199", "0.2 6656.67 -430.437",
+ const char* const input[] = { "0 2905.86 -410.199",
+ "0.2 6656.67 -430.437",
"0.4 5262.44 -409.399" };
// Now check with missing data
TestReferenceData data(ReferenceDataMode::Compare);
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2015,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.
*/
#include "gmxpre.h"
-#include "textblockmatchers.h"
+#include "testutils/textblockmatchers.h"
#include <memory>
#include <regex>
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
#include "gmxpre.h"
-#include "tprfilegenerator.h"
+#include "testutils/tprfilegenerator.h"
#include "gromacs/gmxpreprocess/grompp.h"
#include "gromacs/utility/textwriter.h"
int main(int argc, char* argv[])
{
// Calls ::testing::InitGoogleMock()
- ::gmx::test::initTestUtils(TEST_DATA_PATH, TEST_TEMP_PATH, TEST_USES_MPI,
- TEST_USES_HARDWARE_DETECTION, &argc, &argv);
+ ::gmx::test::initTestUtils(
+ TEST_DATA_PATH, TEST_TEMP_PATH, TEST_USES_MPI, TEST_USES_HARDWARE_DETECTION, &argc, &argv);
int errcode = RUN_ALL_TESTS();
::gmx::test::finalizeTestUtils();
return errcode;
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2016,2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,2017,2018,2019,2020, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
*/
#include "gmxpre.h"
-#include "xvgtest.h"
+#include "testutils/xvgtest.h"
#include <cerrno>
#include <cstdlib>
set(REGRESSIONTEST_DOWNLOAD OFF CACHE BOOL "Tests already downloaded. Set to yes to download again" FORCE)
endif()
-if(REGRESSIONTEST_PATH AND (CMAKE_CROSSCOMPILING OR CMAKE_CONFIGURATION_TYPES OR GMX_BUILD_MDRUN_ONLY))
+if(REGRESSIONTEST_PATH AND (CMAKE_CROSSCOMPILING OR CMAKE_CONFIGURATION_TYPES))
# TODO: It would be nicer to do these checks before potentially downloading the tests.
# Cross-compiling toolchains require us to compile both front-end and
# back-end binaries to run gmxtest.pl.
- # Testing an mdrun-only builds require supporting binaries from a full build
message(WARNING
- "With cross-compiling, multi-configuration generators (e.g. Visual Studio), or with mdrun-only builds, running regressiontests from build system is not supported. Please run gmxtest.pl directly.")
+ "With cross-compiling or multi-configuration generators (e.g. Visual Studio), running regressiontests from build system is not supported. Please run gmxtest.pl directly.")
set(REGRESSIONTEST_PATH OFF CACHE BOOL
"With cross-compiling or multi-configuration generators, running regressiontests from build system is not supported." FORCE)
endif()
list(APPEND ARGS -suffix ${GMX_BINARY_SUFFIX})
endif()
#crosscompile is only used to disable checking whether binaries work
- #given that we know they are there and that mdrun might not be exectuable
+ #given that we know they are there and that mdrun might not be executable
#(e.g. Cray) we enable it.
list(APPEND ARGS -crosscompile)
"GMX_PHYSICAL_VALIDATION set, but physical validation script not found in ${PHYSVALTEST_SOURCE_PATH}.")
endif()
- if(CMAKE_CROSSCOMPILING OR CMAKE_CONFIGURATION_TYPES OR GMX_BUILD_MDRUN_ONLY)
+ if(CMAKE_CROSSCOMPILING OR CMAKE_CONFIGURATION_TYPES)
# The following comment is copied from regression tests:
# Cross-compiling toolchains require us to compile both front-end and
# back-end binaries to run gmxtest.pl.
- # Testing an mdrun-only builds require supporting binaries from a full build
# TODO: Look into the details of this.
# For now, turn it off - our python-gmx interface is probably not that stable for special cases anyway
message(WARNING
- "With cross-compiling, multi-configuration generators (e.g. Visual Studio), or with mdrun-only builds,\
+ "With cross-compiling or multi-configuration generators (e.g. Visual Studio),\
running physical validation tests from build system is not supported.\
Please run physicalvalidation.py directly.")
set(GMX_PHYSICAL_VALIDATION OFF CACHE BOOL