Merge origin/release-2020 into master
authorPaul Bauer <paul.bauer.q@gmail.com>
Sat, 30 Nov 2019 10:58:42 +0000 (11:58 +0100)
committerPaul Bauer <paul.bauer.q@gmail.com>
Sat, 30 Nov 2019 10:58:42 +0000 (11:58 +0100)
Resolved Conflicts:
src/gromacs/mdlib/update.cpp
src/gromacs/mdrun/md.cpp

Change-Id: Ibf1c632cc3096121dccd6c1c1af9bff3d590d18f

49 files changed:
admin/clang-format.sh
cmake/gmxVersionInfo.cmake
docs/CMakeLists.txt
docs/dev-manual/build-system.rst
docs/release-notes/2021/major/bugs-fixed.rst [new file with mode: 0644]
docs/release-notes/2021/major/deprecated-functionality.rst [new file with mode: 0644]
docs/release-notes/2021/major/features.rst [new file with mode: 0644]
docs/release-notes/2021/major/highlights.rst [new file with mode: 0644]
docs/release-notes/2021/major/miscellaneous.rst [new file with mode: 0644]
docs/release-notes/2021/major/performance.rst [new file with mode: 0644]
docs/release-notes/2021/major/portability.rst [new file with mode: 0644]
docs/release-notes/2021/major/removed-functionality.rst [new file with mode: 0644]
docs/release-notes/2021/major/tools.rst [new file with mode: 0644]
docs/release-notes/index.rst
src/CMakeLists.txt
src/gromacs/domdec/domdec.cpp
src/gromacs/domdec/domdec.h
src/gromacs/domdec/domdec_topology.cpp
src/gromacs/domdec/partition.cpp
src/gromacs/domdec/redistribute.cpp
src/gromacs/domdec/utility.h
src/gromacs/gmxlib/nonbonded/nb_free_energy.cpp
src/gromacs/mdlib/force.cpp
src/gromacs/mdlib/forcerec.cpp
src/gromacs/mdlib/forcerec.h
src/gromacs/mdlib/leapfrog_cuda.cu
src/gromacs/mdlib/leapfrog_cuda.cuh
src/gromacs/mdlib/lincs_cuda.cu
src/gromacs/mdlib/lincs_cuda.cuh
src/gromacs/mdlib/qm_gaussian.cpp
src/gromacs/mdlib/qm_gaussian.h
src/gromacs/mdlib/qm_orca.cpp
src/gromacs/mdlib/qm_orca.h
src/gromacs/mdlib/qmmm.cpp
src/gromacs/mdlib/qmmm.h
src/gromacs/mdlib/settle_cuda.cu
src/gromacs/mdlib/settle_cuda.cuh
src/gromacs/mdlib/sim_util.cpp
src/gromacs/mdlib/tests/constrtestrunners.cu
src/gromacs/mdlib/tests/settletestrunners.cu
src/gromacs/mdlib/update_constrain_cuda_impl.cu
src/gromacs/mdlib/wall.cpp
src/gromacs/mdrun/runner.cpp
src/gromacs/mdtypes/forcerec.h
src/gromacs/mdtypes/state_propagator_data_gpu_impl_gpu.cpp
src/gromacs/nbnxm/atomdata.cpp
src/gromacs/nbnxm/atomdata.h
src/gromacs/nbnxm/benchmark/bench_setup.cpp
src/gromacs/nbnxm/benchmark/bench_system.cpp

index ae8f61dfbde939d1e6441f8c0f9bdfd3d190ed4e..e4ab728c0ee440dd51dcc0df853680f05024f5ba 100755 (executable)
@@ -98,7 +98,7 @@ then
     if [ -z "$CLANG_FORMAT" ]
     then
         echo "Please set the path to clang-format using the git hook"
-        echo "git config hooks.clang_formatpath /path/to/clang-format"
+        echo "git config hooks.clangformatpath /path/to/clang-format"
         echo "or by setting an environment variable, e.g."
         echo "CLANG_FORMAT=/path/to/clang-format"
         echo "See docs/dev-manual/code-formatting.rst for how to get clang-format."
index f34389fe3b5142ec0db59a807a0b2a974a127dc1..8f0b1a0ab67399777de9f6851eda13b53c64a9e8 100644 (file)
@@ -58,6 +58,7 @@
 #         GROMACS     2018   3
 #         GROMACS     2019   4
 #         GROMACS     2020   5
+#         GROMACS     2021   6
 #   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 2020)
+set(GMX_VERSION_MAJOR 2021)
 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
 # as after the final release is out.
-set(GMX_VERSION_SUFFIX "-beta2")
+set(GMX_VERSION_SUFFIX "")
 
 # Conventionally with libtool, any ABI change must change the major
 # version number, the minor version number should change if it's just
@@ -212,7 +213,7 @@ set(GMX_VERSION_SUFFIX "-beta2")
 # 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 5)
+set(LIBRARY_SOVERSION_MAJOR 6)
 set(LIBRARY_SOVERSION_MINOR 0)
 set(LIBRARY_VERSION ${LIBRARY_SOVERSION_MAJOR}.${LIBRARY_SOVERSION_MINOR}.0)
 
@@ -254,7 +255,7 @@ if (NOT SOURCE_IS_SOURCE_DISTRIBUTION AND
 endif()
 
 set(REGRESSIONTEST_VERSION "${GMX_VERSION_STRING}")
-set(REGRESSIONTEST_BRANCH "refs/heads/release-2020")
+set(REGRESSIONTEST_BRANCH "refs/heads/master")
 # Run the regressiontests packaging job with the correct pakage
 # version string, and the release box checked, in order to have it
 # build the regressiontests tarball with all the right naming. The
index 4371469b305c1da57432c6019ac9338523916248..85afcbc9b6243844fcb4c4737c52eda3948caeb9 100644 (file)
@@ -361,6 +361,15 @@ if (SPHINX_FOUND)
         how-to/visualize.rst
         install-guide/index.rst
         release-notes/index.rst
+        release-notes/2021/major/highlights.rst
+        release-notes/2021/major/features.rst
+        release-notes/2021/major/performance.rst
+        release-notes/2021/major/tools.rst
+        release-notes/2021/major/bugs-fixed.rst
+        release-notes/2021/major/removed-functionality.rst
+        release-notes/2021/major/deprecated-functionality.rst
+        release-notes/2021/major/portability.rst
+        release-notes/2021/major/miscellaneous.rst
         release-notes/2020/major/highlights.rst
         release-notes/2020/major/features.rst
         release-notes/2020/major/performance.rst
index f7a3f0ab400ef653e9bc95913007e260046d4d58..0b0591138d81a04109dd7ef376db4d35c0d4a74f 100644 (file)
@@ -354,7 +354,7 @@ Variables affecting the ``all`` target
   version 8.0.* with libstdc++<7 or libc++ is supported. Others might miss tests or give false positives.
   It is run automatically on Jenkins for each commit. Many checks have fixes which can automatically be
   applied. To run it, the build has to be configured with
-  ``cmake -DGMX_CLANG_TIDY=ON -DGMX_OPENMP=no -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=on``.
+  ``cmake -DGMX_CLANG_TIDY=ON -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=on``.
   Any ``CMAKE_BUILD_TYPE`` which enables asserts (e.g. ASAN) works. Such a configured build will
   run both the compiler as well as clang-tidy when building. The name of the clang-tidy executable is set with
   ``-DCLANG_TIDY=...``, and the full path to it can be set with ``-DCLANG_TIDY_EXE=...``.
diff --git a/docs/release-notes/2021/major/bugs-fixed.rst b/docs/release-notes/2021/major/bugs-fixed.rst
new file mode 100644 (file)
index 0000000..1db0c1e
--- /dev/null
@@ -0,0 +1,9 @@
+Bugs fixed
+^^^^^^^^^^
+
+.. 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!
+
diff --git a/docs/release-notes/2021/major/deprecated-functionality.rst b/docs/release-notes/2021/major/deprecated-functionality.rst
new file mode 100644 (file)
index 0000000..bf68600
--- /dev/null
@@ -0,0 +1,14 @@
+.. _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 redmine, without the
+   a space between the colon and number!
+
+Changes anticipated to |Gromacs| 2021 functionality
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Functionality deprecated in |Gromacs| 2021
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/docs/release-notes/2021/major/features.rst b/docs/release-notes/2021/major/features.rst
new file mode 100644 (file)
index 0000000..4fab02b
--- /dev/null
@@ -0,0 +1,9 @@
+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 redmine, without the
+   a space between the colon and number!
+
diff --git a/docs/release-notes/2021/major/highlights.rst b/docs/release-notes/2021/major/highlights.rst
new file mode 100644 (file)
index 0000000..3bcb16d
--- /dev/null
@@ -0,0 +1,22 @@
+Highlights
+^^^^^^^^^^
+
+|Gromacs| 2021 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 quote autogenerator
+
+
+.. 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!
diff --git a/docs/release-notes/2021/major/miscellaneous.rst b/docs/release-notes/2021/major/miscellaneous.rst
new file mode 100644 (file)
index 0000000..96513fa
--- /dev/null
@@ -0,0 +1,9 @@
+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 redmine, without the
+   a space between the colon and number!
+
diff --git a/docs/release-notes/2021/major/performance.rst b/docs/release-notes/2021/major/performance.rst
new file mode 100644 (file)
index 0000000..0a72678
--- /dev/null
@@ -0,0 +1,9 @@
+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 redmine, without the
+   a space between the colon and number!
+
diff --git a/docs/release-notes/2021/major/portability.rst b/docs/release-notes/2021/major/portability.rst
new file mode 100644 (file)
index 0000000..48bba8a
--- /dev/null
@@ -0,0 +1,9 @@
+Portability
+^^^^^^^^^^^
+
+.. 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!
+
diff --git a/docs/release-notes/2021/major/removed-functionality.rst b/docs/release-notes/2021/major/removed-functionality.rst
new file mode 100644 (file)
index 0000000..e6a6459
--- /dev/null
@@ -0,0 +1,9 @@
+Removed functionality
+^^^^^^^^^^^^^^^^^^^^^
+
+.. 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!
+
diff --git a/docs/release-notes/2021/major/tools.rst b/docs/release-notes/2021/major/tools.rst
new file mode 100644 (file)
index 0000000..3451957
--- /dev/null
@@ -0,0 +1,9 @@
+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 redmine, without the
+   a space between the colon and number!
+
index bfb9ab19afa60d3101646d7a99b290f10595e0ea..9385728e7612a905d5e5eb33748a10343ad07960 100644 (file)
@@ -8,18 +8,38 @@ releases of |Gromacs|. Major releases contain changes to the
 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 2020
-series and the 2019 series. In the latter, only highly conservative
+Two versions of |Gromacs| are under active maintenance, the 2021
+series and the 2020 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 2019 ends, but we keep 2018 in the name so users understand how
+year 2020 ends, but we keep 2019 in the name so users understand how
 up to date their version is. Such fixes will also be incorporated into
-the 2020 release series, as appropriate. Around the time the 2021
-release is made, the 2019 series will no longer be maintained.
+the 2021 release series, as appropriate. Around the time the 2022
+release is made, the 2020 series will no longer be maintained.
 
 Where issue numbers are reported in these release notes, more details
 can be found at https://redmine.gromacs.org at that issue number.
 
+|Gromacs| 2021 series
+---------------------
+
+Major release
+^^^^^^^^^^^^^
+
+.. toctree::
+   :maxdepth: 1
+
+   2021/major/highlights
+   2021/major/features
+   2021/major/performance
+   2021/major/tools
+   2021/major/bugs-fixed
+   2021/major/deprecated-functionality
+   2021/major/removed-functionality
+   2021/major/portability
+   2021/major/miscellaneous
+
+
 |Gromacs| 2020 series
 ---------------------
 
index 427fce5f081512d8d9a7963ce06fb0bf283386ad..cad3b695122382ce18bdb9262a68add599426613 100644 (file)
@@ -103,15 +103,26 @@ set(IGNORED_CLANG_ALL_WARNINGS
     "-Wno-double-promotion")
 string(REPLACE " " ";" IGNORED_CLANG_ALL_WARNINGS "${IGNORED_CLANG_ALL_WARNINGS}")
 
+option(GMX_CLANG_TIDY "Use clang-tidy" OFF)
 if (GMX_CLANG_TIDY)
+   if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
+   elseif("${CMAKE_BUILD_TYPE}" STREQUAL "RelWithAssert")
+   elseif("${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo")
+   elseif("${CMAKE_BUILD_TYPE}" STREQUAL "ASAN")
+   else()
+       message(FATAL_ERROR "Can only use clang-tidy with build type containing asserts: Debug, RelWithAssert, RelWithDebInfo, ASAN.")
+   endif()
+   set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
+   mark_as_advanced(CMAKE_EXPORT_COMPILE_COMMANDS)
    set(CLANG_TIDY "clang-tidy" CACHE STRING "Name of clang-tidy executable")
    find_program(CLANG_TIDY_EXE NAMES "${CLANG_TIDY}"
        DOC "Path to clang-tidy executable")
    if(NOT CLANG_TIDY_EXE)
        message(FATAL_ERROR "clang-tidy not found.")
    endif()
+   mark_as_advanced(CLANG_TIDY)
+   mark_as_advanced(CLANG_TIDY_EXE)
 endif()
-#####
 
 add_subdirectory(external)
 
index 2f931240e4ccec06a8c6e56ab558ef03a487c6e4..83bdef480341954040855b72c527206655376131 100644 (file)
@@ -2507,17 +2507,17 @@ static void set_dd_limits(const gmx::MDLogger& mdlog,
     }
 }
 
-void dd_init_bondeds(FILE*              fplog,
-                     gmx_domdec_t*      dd,
-                     const gmx_mtop_t*  mtop,
-                     const gmx_vsite_t* vsite,
-                     const t_inputrec*  ir,
-                     gmx_bool           bBCheck,
-                     cginfo_mb_t*       cginfo_mb)
+void dd_init_bondeds(FILE*                      fplog,
+                     gmx_domdec_t*              dd,
+                     const gmx_mtop_t&          mtop,
+                     const gmx_vsite_t*         vsite,
+                     const t_inputrec*          ir,
+                     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);
+    dd_make_reverse_top(fplog, dd, &mtop, vsite, ir, bBCheck);
 
     comm = dd->comm;
 
index 61691d63e3bc338e51f5ef9286b4de138fae8eb6..78c321d624cd60120c0dac951078a7faee853132 100644 (file)
@@ -155,13 +155,13 @@ bool ddHaveSplitConstraints(const gmx_domdec_t& dd);
 bool is1DAnd1PulseDD(const gmx_domdec_t& dd);
 
 /*! \brief Initialize data structures for bonded interactions */
-void dd_init_bondeds(FILE*              fplog,
-                     gmx_domdec_t*      dd,
-                     const gmx_mtop_t*  mtop,
-                     const gmx_vsite_t* vsite,
-                     const t_inputrec*  ir,
-                     gmx_bool           bBCheck,
-                     cginfo_mb_t*       cginfo_mb);
+void dd_init_bondeds(FILE*                      fplog,
+                     gmx_domdec_t*              dd,
+                     const gmx_mtop_t&          mtop,
+                     const gmx_vsite_t*         vsite,
+                     const t_inputrec*          ir,
+                     gmx_bool                   bBCheck,
+                     gmx::ArrayRef<cginfo_mb_t> cginfo_mb);
 
 /*! \brief Returns whether molecules are always whole, i.e. not broken by PBC */
 bool dd_moleculesAreAlwaysWhole(const gmx_domdec_t& dd);
@@ -295,7 +295,7 @@ void dd_init_local_state(struct gmx_domdec_t* dd, const t_state* state_global, t
  *
  * Also stores whether atoms are linked in \p cginfo_mb.
  */
-t_blocka* makeBondedLinks(const gmx_mtop_t* mtop, cginfo_mb_t* cginfo_mb);
+t_blocka* makeBondedLinks(const gmx_mtop_t& mtop, gmx::ArrayRef<cginfo_mb_t> cginfo_mb);
 
 /*! \brief Calculate the maximum distance involved in 2-body and multi-body bonded interactions */
 void dd_bonded_cg_distance(const gmx::MDLogger& mdlog,
index 6e28cad22c6e52fd7adcfc8c8eaf08dd5383f02b..19acbac64bbf6025c254d2c4fba57c9891312fb8 100644 (file)
@@ -1857,7 +1857,7 @@ static void check_link(t_blocka* link, int cg_gl, int cg_gl_j)
     }
 }
 
-t_blocka* makeBondedLinks(const gmx_mtop_t* mtop, cginfo_mb_t* cginfo_mb)
+t_blocka* makeBondedLinks(const gmx_mtop_t& mtop, gmx::ArrayRef<cginfo_mb_t> cginfo_mb)
 {
     t_blocka*    link;
     cginfo_mb_t* cgi_mb;
@@ -1868,35 +1868,35 @@ t_blocka* makeBondedLinks(const gmx_mtop_t* mtop, cginfo_mb_t* cginfo_mb)
      */
 
     reverse_ilist_t ril_intermol;
-    if (mtop->bIntermolecularInteractions)
+    if (mtop.bIntermolecularInteractions)
     {
         t_atoms atoms;
 
-        atoms.nr   = mtop->natoms;
+        atoms.nr   = mtop.natoms;
         atoms.atom = nullptr;
 
-        GMX_RELEASE_ASSERT(mtop->intermolecular_ilist,
+        GMX_RELEASE_ASSERT(mtop.intermolecular_ilist,
                            "We should have an ilist when intermolecular interactions are on");
 
-        make_reverse_ilist(*mtop->intermolecular_ilist, &atoms, FALSE, FALSE, FALSE, TRUE, &ril_intermol);
+        make_reverse_ilist(*mtop.intermolecular_ilist, &atoms, FALSE, FALSE, FALSE, TRUE, &ril_intermol);
     }
 
     snew(link, 1);
-    snew(link->index, mtop->natoms + 1);
+    snew(link->index, mtop.natoms + 1);
     link->nalloc_a = 0;
     link->a        = nullptr;
 
     link->index[0] = 0;
     int cg_offset  = 0;
     int ncgi       = 0;
-    for (size_t mb = 0; mb < mtop->molblock.size(); mb++)
+    for (size_t mb = 0; mb < mtop.molblock.size(); mb++)
     {
-        const gmx_molblock_t& molb = mtop->molblock[mb];
+        const gmx_molblock_t& molb = mtop.molblock[mb];
         if (molb.nmol == 0)
         {
             continue;
         }
-        const gmx_moltype_t& molt = mtop->moltype[molb.type];
+        const gmx_moltype_t& molt = mtop.moltype[molb.type];
         /* Make a reverse ilist in which the interactions are linked
          * to all atoms, not only the first atom as in gmx_reverse_top.
          * The constraints are discarded here.
@@ -1907,7 +1907,7 @@ t_blocka* makeBondedLinks(const gmx_mtop_t* mtop, cginfo_mb_t* cginfo_mb)
         cgi_mb = &cginfo_mb[mb];
 
         int mol;
-        for (mol = 0; mol < (mtop->bIntermolecularInteractions ? molb.nmol : 1); mol++)
+        for (mol = 0; mol < (mtop.bIntermolecularInteractions ? molb.nmol : 1); mol++)
         {
             for (int a = 0; a < molt.atoms.nr; a++)
             {
@@ -1931,7 +1931,7 @@ t_blocka* makeBondedLinks(const gmx_mtop_t* mtop, cginfo_mb_t* cginfo_mb)
                     i += nral_rt(ftype);
                 }
 
-                if (mtop->bIntermolecularInteractions)
+                if (mtop.bIntermolecularInteractions)
                 {
                     int i = ril_intermol.index[cg_gl];
                     while (i < ril_intermol.index[cg_gl + 1])
@@ -1997,7 +1997,7 @@ t_blocka* makeBondedLinks(const gmx_mtop_t* mtop, cginfo_mb_t* cginfo_mb)
 
     if (debug)
     {
-        fprintf(debug, "Of the %d atoms %d are linked via bonded interactions\n", mtop->natoms, ncgi);
+        fprintf(debug, "Of the %d atoms %d are linked via bonded interactions\n", mtop.natoms, ncgi);
     }
 
     return link;
index b00ceec520596409c50bc96b027913a0dc0e7749..2ff39b3a906010485c96926e7ec6438a2da7fa60 100644 (file)
@@ -462,8 +462,8 @@ static void dd_set_cginfo(gmx::ArrayRef<const int> index_gl, int cg0, int cg1, t
 {
     if (fr != nullptr)
     {
-        const cginfo_mb_t* cginfo_mb = fr->cginfo_mb;
-        gmx::ArrayRef<int> cginfo    = fr->cginfo;
+        gmx::ArrayRef<cginfo_mb_t> cginfo_mb = fr->cginfo_mb;
+        gmx::ArrayRef<int>         cginfo    = fr->cginfo;
 
         for (int cg = cg0; cg < cg1; cg++)
         {
@@ -1327,7 +1327,7 @@ static void merge_cg_buffers(int                            ncell,
                              const int*                     recv_i,
                              gmx::ArrayRef<gmx::RVec>       x,
                              gmx::ArrayRef<const gmx::RVec> recv_vr,
-                             cginfo_mb_t*                   cginfo_mb,
+                             gmx::ArrayRef<cginfo_mb_t>     cginfo_mb,
                              gmx::ArrayRef<int>             cginfo)
 {
     gmx_domdec_ind_t *ind, *ind_p;
@@ -1820,7 +1820,6 @@ static void setup_dd_communication(gmx_domdec_t*                dd,
     gmx_domdec_comm_t*     comm;
     gmx_domdec_zones_t*    zones;
     gmx_domdec_comm_dim_t* cd;
-    cginfo_mb_t*           cginfo_mb;
     gmx_bool               bBondComm, bDist2B, bDistMB, bDistBonded;
     dd_corners_t           corners;
     rvec *                 normal, *v_d, *v_0 = nullptr, *v_1 = nullptr;
@@ -1894,8 +1893,8 @@ static void setup_dd_communication(gmx_domdec_t*                dd,
         v_1 = ddbox->v[dim1];
     }
 
-    zone_cg_range = zones->cg_range;
-    cginfo_mb     = fr->cginfo_mb;
+    zone_cg_range                        = zones->cg_range;
+    gmx::ArrayRef<cginfo_mb_t> cginfo_mb = fr->cginfo_mb;
 
     zone_cg_range[0]   = 0;
     zone_cg_range[1]   = dd->ncg_home;
index eb130157c64b42808990291014d794c0e671674c..a747a26a1ccd6d67dc1b94ee97f9ca12c33d9e31 100644 (file)
@@ -736,7 +736,7 @@ void dd_redistribute_cg(FILE*                        fplog,
     /* We reuse the intBuffer without reacquiring since we are in the same scope */
     DDBufferAccess<int>& flagBuffer = moveBuffer;
 
-    const cginfo_mb_t* cginfo_mb = fr->cginfo_mb;
+    gmx::ArrayRef<const cginfo_mb_t> cginfo_mb = fr->cginfo_mb;
 
     /* Temporarily store atoms passed to our rank at the end of the range */
     int home_pos_cg = dd->ncg_home;
index 9d7db1f11235161c117f31deb98b49f368b36ea8..353dc327b0f39a0c4207c7379a080568b583748a 100644 (file)
@@ -44,6 +44,7 @@
 
 #include "gromacs/gpu_utils/hostallocator.h"
 #include "gromacs/mdtypes/forcerec.h"
+#include "gromacs/utility/arrayref.h"
 
 #include "domdec_internal.h"
 
@@ -77,14 +78,16 @@ void make_tric_corr_matrix(int npbcdim, const matrix box, matrix tcm);
 void check_screw_box(const matrix box);
 
 /*! \brief Return the charge group information flags for charge group cg */
-static inline int ddcginfo(const cginfo_mb_t* cginfo_mb, int cg)
+static inline int ddcginfo(gmx::ArrayRef<const cginfo_mb_t> cginfo_mb, int cg)
 {
-    while (cg >= cginfo_mb->cg_end)
+    size_t index = 0;
+    while (cg >= cginfo_mb[index].cg_end)
     {
-        cginfo_mb++;
+        index++;
     }
+    const cginfo_mb_t& cgimb = cginfo_mb[index];
 
-    return cginfo_mb->cginfo[(cg - cginfo_mb->cg_start) % cginfo_mb->cg_mod];
+    return cgimb.cginfo[(cg - cgimb.cg_start) % cgimb.cg_mod];
 };
 
 /*! \brief Returns the number of MD steps for which load has been recorded */
index 8395379dad3f16295d38fe2df94a22242d05126c..e440a146f6489129ac8e6e37eb02af0e64eae1f7 100644 (file)
@@ -265,7 +265,7 @@ static void nb_free_energy_kernel(const t_nblist* gmx_restrict nlist,
     const int*  typeA         = mdatoms->typeA;
     const int*  typeB         = mdatoms->typeB;
     const int   ntype         = fr->ntype;
-    const real* nbfp          = fr->nbfp;
+    const real* nbfp          = fr->nbfp.data();
     const real* nbfp_grid     = fr->ljpme_c6grid;
     real*       Vv            = kernel_data->energygrp_vdw;
     const real  lambda_coul   = kernel_data->lambda[efptCOUL];
index f659874b92a704244cb4c6b0d92dc9a50f89f176..8b36c27e8c51971d255494c600142101a6e9dcbe 100644 (file)
@@ -126,7 +126,7 @@ void do_force_lowlevel(t_forcerec*                         fr,
     /* do QMMM first if requested */
     if (fr->bQMMM)
     {
-        enerd->term[F_EQM] = calculate_QMMM(cr, &forceOutputs->forceWithShiftForces(), fr);
+        enerd->term[F_EQM] = calculate_QMMM(cr, &forceOutputs->forceWithShiftForces(), fr->qr);
     }
 
     /* Call the short range functions all in one go. */
index b702a4a2552b91a025493e0720474fe4fc578451..66c4c33b5647d48e047a7d9ff49dc7f9224b7f78 100644 (file)
 static const bool c_enableGpuPmePpComms =
         (getenv("GMX_GPU_PME_PP_COMMS") != nullptr) && GMX_THREAD_MPI && (GMX_GPU == GMX_GPU_CUDA);
 
-static real* mk_nbfp(const gmx_ffparams_t* idef, gmx_bool bBHAM)
+static std::vector<real> mk_nbfp(const gmx_ffparams_t* idef, gmx_bool bBHAM)
 {
-    real* nbfp;
-    int   i, j, k, atnr;
+    std::vector<real> nbfp;
+    int               atnr;
 
     atnr = idef->atnr;
     if (bBHAM)
     {
-        snew(nbfp, 3 * atnr * atnr);
-        for (i = k = 0; (i < atnr); i++)
+        nbfp.resize(3 * atnr * atnr);
+        int k = 0;
+        for (int i = 0; (i < atnr); i++)
         {
-            for (j = 0; (j < atnr); j++, k++)
+            for (int j = 0; (j < atnr); j++, k++)
             {
                 BHAMA(nbfp, atnr, i, j) = idef->iparams[k].bham.a;
                 BHAMB(nbfp, atnr, i, j) = idef->iparams[k].bham.b;
@@ -124,10 +125,11 @@ static real* mk_nbfp(const gmx_ffparams_t* idef, gmx_bool bBHAM)
     }
     else
     {
-        snew(nbfp, 2 * atnr * atnr);
-        for (i = k = 0; (i < atnr); i++)
+        nbfp.resize(2 * atnr * atnr);
+        int k = 0;
+        for (int i = 0; (i < atnr); i++)
         {
-            for (j = 0; (j < atnr); j++, k++)
+            for (int j = 0; (j < atnr); j++, k++)
             {
                 /* nbfp now includes the 6.0/12.0 derivative prefactors */
                 C6(nbfp, atnr, i, j)  = idef->iparams[k].lj.c6 * 6.0;
@@ -186,14 +188,10 @@ enum
     acSETTLE
 };
 
-static cginfo_mb_t* init_cginfo_mb(const gmx_mtop_t* mtop, const t_forcerec* fr, gmx_bool* bFEP_NonBonded)
+static std::vector<cginfo_mb_t> init_cginfo_mb(const gmx_mtop_t* mtop, const t_forcerec* fr, gmx_bool* bFEP_NonBonded)
 {
-    cginfo_mb_t* cginfo_mb;
-    gmx_bool*    type_VDW;
-    int*         cginfo;
-    int*         a_con;
-
-    snew(cginfo_mb, mtop->molblock.size());
+    gmx_bool* type_VDW;
+    int*      a_con;
 
     snew(type_VDW, fr->ntype);
     for (int ai = 0; ai < fr->ntype; ai++)
@@ -208,7 +206,8 @@ static cginfo_mb_t* init_cginfo_mb(const gmx_mtop_t* mtop, const t_forcerec* fr,
 
     *bFEP_NonBonded = FALSE;
 
-    int a_offset = 0;
+    std::vector<cginfo_mb_t> cginfoPerMolblock;
+    int                      a_offset = 0;
     for (size_t mb = 0; mb < mtop->molblock.size(); mb++)
     {
         const gmx_molblock_t& molb = mtop->molblock[mb];
@@ -241,11 +240,12 @@ static cginfo_mb_t* init_cginfo_mb(const gmx_mtop_t* mtop, const t_forcerec* fr,
             }
         }
 
-        cginfo_mb[mb].cg_start = a_offset;
-        cginfo_mb[mb].cg_end   = a_offset + molb.nmol * molt.atoms.nr;
-        cginfo_mb[mb].cg_mod   = (bId ? 1 : molb.nmol) * molt.atoms.nr;
-        snew(cginfo_mb[mb].cginfo, cginfo_mb[mb].cg_mod);
-        cginfo = cginfo_mb[mb].cginfo;
+        cginfo_mb_t cginfo_mb;
+        cginfo_mb.cg_start = a_offset;
+        cginfo_mb.cg_end   = a_offset + molb.nmol * molt.atoms.nr;
+        cginfo_mb.cg_mod   = (bId ? 1 : molb.nmol) * molt.atoms.nr;
+        cginfo_mb.cginfo.resize(cginfo_mb.cg_mod);
+        gmx::ArrayRef<int> cginfo = cginfo_mb.cginfo;
 
         /* Set constraints flags for constrained atoms */
         snew(a_con, molt.atoms.nr);
@@ -322,14 +322,16 @@ static cginfo_mb_t* init_cginfo_mb(const gmx_mtop_t* mtop, const t_forcerec* fr,
 
         sfree(a_con);
 
+        cginfoPerMolblock.push_back(cginfo_mb);
+
         a_offset += molb.nmol * molt.atoms.nr;
     }
     sfree(type_VDW);
 
-    return cginfo_mb;
+    return cginfoPerMolblock;
 }
 
-static std::vector<int> cginfo_expand(const int nmb, const cginfo_mb_t* cgi_mb)
+static std::vector<int> cginfo_expand(const int nmb, gmx::ArrayRef<const cginfo_mb_t> cgi_mb)
 {
     const int ncg = cgi_mb[nmb - 1].cg_end;
 
@@ -348,19 +350,6 @@ static std::vector<int> cginfo_expand(const int nmb, const cginfo_mb_t* cgi_mb)
     return cginfo;
 }
 
-static void done_cginfo_mb(cginfo_mb_t* cginfo_mb, int numMolBlocks)
-{
-    if (cginfo_mb == nullptr)
-    {
-        return;
-    }
-    for (int mb = 0; mb < numMolBlocks; ++mb)
-    {
-        sfree(cginfo_mb[mb].cginfo);
-    }
-    sfree(cginfo_mb);
-}
-
 /* Sets the sum of charges (squared) and C6 in the system in fr.
  * Returns whether the system has a net charge.
  */
@@ -1271,7 +1260,7 @@ void init_forcerec(FILE*                            fp,
 
     fr->shiftForces.resize(SHIFTS);
 
-    if (fr->nbfp == nullptr)
+    if (fr->nbfp.empty())
     {
         fr->ntype = mtop->ffparams.atnr;
         fr->nbfp  = mk_nbfp(&mtop->ffparams, fr->bBHAM);
@@ -1452,8 +1441,7 @@ void init_forcerec(FILE*                            fp,
     if (ir->eDispCorr != edispcNO)
     {
         fr->dispersionCorrection = std::make_unique<DispersionCorrection>(
-                *mtop, *ir, fr->bBHAM, fr->ntype,
-                gmx::arrayRefFromArray(fr->nbfp, fr->ntype * fr->ntype * 2), *fr->ic, tabfn);
+                *mtop, *ir, fr->bBHAM, fr->ntype, fr->nbfp, *fr->ic, tabfn);
         fr->dispersionCorrection->print(mdlog);
     }
 
@@ -1474,67 +1462,10 @@ void init_forcerec(FILE*                            fp,
 
 t_forcerec::t_forcerec() = default;
 
-t_forcerec::~t_forcerec() = default;
-
-/* Frees GPU memory and sets a tMPI node barrier.
- *
- * Note that this function needs to be called even if GPUs are not used
- * in this run because the PME ranks have no knowledge of whether GPUs
- * are used or not, but all ranks need to enter the barrier below.
- * \todo Remove physical node barrier from this function after making sure
- * that it's not needed anymore (with a shared GPU run).
- */
-void free_gpu_resources(t_forcerec*                          fr,
-                        const gmx::PhysicalNodeCommunicator& physicalNodeCommunicator,
-                        const gmx_gpu_info_t&                gpu_info)
+t_forcerec::~t_forcerec()
 {
-    bool isPPrankUsingGPU = (fr != nullptr) && (fr->nbv != nullptr) && fr->nbv->useGpu();
-
-    /* stop the GPU profiler (only CUDA) */
-    if (gpu_info.n_dev > 0)
-    {
-        stopGpuProfiler();
-    }
-
-    if (isPPrankUsingGPU)
-    {
-        /* Free data in GPU memory and pinned memory before destroying the GPU context */
-        fr->nbv.reset();
-
-        delete fr->gpuBonded;
-        fr->gpuBonded = nullptr;
-    }
-
-    /* With tMPI we need to wait for all ranks to finish deallocation before
-     * destroying the CUDA context in free_gpu() as some tMPI ranks may be sharing
-     * GPU and context.
-     *
-     * This is not a concern in OpenCL where we use one context per rank which
-     * is freed in nbnxn_gpu_free().
-     *
-     * Note: it is safe to not call the barrier on the ranks which do not use GPU,
-     * but it is easier and more futureproof to call it on the whole node.
-     */
-    if (GMX_THREAD_MPI)
-    {
-        physicalNodeCommunicator.barrier();
-    }
-}
-
-void done_forcerec(t_forcerec* fr, int numMolBlocks)
-{
-    if (fr == nullptr)
-    {
-        // PME-only ranks don't have a forcerec
-        return;
-    }
-    done_cginfo_mb(fr->cginfo_mb, numMolBlocks);
-    sfree(fr->nbfp);
-    delete fr->ic;
-    sfree(fr->shift_vec);
-    sfree(fr->ewc_t);
-    tear_down_bonded_threading(fr->bondedThreading);
-    GMX_RELEASE_ASSERT(fr->gpuBonded == nullptr, "Should have been deleted earlier, when used");
-    fr->bondedThreading = nullptr;
-    delete fr;
+    /* Note: This code will disappear when types are converted to C++ */
+    sfree(shift_vec);
+    sfree(ewc_t);
+    tear_down_bonded_threading(bondedThreading);
 }
index e28e717b501fdd0d55f9e302fd547d3c643100dc..0c9033f84e0232910783d220d72ff72b1eecce33 100644 (file)
@@ -59,9 +59,6 @@ class MDLogger;
 class PhysicalNodeCommunicator;
 } // namespace gmx
 
-//! Destroy a forcerec.
-void done_forcerec(t_forcerec* fr, int numMolBlocks);
-
 /*! \brief Print the contents of the forcerec to a file
  *
  * \param[in] fplog The log file to print to
@@ -135,8 +132,4 @@ void init_forcerec(FILE*                            fplog,
  */
 void forcerec_set_excl_load(t_forcerec* fr, const gmx_localtop_t* top);
 
-void free_gpu_resources(t_forcerec*                          fr,
-                        const gmx::PhysicalNodeCommunicator& physicalNodeCommunicator,
-                        const gmx_gpu_info_t&                gpu_info);
-
 #endif
index 4415158d32ea7d051e16d327afa515c1b4b28934..ac4135960740aea0c45f4e8db8deb27856b2db45 100644 (file)
@@ -336,11 +336,6 @@ LeapFrogCuda::~LeapFrogCuda()
     freeDeviceBuffer(&d_inverseMasses_);
 }
 
-void LeapFrogCuda::setPbc(const t_pbc* pbc)
-{
-    setPbcAiuc(pbc->ndim_ePBC, pbc->box, &pbcAiuc_);
-}
-
 void LeapFrogCuda::set(const t_mdatoms& md, const int numTempScaleValues, const unsigned short* tempScaleGroups)
 {
     numAtoms_                       = md.nr;
index cb71267a209ff1619f4dc331a734fdf0ceb783b0..cbf3738a8f82e6270f4363b67b29acba725f4583 100644 (file)
@@ -69,15 +69,6 @@ public:
     LeapFrogCuda(CommandStream commandStream);
     ~LeapFrogCuda();
 
-    /*! \brief
-     * Update PBC data.
-     *
-     * Converts PBC data from t_pbc into the PbcAiuc format and stores the latter.
-     *
-     * \param[in] pbc The PBC data in t_pbc format.
-     */
-    void setPbc(const t_pbc* pbc);
-
     /*! \brief Integrate
      *
      * Integrates the equation of motion using Leap-Frog algorithm.
@@ -125,8 +116,6 @@ private:
     CommandStream commandStream_;
     //! CUDA kernel launch config
     KernelLaunchConfig kernelLaunchConfig_;
-    //! Periodic boundary data
-    PbcAiuc pbcAiuc_;
     //! Number of atoms
     int numAtoms_;
 
index 84325141ad5365b3e9a5200799835f4eac332a8f..ce1b442f84902e61797ac90035188e9309839be1 100644 (file)
@@ -40,8 +40,6 @@
  * using CUDA, including class initialization, data-structures management
  * and GPU kernel.
  *
- * \note Management of periodic boundary should be unified with SETTLE and
- *       removed from here.
  * \todo Reconsider naming, i.e. "cuda" suffics should be changed to "gpu".
  *
  * \author Artem Zhmurov <zhmurov@gmail.com>
@@ -434,7 +432,8 @@ void LincsCuda::apply(const float3* d_x,
                       float3*       d_v,
                       const real    invdt,
                       const bool    computeVirial,
-                      tensor        virialScaled)
+                      tensor        virialScaled,
+                      const PbcAiuc pbcAiuc)
 {
     ensureNoPendingCudaError("In CUDA version of LINCS");
 
@@ -478,6 +477,8 @@ void LincsCuda::apply(const float3* d_x,
     }
     config.stream = commandStream_;
 
+    kernelParams_.pbcAiuc = pbcAiuc;
+
     const auto kernelArgs =
             prepareGpuKernelArguments(kernelPtr, config, &kernelParams_, &d_x, &d_xp, &d_v, &invdt);
 
@@ -892,9 +893,4 @@ void LincsCuda::set(const t_idef& idef, const t_mdatoms& md)
                        GpuApiCallBehavior::Sync, nullptr);
 }
 
-void LincsCuda::setPbc(const t_pbc* pbc)
-{
-    setPbcAiuc(pbc->ndim_ePBC, pbc->box, &kernelParams_.pbcAiuc);
-}
-
 } // namespace gmx
index 99589f33cf9ec843c5fe315caa8328240ab0cd1c..aea6938831729da411e800464e2aa2d30e2ca010 100644 (file)
@@ -125,6 +125,7 @@ public:
      *                                  multipliers when velocities are updated)
      * \param[in]     computeVirial     If virial should be updated.
      * \param[in,out] virialScaled      Scaled virial tensor to be updated.
+     * \param[in]     pbcAiuc           PBC data.
      */
     void apply(const float3* d_x,
                float3*       d_xp,
@@ -132,7 +133,8 @@ public:
                float3*       d_v,
                const real    invdt,
                const bool    computeVirial,
-               tensor        virialScaled);
+               tensor        virialScaled,
+               const PbcAiuc pbcAiuc);
 
     /*! \brief
      * Update data-structures (e.g. after NB search step).
@@ -155,18 +157,6 @@ public:
      */
     void set(const t_idef& idef, const t_mdatoms& md);
 
-    /*! \brief
-     * Update PBC data.
-     *
-     * Converts pbc data from t_pbc into the PbcAiuc format and stores the latter.
-     *
-     * \todo Remove this method. LINCS should not manage PBC.
-     *
-     * \param[in] pbc The PBC data in t_pbc format.
-     */
-    void setPbc(const t_pbc* pbc);
-
-
 private:
     //! CUDA stream
     CommandStream commandStream_;
index b9885bfff340c261b5e4abe841d0b41512292731..60fb57d0f2ddfb73ec7c000fa11a366401ee1a4b 100644 (file)
@@ -52,7 +52,6 @@
 #include "gromacs/math/units.h"
 #include "gromacs/math/vec.h"
 #include "gromacs/mdlib/force.h"
-#include "gromacs/mdlib/forcerec.h"
 #include "gromacs/mdlib/qmmm.h"
 #include "gromacs/mdtypes/md_enums.h"
 #include "gromacs/utility/cstringutil.h"
@@ -216,16 +215,11 @@ void init_gaussian(t_QMrec* qm)
 }
 
 
-static void write_gaussian_SH_input(int step, gmx_bool swap, const t_forcerec* fr, t_QMrec* qm, t_MMrec* mm)
+static void write_gaussian_SH_input(int step, gmx_bool swap, const t_QMMMrec* QMMMrec, t_QMrec* qm, t_MMrec* mm)
 {
-    int        i;
-    gmx_bool   bSA;
-    FILE*      out;
-    t_QMMMrec* QMMMrec;
-    QMMMrec = fr->qr;
-    bSA     = (qm->SAstep > 0);
-
-    out = fopen("input.com", "w");
+    int   i;
+    bool  bSA = (qm->SAstep > 0);
+    FILE* out = fopen("input.com", "w");
     /* write the route */
     fprintf(out, "%s", "%scr=input\n");
     fprintf(out, "%s", "%rwf=input\n");
@@ -380,14 +374,11 @@ static void write_gaussian_SH_input(int step, gmx_bool swap, const t_forcerec* f
     fclose(out);
 } /* write_gaussian_SH_input */
 
-static void write_gaussian_input(int step, const t_forcerec* fr, t_QMrec* qm, t_MMrec* mm)
+static void write_gaussian_input(int step, const t_QMMMrec* QMMMrec, t_QMrec* qm, t_MMrec* mm)
 {
-    int        i;
-    t_QMMMrec* QMMMrec;
-    FILE*      out;
+    int i;
 
-    QMMMrec = fr->qr;
-    out     = fopen("input.com", "w");
+    FILE* out = fopen("input.com", "w");
     /* write the route */
 
     if (qm->QMmethod >= eQMmethodRHF)
@@ -758,7 +749,7 @@ static void do_gaussian(int step, char* exe)
     }
 }
 
-real call_gaussian(const t_forcerec* fr, t_QMrec* qm, t_MMrec* mm, rvec f[], rvec fshift[])
+real call_gaussian(const t_QMMMrec* qmmm, t_QMrec* qm, t_MMrec* mm, rvec f[], rvec fshift[])
 {
     /* normal gaussian jobs */
     static int step = 0;
@@ -772,7 +763,7 @@ real call_gaussian(const t_forcerec* fr, t_QMrec* qm, t_MMrec* mm, rvec f[], rve
     snew(QMgrad, qm->nrQMatoms);
     snew(MMgrad, mm->nrMMatoms);
 
-    write_gaussian_input(step, fr, qm, mm);
+    write_gaussian_input(step, qmmm, qm, mm);
     do_gaussian(step, exe);
     QMener = read_gaussian_output(QMgrad, MMgrad, qm, mm);
     /* put the QMMM forces in the force array and to the fshift
@@ -800,7 +791,7 @@ real call_gaussian(const t_forcerec* fr, t_QMrec* qm, t_MMrec* mm, rvec f[], rve
 
 } /* call_gaussian */
 
-real call_gaussian_SH(const t_forcerec* fr, t_QMrec* qm, t_MMrec* mm, rvec f[], rvec fshift[])
+real call_gaussian_SH(const t_QMMMrec* qmmm, t_QMrec* qm, t_MMrec* mm, rvec f[], rvec fshift[])
 {
     /* a gaussian call routine intended for doing diabatic surface
      * "sliding". See the manual for the theoretical background of this
@@ -845,7 +836,7 @@ real call_gaussian_SH(const t_forcerec* fr, t_QMrec* qm, t_MMrec* mm, rvec f[],
     /*  if(!step)
      * qr->bSA=FALSE;*/
     /* temporray set to step + 1, since there is a chk start */
-    write_gaussian_SH_input(step, swapped, fr, qm, mm);
+    write_gaussian_SH_input(step, swapped, qmmm, qm, mm);
 
     do_gaussian(step, exe);
     QMener = read_gaussian_SH_output(QMgrad, MMgrad, step, qm, mm);
@@ -867,7 +858,7 @@ real call_gaussian_SH(const t_forcerec* fr, t_QMrec* qm, t_MMrec* mm, rvec f[],
         }
         if (swap) /* change surface, so do another call */
         {
-            write_gaussian_SH_input(step, swapped, fr, qm, mm);
+            write_gaussian_SH_input(step, swapped, qmmm, qm, mm);
             do_gaussian(step, exe);
             QMener = read_gaussian_SH_output(QMgrad, MMgrad, step, qm, mm);
         }
index 1933fc7893c39d628e4ef264da49f30fc8063a54..9c3088413232c801a9420865f64fd12635312ee3 100644 (file)
@@ -50,23 +50,23 @@ void init_gaussian(t_QMrec* qm);
 /*! \brief
  * Call gaussian to do qm calculation.
  *
- * \param[in] fr Global forcerec.
- * \param[in] qm QM part of forcerec.
- * \param[in] mm mm part of forcerec.
- * \param[in] f  force vector.
+ * \param[in] qmmm   QMMM part forcerec.
+ * \param[in] qm     QM part of forcerec.
+ * \param[in] mm     mm part of forcerec.
+ * \param[in] f      force vector.
  * \param[in] fshift shift of force vector.
  */
-real call_gaussian(const t_forcerec* fr, t_QMrec* qm, t_MMrec* mm, rvec f[], rvec fshift[]);
+real call_gaussian(const t_QMMMrec* qmmm, t_QMrec* qm, t_MMrec* mm, rvec f[], rvec fshift[]);
 
 /*! \brief
  * Call gaussian SH(?) to do qm calculation.
  *
- * \param[in] fr Global forcerec.
- * \param[in] qm QM part of forcerec.
- * \param[in] mm mm part of forcerec.
- * \param[in] f  force vector.
+ * \param[in] qmmm   QMMM part forcerec.
+ * \param[in] qm     QM part of forcerec.
+ * \param[in] mm     mm part of forcerec.
+ * \param[in] f      force vector.
  * \param[in] fshift shift of force vector.
  */
-real call_gaussian_SH(const t_forcerec* fr, t_QMrec* qm, t_MMrec* mm, rvec f[], rvec fshift[]);
+real call_gaussian_SH(const t_QMMMrec* qmmm, t_QMrec* qm, t_MMrec* mm, rvec f[], rvec fshift[]);
 
 #endif
index 075d8d68340f8e5f296ddb22f31a0fbde91430be..1bd0cca0738566ae0d625a27866189e5d29e3e0e 100644 (file)
@@ -51,7 +51,6 @@
 #include "gromacs/math/units.h"
 #include "gromacs/math/vec.h"
 #include "gromacs/mdlib/qmmm.h"
-#include "gromacs/mdtypes/forcerec.h"
 #include "gromacs/mdtypes/md_enums.h"
 #include "gromacs/utility/fatalerror.h"
 #include "gromacs/utility/smalloc.h"
@@ -110,19 +109,16 @@ void init_orca(t_QMrec* qm)
 }
 
 
-static void write_orca_input(const t_forcerec* fr, t_QMrec* qm, t_MMrec* mm)
+static void write_orca_input(const t_QMMMrec* QMMMrec, t_QMrec* qm, t_MMrec* mm)
 {
-    int        i;
-    t_QMMMrec* QMMMrec;
-    FILE *     out, *pcFile, *addInputFile;
-    char *     buf, *orcaInput, *addInputFilename, *pcFilename;
-
-    QMMMrec = fr->qr;
+    int   i;
+    FILE *pcFile, *addInputFile;
+    char *buf, *orcaInput, *addInputFilename, *pcFilename;
 
     /* write the first part of the input-file */
     snew(orcaInput, 200);
     sprintf(orcaInput, "%s.inp", qm->orca_basename);
-    out = fopen(orcaInput, "w");
+    FILE* out = fopen(orcaInput, "w");
 
     snew(addInputFilename, 200);
     sprintf(addInputFilename, "%s.ORCAINFO", qm->orca_basename);
@@ -193,15 +189,13 @@ static void write_orca_input(const t_forcerec* fr, t_QMrec* qm, t_MMrec* mm)
     fclose(out);
 } /* write_orca_input */
 
-static real read_orca_output(rvec QMgrad[], rvec MMgrad[], const t_forcerec* fr, t_QMrec* qm, t_MMrec* mm)
+static real read_orca_output(rvec QMgrad[], rvec MMgrad[], const t_QMMMrec* QMMMrec, t_QMrec* qm, t_MMrec* mm)
 {
-    int        i, j;
-    char       buf[300], orca_pcgradFilename[300], orca_engradFilename[300];
-    real       QMener;
-    FILE *     pcgrad, *engrad;
-    int        k;
-    t_QMMMrec* QMMMrec;
-    QMMMrec = fr->qr;
+    int   i, j;
+    char  buf[300], orca_pcgradFilename[300], orca_engradFilename[300];
+    real  QMener;
+    FILE *pcgrad, *engrad;
+    int   k;
 
     /* the energy and gradients for the QM part are stored in the engrad file
      * and the gradients for the point charges are stored in the pc file.
@@ -328,7 +322,7 @@ static void do_orca(char* orca_dir, char* basename)
     }
 }
 
-real call_orca(const t_forcerec* fr, t_QMrec* qm, t_MMrec* mm, rvec f[], rvec fshift[])
+real call_orca(const t_QMMMrec* qmmm, t_QMrec* qm, t_MMrec* mm, rvec f[], rvec fshift[])
 {
     /* normal orca jobs */
     static int step = 0;
@@ -342,9 +336,9 @@ real call_orca(const t_forcerec* fr, t_QMrec* qm, t_MMrec* mm, rvec f[], rvec fs
     snew(QMgrad, qm->nrQMatoms);
     snew(MMgrad, mm->nrMMatoms);
 
-    write_orca_input(fr, qm, mm);
+    write_orca_input(qmmm, qm, mm);
     do_orca(qm->orca_dir, qm->orca_basename);
-    QMener = read_orca_output(QMgrad, MMgrad, fr, qm, mm);
+    QMener = read_orca_output(QMgrad, MMgrad, qmmm, qm, mm);
     /* put the QMMM forces in the force array and to the fshift
      */
     for (i = 0; i < qm->nrQMatoms; i++)
index cf89d941c8fc907e3d15d3331147fc9172253487..c6a3b55917bb8e9038bf5d8838b21440b4cca37d 100644 (file)
@@ -39,6 +39,6 @@
 
 void init_orca(t_QMrec* qm);
 
-real call_orca(const t_forcerec* fr, t_QMrec* qm, t_MMrec* mm, rvec f[], rvec fshift[]);
+real call_orca(const t_QMMMrec* qmmm, t_QMrec* qm, t_MMrec* mm, rvec f[], rvec fshift[]);
 
 #endif
index 2482bf592712f7d86d2c09f694cbc7ddfbea4dab..24b3c75d2adbb5f0268a941f659659b06c3c6b4a 100644 (file)
@@ -95,7 +95,7 @@ static bool struct_comp(const t_j_particle& a, const t_j_particle& b)
 }
 
 static real call_QMroutine(const t_commrec gmx_unused* cr,
-                           const t_forcerec gmx_unused* fr,
+                           const t_QMMMrec gmx_unused* qmmm,
                            t_QMrec gmx_unused* qm,
                            t_MMrec gmx_unused* mm,
                            rvec gmx_unused f[],
@@ -131,7 +131,7 @@ static real call_QMroutine(const t_commrec gmx_unused* cr,
         {
             if (GMX_QMMM_GAUSSIAN)
             {
-                return call_gaussian_SH(fr, qm, mm, f, fshift);
+                return call_gaussian_SH(qmmm, qm, mm, f, fshift);
             }
             else
             {
@@ -146,11 +146,11 @@ static real call_QMroutine(const t_commrec gmx_unused* cr,
             }
             else if (GMX_QMMM_GAUSSIAN)
             {
-                return call_gaussian(fr, qm, mm, f, fshift);
+                return call_gaussian(qmmm, qm, mm, f, fshift);
             }
             else if (GMX_QMMM_ORCA)
             {
-                return call_orca(fr, qm, mm, f, fshift);
+                return call_orca(qmmm, qm, mm, f, fshift);
             }
             else
             {
@@ -827,17 +827,16 @@ void update_QMMMrec(const t_commrec* cr, const t_forcerec* fr, const rvec* x, co
     }
 } /* update_QMMM_rec */
 
-real calculate_QMMM(const t_commrec* cr, gmx::ForceWithShiftForces* forceWithShiftForces, const t_forcerec* fr)
+real calculate_QMMM(const t_commrec* cr, gmx::ForceWithShiftForces* forceWithShiftForces, const t_QMMMrec* qr)
 {
     real QMener = 0.0;
     /* a selection for the QM package depending on which is requested
      * (Gaussian, GAMESS-UK, MOPAC or ORCA) needs to be implemented here. Now
      * it works through defines.... Not so nice yet
      */
-    t_QMMMrec* qr;
-    t_QMrec *  qm, *qm2;
-    t_MMrec*   mm     = nullptr;
-    rvec *     forces = nullptr, *fshift = nullptr, *forces2 = nullptr,
+    t_QMrec *qm, *qm2;
+    t_MMrec* mm     = nullptr;
+    rvec *   forces = nullptr, *fshift = nullptr, *forces2 = nullptr,
          *fshift2 = nullptr; /* needed for multilayer ONIOM */
     int i, j, k;
 
@@ -848,7 +847,6 @@ real calculate_QMMM(const t_commrec* cr, gmx::ForceWithShiftForces* forceWithShi
 
     /* make a local copy the QMMMrec pointer
      */
-    qr = fr->qr;
     mm = qr->mm;
 
     /* now different procedures are carried out for one layer ONION and
@@ -861,7 +859,7 @@ real calculate_QMMM(const t_commrec* cr, gmx::ForceWithShiftForces* forceWithShi
         qm = qr->qm[0];
         snew(forces, (qm->nrQMatoms + mm->nrMMatoms));
         snew(fshift, (qm->nrQMatoms + mm->nrMMatoms));
-        QMener = call_QMroutine(cr, fr, qm, mm, forces, fshift);
+        QMener = call_QMroutine(cr, qr, qm, mm, forces, fshift);
         for (i = 0; i < qm->nrQMatoms; i++)
         {
             for (j = 0; j < DIM; j++)
@@ -907,13 +905,13 @@ real calculate_QMMM(const t_commrec* cr, gmx::ForceWithShiftForces* forceWithShi
             srenew(fshift, qm->nrQMatoms);
             /* we need to re-initialize the QMroutine every step... */
             init_QMroutine(cr, qm, mm);
-            QMener += call_QMroutine(cr, fr, qm, mm, forces, fshift);
+            QMener += call_QMroutine(cr, qr, qm, mm, forces, fshift);
 
             /* this layer at the lower level of theory */
             srenew(forces2, qm->nrQMatoms);
             srenew(fshift2, qm->nrQMatoms);
             init_QMroutine(cr, qm2, mm);
-            QMener -= call_QMroutine(cr, fr, qm2, mm, forces2, fshift2);
+            QMener -= call_QMroutine(cr, qr, qm2, mm, forces2, fshift2);
             /* E = E1high-E1low The next layer includes the current layer at
              * the lower level of theory, which provides + E2low
              * this is similar for gradients
@@ -933,7 +931,7 @@ real calculate_QMMM(const t_commrec* cr, gmx::ForceWithShiftForces* forceWithShi
         init_QMroutine(cr, qm, mm);
         srenew(forces, qm->nrQMatoms);
         srenew(fshift, qm->nrQMatoms);
-        QMener += call_QMroutine(cr, fr, qm, mm, forces, fshift);
+        QMener += call_QMroutine(cr, qr, qm, mm, forces, fshift);
         for (i = 0; i < qm->nrQMatoms; i++)
         {
             for (j = 0; j < DIM; j++)
index 8172e9766007e9b1f51e3c48f455e8dbc4a0facd..8de4084926469fa39c73dde1186c99d88bfce919 100644 (file)
@@ -139,7 +139,7 @@ void update_QMMMrec(const t_commrec* cr, const t_forcerec* fr, const rvec* x, co
  * routine should be called at every step, since it updates the MM
  * elements of the t_QMMMrec struct.
  */
-real calculate_QMMM(const t_commrec* cr, gmx::ForceWithShiftForces* forceWithShiftForces, const t_forcerec* fr);
+real calculate_QMMM(const t_commrec* cr, gmx::ForceWithShiftForces* forceWithShiftForces, const t_QMMMrec* qmmm);
 
 /* QMMM computes the QM forces. This routine makes either function
  * calls to gmx QM routines (derived from MOPAC7 (semi-emp.) and MPQC
index d09bc9bf7a4dab51846f365ff503552ec13af1bd..7a4113399999520f24bba256acfe7fc0d4dd001a 100644 (file)
@@ -40,8 +40,6 @@
  * using CUDA, including class initialization, data-structures management
  * and GPU kernel.
  *
- * \note Management of CUDA stream and periodic boundary should be unified with LINCS
- *       and removed from here once constraints are fully integrated with update module.
  * \todo Reconsider naming to use "gpu" suffix instead of "cuda".
  *
  * \author Artem Zhmurov <zhmurov@gmail.com>
@@ -89,10 +87,10 @@ constexpr static int c_maxThreadsPerBlock = c_threadsPerBlock;
  * \param [in]      gm_x             Coordinates of atoms before the timestep.
  * \param [in,out]  gm_x             Coordinates of atoms after the timestep (constrained coordinates will be
  *                                   saved here).
- * \param [in]      pbcAiuc          Periodic boundary conditions data.
  * \param [in]      invdt            Reciprocal timestep.
  * \param [in]      gm_v             Velocities of the particles.
  * \param [in]      gm_virialScaled  Virial tensor.
+ * \param [in]      pbcAiuc          Periodic boundary conditions data.
  */
 template<bool updateVelocities, bool computeVirial>
 __launch_bounds__(c_maxThreadsPerBlock) __global__
@@ -101,10 +99,10 @@ __launch_bounds__(c_maxThreadsPerBlock) __global__
                            const SettleParameters pars,
                            const float3* __restrict__ gm_x,
                            float3* __restrict__ gm_xprime,
-                           const PbcAiuc pbcAiuc,
-                           float         invdt,
+                           float invdt,
                            float3* __restrict__ gm_v,
-                           float* __restrict__ gm_virialScaled)
+                           float* __restrict__ gm_virialScaled,
+                           const PbcAiuc pbcAiuc)
 {
     /* ******************************************************************* */
     /*                                                                  ** */
@@ -421,7 +419,8 @@ void SettleCuda::apply(const float3* d_x,
                        float3*       d_v,
                        const real    invdt,
                        const bool    computeVirial,
-                       tensor        virialScaled)
+                       tensor        virialScaled,
+                       const PbcAiuc pbcAiuc)
 {
 
     ensureNoPendingCudaError("In CUDA version SETTLE");
@@ -460,8 +459,8 @@ void SettleCuda::apply(const float3* d_x,
     config.stream = commandStream_;
 
     const auto kernelArgs = prepareGpuKernelArguments(kernelPtr, config, &numSettles_, &d_atomIds_,
-                                                      &settleParameters_, &d_x, &d_xp, &pbcAiuc_,
-                                                      &invdt, &d_v, &d_virialScaled_);
+                                                      &settleParameters_, &d_x, &d_xp, &invdt, &d_v,
+                                                      &d_virialScaled_, &pbcAiuc);
 
     launchGpuKernel(kernelPtr, config, nullptr, "settle_kernel<updateVelocities, computeVirial>", kernelArgs);
 
@@ -627,9 +626,4 @@ void SettleCuda::set(const t_idef& idef, const t_mdatoms gmx_unused& md)
                        GpuApiCallBehavior::Sync, nullptr);
 }
 
-void SettleCuda::setPbc(const t_pbc* pbc)
-{
-    setPbcAiuc(pbc->ndim_ePBC, pbc->box, &pbcAiuc_);
-}
-
 } // namespace gmx
index caef2dbedcdba5e539c697da2821ffd4719e0b8f..ca666156125064c9782f4d12c818575856557b66 100644 (file)
@@ -222,6 +222,7 @@ public:
      *                                  multipliers when velocities are updated)
      * \param[in]     computeVirial     If virial should be updated.
      * \param[in,out] virialScaled      Scaled virial tensor to be updated.
+     * \param[in]     pbcAiuc           PBC data.
      */
     void apply(const float3* d_x,
                float3*       d_xp,
@@ -229,7 +230,8 @@ public:
                float3*       d_v,
                const real    invdt,
                const bool    computeVirial,
-               tensor        virialScaled);
+               tensor        virialScaled,
+               const PbcAiuc pbcAiuc);
 
     /*! \brief
      * Update data-structures (e.g. after NB search step).
@@ -246,23 +248,9 @@ public:
      */
     void set(const t_idef& idef, const t_mdatoms& md);
 
-    /*! \brief
-     * Update PBC data.
-     *
-     * Converts pbc data from t_pbc into the PbcAiuc format and stores the latter.
-     *
-     * \todo PBC should not be handled by constraints.
-     *
-     * \param[in] pbc The PBC data in t_pbc format.
-     */
-    void setPbc(const t_pbc* pbc);
-
-
 private:
     //! CUDA stream
     CommandStream commandStream_;
-    //! Periodic boundary data
-    PbcAiuc pbcAiuc_;
 
     //! Scaled virial tensor (9 reals, GPU)
     std::vector<float> h_virialScaled_;
index c6adc7b73c3a545bca023176f0c268c112a11ec8..692c2570b66f9dfa613e29dae78d4f183685027f 100644 (file)
@@ -843,7 +843,7 @@ static StepWorkload setupStepWorkload(const int                 legacyFlags,
 
 /* \brief Launch end-of-step GPU tasks: buffer clearing and rolling pruning.
  *
- * TODO: eliminate the \p useGpuNonbonded and \p useGpuNonbonded when these are
+ * TODO: eliminate \p useGpuPmeOnThisRank when this is
  * incorporated in DomainLifetimeWorkload.
  */
 static void launchGpuEndOfStepTasks(nonbonded_verlet_t*               nbv,
@@ -851,12 +851,11 @@ static void launchGpuEndOfStepTasks(nonbonded_verlet_t*               nbv,
                                     gmx_pme_t*                        pmedata,
                                     gmx_enerdata_t*                   enerd,
                                     const gmx::MdrunScheduleWorkload& runScheduleWork,
-                                    bool                              useGpuNonbonded,
-                                    bool                              useGpuPme,
+                                    bool                              useGpuPmeOnThisRank,
                                     int64_t                           step,
                                     gmx_wallcycle_t                   wcycle)
 {
-    if (useGpuNonbonded)
+    if (runScheduleWork.simulationWork.useGpuNonbonded)
     {
         /* Launch pruning before buffer clearing because the API overhead of the
          * clear kernel launches can leave the GPU idle while it could be running
@@ -875,7 +874,7 @@ static void launchGpuEndOfStepTasks(nonbonded_verlet_t*               nbv,
         wallcycle_stop(wcycle, ewcLAUNCH_GPU);
     }
 
-    if (useGpuPme)
+    if (useGpuPmeOnThisRank)
     {
         pme_gpu_reinit_computation(pmedata, wcycle);
     }
@@ -1135,10 +1134,7 @@ void do_force(FILE*                               fplog,
             }
             wallcycle_stop(wcycle, ewcLAUNCH_GPU);
         }
-    }
 
-    if (stepWork.doNeighborSearch)
-    {
         // Need to run after the GPU-offload bonded interaction lists
         // are set up to be able to determine whether there is bonded work.
         runScheduleWork->domainWork = setupDomainLifetimeWorkload(
@@ -1728,7 +1724,7 @@ void do_force(FILE*                               fplog,
     }
 
     launchGpuEndOfStepTasks(nbv, fr->gpuBonded, fr->pmedata, enerd, *runScheduleWork,
-                            simulationWork.useGpuNonbonded, useGpuPmeOnThisRank, step, wcycle);
+                            useGpuPmeOnThisRank, step, wcycle);
 
     if (DOMAINDECOMP(cr))
     {
index c62e67e94b151065af69960c42d3595613a542e1..43c7edca6a5f5c70da27ad6ec94b520306d05ccb 100644 (file)
@@ -78,7 +78,8 @@ void applyLincsCuda(ConstraintsTestData* testData, t_pbc pbc)
     float3 *d_x, *d_xp, *d_v;
 
     lincsCuda->set(testData->idef_, testData->md_);
-    lincsCuda->setPbc(&pbc);
+    PbcAiuc pbcAiuc;
+    setPbcAiuc(pbc.ndim_ePBC, pbc.box, &pbcAiuc);
 
     allocateDeviceBuffer(&d_x, numAtoms, nullptr);
     allocateDeviceBuffer(&d_xp, numAtoms, nullptr);
@@ -94,7 +95,7 @@ void applyLincsCuda(ConstraintsTestData* testData, t_pbc pbc)
                            GpuApiCallBehavior::Sync, nullptr);
     }
     lincsCuda->apply(d_x, d_xp, updateVelocities, d_v, testData->invdt_, testData->computeVirial_,
-                     testData->virialScaled_);
+                     testData->virialScaled_, pbcAiuc);
 
     copyFromDeviceBuffer((float3*)(testData->xPrime_.data()), &d_xp, 0, numAtoms, nullptr,
                          GpuApiCallBehavior::Sync, nullptr);
index e75466af86ac5b247a502df0e12d4bbf726e8199..b8823389902be63c177b4ce2c5b9a1bd0d72fe8f 100644 (file)
@@ -87,8 +87,10 @@ void applySettleGpu(SettleTestData*  testData,
     GMX_RELEASE_ASSERT(canPerformGpuDetection(), "Can't detect CUDA-capable GPUs.");
 
     auto settleCuda = std::make_unique<SettleCuda>(testData->mtop_, nullptr);
-    settleCuda->setPbc(&pbc);
+
     settleCuda->set(testData->idef_, testData->mdatoms_);
+    PbcAiuc pbcAiuc;
+    setPbcAiuc(pbc.ndim_ePBC, pbc.box, &pbcAiuc);
 
     int numAtoms = testData->mdatoms_.homenr;
 
@@ -109,7 +111,7 @@ void applySettleGpu(SettleTestData*  testData,
         copyToDeviceBuffer(&d_v, (float3*)h_v, 0, numAtoms, nullptr, GpuApiCallBehavior::Sync, nullptr);
     }
     settleCuda->apply(d_x, d_xp, updateVelocities, d_v, testData->reciprocalTimeStep_, calcVirial,
-                      testData->virial_);
+                      testData->virial_, pbcAiuc);
 
     copyFromDeviceBuffer((float3*)h_xp, &d_xp, 0, numAtoms, nullptr, GpuApiCallBehavior::Sync, nullptr);
     if (updateVelocities)
index add995f26a0322b281321bf1608557f319e417a4..7f38b8d74cc74a1b9917dea8f23c2d17b13b9f33 100644 (file)
@@ -127,8 +127,8 @@ void UpdateConstrainCuda::Impl::integrate(GpuEventSynchronizer*             fRea
     // 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.
-    lincsCuda_->apply(d_xp_, d_x_, updateVelocities, d_v_, 1.0 / dt, computeVirial, virial);
-    settleCuda_->apply(d_xp_, d_x_, updateVelocities, d_v_, 1.0 / dt, computeVirial, virial);
+    lincsCuda_->apply(d_xp_, d_x_, updateVelocities, d_v_, 1.0 / dt, computeVirial, virial, pbcAiuc_);
+    settleCuda_->apply(d_xp_, d_x_, updateVelocities, d_v_, 1.0 / dt, computeVirial, virial, pbcAiuc_);
 
     // scaledVirial -> virial (methods above returns scaled values)
     float scaleFactor = 0.5f / (dt * dt);
@@ -222,9 +222,6 @@ void UpdateConstrainCuda::Impl::set(DeviceBuffer<float>       d_x,
 void UpdateConstrainCuda::Impl::setPbc(const t_pbc* pbc)
 {
     setPbcAiuc(pbc->ndim_ePBC, pbc->box, &pbcAiuc_);
-    integrator_->setPbc(pbc);
-    lincsCuda_->setPbc(pbc);
-    settleCuda_->setPbc(pbc);
 }
 
 GpuEventSynchronizer* UpdateConstrainCuda::Impl::getCoordinatesReadySync()
index d03f55344c6d58cee867920516f3740ae0e81267..aab096a6f45204a63bae9397e3ee57d88462f45b 100644 (file)
@@ -176,7 +176,7 @@ real do_walls(const t_inputrec&     ir,
     const int   nwall     = ir.nwall;
     const int   ngid      = ir.opts.ngener;
     const int   ntype     = fr.ntype;
-    const real* nbfp      = fr.nbfp;
+    const real* nbfp      = fr.nbfp.data();
     const int*  egp_flags = fr.egp_flags;
 
     for (int w = 0; w < nwall; w++)
index d68a5fec5414746cd2e373289dfcfc7db653f9f3..75a6f6d14cb18b3607a68c2f2cec1135ea7fbe6d 100644 (file)
@@ -1544,7 +1544,7 @@ int Mdrunner::mdrunner()
             /* 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,
+            dd_init_bondeds(fplog, cr->dd, mtop, vsite.get(), inputrec,
                             domdecOptions.checkBondedInteractions, fr->cginfo_mb);
         }
 
@@ -1644,18 +1644,45 @@ int Mdrunner::mdrunner()
     }
 
     // FIXME: this is only here to manually unpin mdAtoms->chargeA_ and state->x,
-    // before we destroy the GPU context(s) in free_gpu_resources().
+    // before we destroy the GPU context(s) in free_gpu().
     // Pinned buffers are associated with contexts in CUDA.
     // As soon as we destroy GPU contexts after mdrunner() exits, these lines should go.
     mdAtoms.reset(nullptr);
     globalState.reset(nullptr);
     mdModules_.reset(nullptr); // destruct force providers here as they might also use the GPU
+    /* Free pinned buffers in *fr */
+    delete fr;
+    fr = nullptr;
+
+    if (hwinfo->gpu_info.n_dev > 0)
+    {
+        /* stop the GPU profiler (only CUDA) */
+        stopGpuProfiler();
+    }
+
+    /* With tMPI we need to wait for all ranks to finish deallocation before
+     * destroying the CUDA context in free_gpu() as some tMPI ranks may be sharing
+     * GPU and context.
+     *
+     * This is not a concern in OpenCL where we use one context per rank which
+     * is freed in nbnxn_gpu_free().
+     *
+     * Note: it is safe to not call the barrier on the ranks which do not use GPU,
+     * but it is easier and more futureproof to call it on the whole node.
+     *
+     * Note that this function needs to be called even if GPUs are not used
+     * in this run because the PME ranks have no knowledge of whether GPUs
+     * are used or not, but all ranks need to enter the barrier below.
+     * \todo Remove this physical node barrier after making sure
+     * that it's not needed anymore (with a shared GPU run).
+     */
+    if (GMX_THREAD_MPI)
+    {
+        physicalNodeComm.barrier();
+    }
 
-    /* Free GPU memory and set a physical node tMPI barrier (which should eventually go away) */
-    free_gpu_resources(fr, physicalNodeComm, hwinfo->gpu_info);
     free_gpu(nonbondedDeviceInfo);
     free_gpu(pmeDeviceInfo);
-    done_forcerec(fr, mtop.molblock.size());
     sfree(fcd);
 
     if (doMembed)
index 2b0832a80a7503dc61bfd10ef2488bd63022ddbd..05bcab152e7729ab6abf4ac48e19d4cd8c72359c 100644 (file)
@@ -110,10 +110,10 @@ enum
 
 struct cginfo_mb_t
 {
-    int  cg_start;
-    int  cg_end;
-    int  cg_mod;
-    int* cginfo;
+    int              cg_start = 0;
+    int              cg_end   = 0;
+    int              cg_mod   = 0;
+    std::vector<int> cginfo;
 };
 
 
@@ -192,7 +192,7 @@ struct t_forcerec
     real sc_sigma6_min = 0;
 
     /* Information about atom properties for the molecule blocks in the system */
-    struct cginfo_mb_t* cginfo_mb = nullptr;
+    std::vector<cginfo_mb_t> cginfo_mb;
     /* Information about atom properties for local and non-local atoms */
     std::vector<int> cginfo;
 
@@ -234,10 +234,10 @@ struct t_forcerec
     std::vector<gmx::RVec> shiftForces;
 
     /* Non bonded Parameter lists */
-    int      ntype        = 0; /* Number of atom types */
-    gmx_bool bBHAM        = FALSE;
-    real*    nbfp         = nullptr;
-    real*    ljpme_c6grid = nullptr; /* C6-values used on grid in LJPME */
+    int               ntype = 0; /* Number of atom types */
+    gmx_bool          bBHAM = FALSE;
+    std::vector<real> nbfp;
+    real*             ljpme_c6grid = nullptr; /* C6-values used on grid in LJPME */
 
     /* Energy group pair flags */
     int* egp_flags = nullptr;
index f42ad7230e9b220eaca5be3cae2ebb401fa8390f..9d674afd8f5d05c8abdbadeab75010efe7c032ff 100644 (file)
@@ -246,8 +246,13 @@ void StatePropagatorDataGpu::Impl::copyToDevice(DeviceBuffer<float>
 
     GMX_UNUSED_VALUE(dataSize);
 
+    GMX_ASSERT(atomLocality < AtomLocality::Count, "Wrong atom locality.");
+
     GMX_ASSERT(dataSize >= 0, "Trying to copy to device buffer before it was allocated.");
 
+    GMX_ASSERT(commandStream != nullptr,
+               "No stream is valid for copying with given atom locality.");
+
     int atomsStartAt, numAtomsToCopy;
     std::tie(atomsStartAt, numAtomsToCopy) = getAtomRangesFromAtomLocality(atomLocality);
 
@@ -275,8 +280,13 @@ void StatePropagatorDataGpu::Impl::copyFromDevice(gmx::ArrayRef<gmx::RVec> h_dat
 
     GMX_UNUSED_VALUE(dataSize);
 
+    GMX_ASSERT(atomLocality < AtomLocality::Count, "Wrong atom locality.");
+
     GMX_ASSERT(dataSize >= 0, "Trying to copy from device buffer before it was allocated.");
 
+    GMX_ASSERT(commandStream != nullptr,
+               "No stream is valid for copying with given atom locality.");
+
     int atomsStartAt, numAtomsToCopy;
     std::tie(atomsStartAt, numAtomsToCopy) = getAtomRangesFromAtomLocality(atomLocality);
 
@@ -303,12 +313,7 @@ DeviceBuffer<float> StatePropagatorDataGpu::Impl::getCoordinates()
 void StatePropagatorDataGpu::Impl::copyCoordinatesToGpu(const gmx::ArrayRef<const gmx::RVec> h_x,
                                                         AtomLocality atomLocality)
 {
-    GMX_ASSERT(atomLocality < AtomLocality::Count, "Wrong atom locality.");
-    CommandStream commandStream = xCopyStreams_[atomLocality];
-    GMX_ASSERT(commandStream != nullptr,
-               "No stream is valid for copying positions with given atom locality.");
-
-    copyToDevice(d_x_, h_x, d_xSize_, atomLocality, commandStream);
+    copyToDevice(d_x_, h_x, d_xSize_, atomLocality, xCopyStreams_[atomLocality]);
 
     // markEvent is skipped in OpenCL as:
     //   - it's not needed, copy is done in the same stream as the only consumer task (PME)
@@ -316,7 +321,7 @@ void StatePropagatorDataGpu::Impl::copyCoordinatesToGpu(const gmx::ArrayRef<cons
     // TODO: remove this by adding an event-mark free flavor of this function
     if (GMX_GPU == GMX_GPU_CUDA)
     {
-        xReadyOnDevice_[atomLocality].markEvent(commandStream);
+        xReadyOnDevice_[atomLocality].markEvent(xCopyStreams_[atomLocality]);
     }
 }
 
@@ -360,14 +365,9 @@ GpuEventSynchronizer* StatePropagatorDataGpu::Impl::xUpdatedOnDevice()
 
 void StatePropagatorDataGpu::Impl::copyCoordinatesFromGpu(gmx::ArrayRef<gmx::RVec> h_x, AtomLocality atomLocality)
 {
-    GMX_ASSERT(atomLocality < AtomLocality::Count, "Wrong atom locality.");
-    CommandStream commandStream = xCopyStreams_[atomLocality];
-    GMX_ASSERT(commandStream != nullptr,
-               "No stream is valid for copying positions with given atom locality.");
-
-    copyFromDevice(h_x, d_x_, d_xSize_, atomLocality, commandStream);
+    copyFromDevice(h_x, d_x_, d_xSize_, atomLocality, xCopyStreams_[atomLocality]);
     // Note: unlike copyCoordinatesToGpu this is not used in OpenCL, and the conditional is not needed.
-    xReadyOnHost_[atomLocality].markEvent(commandStream);
+    xReadyOnHost_[atomLocality].markEvent(xCopyStreams_[atomLocality]);
 }
 
 void StatePropagatorDataGpu::Impl::waitCoordinatesReadyOnHost(AtomLocality atomLocality)
@@ -384,13 +384,8 @@ DeviceBuffer<float> StatePropagatorDataGpu::Impl::getVelocities()
 void StatePropagatorDataGpu::Impl::copyVelocitiesToGpu(const gmx::ArrayRef<const gmx::RVec> h_v,
                                                        AtomLocality atomLocality)
 {
-    GMX_ASSERT(atomLocality < AtomLocality::Count, "Wrong atom locality.");
-    CommandStream commandStream = vCopyStreams_[atomLocality];
-    GMX_ASSERT(commandStream != nullptr,
-               "No stream is valid for copying velocities with given atom locality.");
-
-    copyToDevice(d_v_, h_v, d_vSize_, atomLocality, commandStream);
-    vReadyOnDevice_[atomLocality].markEvent(commandStream);
+    copyToDevice(d_v_, h_v, d_vSize_, atomLocality, vCopyStreams_[atomLocality]);
+    vReadyOnDevice_[atomLocality].markEvent(vCopyStreams_[atomLocality]);
 }
 
 GpuEventSynchronizer* StatePropagatorDataGpu::Impl::getVelocitiesReadyOnDeviceEvent(AtomLocality atomLocality)
@@ -401,13 +396,8 @@ GpuEventSynchronizer* StatePropagatorDataGpu::Impl::getVelocitiesReadyOnDeviceEv
 
 void StatePropagatorDataGpu::Impl::copyVelocitiesFromGpu(gmx::ArrayRef<gmx::RVec> h_v, AtomLocality atomLocality)
 {
-    GMX_ASSERT(atomLocality < AtomLocality::Count, "Wrong atom locality.");
-    CommandStream commandStream = vCopyStreams_[atomLocality];
-    GMX_ASSERT(commandStream != nullptr,
-               "No stream is valid for copying velocities with given atom locality.");
-
-    copyFromDevice(h_v, d_v_, d_vSize_, atomLocality, commandStream);
-    vReadyOnHost_[atomLocality].markEvent(commandStream);
+    copyFromDevice(h_v, d_v_, d_vSize_, atomLocality, vCopyStreams_[atomLocality]);
+    vReadyOnHost_[atomLocality].markEvent(vCopyStreams_[atomLocality]);
 }
 
 void StatePropagatorDataGpu::Impl::waitVelocitiesReadyOnHost(AtomLocality atomLocality)
@@ -424,13 +414,8 @@ DeviceBuffer<float> StatePropagatorDataGpu::Impl::getForces()
 void StatePropagatorDataGpu::Impl::copyForcesToGpu(const gmx::ArrayRef<const gmx::RVec> h_f,
                                                    AtomLocality atomLocality)
 {
-    GMX_ASSERT(atomLocality < AtomLocality::Count, "Wrong atom locality.");
-    CommandStream commandStream = fCopyStreams_[atomLocality];
-    GMX_ASSERT(commandStream != nullptr,
-               "No stream is valid for copying forces with given atom locality.");
-
-    copyToDevice(d_f_, h_f, d_fSize_, atomLocality, commandStream);
-    fReadyOnDevice_[atomLocality].markEvent(commandStream);
+    copyToDevice(d_f_, h_f, d_fSize_, atomLocality, fCopyStreams_[atomLocality]);
+    fReadyOnDevice_[atomLocality].markEvent(fCopyStreams_[atomLocality]);
 }
 
 GpuEventSynchronizer* StatePropagatorDataGpu::Impl::getForcesReadyOnDeviceEvent(AtomLocality atomLocality,
@@ -453,13 +438,8 @@ GpuEventSynchronizer* StatePropagatorDataGpu::Impl::fReducedOnDevice()
 
 void StatePropagatorDataGpu::Impl::copyForcesFromGpu(gmx::ArrayRef<gmx::RVec> h_f, AtomLocality atomLocality)
 {
-    GMX_ASSERT(atomLocality < AtomLocality::Count, "Wrong atom locality.");
-    CommandStream commandStream = fCopyStreams_[atomLocality];
-    GMX_ASSERT(commandStream != nullptr,
-               "No stream is valid for copying forces with given atom locality.");
-
-    copyFromDevice(h_f, d_f_, d_fSize_, atomLocality, commandStream);
-    fReadyOnHost_[atomLocality].markEvent(commandStream);
+    copyFromDevice(h_f, d_f_, d_fSize_, atomLocality, fCopyStreams_[atomLocality]);
+    fReadyOnHost_[atomLocality].markEvent(fCopyStreams_[atomLocality]);
 }
 
 void StatePropagatorDataGpu::Impl::waitForcesReadyOnHost(AtomLocality atomLocality)
index c4a15ba97481dd5a79421b220172412c47bd296e..07684c90092d0db2957748c738695f5e1252490c 100644 (file)
@@ -442,7 +442,7 @@ static void nbnxn_atomdata_params_init(const gmx::MDLogger&      mdlog,
                                        const Nbnxm::KernelType   kernelType,
                                        int                       enbnxninitcombrule,
                                        int                       ntype,
-                                       const real*               nbfp,
+                                       ArrayRef<const real>      nbfp,
                                        int                       n_energygroups)
 {
     real     c6, c12, tol;
@@ -625,7 +625,7 @@ void nbnxn_atomdata_init(const gmx::MDLogger&    mdlog,
                          const Nbnxm::KernelType kernelType,
                          int                     enbnxninitcombrule,
                          int                     ntype,
-                         const real*             nbfp,
+                         ArrayRef<const real>    nbfp,
                          int                     n_energygroups,
                          int                     nout)
 {
index 1b1e3b763a17f9c23b09007c27a5233e835b6750..6f4e11561ca0131bc31756e7b2f289bac310facc 100644 (file)
@@ -288,14 +288,14 @@ enum
  * to the atom data structure.
  * enbnxninitcombrule sets what combination rule data gets stored in nbat.
  */
-void nbnxn_atomdata_init(const gmx::MDLogger& mdlog,
-                         nbnxn_atomdata_t*    nbat,
-                         Nbnxm::KernelType    kernelType,
-                         int                  enbnxninitcombrule,
-                         int                  ntype,
-                         const real*          nbfp,
-                         int                  n_energygroups,
-                         int                  nout);
+void nbnxn_atomdata_init(const gmx::MDLogger&      mdlog,
+                         nbnxn_atomdata_t*         nbat,
+                         Nbnxm::KernelType         kernelType,
+                         int                       enbnxninitcombrule,
+                         int                       ntype,
+                         gmx::ArrayRef<const real> nbfp,
+                         int                       n_energygroups,
+                         int                       nout);
 
 void nbnxn_atomdata_set(nbnxn_atomdata_t*     nbat,
                         const Nbnxm::GridSet& gridSet,
index ecfe6af14de3ee1e349ed0f3d2d3a0679f376120..f3d6b27526a0eee43ed7f1786b5ed1772d0f812c 100644 (file)
@@ -199,7 +199,7 @@ static std::unique_ptr<nonbonded_verlet_t> setupNbnxmForBenchInstance(const Kern
                                                     std::move(atomData), kernelSetup, nullptr, nullptr);
 
     nbnxn_atomdata_init(gmx::MDLogger(), nbv->nbat.get(), kernelSetup.kernelType, combinationRule,
-                        system.numAtomTypes, system.nonbondedParameters.data(), 1, numThreads);
+                        system.numAtomTypes, system.nonbondedParameters, 1, numThreads);
 
     t_nrnb nrnb;
 
index ffe0a899ff9b7e820f95ac5b1652561c421c447f..fba71d2b9a0ca899ff30e3257d137485e354da7e 100644 (file)
@@ -200,7 +200,7 @@ BenchmarkSystem::BenchmarkSystem(const int multiplicationFactor)
     }
 
     forceRec.ntype = numAtomTypes;
-    forceRec.nbfp  = nonbondedParameters.data();
+    forceRec.nbfp  = nonbondedParameters;
     snew(forceRec.shift_vec, SHIFTS);
     calc_shifts(box, forceRec.shift_vec);
 }