Merge branch release-2018
[alexxy/gromacs.git] / src / programs / mdrun / md.cpp
index d302c1f425b37a62b3eb352e2802eb867e46dedb..a8319e4bf8c89905242648c97b6766d92a4ec039 100644 (file)
@@ -95,6 +95,7 @@
 #include "gromacs/mdlib/vcm.h"
 #include "gromacs/mdlib/vsite.h"
 #include "gromacs/mdtypes/awh-history.h"
+#include "gromacs/mdtypes/awh-params.h"
 #include "gromacs/mdtypes/commrec.h"
 #include "gromacs/mdtypes/df_history.h"
 #include "gromacs/mdtypes/energyhistory.h"
@@ -318,14 +319,13 @@ double gmx::do_md(FILE *fplog, t_commrec *cr,
                   gmx_membed_t *membed,
                   gmx_walltime_accounting_t walltime_accounting)
 {
-    gmx_mdoutf_t    outf = nullptr;
-    gmx_int64_t     step, step_rel;
-    double          elapsed_time;
-    double          t, t0, lam0[efptNR];
-    gmx_bool        bGStatEveryStep, bGStat, bCalcVir, bCalcEnerStep, bCalcEner;
-    gmx_bool        bNS, bNStList, bSimAnn, bStopCM,
-                    bFirstStep, bInitStep, bLastStep = FALSE,
-                    bUsingEnsembleRestraints;
+    gmx_mdoutf_t      outf = nullptr;
+    gmx_int64_t       step, step_rel;
+    double            elapsed_time;
+    double            t, t0, lam0[efptNR];
+    gmx_bool          bGStatEveryStep, bGStat, bCalcVir, bCalcEnerStep, bCalcEner;
+    gmx_bool          bNS, bNStList, bSimAnn, bStopCM,
+                      bFirstStep, bInitStep, bLastStep = FALSE;
     gmx_bool          bDoDHDL = FALSE, bDoFEP = FALSE, bDoExpanded = FALSE;
     gmx_bool          do_ene, do_log, do_verbose, bRerunWarnNoV = TRUE,
                       bForceUpdate = FALSE, bCPT;
@@ -641,7 +641,6 @@ double gmx::do_md(FILE *fplog, t_commrec *cr,
         repl_ex = init_replica_exchange(fplog, ms, top_global->natoms, ir,
                                         replExParams);
     }
-
     /* PME tuning is only supported in the Verlet scheme, with PME for
      * Coulomb. It is not supported with only LJ PME, or for
      * reruns. */
@@ -919,22 +918,34 @@ double gmx::do_md(FILE *fplog, t_commrec *cr,
     bSumEkinhOld     = FALSE;
     bExchanged       = FALSE;
     bNeedRepartition = FALSE;
-    // TODO This implementation of ensemble orientation restraints is nasty because
-    // a user can't just do multi-sim with single-sim orientation restraints.
-    bUsingEnsembleRestraints = (fcd->disres.nsystems > 1) || (ms && fcd->orires.nr);
 
+    bool simulationsShareState = false;
+    int  nstSignalComm         = nstglobalcomm;
     {
-        // Replica exchange and ensemble restraints need all
+        // TODO This implementation of ensemble orientation restraints is nasty because
+        // a user can't just do multi-sim with single-sim orientation restraints.
+        bool usingEnsembleRestraints = (fcd->disres.nsystems > 1) || (ms && fcd->orires.nr);
+        bool awhUsesMultiSim         = (ir->bDoAwh && ir->awhParams->shareBiasMultisim && ms);
+
+        // Replica exchange, ensemble restraints and AWH need all
         // simulations to remain synchronized, so they need
         // checkpoints and stop conditions to act on the same step, so
         // the propagation of such signals must take place between
         // simulations, not just within simulations.
-        bool checkpointIsLocal    = !useReplicaExchange && !bUsingEnsembleRestraints;
-        bool stopConditionIsLocal = !useReplicaExchange && !bUsingEnsembleRestraints;
+        // TODO: Make algorithm initializers set these flags.
+        simulationsShareState     = useReplicaExchange || usingEnsembleRestraints || awhUsesMultiSim;
         bool resetCountersIsLocal = true;
-        signals[eglsCHKPT]         = SimulationSignal(checkpointIsLocal);
-        signals[eglsSTOPCOND]      = SimulationSignal(stopConditionIsLocal);
+        signals[eglsCHKPT]         = SimulationSignal(!simulationsShareState);
+        signals[eglsSTOPCOND]      = SimulationSignal(!simulationsShareState);
         signals[eglsRESETCOUNTERS] = SimulationSignal(resetCountersIsLocal);
+
+        if (simulationsShareState)
+        {
+            // Inter-simulation signal communication does not need to happen
+            // often, so we use a minimum of 200 steps to reduce overhead.
+            const int c_minimumInterSimulationSignallingInterval = 200;
+            nstSignalComm = ((c_minimumInterSimulationSignallingInterval + nstglobalcomm - 1)/nstglobalcomm)*nstglobalcomm;
+        }
     }
 
     DdOpenBalanceRegionBeforeForceComputation ddOpenBalanceRegion   = (DOMAINDECOMP(cr) ? DdOpenBalanceRegionBeforeForceComputation::yes : DdOpenBalanceRegionBeforeForceComputation::no);
@@ -1454,7 +1465,7 @@ double gmx::do_md(FILE *fplog, t_commrec *cr,
                  * to allow for exact continuation, when possible.
                  */
                 signals[eglsSTOPCOND].sig = 1;
-                nsteps_stop               = std::max(ir->nstlist, 2*nstglobalcomm);
+                nsteps_stop               = std::max(ir->nstlist, 2*nstSignalComm);
             }
             else if (gmx_get_stop_condition() == gmx_stop_cond_next)
             {
@@ -1462,7 +1473,7 @@ double gmx::do_md(FILE *fplog, t_commrec *cr,
                  * This breaks exact continuation.
                  */
                 signals[eglsSTOPCOND].sig = -1;
-                nsteps_stop               = nstglobalcomm + 1;
+                nsteps_stop               = nstSignalComm + 1;
             }
             if (fplog)
             {
@@ -1679,7 +1690,7 @@ double gmx::do_md(FILE *fplog, t_commrec *cr,
         {
             // Organize to do inter-simulation signalling on steps if
             // and when algorithms require it.
-            bool doInterSimSignal = (!bFirstStep && bDoReplEx) || bUsingEnsembleRestraints;
+            bool doInterSimSignal = (simulationsShareState && do_per_step(step, nstSignalComm));
 
             if (bGStat || (!EI_VV(ir->eI) && do_per_step(step+1, nstglobalcomm)) || doInterSimSignal)
             {