Fix segfault with EM, DD and group scheme
authorBerk Hess <hess@kth.se>
Wed, 6 Feb 2019 12:39:55 +0000 (13:39 +0100)
committerMark Abraham <mark.j.abraham@gmail.com>
Wed, 6 Feb 2019 16:58:10 +0000 (17:58 +0100)
Resetting to an old DD state during EM would leave the cg sorting array
used with the group scheme in an invalid state. This could cause
out of bounds vector access one DD step after rejecting an EM step.

When merging this into master branch, prefer to change to use ssize
rather than the static_cast.

Fixes #2813

Change-Id: I7f13b46d7ff5352ce41838b813c46f2e90c93b1c

docs/release-notes/2019/2019.1.rst
src/gromacs/domdec/partition.cpp

index fc2f4b0c1c7d6db564e9699ef7fe1a7291d0dccf..1c52ed63d6c7ffabc69f82dddbe2cbe5f58066f5 100644 (file)
@@ -38,6 +38,14 @@ Fix segmentation fault in mdrun with domain decomposition
 
 :issue:`2813`
 
+Fix segmentation fault with energy minimization with the group scheme
+---------------------------------------------------------------------
+
+Using energy minimization in combination with the group cutoff scheme
+and domain decomposition could lead to a segmentation fault.
+
+:issue:`2813`
+
 Fix possible division by zero in enforced-rotation code
 -------------------------------------------------------
 
index 96ae045367318a1af2f980e00e360e876f49852f..9c963f502118c91ade558a9a2f501cbd08eff90f 100644 (file)
@@ -2710,8 +2710,11 @@ static void dd_sort_order(const gmx_domdec_t *dd,
 
     const int  movedValue = NSGRID_SIGNAL_MOVED_FAC*fr->ns->grid->ncells;
 
-    if (ncg_home_old >= 0)
+    if (ncg_home_old >= 0 && !sort->sorted.empty())
     {
+        GMX_RELEASE_ASSERT(sort->sorted.size() == static_cast<size_t>(ncg_home_old),
+                           "The sorting buffer should contain the old home charge group indices");
+
         std::vector<gmx_cgsort_t> &stationary = sort->stationary;
         std::vector<gmx_cgsort_t> &moved      = sort->moved;
 
@@ -3467,6 +3470,16 @@ void dd_partition_system(FILE                    *fplog,
 
         wallcycle_sub_stop(wcycle, ewcsDD_GRID);
     }
+    else
+    {
+        /* With the group scheme the sorting array is part of the DD state,
+         * but it just got out of sync, so mark as invalid by emptying it.
+         */
+        if (ir->cutoff_scheme == ecutsGROUP)
+        {
+            comm->sort->sorted.clear();
+        }
+    }
 
     if (comm->useUpdateGroups)
     {