From ef7ebd0f7e7679002cb1be33430ce5a768902413 Mon Sep 17 00:00:00 2001
From: Giovanni Bussi <giovanni.bussi@gmail.com>
Date: Fri, 21 Sep 2018 17:40:21 +0200
Subject: [PATCH] Updated patch to GMX 2018.3

---
 ...cs-2018.1.config => gromacs-2018.3.config} |  0
 .../src/gromacs/CMakeLists.txt                | 20 ++---
 .../src/gromacs/CMakeLists.txt.preplumed      | 20 ++---
 .../src/gromacs/mdlib/force.cpp               |  0
 .../src/gromacs/mdlib/force.cpp.preplumed     |  0
 .../src/gromacs/mdlib/minimize.cpp            | 73 ++++++++++++++-----
 .../src/gromacs/mdlib/minimize.cpp.preplumed  | 73 ++++++++++++++-----
 .../src/programs/mdrun/md.cpp                 |  0
 .../src/programs/mdrun/md.cpp.preplumed       |  0
 .../src/programs/mdrun/mdrun.cpp              |  0
 .../src/programs/mdrun/mdrun.cpp.preplumed    |  0
 .../src/programs/mdrun/repl_ex.cpp            |  0
 .../src/programs/mdrun/repl_ex.cpp.preplumed  |  0
 .../src/programs/mdrun/repl_ex.h              |  0
 .../src/programs/mdrun/repl_ex.h.preplumed    |  0
 .../src/programs/mdrun/runner.cpp             |  2 +-
 .../src/programs/mdrun/runner.cpp.preplumed   |  2 +-
 .../src/programs/mdrun/runner.h               |  0
 .../src/programs/mdrun/runner.h.preplumed     |  0
 19 files changed, 132 insertions(+), 58 deletions(-)
 rename patches/{gromacs-2018.1.config => gromacs-2018.3.config} (100%)
 rename patches/{gromacs-2018.1.diff => gromacs-2018.3.diff}/src/gromacs/CMakeLists.txt (92%)
 rename patches/{gromacs-2018.1.diff => gromacs-2018.3.diff}/src/gromacs/CMakeLists.txt.preplumed (92%)
 rename patches/{gromacs-2018.1.diff => gromacs-2018.3.diff}/src/gromacs/mdlib/force.cpp (100%)
 rename patches/{gromacs-2018.1.diff => gromacs-2018.3.diff}/src/gromacs/mdlib/force.cpp.preplumed (100%)
 rename patches/{gromacs-2018.1.diff => gromacs-2018.3.diff}/src/gromacs/mdlib/minimize.cpp (97%)
 rename patches/{gromacs-2018.1.diff => gromacs-2018.3.diff}/src/gromacs/mdlib/minimize.cpp.preplumed (97%)
 rename patches/{gromacs-2018.1.diff => gromacs-2018.3.diff}/src/programs/mdrun/md.cpp (100%)
 rename patches/{gromacs-2018.1.diff => gromacs-2018.3.diff}/src/programs/mdrun/md.cpp.preplumed (100%)
 rename patches/{gromacs-2018.1.diff => gromacs-2018.3.diff}/src/programs/mdrun/mdrun.cpp (100%)
 rename patches/{gromacs-2018.1.diff => gromacs-2018.3.diff}/src/programs/mdrun/mdrun.cpp.preplumed (100%)
 rename patches/{gromacs-2018.1.diff => gromacs-2018.3.diff}/src/programs/mdrun/repl_ex.cpp (100%)
 rename patches/{gromacs-2018.1.diff => gromacs-2018.3.diff}/src/programs/mdrun/repl_ex.cpp.preplumed (100%)
 rename patches/{gromacs-2018.1.diff => gromacs-2018.3.diff}/src/programs/mdrun/repl_ex.h (100%)
 rename patches/{gromacs-2018.1.diff => gromacs-2018.3.diff}/src/programs/mdrun/repl_ex.h.preplumed (100%)
 rename patches/{gromacs-2018.1.diff => gromacs-2018.3.diff}/src/programs/mdrun/runner.cpp (99%)
 rename patches/{gromacs-2018.1.diff => gromacs-2018.3.diff}/src/programs/mdrun/runner.cpp.preplumed (99%)
 rename patches/{gromacs-2018.1.diff => gromacs-2018.3.diff}/src/programs/mdrun/runner.h (100%)
 rename patches/{gromacs-2018.1.diff => gromacs-2018.3.diff}/src/programs/mdrun/runner.h.preplumed (100%)

diff --git a/patches/gromacs-2018.1.config b/patches/gromacs-2018.3.config
similarity index 100%
rename from patches/gromacs-2018.1.config
rename to patches/gromacs-2018.3.config
diff --git a/patches/gromacs-2018.1.diff/src/gromacs/CMakeLists.txt b/patches/gromacs-2018.3.diff/src/gromacs/CMakeLists.txt
similarity index 92%
rename from patches/gromacs-2018.1.diff/src/gromacs/CMakeLists.txt
rename to patches/gromacs-2018.3.diff/src/gromacs/CMakeLists.txt
index 41d5aa5a8..0e0d82c68 100644
--- a/patches/gromacs-2018.1.diff/src/gromacs/CMakeLists.txt
+++ b/patches/gromacs-2018.3.diff/src/gromacs/CMakeLists.txt
@@ -1,7 +1,7 @@
 #
 # This file is part of the GROMACS molecular simulation package.
 #
-# Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017, by the GROMACS development team, led by
+# Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by
 # Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
 # and including many others, as listed in the AUTHORS file in the
 # top-level source directory and at http://www.gromacs.org.
@@ -63,7 +63,7 @@ function (gmx_install_headers)
     if (NOT GMX_BUILD_MDRUN_ONLY)
         file(RELATIVE_PATH _dest ${PROJECT_SOURCE_DIR}/src ${CMAKE_CURRENT_LIST_DIR})
         install(FILES       ${ARGN}
-                DESTINATION "${INCL_INSTALL_DIR}/${_dest}"
+                DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${_dest}"
                 COMPONENT   development)
     endif()
     _gmx_add_files_to_property(GMX_INSTALLED_HEADERS ${ARGN})
@@ -194,8 +194,10 @@ if (HAS_NO_UNUSED)
 endif()
 set_source_files_properties(selection/scanner.cpp PROPERTIES COMPILE_FLAGS "${_scanner_cpp_compiler_flags}")
 
-if(SIMD_AVX_512_CXX_SUPPORTED)
-    # Since we might be overriding -march=core-avx2, add a flag so we don't warn for this specific file
+if(SIMD_AVX_512_CXX_SUPPORTED AND NOT ("${GMX_SIMD_ACTIVE}" STREQUAL "AVX_512_KNL"))
+    # Since we might be overriding -march=core-avx2, add a flag so we don't warn for this specific file.
+    # On KNL this can cause illegal instruction because the compiler might use non KNL AVX instructions
+    # with the SIMD_AVX_512_CXX_FLAGS flags.
     set_source_files_properties(hardware/identifyavx512fmaunits.cpp PROPERTIES COMPILE_FLAGS "${SIMD_AVX_512_CXX_FLAGS} ${CXX_NO_UNUSED_OPTION_WARNING_FLAGS}")
 endif()
 
@@ -227,9 +229,9 @@ gmx_write_installed_header_list()
 if (NOT GMX_BUILD_MDRUN_ONLY OR BUILD_SHARED_LIBS)
     install(TARGETS libgromacs
             EXPORT libgromacs
-            LIBRARY DESTINATION ${LIB_INSTALL_DIR}
-            RUNTIME DESTINATION ${BIN_INSTALL_DIR}
-            ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
+            LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+            RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+            ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
             COMPONENT libraries)
 endif()
 
@@ -248,7 +250,7 @@ if (INSTALL_CUDART_LIB) #can be set manual by user
                 #install also name-links (linker uses those)
                 file(GLOB CUDA_LIBS ${CUDA_LIB}*)
                 install(FILES ${CUDA_LIBS} DESTINATION
-                    ${LIB_INSTALL_DIR} COMPONENT libraries)
+                    ${CMAKE_INSTALL_LIBDIR} COMPONENT libraries)
             endif()
         endforeach()
     else()
@@ -260,7 +262,7 @@ if(GMX_USE_OPENCL)
     set(OPENCL_KERNELS ${MDLIB_OPENCL_KERNELS})
 
     install(FILES ${OPENCL_KERNELS} DESTINATION
-        ${OCL_INSTALL_DIR} COMPONENT libraries)
+        ${GMX_INSTALL_OCLDIR} COMPONENT libraries)
 endif()
 
 if (BUILD_TESTING)
diff --git a/patches/gromacs-2018.1.diff/src/gromacs/CMakeLists.txt.preplumed b/patches/gromacs-2018.3.diff/src/gromacs/CMakeLists.txt.preplumed
similarity index 92%
rename from patches/gromacs-2018.1.diff/src/gromacs/CMakeLists.txt.preplumed
rename to patches/gromacs-2018.3.diff/src/gromacs/CMakeLists.txt.preplumed
index a88015302..2be059308 100644
--- a/patches/gromacs-2018.1.diff/src/gromacs/CMakeLists.txt.preplumed
+++ b/patches/gromacs-2018.3.diff/src/gromacs/CMakeLists.txt.preplumed
@@ -1,7 +1,7 @@
 #
 # This file is part of the GROMACS molecular simulation package.
 #
-# Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017, by the GROMACS development team, led by
+# Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by
 # Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
 # and including many others, as listed in the AUTHORS file in the
 # top-level source directory and at http://www.gromacs.org.
@@ -61,7 +61,7 @@ function (gmx_install_headers)
     if (NOT GMX_BUILD_MDRUN_ONLY)
         file(RELATIVE_PATH _dest ${PROJECT_SOURCE_DIR}/src ${CMAKE_CURRENT_LIST_DIR})
         install(FILES       ${ARGN}
-                DESTINATION "${INCL_INSTALL_DIR}/${_dest}"
+                DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${_dest}"
                 COMPONENT   development)
     endif()
     _gmx_add_files_to_property(GMX_INSTALLED_HEADERS ${ARGN})
@@ -192,8 +192,10 @@ if (HAS_NO_UNUSED)
 endif()
 set_source_files_properties(selection/scanner.cpp PROPERTIES COMPILE_FLAGS "${_scanner_cpp_compiler_flags}")
 
-if(SIMD_AVX_512_CXX_SUPPORTED)
-    # Since we might be overriding -march=core-avx2, add a flag so we don't warn for this specific file
+if(SIMD_AVX_512_CXX_SUPPORTED AND NOT ("${GMX_SIMD_ACTIVE}" STREQUAL "AVX_512_KNL"))
+    # Since we might be overriding -march=core-avx2, add a flag so we don't warn for this specific file.
+    # On KNL this can cause illegal instruction because the compiler might use non KNL AVX instructions
+    # with the SIMD_AVX_512_CXX_FLAGS flags.
     set_source_files_properties(hardware/identifyavx512fmaunits.cpp PROPERTIES COMPILE_FLAGS "${SIMD_AVX_512_CXX_FLAGS} ${CXX_NO_UNUSED_OPTION_WARNING_FLAGS}")
 endif()
 
@@ -224,9 +226,9 @@ gmx_write_installed_header_list()
 if (NOT GMX_BUILD_MDRUN_ONLY OR BUILD_SHARED_LIBS)
     install(TARGETS libgromacs
             EXPORT libgromacs
-            LIBRARY DESTINATION ${LIB_INSTALL_DIR}
-            RUNTIME DESTINATION ${BIN_INSTALL_DIR}
-            ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
+            LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+            RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+            ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
             COMPONENT libraries)
 endif()
 
@@ -245,7 +247,7 @@ if (INSTALL_CUDART_LIB) #can be set manual by user
                 #install also name-links (linker uses those)
                 file(GLOB CUDA_LIBS ${CUDA_LIB}*)
                 install(FILES ${CUDA_LIBS} DESTINATION
-                    ${LIB_INSTALL_DIR} COMPONENT libraries)
+                    ${CMAKE_INSTALL_LIBDIR} COMPONENT libraries)
             endif()
         endforeach()
     else()
@@ -257,7 +259,7 @@ if(GMX_USE_OPENCL)
     set(OPENCL_KERNELS ${MDLIB_OPENCL_KERNELS})
 
     install(FILES ${OPENCL_KERNELS} DESTINATION
-        ${OCL_INSTALL_DIR} COMPONENT libraries)
+        ${GMX_INSTALL_OCLDIR} COMPONENT libraries)
 endif()
 
 if (BUILD_TESTING)
diff --git a/patches/gromacs-2018.1.diff/src/gromacs/mdlib/force.cpp b/patches/gromacs-2018.3.diff/src/gromacs/mdlib/force.cpp
similarity index 100%
rename from patches/gromacs-2018.1.diff/src/gromacs/mdlib/force.cpp
rename to patches/gromacs-2018.3.diff/src/gromacs/mdlib/force.cpp
diff --git a/patches/gromacs-2018.1.diff/src/gromacs/mdlib/force.cpp.preplumed b/patches/gromacs-2018.3.diff/src/gromacs/mdlib/force.cpp.preplumed
similarity index 100%
rename from patches/gromacs-2018.1.diff/src/gromacs/mdlib/force.cpp.preplumed
rename to patches/gromacs-2018.3.diff/src/gromacs/mdlib/force.cpp.preplumed
diff --git a/patches/gromacs-2018.1.diff/src/gromacs/mdlib/minimize.cpp b/patches/gromacs-2018.3.diff/src/gromacs/mdlib/minimize.cpp
similarity index 97%
rename from patches/gromacs-2018.1.diff/src/gromacs/mdlib/minimize.cpp
rename to patches/gromacs-2018.3.diff/src/gromacs/mdlib/minimize.cpp
index 8fcef5673..a268949cb 100644
--- a/patches/gromacs-2018.1.diff/src/gromacs/mdlib/minimize.cpp
+++ b/patches/gromacs-2018.3.diff/src/gromacs/mdlib/minimize.cpp
@@ -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, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
@@ -577,27 +577,36 @@ static void write_em_traj(FILE *fplog, t_commrec *cr,
                                      &state->s, state_global, observablesHistory,
                                      state->f);
 
-    if (confout != nullptr && MASTER(cr))
+    if (confout != nullptr)
     {
-        GMX_RELEASE_ASSERT(bX, "The code below assumes that (with domain decomposition), x is collected to state_global in the call above.");
-        /* With domain decomposition the call above collected the state->s.x
-         * into state_global->x. Without DD we copy the local state pointer.
-         */
-        if (!DOMAINDECOMP(cr))
+        if (DOMAINDECOMP(cr))
+        {
+            /* If bX=true, x was collected to state_global in the call above */
+            if (!bX)
+            {
+                gmx::ArrayRef<gmx::RVec> globalXRef = MASTER(cr) ? gmx::makeArrayRef(state_global->x) : gmx::EmptyArrayRef();
+                dd_collect_vec(cr->dd, &state->s, state->s.x, globalXRef);
+            }
+        }
+        else
         {
+            /* Copy the local state pointer */
             state_global = &state->s;
         }
 
-        if (ir->ePBC != epbcNONE && !ir->bPeriodicMols && DOMAINDECOMP(cr))
+        if (MASTER(cr))
         {
-            /* Make molecules whole only for confout writing */
-            do_pbc_mtop(fplog, ir->ePBC, state->s.box, top_global,
-                        as_rvec_array(state_global->x.data()));
-        }
+            if (ir->ePBC != epbcNONE && !ir->bPeriodicMols && DOMAINDECOMP(cr))
+            {
+                /* Make molecules whole only for confout writing */
+                do_pbc_mtop(fplog, ir->ePBC, state->s.box, top_global,
+                            as_rvec_array(state_global->x.data()));
+            }
 
-        write_sto_conf_mtop(confout,
-                            *top_global->name, top_global,
-                            as_rvec_array(state_global->x.data()), nullptr, ir->ePBC, state->s.box);
+            write_sto_conf_mtop(confout,
+                                *top_global->name, top_global,
+                                as_rvec_array(state_global->x.data()), nullptr, ir->ePBC, state->s.box);
+        }
     }
 }
 
@@ -724,6 +733,17 @@ static bool do_em_step(t_commrec *cr, t_inputrec *ir, t_mdatoms *md,
                       nullptr, nullptr, nrnb, econqCoord);
         wallcycle_stop(wcycle, ewcCONSTR);
 
+        if (cr->nnodes > 1)
+        {
+            /* This global reduction will affect performance at high
+             * parallelization, but we can not really avoid it.
+             * But usually EM is not run at high parallelization.
+             */
+            int reductionBuffer = !validStep;
+            gmx_sumi(1, &reductionBuffer, cr);
+            validStep           = (reductionBuffer == 0);
+        }
+
         // We should move this check to the different minimizers
         if (!validStep && ir->eI != eiSteep)
         {
@@ -1106,8 +1126,20 @@ double do_cg(FILE *fplog, t_commrec *cr, const gmx::MDLogger gmx_unused &mdlog,
 
     step = 0;
 
-    // Ensure the extra per-atom state array gets allocated
-    state_global->flags |= (1<<estCGP);
+    if (MASTER(cr))
+    {
+        // In CG, the state is extended with a search direction
+        state_global->flags |= (1<<estCGP);
+
+        // Ensure the extra per-atom state array gets allocated
+        state_change_natoms(state_global, state_global->natoms);
+
+        // Initialize the search direction to zero
+        for (RVec &cg_p : state_global->cg_p)
+        {
+            cg_p = { 0, 0, 0 };
+        }
+    }
 
     /* Create 4 states on the stack and extract pointers that we will swap */
     em_state_t  s0 {}, s1 {}, s2 {}, s3 {};
@@ -1270,7 +1302,7 @@ double do_cg(FILE *fplog, t_commrec *cr, const gmx::MDLogger gmx_unused &mdlog,
             gmx_sumd(1, &minstep, cr);
         }
 
-        minstep = GMX_REAL_EPS/sqrt(minstep/(3*state_global->natoms));
+        minstep = GMX_REAL_EPS/sqrt(minstep/(3*top_global->natoms));
 
         if (stepsize < minstep)
         {
@@ -1603,7 +1635,7 @@ double do_cg(FILE *fplog, t_commrec *cr, const gmx::MDLogger gmx_unused &mdlog,
         }
 
         /* Send energies and positions to the IMD client if bIMD is TRUE. */
-        if (do_IMD(inputrec->bIMD, step, cr, TRUE, state_global->box, as_rvec_array(state_global->x.data()), inputrec, 0, wcycle) && MASTER(cr))
+        if (MASTER(cr) && do_IMD(inputrec->bIMD, step, cr, TRUE, state_global->box, as_rvec_array(state_global->x.data()), inputrec, 0, wcycle))
         {
             IMD_send_positions(inputrec->imd);
         }
@@ -1665,6 +1697,9 @@ double do_cg(FILE *fplog, t_commrec *cr, const gmx::MDLogger gmx_unused &mdlog,
      * However, we should only do it if we did NOT already write this step
      * above (which we did if do_x or do_f was true).
      */
+    /* Note that with 0 < nstfout != nstxout we can end up with two frames
+     * in the trajectory with the same step number.
+     */
     do_x = !do_per_step(step, inputrec->nstxout);
     do_f = (inputrec->nstfout > 0 && !do_per_step(step, inputrec->nstfout));
 
diff --git a/patches/gromacs-2018.1.diff/src/gromacs/mdlib/minimize.cpp.preplumed b/patches/gromacs-2018.3.diff/src/gromacs/mdlib/minimize.cpp.preplumed
similarity index 97%
rename from patches/gromacs-2018.1.diff/src/gromacs/mdlib/minimize.cpp.preplumed
rename to patches/gromacs-2018.3.diff/src/gromacs/mdlib/minimize.cpp.preplumed
index a27575016..d06da48c4 100644
--- a/patches/gromacs-2018.1.diff/src/gromacs/mdlib/minimize.cpp.preplumed
+++ b/patches/gromacs-2018.3.diff/src/gromacs/mdlib/minimize.cpp.preplumed
@@ -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, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
@@ -533,27 +533,36 @@ static void write_em_traj(FILE *fplog, t_commrec *cr,
                                      &state->s, state_global, observablesHistory,
                                      state->f);
 
-    if (confout != nullptr && MASTER(cr))
+    if (confout != nullptr)
     {
-        GMX_RELEASE_ASSERT(bX, "The code below assumes that (with domain decomposition), x is collected to state_global in the call above.");
-        /* With domain decomposition the call above collected the state->s.x
-         * into state_global->x. Without DD we copy the local state pointer.
-         */
-        if (!DOMAINDECOMP(cr))
+        if (DOMAINDECOMP(cr))
+        {
+            /* If bX=true, x was collected to state_global in the call above */
+            if (!bX)
+            {
+                gmx::ArrayRef<gmx::RVec> globalXRef = MASTER(cr) ? gmx::makeArrayRef(state_global->x) : gmx::EmptyArrayRef();
+                dd_collect_vec(cr->dd, &state->s, state->s.x, globalXRef);
+            }
+        }
+        else
         {
+            /* Copy the local state pointer */
             state_global = &state->s;
         }
 
-        if (ir->ePBC != epbcNONE && !ir->bPeriodicMols && DOMAINDECOMP(cr))
+        if (MASTER(cr))
         {
-            /* Make molecules whole only for confout writing */
-            do_pbc_mtop(fplog, ir->ePBC, state->s.box, top_global,
-                        as_rvec_array(state_global->x.data()));
-        }
+            if (ir->ePBC != epbcNONE && !ir->bPeriodicMols && DOMAINDECOMP(cr))
+            {
+                /* Make molecules whole only for confout writing */
+                do_pbc_mtop(fplog, ir->ePBC, state->s.box, top_global,
+                            as_rvec_array(state_global->x.data()));
+            }
 
-        write_sto_conf_mtop(confout,
-                            *top_global->name, top_global,
-                            as_rvec_array(state_global->x.data()), nullptr, ir->ePBC, state->s.box);
+            write_sto_conf_mtop(confout,
+                                *top_global->name, top_global,
+                                as_rvec_array(state_global->x.data()), nullptr, ir->ePBC, state->s.box);
+        }
     }
 }
 
@@ -680,6 +689,17 @@ static bool do_em_step(t_commrec *cr, t_inputrec *ir, t_mdatoms *md,
                       nullptr, nullptr, nrnb, econqCoord);
         wallcycle_stop(wcycle, ewcCONSTR);
 
+        if (cr->nnodes > 1)
+        {
+            /* This global reduction will affect performance at high
+             * parallelization, but we can not really avoid it.
+             * But usually EM is not run at high parallelization.
+             */
+            int reductionBuffer = !validStep;
+            gmx_sumi(1, &reductionBuffer, cr);
+            validStep           = (reductionBuffer == 0);
+        }
+
         // We should move this check to the different minimizers
         if (!validStep && ir->eI != eiSteep)
         {
@@ -1032,8 +1052,20 @@ double do_cg(FILE *fplog, t_commrec *cr, const gmx::MDLogger gmx_unused &mdlog,
 
     step = 0;
 
-    // Ensure the extra per-atom state array gets allocated
-    state_global->flags |= (1<<estCGP);
+    if (MASTER(cr))
+    {
+        // In CG, the state is extended with a search direction
+        state_global->flags |= (1<<estCGP);
+
+        // Ensure the extra per-atom state array gets allocated
+        state_change_natoms(state_global, state_global->natoms);
+
+        // Initialize the search direction to zero
+        for (RVec &cg_p : state_global->cg_p)
+        {
+            cg_p = { 0, 0, 0 };
+        }
+    }
 
     /* Create 4 states on the stack and extract pointers that we will swap */
     em_state_t  s0 {}, s1 {}, s2 {}, s3 {};
@@ -1196,7 +1228,7 @@ double do_cg(FILE *fplog, t_commrec *cr, const gmx::MDLogger gmx_unused &mdlog,
             gmx_sumd(1, &minstep, cr);
         }
 
-        minstep = GMX_REAL_EPS/sqrt(minstep/(3*state_global->natoms));
+        minstep = GMX_REAL_EPS/sqrt(minstep/(3*top_global->natoms));
 
         if (stepsize < minstep)
         {
@@ -1529,7 +1561,7 @@ double do_cg(FILE *fplog, t_commrec *cr, const gmx::MDLogger gmx_unused &mdlog,
         }
 
         /* Send energies and positions to the IMD client if bIMD is TRUE. */
-        if (do_IMD(inputrec->bIMD, step, cr, TRUE, state_global->box, as_rvec_array(state_global->x.data()), inputrec, 0, wcycle) && MASTER(cr))
+        if (MASTER(cr) && do_IMD(inputrec->bIMD, step, cr, TRUE, state_global->box, as_rvec_array(state_global->x.data()), inputrec, 0, wcycle))
         {
             IMD_send_positions(inputrec->imd);
         }
@@ -1591,6 +1623,9 @@ double do_cg(FILE *fplog, t_commrec *cr, const gmx::MDLogger gmx_unused &mdlog,
      * However, we should only do it if we did NOT already write this step
      * above (which we did if do_x or do_f was true).
      */
+    /* Note that with 0 < nstfout != nstxout we can end up with two frames
+     * in the trajectory with the same step number.
+     */
     do_x = !do_per_step(step, inputrec->nstxout);
     do_f = (inputrec->nstfout > 0 && !do_per_step(step, inputrec->nstfout));
 
diff --git a/patches/gromacs-2018.1.diff/src/programs/mdrun/md.cpp b/patches/gromacs-2018.3.diff/src/programs/mdrun/md.cpp
similarity index 100%
rename from patches/gromacs-2018.1.diff/src/programs/mdrun/md.cpp
rename to patches/gromacs-2018.3.diff/src/programs/mdrun/md.cpp
diff --git a/patches/gromacs-2018.1.diff/src/programs/mdrun/md.cpp.preplumed b/patches/gromacs-2018.3.diff/src/programs/mdrun/md.cpp.preplumed
similarity index 100%
rename from patches/gromacs-2018.1.diff/src/programs/mdrun/md.cpp.preplumed
rename to patches/gromacs-2018.3.diff/src/programs/mdrun/md.cpp.preplumed
diff --git a/patches/gromacs-2018.1.diff/src/programs/mdrun/mdrun.cpp b/patches/gromacs-2018.3.diff/src/programs/mdrun/mdrun.cpp
similarity index 100%
rename from patches/gromacs-2018.1.diff/src/programs/mdrun/mdrun.cpp
rename to patches/gromacs-2018.3.diff/src/programs/mdrun/mdrun.cpp
diff --git a/patches/gromacs-2018.1.diff/src/programs/mdrun/mdrun.cpp.preplumed b/patches/gromacs-2018.3.diff/src/programs/mdrun/mdrun.cpp.preplumed
similarity index 100%
rename from patches/gromacs-2018.1.diff/src/programs/mdrun/mdrun.cpp.preplumed
rename to patches/gromacs-2018.3.diff/src/programs/mdrun/mdrun.cpp.preplumed
diff --git a/patches/gromacs-2018.1.diff/src/programs/mdrun/repl_ex.cpp b/patches/gromacs-2018.3.diff/src/programs/mdrun/repl_ex.cpp
similarity index 100%
rename from patches/gromacs-2018.1.diff/src/programs/mdrun/repl_ex.cpp
rename to patches/gromacs-2018.3.diff/src/programs/mdrun/repl_ex.cpp
diff --git a/patches/gromacs-2018.1.diff/src/programs/mdrun/repl_ex.cpp.preplumed b/patches/gromacs-2018.3.diff/src/programs/mdrun/repl_ex.cpp.preplumed
similarity index 100%
rename from patches/gromacs-2018.1.diff/src/programs/mdrun/repl_ex.cpp.preplumed
rename to patches/gromacs-2018.3.diff/src/programs/mdrun/repl_ex.cpp.preplumed
diff --git a/patches/gromacs-2018.1.diff/src/programs/mdrun/repl_ex.h b/patches/gromacs-2018.3.diff/src/programs/mdrun/repl_ex.h
similarity index 100%
rename from patches/gromacs-2018.1.diff/src/programs/mdrun/repl_ex.h
rename to patches/gromacs-2018.3.diff/src/programs/mdrun/repl_ex.h
diff --git a/patches/gromacs-2018.1.diff/src/programs/mdrun/repl_ex.h.preplumed b/patches/gromacs-2018.3.diff/src/programs/mdrun/repl_ex.h.preplumed
similarity index 100%
rename from patches/gromacs-2018.1.diff/src/programs/mdrun/repl_ex.h.preplumed
rename to patches/gromacs-2018.3.diff/src/programs/mdrun/repl_ex.h.preplumed
diff --git a/patches/gromacs-2018.1.diff/src/programs/mdrun/runner.cpp b/patches/gromacs-2018.3.diff/src/programs/mdrun/runner.cpp
similarity index 99%
rename from patches/gromacs-2018.1.diff/src/programs/mdrun/runner.cpp
rename to patches/gromacs-2018.3.diff/src/programs/mdrun/runner.cpp
index 983d71938..4dfff857a 100644
--- a/patches/gromacs-2018.1.diff/src/programs/mdrun/runner.cpp
+++ b/patches/gromacs-2018.3.diff/src/programs/mdrun/runner.cpp
@@ -572,7 +572,7 @@ int Mdrunner::mdrunner()
     }
 
     /* Check and update the hardware options for internal consistency */
-    check_and_update_hw_opt_1(&hw_opt, cr, domdecOptions.numPmeRanks);
+    check_and_update_hw_opt_1(mdlog, &hw_opt, cr, domdecOptions.numPmeRanks);
 
     /* Early check for externally set process affinity. */
     gmx_check_thread_affinity_set(mdlog, cr,
diff --git a/patches/gromacs-2018.1.diff/src/programs/mdrun/runner.cpp.preplumed b/patches/gromacs-2018.3.diff/src/programs/mdrun/runner.cpp.preplumed
similarity index 99%
rename from patches/gromacs-2018.1.diff/src/programs/mdrun/runner.cpp.preplumed
rename to patches/gromacs-2018.3.diff/src/programs/mdrun/runner.cpp.preplumed
index ea058f65c..917ada568 100644
--- a/patches/gromacs-2018.1.diff/src/programs/mdrun/runner.cpp.preplumed
+++ b/patches/gromacs-2018.3.diff/src/programs/mdrun/runner.cpp.preplumed
@@ -566,7 +566,7 @@ int Mdrunner::mdrunner()
     }
 
     /* Check and update the hardware options for internal consistency */
-    check_and_update_hw_opt_1(&hw_opt, cr, domdecOptions.numPmeRanks);
+    check_and_update_hw_opt_1(mdlog, &hw_opt, cr, domdecOptions.numPmeRanks);
 
     /* Early check for externally set process affinity. */
     gmx_check_thread_affinity_set(mdlog, cr,
diff --git a/patches/gromacs-2018.1.diff/src/programs/mdrun/runner.h b/patches/gromacs-2018.3.diff/src/programs/mdrun/runner.h
similarity index 100%
rename from patches/gromacs-2018.1.diff/src/programs/mdrun/runner.h
rename to patches/gromacs-2018.3.diff/src/programs/mdrun/runner.h
diff --git a/patches/gromacs-2018.1.diff/src/programs/mdrun/runner.h.preplumed b/patches/gromacs-2018.3.diff/src/programs/mdrun/runner.h.preplumed
similarity index 100%
rename from patches/gromacs-2018.1.diff/src/programs/mdrun/runner.h.preplumed
rename to patches/gromacs-2018.3.diff/src/programs/mdrun/runner.h.preplumed
-- 
GitLab