Merge branch origin/release-2020 into master
authorPaul Bauer <paul.bauer.q@gmail.com>
Tue, 7 Jan 2020 13:09:57 +0000 (14:09 +0100)
committerPaul Bauer <paul.bauer.q@gmail.com>
Tue, 7 Jan 2020 13:09:57 +0000 (14:09 +0100)
Final merge needed for release-2020 into master

Change-Id: I93a44684f002997dfa8590c865103b436f3e3e93

24 files changed:
.gitlab-ci.yml
admin/builds/gromacs.py
admin/ci-templates/.build-cache-template.yml
admin/ci-templates/.build-docs-template.yml
admin/ci-templates/.build-template.yml
cmake/gmxVersionInfo.cmake
docs/CMakeLists.txt
docs/gmxapi/userguide-stub/pythonreference.rst
docs/gmxapi/userguide/install.rst
docs/release-notes/2020/2020.1.rst [new file with mode: 0644]
docs/release-notes/2020/major/highlights.rst
docs/release-notes/index.rst
docs/user-guide/environment-variables.rst
src/gromacs/fileio/tests/CMakeLists.txt
src/gromacs/fileio/tests/fileioxdrserializer.cpp [new file with mode: 0644]
src/gromacs/gmxpreprocess/topio.cpp
src/gromacs/listed_forces/bonded.cpp
src/gromacs/mdlib/lincs_cuda.cu
src/gromacs/mdlib/sim_util.cpp
src/gromacs/mdrun/runner.cpp
src/gromacs/taskassignment/decidegpuusage.cpp
src/gromacs/taskassignment/decidegpuusage.h
src/gromacs/utility/inmemoryserializer.cpp
src/gromacs/utility/tests/inmemoryserializer.cpp

index a1081c2f83ebc974505c01f96c296acd82f522c4..813245e0a41e819b082843bf26cd32a14ba3413e 100644 (file)
@@ -4,14 +4,14 @@ include:
 .configure-extends-template:
     extends:
         - .configure-build-template
-        - .configure-cache-template
+        - .no-cache-template
         - .variables-template
         - .tags-template
 
 .configure-release-extends-template:
     extends:
         - .configure-build-release-template
-        - .release-configure-cache-template
+        - .no-cache-template
         - .variables-template
         - .tags-template
 
@@ -181,7 +181,7 @@ prepare-release-version:
 simple-build:
     extends:
       - .simple-build-template
-      - .simple-build-cache-template
+      - .build-cache-template
       - .variables-template
       - .tags-template
       - .gcc-before-script-template
@@ -962,7 +962,7 @@ webpage-configure-release:
     extends:
       - .configure-docs-release
       - .configure-gmxapi-template
-      - .release-configure-cache-template
+      - .no-cache-template
     only:
       refs:
         - web
@@ -980,7 +980,7 @@ webpage-configure-release:
 configure-gcc-7-release:
     extends:
       - .configure-gcc-release
-      - .release-configure-cache-template
+      - .no-cache-template
       - .gcc7-template
     variables:
         COMPILER_MAJOR_VERSION: 7
@@ -1001,7 +1001,7 @@ configure-gcc-7-gmxapi-release:
     extends:
       - .configure-gcc-release
       - .configure-gmxapi-template
-      - .release-configure-cache-template
+      - .no-cache-template
       - .gcc7-template
     variables:
         COMPILER_MAJOR_VERSION: 7
@@ -1021,7 +1021,7 @@ configure-gcc-7-gmxapi-release:
 configure-gcc-7-double-release:
     extends:
       - .configure-gcc-release
-      - .release-configure-cache-template
+      - .no-cache-template
       - .gcc7-template
     variables:
         COMPILER_MAJOR_VERSION: 7
@@ -1042,7 +1042,7 @@ configure-gcc-7-double-release:
 configure-gcc-8-release:
     extends:
       - .configure-gcc-release
-      - .release-configure-cache-template
+      - .no-cache-template
       - .gcc8-template
     variables:
         COMPILER_MAJOR_VERSION: 8
@@ -1062,7 +1062,7 @@ configure-gcc-8-release:
 configure-clang-7-release:
     extends:
       - .configure-clang-release
-      - .release-configure-cache-template
+      - .no-cache-template
       - .clang7-template
     variables:
         COMPILER_MAJOR_VERSION: 7
@@ -1083,7 +1083,7 @@ configure-clang-7-gmxapi-release:
     extends:
       - .configure-clang-release
       - .configure-gmxapi-template
-      - .release-configure-cache-template
+      - .no-cache-template
       - .clang7-template
     variables:
         COMPILER_MAJOR_VERSION: 7
@@ -1103,7 +1103,7 @@ configure-clang-7-gmxapi-release:
 configure-clang-8-release:
     extends:
       - .configure-clang-release
-      - .release-configure-cache-template
+      - .no-cache-template
       - .clang8-template
     variables:
         COMPILER_MAJOR_VERSION: 8
index e429c623bc650b256c17992060950b8a5cd426dc..a8a4f7047df1ca6bb64849489056016bc1146732 100644 (file)
@@ -1,7 +1,7 @@
 #
 # 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.
@@ -186,6 +186,8 @@ def do_build(context):
     # GPU update flag enables GPU update+constraints as well as buffer ops (dependency)
     if context.opts.gpuupdate:
         context.env.set_env_var('GMX_FORCE_UPDATE_DEFAULT_GPU', "1")
+        context.env.set_env_var('GMX_GPU_DD_COMMS', "1")
+        context.env.set_env_var('GMX_GPU_PME_PP_COMMS', "1")
 
     regressiontests_path = context.workspace.get_project_dir(Project.REGRESSIONTESTS)
 
index dbdfda82755975adc8ebcc72e4087ea27757c5ce..c65c8333e33796cbadde39f5706b0157961ba4ca 100644 (file)
@@ -1,24 +1,5 @@
-.configure-cache-template:
-    cache:
-      key: "$CI_JOB_NAME-$CI_JOB_STAGE-$CI_COMMIT_REF_SLUG"
-      paths:
-        - $BUILD_DIR/CMakeCache.txt
-
 .build-cache-template:
     cache:
       key: "$CI_JOB_NAME-$CI_JOB_STAGE-$CI_COMMIT_REF_SLUG"
       paths:
         - ccache/
-
-.release-configure-cache-template:
-    cache:
-      key: "$CI_JOB_NAME-$CI_JOB_STAGE-$CI_COMMIT_REF_SLUG"
-      paths:
-        - $RELEASE_BUILD_DIR/CMakeCache.txt
-
-.simple-build-cache-template:
-    cache:
-      key: "$CI_JOB_NAME-$CI_JOB_STAGE-$CI_COMMIT_REF_SLUG"
-      paths:
-        - $BUILD_DIR/CMakeCache.txt
-        - ccache/
index 51a7b967e6481790f5290ec0610eb11c14ff50a2..45274461466733916ecca615e4061396a6dbbd6d 100644 (file)
     - echo $CMAKE_GMXAPI_OPTIONS
     - echo $REL_OPTION
     - if [[ -d $BUILD_DIR ]] ; then
-      echo "Cleaning up build directory" ;
-      mv $BUILD_DIR/CMakeCache.txt . ;
-      rm -rf $BUILD_DIR && mkdir $BUILD_DIR ;
-      mv CMakeCache.txt $BUILD_DIR ;
+        rm -rf $BUILD_DIR && mkdir $BUILD_DIR ;
       else
-      echo "Preparing new build directory" ;
-      mkdir $BUILD_DIR ;
+        echo "Preparing new build directory" ;
+        mkdir $BUILD_DIR ;
       fi
     - cd $BUILD_DIR
     - cmake ..
     KUBERNETES_MEMORY_LIMIT: 2Gi
     CMAKE_COMPILER_SCRIPT: "-DCMAKE_C_COMPILER=clang-7 -DCMAKE_CXX_COMPILER=clang++-7"
     CMAKE_EXTRA_OPTIONS: ""
-    CMAKE_SIMD_OPTIONS: "-DGMX_SIMD=AUTO"
+    CMAKE_SIMD_OPTIONS: "-DGMX_SIMD=None"
     CMAKE_MPI_OPTIONS: "-DGMX_THREAD_MPI=ON"
     CMAKE_PRECISION_OPTIONS: "-DGMX_DOUBLE=OFF"
     CMAKE_BUILD_TYPE_OPTIONS: "-DCMAKE_BUILD_TYPE=Debug"
     CMAKE_GPU_OPTIONS: "-DGMX_GPU=OFF"
     CMAKE_GMXAPI_OPTIONS: "-DGMX_PYTHON_PACKAGE=OFF"
-    RELEASE_FILE_DIR: release-files
     RELEASE_BUILD_DIR: release-doc-builds
+    RELEASE_SOURCE: release-source-from-tarball
+    RELEASE_REGRESSIONTESTS: release-regressiontests-from-tarball
 
   only:
     refs:
     - REGTESTNAME=regressiontests-$VERSION
     - REGTESTTARBALL=$REGTESTNAME.tar.gz
     - SOURCE_MD5SUM=`md5sum $SOURCETARBALL | awk '{print $1}'`
-    - rm -rf $RELEASE_FILE_DIR && mkdir $RELEASE_FILE_DIR
-    - mv $SOURCETARBALL $RELEASE_FILE_DIR
-    - mv $REGTESTTARBALL $RELEASE_FILE_DIR 
-    - cd $RELEASE_FILE_DIR
+    - RELEASE_TARBALLS=release-tarballs
+    - rm -rf $RELEASE_TARBALLS $RELEASE_SOURCE $RELEASE_REGRESSIONTESTS && mkdir $RELEASE_TARBALLS
+    - mv $SOURCETARBALL $RELEASE_TARBALLS
+    - mv $REGTESTTARBALL $RELEASE_TARBALLS
+    - cd $RELEASE_TARBALLS
+# We rename the source and regressiontest directories
+# to have names for them that don't change for different versions.
     - tar -xf $SOURCETARBALL
+    - mv $SOURCENAME ../$RELEASE_SOURCE
     - tar -xf $REGTESTTARBALL
+    - mv $REGTESTNAME ../$RELEASE_REGRESSIONTESTS
     - rm $SOURCETARBALL $REGTESTTARBALL
     - cd ..
+    - echo $CMAKE_COMPILER_SCRIPT
+    - echo $CMAKE_EXTRA_OPTIONS
+    - echo $CMAKE_SIMD_OPTIONS
+    - echo $CMAKE_GPU_OPTIONS
+    - echo $CMAKE_MPI_OPTIONS
+    - echo $CMAKE_PRECISION_OPTIONS
+    - echo $CMAKE_BUILD_TYPE_OPTIONS
+    - echo $CMAKE_GMXAPI_OPTIONS
     - if [[ -d $RELEASE_BUILD_DIR ]] ; then
-      echo "Cleaning up build directory" ;
-      mv $RELEASE_BUILD_DIR/CMakeCache.txt . ;
-      rm -rf $RELEASE_BUILD_DIR && mkdir $RELEASE_BUILD_DIR ;
-      mv CMakeCache.txt $RELEASE_BUILD_DIR ;
+        echo "Cleaning up build directory" ;
+        rm -rf $RELEASE_BUILD_DIR && mkdir $RELEASE_BUILD_DIR ;
       else
-      echo "Preparing new build directory" ;
-      mkdir $RELEASE_BUILD_DIR ;
+        echo "Preparing new build directory" ;
+        mkdir $RELEASE_BUILD_DIR ;
       fi
     - cd $RELEASE_BUILD_DIR
-    - cmake ../$RELEASE_FILE_DIR/$SOURCENAME
+    - cmake ../$RELEASE_SOURCE/
         -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
         $CMAKE_COMPILER_SCRIPT
         $CMAKE_EXTRA_OPTIONS
         $CMAKE_GMXAPI_OPTIONS
         $REL_OPTION
         "-DSOURCE_MD5SUM=$SOURCE_MD5SUM"
-        "-DREGRESSIONTEST_PATH=../$RELEASE_FILE_DIR/$REGTESTNAME"
+        "-DREGRESSIONTEST_PATH=../$RELEASE_REGRESSIONTESTS"
         -DCMAKE_INSTALL_PREFIX=../$INSTALL_DIR -DGMX_COMPILER_WARNINGS=ON
         2>&1 | tee cmakeLog.log
     - awk '/CMake Warning/,/^--|^$/' cmakeLog.log | tee cmakeErrors.log
     expire_in: 1 week
     paths:
       - $RELEASE_BUILD_DIR
-      - $RELEASE_FILE_DIR
+      - $RELEASE_REGRESSIONTESTS
+      - $RELEASE_SOURCE
index 2465d3d1d54bdc2c9a2c0cd29a6b8659d25d45ff..9911a1de48cdc0b95d1e8f219bb237427b2401a0 100644 (file)
     - echo $CMAKE_BUILD_TYPE_OPTIONS
     - echo $CMAKE_GMXAPI_OPTIONS
     - if [[ -d $BUILD_DIR ]] ; then
-      echo "Cleaning up build directory" ;
-      mv $BUILD_DIR/CMakeCache.txt . ;
-      rm -rf $BUILD_DIR && mkdir $BUILD_DIR ;
-      mv CMakeCache.txt $BUILD_DIR ;
+        rm -rf $BUILD_DIR && mkdir $BUILD_DIR ;
       else
-      echo "Preparing new build directory" ;
-      mkdir $BUILD_DIR ;
+        echo "Preparing new build directory" ;
+        mkdir $BUILD_DIR ;
       fi
     - cd $BUILD_DIR
     - cmake ..
@@ -72,8 +69,9 @@
     CMAKE_BUILD_TYPE_OPTIONS: "-DCMAKE_BUILD_TYPE=RelWithAssert"
     CMAKE_GPU_OPTIONS: "-DGMX_GPU=OFF"
     CMAKE_GMXAPI_OPTIONS: "-DGMX_PYTHON_PACKAGE=OFF"
-    RELEASE_FILE_DIR: release-files
     RELEASE_BUILD_DIR: release-builds
+    RELEASE_SOURCE: release-source-from-tarball
+    RELEASE_REGRESSIONTESTS: release-regressiontests-from-tarball
 
   only:
     refs:
     - REGTESTTARBALL=$REGTESTNAME.tar.gz
     - echo "$SOURCETARBALL"
     - echo "$REGTESTTARBALL"
-    - rm -rf $RELEASE_FILE_DIR && mkdir $RELEASE_FILE_DIR
-    - mv $SOURCETARBALL $RELEASE_FILE_DIR
-    - mv $REGTESTTARBALL $RELEASE_FILE_DIR
-    - cd $RELEASE_FILE_DIR
+    - RELEASE_TARBALLS=release-tarballs
+    - rm -rf $RELEASE_TARBALLS $RELEASE_SOURCE $RELEASE_REGRESSIONTESTS && mkdir $RELEASE_TARBALLS
+    - mv $SOURCETARBALL $RELEASE_TARBALLS
+    - mv $REGTESTTARBALL $RELEASE_TARBALLS
+    - cd $RELEASE_TARBALLS
+# We rename the source and regressiontest directories
+# to have names for them that don't change for different versions.
     - tar -xf $SOURCETARBALL
+    - mv $SOURCENAME ../$RELEASE_SOURCE
     - tar -xf $REGTESTTARBALL
+    - mv $REGTESTNAME ../$RELEASE_REGRESSIONTESTS
     - rm $SOURCETARBALL $REGTESTTARBALL
     - cd ..
     - echo $CMAKE_COMPILER_SCRIPT
     - echo $CMAKE_BUILD_TYPE_OPTIONS
     - echo $CMAKE_GMXAPI_OPTIONS
     - if [[ -d $RELEASE_BUILD_DIR ]] ; then
-      echo "Cleaning up build directory" ;
-      mv $RELEASE_BUILD_DIR/CMakeCache.txt . ;
-      rm -rf $RELEASE_BUILD_DIR && mkdir $RELEASE_BUILD_DIR ;
-      mv CMakeCache.txt $RELEASE_BUILD_DIR ;
+        echo "Cleaning up build directory" ;
+        rm -rf $RELEASE_BUILD_DIR && mkdir $RELEASE_BUILD_DIR ;
       else
-      echo "Preparing new build directory" ;
-      mkdir $RELEASE_BUILD_DIR ;
+        echo "Preparing new build directory" ;
+        mkdir $RELEASE_BUILD_DIR ;
       fi
     - cd $RELEASE_BUILD_DIR
-    - cmake ../$RELEASE_FILE_DIR/$SOURCENAME
+    - cmake ../$RELEASE_SOURCE/
         -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
         $CMAKE_COMPILER_SCRIPT
         $CMAKE_EXTRA_OPTIONS
         $CMAKE_BUILD_TYPE_OPTIONS
         $CMAKE_GPU_OPTIONS
         $CMAKE_GMXAPI_OPTIONS
-        "-DREGRESSIONTEST_PATH=../$RELEASE_FILE_DIR/$REGTESTNAME"
+        "-DREGRESSIONTEST_PATH=../$RELEASE_REGRESSIONTESTS"
         -DCMAKE_INSTALL_PREFIX=../$INSTALL_DIR -DGMX_COMPILER_WARNINGS=ON
         2>&1 | tee cmakeLog.log
     - awk '/CMake Warning/,/^--|^$/' cmakeLog.log | tee cmakeErrors.log
     when: always
     paths:
       - $RELEASE_BUILD_DIR
-      - $RELEASE_FILE_DIR
+      - $RELEASE_REGRESSIONTESTS
+      - $RELEASE_SOURCE
 
 .binary-build-template:
   # Dockerfiles are from dockerhub, user eriklindahl
     - echo $CMAKE_BUILD_TYPE_OPTIONS
     - echo $CMAKE_GMXAPI_OPTIONS
     - if [[ -d $BUILD_DIR ]] ; then
-      echo "Cleaning up build directory" ;
-      mv $BUILD_DIR/CMakeCache.txt . ;
-      rm -rf $BUILD_DIR && mkdir $BUILD_DIR ;
-      mv CMakeCache.txt $BUILD_DIR ;
+        echo "Cleaning up build directory" ;
+        rm -rf $BUILD_DIR && mkdir $BUILD_DIR ;
       else
-      echo "Preparing new build directory" ;
-      mkdir $BUILD_DIR ;
+        echo "Preparing new build directory" ;
+        mkdir $BUILD_DIR ;
       fi
     - cd $BUILD_DIR
     - cmake ..
index 42f59adeab0737fe75f04e4aebe7bfbfb52148d0..d5788c7ff3107267df35249bc42f475262f5fc49 100644 (file)
@@ -261,7 +261,7 @@ set(REGRESSIONTEST_BRANCH "refs/heads/master")
 # build the regressiontests tarball with all the right naming. The
 # naming affects the md5sum that has to go here, and if it isn't right
 # release workflow will report a failure.
-set(REGRESSIONTEST_MD5SUM "42e3bfe74a8e8bf8e38919e10aaf8fa1" CACHE INTERNAL "MD5 sum of the regressiontests tarball for this GROMACS version")
+set(REGRESSIONTEST_MD5SUM "2fe8e35878bc9ee3cf60e92d5b250175" CACHE INTERNAL "MD5 sum of the regressiontests tarball for this GROMACS version")
 
 math(EXPR GMX_VERSION_NUMERIC
      "${GMX_VERSION_MAJOR}*10000 + ${GMX_VERSION_PATCH}")
index 99310f3417a84c977c67c63110ea08217d74de8c..3830be1293ef17df9af99d03faa440195f5c3a27 100644 (file)
@@ -370,6 +370,7 @@ if (SPHINX_FOUND)
         release-notes/2021/major/deprecated-functionality.rst
         release-notes/2021/major/portability.rst
         release-notes/2021/major/miscellaneous.rst
+        release-notes/2020/2020.1.rst
         release-notes/2020/major/highlights.rst
         release-notes/2020/major/features.rst
         release-notes/2020/major/performance.rst
index 40fbf8f78af0d8c9401775db5debbed9694d3f4d..d6d73bc9af029b46cd62ade3b819bcb5aec1ea24 100644 (file)
@@ -29,6 +29,4 @@ Refer to the Python source code itself for additional clarification.
     :doc:`installing the gmxapi package <../userguide/install>`,
     and therefore lacks the full module reference.
     Refer to :ref:`gmxapi_package_documentation` for instructions on building
-    complete documentation, or `view online <http://gmxapi.org/>`__.
-
-.. todo:: :issue:`2985` Replace reference URL with http://manual.gromacs.org/current/gmxapi/
+    complete documentation, or `view online <http://manual.gromacs.org/current/gmxapi/>`__.
index 10d9c36bfacf0f136082aa8f5efc7d77b4327a5d..f4fb5844ea0f9aca27f94817d9a80c7c3e83cdae 100644 (file)
@@ -466,11 +466,9 @@ be accessed in the usual ways, using ``pydoc`` from the command line or
 ``help()`` in an interactive Python session.
 
 The complete documentation (which you are currently reading)
-can be browsed `online <http://gmxapi.org/>`__
+can be browsed `online <http://manual.gromacs.org/current/gmxapi/>`__
 or built from a copy of the GROMACS source repository.
 
-.. todo:: :issue:`2985` Replace reference URL with http://manual.gromacs.org/current/gmxapi/
-
 Documentation is built from a combination of Python module documentation and
 static content, and requires a local copy of the GROMACS source repository.
 
diff --git a/docs/release-notes/2020/2020.1.rst b/docs/release-notes/2020/2020.1.rst
new file mode 100644 (file)
index 0000000..6bee9f5
--- /dev/null
@@ -0,0 +1,28 @@
+GROMACS 2020.1 release notes
+----------------------------
+
+This version was released on TODO, 2020. These release notes
+document the changes that have taken place in GROMACS since the
+previous 2020 version, to fix known issues. It also incorporates all
+fixes made in version 2019.5 and earlier, which you can find described
+in the :ref:`release-notes`.
+
+.. 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 redmine, without the
+   a space between the colon and number!
+
+Fixes where mdrun could behave incorrectly
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Fixes for ``gmx`` tools
+^^^^^^^^^^^^^^^^^^^^^^^
+
+Fixes that affect portability
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+
+Miscellaneous
+^^^^^^^^^^^^^
+
index 2cb6fd097f5ba93612bf871028021225a4bd72f4..316064f872b8ab870459f95df457a620fecc858b 100644 (file)
@@ -1,7 +1,7 @@
 Highlights
 ^^^^^^^^^^
 
-|Gromacs| 2020 was released on INSERT DATE HERE. Patch releases may
+|Gromacs| 2020 was released on January 1, 2020. 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!
@@ -19,6 +19,8 @@ simulations and hardware. The new features are:
 * New modular simulator that can be built from individual objects describing different
   calculations happening at each simulation step.
 * Parrinello-Rahman pressure coupling is now also available for the md-vv integrator.
+* Running almost the entire simulation step on a single CUDA compatible GPU for supported
+  types of simulations, including coordinate update and constraint calculation.
 
 
 .. Note to developers!
index ee390badc02d75946af0be1ea6b1008f569bdd35..db768ddfee3518c6f9652e702a577725995913f2 100644 (file)
@@ -45,6 +45,14 @@ Major release
 |Gromacs| 2020 series
 ---------------------
 
+Patch releases
+^^^^^^^^^^^^^^
+
+.. toctree::
+   :maxdepth: 1
+
+   2020/2020.1
+
 Major release
 ^^^^^^^^^^^^^
 
index d0fd44c7e9031ad1b9e8ef73cb7210c0a4cfe379..832554796881bc10ed30de5c69758fd3825b1793 100644 (file)
@@ -230,6 +230,14 @@ Performance and Run Control
 ``GMX_FORCE_UPDATE``
         update forces when invoking ``mdrun -rerun``.
 
+``GMX_FORCE_UPDATE_DEFAULT_GPU``
+        Force update to run on the GPU by default, overriding the ``mdrun -update auto`` option. Works similar to setting
+        ``mdrun -update gpu``, but (1) falls back to the CPU code-path, if set with input that is not supported and
+        (2) can be used to run update on GPUs in multi-rank cases. The latter case should be
+        considered experimental since it lacks substantial testing. Also, GPU update is only supported with the GPU direct
+        communications and ``GMX_FORCE_UPDATE_DEFAULT_GPU`` variable should be set simultaneously with ``GMX_GPU_DD_COMMS``
+        and ``GMX_GPU_PME_PP_COMMS`` environment variables in multi-rank case. Does not override ``mdrun -update cpu``.
+
 ``GMX_GPU_ID``
         set in the same way as ``mdrun -gpu_id``, ``GMX_GPU_ID``
         allows the user to specify different GPU IDs for different ranks, which can be useful for selecting different
index 788cdaa6da486929845760af4efa64cb151699d0..72984e185e26a12052d6c5b1c91ecce413084f63 100644 (file)
@@ -1,7 +1,7 @@
 #
 # This file is part of the GROMACS molecular simulation package.
 #
-# Copyright (c) 2013,2014,2015,2016,2018,2019, by the GROMACS development team, led by
+# Copyright (c) 2013,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.
@@ -39,6 +39,7 @@ set(test_sources
     mrcdensitymap.cpp
     mrcdensitymapheader.cpp
     readinp.cpp
+    fileioxdrserializer.cpp
     )
 if (GMX_USE_TNG)
     list(APPEND test_sources tngio.cpp)
diff --git a/src/gromacs/fileio/tests/fileioxdrserializer.cpp b/src/gromacs/fileio/tests/fileioxdrserializer.cpp
new file mode 100644 (file)
index 0000000..fb4dcf5
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * 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.
+ */
+/*! \internal \file
+ * \brief
+ * Tests for gmx::FileIOXdrSerializer.
+ *
+ * \author Mark Abraham <mark.j.abraham@gmail.com>
+ * \ingroup module_fileio
+ */
+
+#include "gmxpre.h"
+
+#include <gtest/gtest.h>
+
+#include "gromacs/fileio/gmxfio.h"
+#include "gromacs/fileio/gmxfio_xdr.h"
+#include "gromacs/utility/futil.h"
+
+#include "testutils/testfilemanager.h"
+
+namespace gmx
+{
+namespace test
+{
+namespace
+{
+union IntAndFloat32 {
+    std::int32_t int32Value_;
+    float        floatValue_;
+};
+
+union IntAndFloat64 {
+    std::int64_t int64Value_;
+    double       doubleValue_;
+};
+
+//! Constants used for testing endian swap operations
+//! \{
+constexpr std::int16_t c_int16Value = static_cast<std::int16_t>(0x7A2B);
+constexpr std::int32_t c_int32Value = static_cast<std::int32_t>(0x78ABCDEF);
+constexpr std::int64_t c_int64Value = static_cast<std::int64_t>(0x78ABCDEF12345678);
+
+constexpr const IntAndFloat32 c_intAndFloat32{ c_int32Value };
+constexpr const IntAndFloat64 c_intAndFloat64{ c_int64Value };
+//! \}
+
+//! Return the integer used for testing, depending on the size of int.
+constexpr int integerSizeDependentTestingValue()
+{
+    return sizeof(int) == 4 ? c_int32Value : sizeof(int) == 8 ? c_int64Value : c_int16Value;
+}
+
+class FileIOXdrSerializerTest : public ::testing::Test
+{
+public:
+    ~FileIOXdrSerializerTest() override
+    {
+        if (file_)
+        {
+            gmx_fio_close(file_);
+        }
+    }
+    struct SerializerValues
+    {
+        bool           boolValue_          = true;
+        unsigned char  unsignedCharValue_  = 0x78;
+        char           charValue_          = 0x78;
+        unsigned short unsignedShortValue_ = static_cast<unsigned short>(c_int16Value);
+        std::int32_t   int32Value_         = c_int32Value;
+        float          floatValue_         = c_intAndFloat32.floatValue_;
+        std::int64_t   int64Value_         = c_int64Value;
+        double         doubleValue_        = c_intAndFloat64.doubleValue_;
+        int            intValue_           = integerSizeDependentTestingValue();
+        real           realValue_          = std::is_same<real, double>::value
+                                  ? static_cast<real>(c_intAndFloat64.doubleValue_)
+                                  : static_cast<real>(c_intAndFloat32.floatValue_);
+    } defaultValues_;
+
+    TestFileManager fileManager_;
+    // Make sure the file extension is one that gmx_fio_open will
+    // recognize to open as binary, even though we're just abusing it
+    // to write arbitrary XDR output.
+    std::string filename_ = fileManager_.getTemporaryFilePath("data.edr");
+    t_fileio*   file_     = nullptr;
+};
+
+TEST_F(FileIOXdrSerializerTest, SizeIsCorrect)
+{
+    file_ = gmx_fio_open(filename_.c_str(), "w");
+    FileIOXdrSerializer serializer(file_);
+    // These types all have well-defined widths in bytes AFTER XDR serialization,
+    // which we can test below.
+    serializer.doBool(&defaultValues_.boolValue_);     // 4 bytes
+    serializer.doChar(&defaultValues_.charValue_);     // 4 bytes
+    serializer.doInt32(&defaultValues_.int32Value_);   // 4 bytes
+    serializer.doInt64(&defaultValues_.int64Value_);   // 8 bytes
+    serializer.doFloat(&defaultValues_.floatValue_);   // 4 bytes
+    serializer.doDouble(&defaultValues_.doubleValue_); // 8 bytes
+    std::vector<char> charBuffer = { 'a', 'b', 'c' };
+    serializer.doCharArray(charBuffer.data(), charBuffer.size()); // 12 bytes
+    serializer.doOpaque(charBuffer.data(), charBuffer.size());    // 4 bytes
+    std::vector<int32_t> int32Buffer = { 0x1BCDEF78, 0x654321FE };
+    serializer.doInt32Array(int32Buffer.data(), int32Buffer.size()); // 8 bytes
+    std::vector<int64_t> int64Buffer = { 0x1BCDEF78654321FE, 0x3726ABFEAB34716C };
+    serializer.doInt64Array(int64Buffer.data(), int64Buffer.size()); // 16 bytes
+    gmx_fio_close(file_);
+
+    file_ = gmx_fio_open(filename_.c_str(), "r");
+
+    // Determine file size
+    gmx_fseek(gmx_fio_getfp(file_), 0, SEEK_END);
+    gmx_off_t fileSize = gmx_fio_ftell(file_);
+    EXPECT_EQ(fileSize, 72);
+}
+
+} // namespace
+} // namespace test
+} // namespace gmx
index 041cb951369c199c3d1edc0ab149e35e61be157b..40d6dde12c63f9b5ecb92289e3de5ea4237c6116 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016,2017,2018,2019,2020, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
@@ -886,8 +886,14 @@ static char** read_topol(const char*                           infile,
                 "multiple-time-stepping scheme for a twin-range cut-off. When used with "
                 "a single-range cut-off (or a correct Trotter multiple-time-stepping scheme), "
                 "physical properties, such as the density, might differ from the intended values. "
-                "Check if molecules in your system are affected by such issues before proceeding. "
-                "Further information may be available at https://redmine.gromacs.org/issues/2884.");
+                "Since there are researchers actively working on validating GROMOS with modern "
+                "integrators we have not yet removed the GROMOS force fields, but you should be "
+                "aware of these issues and check if molecules in your system are affected before "
+                "proceeding. "
+                "Further information is available at https://redmine.gromacs.org/issues/2884 , "
+                "and a longer explanation of our decision to remove physically incorrect "
+                "algorithms "
+                "can be found at https://doi.org/10.26434/chemrxiv.11474583.v1 .");
     }
 
     cpp_done(handle);
index 0d6fe533e511b8795c968333f7fe12ad421632ed..db99ec4d954df9312af6614a700bf05dfeafb8a4 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016,2017,2018,2019,2020, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
@@ -896,7 +896,7 @@ real thole_pol(int             nbonds,
 // #3205 for more information)
 #if defined(__GNUC__) && defined(__i386__) && defined(__OPTIMIZE__)
 #    pragma GCC push_options
-#    pragma GCC optimize("O2")
+#    pragma GCC optimize("O1")
 #    define avoid_gcc_i386_o3_code_generation_bug
 #endif
 
index 1a48c3bc955bc92b089c4d1ba4cfccd513948897..08b17e3083ddde0275c9bc41374c216154eeba49 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * 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.
@@ -548,18 +548,35 @@ LincsCuda::~LincsCuda()
     }
 }
 
-/*! \brief Constructs and returns an atom constraint adjacency list
- *
- * Each constraint will be represented as a tuple, containing index of the second
- * constrained atom, index of the constraint and a sign that indicates the order of atoms in
- * which they are listed. Sign is needed to compute the mass factors.
- */
-static std::vector<std::vector<std::tuple<int, int, int>>>
+//! Helper type for discovering coupled constraints
+struct AtomsAdjacencyListElement
+{
+    AtomsAdjacencyListElement(const int indexOfSecondConstrainedAtom,
+                              const int indexOfConstraint,
+                              const int signFactor) :
+        indexOfSecondConstrainedAtom_(indexOfSecondConstrainedAtom),
+        indexOfConstraint_(indexOfConstraint),
+        signFactor_(signFactor)
+    {
+    }
+    //! The index of the other atom constrained to this atom.
+    int indexOfSecondConstrainedAtom_;
+    //! The index of this constraint in the container of constraints.
+    int indexOfConstraint_;
+    /*! \brief A multiplicative factor that indicates the relative
+     * order of the atoms in the atom list.
+     *
+     * Used for computing the mass factor of this constraint
+     * relative to any coupled constraints. */
+    int signFactor_;
+};
+//! Constructs and returns an atom constraint adjacency list
+static std::vector<std::vector<AtomsAdjacencyListElement>>
 constructAtomsAdjacencyList(const int numAtoms, ArrayRef<const int> iatoms)
 {
     const int                                           stride         = 1 + NRAL(F_CONSTR);
     const int                                           numConstraints = iatoms.ssize() / stride;
-    std::vector<std::vector<std::tuple<int, int, int>>> atomsAdjacencyList(numAtoms);
+    std::vector<std::vector<AtomsAdjacencyListElement>> atomsAdjacencyList(numAtoms);
     for (int c = 0; c < numConstraints; c++)
     {
         int a1 = iatoms[stride * c + 1];
@@ -568,8 +585,8 @@ constructAtomsAdjacencyList(const int numAtoms, ArrayRef<const int> iatoms)
         // Each constraint will be represented as a tuple, containing index of the second
         // constrained atom, index of the constraint and a sign that indicates the order of atoms in
         // which they are listed. Sign is needed to compute the mass factors.
-        atomsAdjacencyList[a1].push_back(std::make_tuple(a2, c, +1));
-        atomsAdjacencyList[a2].push_back(std::make_tuple(a1, c, -1));
+        atomsAdjacencyList[a1].emplace_back(a2, c, +1);
+        atomsAdjacencyList[a2].emplace_back(a1, c, -1);
     }
 
     return atomsAdjacencyList;
@@ -595,17 +612,19 @@ constructAtomsAdjacencyList(const int numAtoms, ArrayRef<const int> iatoms)
  */
 inline int countCoupled(int           a,
                         ArrayRef<int> numCoupledConstraints,
-                        ArrayRef<const std::vector<std::tuple<int, int, int>>> atomsAdjacencyList)
+                        ArrayRef<const std::vector<AtomsAdjacencyListElement>> atomsAdjacencyList)
 
 {
     int counted = 0;
     for (const auto& adjacentAtom : atomsAdjacencyList[a])
     {
-        const int c2 = std::get<1>(adjacentAtom);
+        const int c2 = adjacentAtom.indexOfConstraint_;
         if (numCoupledConstraints[c2] == -1)
         {
             numCoupledConstraints[c2] = 0; // To indicate we've been here
-            counted += 1 + countCoupled(std::get<0>(adjacentAtom), numCoupledConstraints, atomsAdjacencyList);
+            counted += 1
+                       + countCoupled(adjacentAtom.indexOfSecondConstrainedAtom_,
+                                      numCoupledConstraints, atomsAdjacencyList);
         }
     }
     return counted;
@@ -629,7 +648,7 @@ inline int countCoupled(int           a,
  */
 inline void addWithCoupled(ArrayRef<const int>                                    iatoms,
                            const int                                              stride,
-                           ArrayRef<const std::vector<std::tuple<int, int, int>>> atomsAdjacencyList,
+                           ArrayRef<const std::vector<AtomsAdjacencyListElement>> atomsAdjacencyList,
                            ArrayRef<int>                                          splitMap,
                            const int                                              c,
                            int*                                                   currentMapIndex)
@@ -645,7 +664,7 @@ inline void addWithCoupled(ArrayRef<const int>
             const int a1 = iatoms[stride * c + 1 + atomIndexInConstraint];
             for (const auto& adjacentAtom : atomsAdjacencyList[a1])
             {
-                const int c2 = std::get<1>(adjacentAtom);
+                const int c2 = adjacentAtom.indexOfConstraint_;
                 if (c2 != c)
                 {
                     addWithCoupled(iatoms, stride, atomsAdjacencyList, splitMap, c2, currentMapIndex);
@@ -664,7 +683,7 @@ inline void addWithCoupled(ArrayRef<const int>
  * numCoupledConstraints vector is also used to keep track if the constrain was already counted.
  */
 static std::vector<int> countNumCoupledConstraints(ArrayRef<const int> iatoms,
-                                                   ArrayRef<const std::vector<std::tuple<int, int, int>>> atomsAdjacencyList)
+                                                   ArrayRef<const std::vector<AtomsAdjacencyListElement>> atomsAdjacencyList)
 {
     const int        stride         = 1 + NRAL(F_CONSTR);
     const int        numConstraints = iatoms.ssize() / stride;
@@ -821,21 +840,17 @@ void LincsCuda::set(const t_idef& idef, const t_mdatoms& md)
         coupledConstraintsCountsHost.at(splitMap.at(c1)) = 0;
         int c1a1                                         = iatoms[stride * c1 + 1];
         int c1a2                                         = iatoms[stride * c1 + 2];
-        int c2;
-        int c2a1;
-        int c2a2;
 
-        int sign;
-
-        // Constraints, coupled trough the first atom.
-        c2a1 = c1a1;
-        for (unsigned j = 0; j < atomsAdjacencyList.at(c1a1).size(); j++)
+        // Constraints, coupled through the first atom.
+        int c2a1 = c1a1;
+        for (const auto& atomAdjacencyList : atomsAdjacencyList[c1a1])
         {
-
-            std::tie(c2a2, c2, sign) = atomsAdjacencyList.at(c1a1).at(j);
+            int c2 = atomAdjacencyList.indexOfConstraint_;
 
             if (c1 != c2)
             {
+                int c2a2  = atomAdjacencyList.indexOfSecondConstrainedAtom_;
+                int sign  = atomAdjacencyList.signFactor_;
                 int index = kernelParams_.numConstraintsThreads
                                     * coupledConstraintsCountsHost.at(splitMap.at(c1))
                             + splitMap.at(c1);
@@ -855,13 +870,14 @@ void LincsCuda::set(const t_idef& idef, const t_mdatoms& md)
 
         // Constraints, coupled through the second atom.
         c2a1 = c1a2;
-        for (unsigned j = 0; j < atomsAdjacencyList.at(c1a2).size(); j++)
+        for (const auto& atomAdjacencyList : atomsAdjacencyList[c1a2])
         {
-
-            std::tie(c2a2, c2, sign) = atomsAdjacencyList.at(c1a2).at(j);
+            int c2 = atomAdjacencyList.indexOfConstraint_;
 
             if (c1 != c2)
             {
+                int c2a2  = atomAdjacencyList.indexOfSecondConstrainedAtom_;
+                int sign  = atomAdjacencyList.signFactor_;
                 int index = kernelParams_.numConstraintsThreads
                                     * coupledConstraintsCountsHost.at(splitMap.at(c1))
                             + splitMap.at(c1);
index 938e774d5d85a65cd365b78d3ffbc2d2eb7d925f..2f0018f4d12e188329570591505d4b2af24df3e1 100644 (file)
@@ -1297,7 +1297,7 @@ void do_force(FILE*                               fplog,
                 // Note: GPU update + DD without direct communication is not supported,
                 // a waitCoordinatesReadyOnHost() should be issued if it will be.
                 GMX_ASSERT(!simulationWork.useGpuUpdate,
-                           "GPU update is not supported with halo exchange");
+                           "GPU update is not supported with CPU halo exchange");
                 dd_move_x(cr->dd, box, x.unpaddedArrayRef(), wcycle);
             }
 
index 95a95f5c24decd92f1de1f8df98417ca5ec6c3a6..6f287b8d93c1dd1405c4893867ff3c9528c37fa7 100644 (file)
@@ -1191,9 +1191,10 @@ int Mdrunner::mdrunner()
         const bool useUpdateGroups = cr->dd ? ddUsesUpdateGroups(*cr->dd) : false;
 
         useGpuForUpdate = decideWhetherToUseGpuForUpdate(
-                devFlags.forceGpuUpdateDefault, useDomainDecomposition, useUpdateGroups, useGpuForPme,
-                useGpuForNonbonded, updateTarget, gpusWereDetected, *inputrec, mtop, doEssentialDynamics,
-                gmx_mtop_ftype_count(mtop, F_ORIRES) > 0, replExParams.exchangeInterval > 0, doRerun);
+                devFlags.forceGpuUpdateDefault, useDomainDecomposition, useUpdateGroups, pmeRunMode,
+                domdecOptions.numPmeRanks > 0, useGpuForNonbonded, updateTarget, gpusWereDetected,
+                *inputrec, mtop, doEssentialDynamics, gmx_mtop_ftype_count(mtop, F_ORIRES) > 0,
+                replExParams.exchangeInterval > 0, doRerun, mdlog);
     }
     GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
 
index bfd43291b253cb55c63ad9c10c65d26064b208ff..c184f89a7698117d27fd597f90c11179fff99b75 100644 (file)
@@ -489,19 +489,21 @@ bool decideWhetherToUseGpusForBonded(const bool       useGpuForNonbonded,
     return gpusWereDetected && usingOurCpuForPmeOrEwald;
 }
 
-bool decideWhetherToUseGpuForUpdate(const bool        forceGpuUpdateDefault,
-                                    const bool        isDomainDecomposition,
-                                    const bool        useUpdateGroups,
-                                    const bool        useGpuForPme,
-                                    const bool        useGpuForNonbonded,
-                                    const TaskTarget  updateTarget,
-                                    const bool        gpusWereDetected,
-                                    const t_inputrec& inputrec,
-                                    const gmx_mtop_t& mtop,
-                                    const bool        useEssentialDynamics,
-                                    const bool        doOrientationRestraints,
-                                    const bool        useReplicaExchange,
-                                    const bool        doRerun)
+bool decideWhetherToUseGpuForUpdate(const bool           forceGpuUpdateDefault,
+                                    const bool           isDomainDecomposition,
+                                    const bool           useUpdateGroups,
+                                    const PmeRunMode     pmeRunMode,
+                                    const bool           havePmeOnlyRank,
+                                    const bool           useGpuForNonbonded,
+                                    const TaskTarget     updateTarget,
+                                    const bool           gpusWereDetected,
+                                    const t_inputrec&    inputrec,
+                                    const gmx_mtop_t&    mtop,
+                                    const bool           useEssentialDynamics,
+                                    const bool           doOrientationRestraints,
+                                    const bool           useReplicaExchange,
+                                    const bool           doRerun,
+                                    const gmx::MDLogger& mdlog)
 {
 
     // '-update cpu' overrides the environment variable, '-update auto' does not
@@ -536,11 +538,16 @@ bool decideWhetherToUseGpuForUpdate(const bool        forceGpuUpdateDefault,
     // Using the GPU-version of update if:
     // 1. PME is on the GPU (there should be a copy of coordinates on GPU for PME spread), or
     // 2. Non-bonded interactions are on the GPU.
-    if (!(useGpuForPme || useGpuForNonbonded))
+    if (pmeRunMode == PmeRunMode::CPU && !useGpuForNonbonded)
     {
         errorMessage +=
                 "Either PME or short-ranged non-bonded interaction tasks must run on the GPU.\n";
     }
+    // Since only direct GPU communications are supported with GPU update, PME should be fully offloaded in DD and PME only cases.
+    if (pmeRunMode != PmeRunMode::GPU && (isDomainDecomposition || havePmeOnlyRank))
+    {
+        errorMessage += "PME should run on GPU.\n";
+    }
     if (!gpusWereDetected)
     {
         errorMessage += "Compatible GPUs must have been found.\n";
@@ -616,7 +623,18 @@ bool decideWhetherToUseGpuForUpdate(const bool        forceGpuUpdateDefault,
 
     if (!errorMessage.empty())
     {
-        if (updateTarget == TaskTarget::Gpu)
+        if (updateTarget != TaskTarget::Gpu && forceGpuUpdateDefault)
+        {
+            GMX_LOG(mdlog.warning)
+                    .asParagraph()
+                    .appendText(
+                            "Update task on the GPU was required, by the "
+                            "GMX_FORCE_UPDATE_DEFAULT_GPU environment variable, but the following "
+                            "condition(s) were not satisfied:");
+            GMX_LOG(mdlog.warning).asParagraph().appendText(errorMessage.c_str());
+            GMX_LOG(mdlog.warning).asParagraph().appendText("Will use CPU version of update.");
+        }
+        else if (updateTarget == TaskTarget::Gpu)
         {
             std::string prefix = gmx::formatString(
                     "Update task on the GPU was required,\n"
index 573cac02cfcbf742df5015b9a403c6913643f275..4d924438fbe3d01662799dce118a485e6729f410 100644 (file)
 struct gmx_hw_info_t;
 struct gmx_mtop_t;
 struct t_inputrec;
+enum class PmeRunMode;
 
 namespace gmx
 {
 
+class MDLogger;
+
 //! Record where a compute task is targetted.
 enum class TaskTarget : int
 {
@@ -235,7 +238,8 @@ bool decideWhetherToUseGpusForBonded(bool       useGpuForNonbonded,
  * \param[in]  forceGpuUpdateDefault        If update should run on GPU by default.
  * \param[in]  isDomainDecomposition        Whether there more than one domain.
  * \param[in]  useUpdateGroups              If the constraints can be split across domains.
- * \param[in]  useGpuForPme                 Whether GPUs will be used for PME interactions.
+ * \param[in]  pmeRunMode                   PME running mode: CPU, GPU or mixed.
+ * \param[in]  havePmeOnlyRank              If there is a PME-only rank in the simulation.
  * \param[in]  useGpuForNonbonded           Whether GPUs will be used for nonbonded interactions.
  * \param[in]  updateTarget                 User choice for running simulation on GPU.
  * \param[in]  gpusWereDetected             Whether compatible GPUs were detected on any node.
@@ -245,24 +249,27 @@ bool decideWhetherToUseGpusForBonded(bool       useGpuForNonbonded,
  * \param[in]  doOrientationRestraints      If orientation restraints are enabled.
  * \param[in]  useReplicaExchange           If this is a REMD simulation.
  * \param[in]  doRerun                      It this is a rerun.
+ * \param[in]  mdlog                        MD logger.
  *
  * \returns    Whether complete simulation can be run on GPU.
  * \throws     std::bad_alloc            If out of memory
  *             InconsistentInputError    If the user requirements are inconsistent.
  */
-bool decideWhetherToUseGpuForUpdate(bool              forceGpuUpdateDefault,
-                                    bool              isDomainDecomposition,
-                                    bool              useUpdateGroups,
-                                    bool              useGpuForPme,
-                                    bool              useGpuForNonbonded,
-                                    TaskTarget        updateTarget,
-                                    bool              gpusWereDetected,
-                                    const t_inputrec& inputrec,
-                                    const gmx_mtop_t& mtop,
-                                    bool              useEssentialDynamics,
-                                    bool              doOrientationRestraints,
-                                    bool              useReplicaExchange,
-                                    bool              doRerun);
+bool decideWhetherToUseGpuForUpdate(bool                 forceGpuUpdateDefault,
+                                    bool                 isDomainDecomposition,
+                                    bool                 useUpdateGroups,
+                                    PmeRunMode           pmeRunMode,
+                                    bool                 havePmeOnlyRank,
+                                    bool                 useGpuForNonbonded,
+                                    TaskTarget           updateTarget,
+                                    bool                 gpusWereDetected,
+                                    const t_inputrec&    inputrec,
+                                    const gmx_mtop_t&    mtop,
+                                    bool                 useEssentialDynamics,
+                                    bool                 doOrientationRestraints,
+                                    bool                 useReplicaExchange,
+                                    bool                 doRerun,
+                                    const gmx::MDLogger& mdlog);
 
 
 } // namespace gmx
index e24befae3f47af7ca253e5f1dcfa722bf8167a88..832077e9da5c354dc7f182c8d5825e16b7b96ee3 100644 (file)
  * 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
+ * Defines gmx::ISerializer implementation for in-memory serialization.
+ *
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
+ * \ingroup module_utility
+ */
 #include "gmxpre.h"
 
 #include "inmemoryserializer.h"
@@ -90,11 +97,11 @@ T swapEndian(const T& value)
     return endianessSwappedValue.value_;
 }
 
-//! \brief Change the host-dependent endian settings to either Swap or DoNotSwap.
-//
-// \param endianSwapBehavior input swap behavior, might depend on host.
-//
-// \return Host-independent setting, either Swap or DoNotSwap.
+/*! \brief Change the host-dependent endian settings to either Swap or DoNotSwap.
+ *
+ * \param endianSwapBehavior input swap behavior, might depend on host.
+ *
+ * \return Host-independent setting, either Swap or DoNotSwap. */
 EndianSwapBehavior setEndianSwapBehaviorFromHost(EndianSwapBehavior endianSwapBehavior)
 {
     if (endianSwapBehavior == EndianSwapBehavior::SwapIfHostIsBigEndian)
index d11e6c91697dafe448431750ea50ecd196437a7f..06b3d0e23683b8d4fd6fec95df76cb98d89051a6 100644 (file)
@@ -241,6 +241,28 @@ TEST_F(InMemorySerializerTest, DeserializerExplicitEndianessSwap)
     checkSerializerValuesforEquality(endianessSwappedValues_, deserialisedValues);
 }
 
+TEST_F(InMemorySerializerTest, SizeIsCorrect)
+{
+    InMemorySerializer serializer;
+    // These types all have well-defined widths in bytes,
+    // which we can test below.
+    serializer.doBool(&defaultValues_.boolValue_);     // 1 bytes
+    serializer.doChar(&defaultValues_.charValue_);     // 1 bytes
+    serializer.doInt32(&defaultValues_.int32Value_);   // 4 bytes
+    serializer.doInt64(&defaultValues_.int64Value_);   // 8 bytes
+    serializer.doFloat(&defaultValues_.floatValue_);   // 4 bytes
+    serializer.doDouble(&defaultValues_.doubleValue_); // 8 bytes
+    std::vector<char> charBuffer = { 'a', 'b', 'c' };
+    serializer.doCharArray(charBuffer.data(), charBuffer.size()); // 3 bytes
+    serializer.doOpaque(charBuffer.data(), charBuffer.size());    // 3 bytes
+    std::vector<int32_t> int32Buffer = { 0x1BCDEF78, 0x654321FE };
+    serializer.doInt32Array(int32Buffer.data(), int32Buffer.size()); // 8 bytes
+    std::vector<int64_t> int64Buffer = { 0x1BCDEF78654321FE, 0x3726ABFEAB34716C };
+    serializer.doInt64Array(int64Buffer.data(), int64Buffer.size()); // 16 bytes
+    auto buffer = serializer.finishAndGetBuffer();
+    EXPECT_EQ(buffer.size(), 56);
+}
+
 } // namespace
 } // namespace test
 } // namespace gmx