Separate multisim from commrec
authorMark Abraham <mark.j.abraham@gmail.com>
Sun, 21 Jan 2018 18:26:14 +0000 (19:26 +0100)
committerMark Abraham <mark.j.abraham@gmail.com>
Tue, 13 Feb 2018 06:47:26 +0000 (07:47 +0100)
Changed default value for nmultidir variable.

Called done_commrec.

Change-Id: Ie5f531389d682b9a619b5fc6314cb687f1a68828

52 files changed:
src/gromacs/awh/awh.cpp
src/gromacs/awh/awh.h
src/gromacs/gmxana/gmx_disre.cpp
src/gromacs/gmxlib/network.cpp
src/gromacs/gmxlib/network.h
src/gromacs/hardware/printhardware.cpp
src/gromacs/hardware/printhardware.h
src/gromacs/imd/imd.cpp
src/gromacs/imd/imd.h
src/gromacs/listed-forces/disre.cpp
src/gromacs/listed-forces/disre.h
src/gromacs/listed-forces/listed-forces.cpp
src/gromacs/listed-forces/listed-forces.h
src/gromacs/listed-forces/orires.cpp
src/gromacs/listed-forces/orires.h
src/gromacs/mdlib/clincs.cpp
src/gromacs/mdlib/constr.cpp
src/gromacs/mdlib/constr.h
src/gromacs/mdlib/force.cpp
src/gromacs/mdlib/force.h
src/gromacs/mdlib/forcerec.cpp
src/gromacs/mdlib/integrator.h
src/gromacs/mdlib/main.cpp
src/gromacs/mdlib/main.h
src/gromacs/mdlib/minimize.cpp
src/gromacs/mdlib/shellfc.cpp
src/gromacs/mdlib/shellfc.h
src/gromacs/mdlib/sim_util.cpp
src/gromacs/mdlib/sim_util.h
src/gromacs/mdlib/simulationsignal.cpp
src/gromacs/mdlib/simulationsignal.h
src/gromacs/mdlib/tests/simulationsignal.cpp
src/gromacs/mdlib/tpi.cpp
src/gromacs/mdlib/update.cpp
src/gromacs/mdlib/update.h
src/gromacs/mdrunutility/handlerestart.cpp
src/gromacs/mdrunutility/handlerestart.h
src/gromacs/mdrunutility/tests/threadaffinitytest.h
src/gromacs/mdrunutility/threadaffinity.cpp
src/gromacs/mdrunutility/threadaffinity.h
src/gromacs/mdtypes/commrec.h
src/gromacs/taskassignment/resourcedivision.cpp
src/gromacs/taskassignment/resourcedivision.h
src/gromacs/taskassignment/taskassignment.cpp
src/gromacs/taskassignment/taskassignment.h
src/gromacs/utility/gmxmpi.h
src/programs/mdrun/md.cpp
src/programs/mdrun/mdrun.cpp
src/programs/mdrun/repl_ex.cpp
src/programs/mdrun/repl_ex.h
src/programs/mdrun/runner.cpp
src/programs/mdrun/runner.h

index 24c66ddaa77cae3398a13e345530a55fdbf07a7c..6337ab6e71e0e8319a791a49604aae5524577423 100644 (file)
@@ -114,15 +114,17 @@ BiasCoupledToSystem::BiasCoupledToSystem(Bias                    bias,
     GMX_RELEASE_ASSERT(static_cast<size_t>(bias.ndim()) == pullCoordIndex.size(), "The bias dimensionality should match the number of pull coordinates.");
 }
 
-Awh::Awh(FILE              *fplog,
-         const t_inputrec  &inputRecord,
-         const t_commrec   *commRecord,
-         const AwhParams   &awhParams,
-         const std::string &biasInitFilename,
-         pull_t            *pull_work) :
+Awh::Awh(FILE                 *fplog,
+         const t_inputrec     &inputRecord,
+         const t_commrec      *commRecord,
+         const gmx_multisim_t *multiSimRecord,
+         const AwhParams      &awhParams,
+         const std::string    &biasInitFilename,
+         pull_t               *pull_work) :
     seed_(awhParams.seed),
     nstout_(awhParams.nstOut),
     commRecord_(commRecord),
+    multiSimRecord_(multiSimRecord),
     pull_(pull_work),
     potentialOffset_(0)
 {
@@ -142,9 +144,9 @@ Awh::Awh(FILE              *fplog,
     }
 
     int numSharingSimulations = 1;
-    if (awhParams.shareBiasMultisim && isMultiSim(commRecord_->ms))
+    if (awhParams.shareBiasMultisim && isMultiSim(multiSimRecord_))
     {
-        numSharingSimulations = commRecord_->ms->nsim;
+        numSharingSimulations = multiSimRecord_->nsim;
     }
 
     /* Initialize all the biases */
@@ -185,7 +187,7 @@ Awh::Awh(FILE              *fplog,
             pointSize.push_back(biasCts.bias.state().points().size());
         }
         /* Ensure that the shared biased are compatible between simulations */
-        biasesAreCompatibleForSharingBetweenSimulations(awhParams, pointSize, commRecord_->ms);
+        biasesAreCompatibleForSharingBetweenSimulations(awhParams, pointSize, multiSimRecord_);
     }
 }
 
@@ -240,7 +242,7 @@ real Awh::applyBiasForcesAndUpdateBias(int                     ePBC,
         gmx::ArrayRef<const double> biasForce =
             biasCts.bias.calcForceAndUpdateBias(coordValue,
                                                 &biasPotential, &biasPotentialJump,
-                                                commRecord_->ms,
+                                                multiSimRecord_,
                                                 t, step, seed_, fplog);
 
         awhPotential += biasPotential;
index 1fe09c9ff14d53cd342454a492ed11cf995a2648..26d4efe5bd685fb93772843aaf8ed96774067fbc 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2015,2016,2017, by the GROMACS development team, led by
+ * Copyright (c) 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.
@@ -118,16 +118,18 @@ class Awh
          * \param[in,out] fplog             General output file, normally md.log, can be nullptr.
          * \param[in]     inputRecord       General input parameters (as set up by grompp).
          * \param[in]     commRecord        Struct for communication, can be nullptr.
+         * \param[in]     multiSimRecord    Multi-sim handler
          * \param[in]     awhParams         AWH input parameters, consistent with the relevant parts of \p inputRecord (as set up by grompp).
          * \param[in]     biasInitFilename  Name of file to read PMF and target from.
          * \param[in,out] pull_work         Pointer to a pull struct which AWH will couple to, has to be initialized, is assumed not to change during the lifetime of the Awh object.
          */
-        Awh(FILE              *fplog,
-            const t_inputrec  &inputRecord,
-            const t_commrec   *commRecord,
-            const AwhParams   &awhParams,
-            const std::string &biasInitFilename,
-            pull_t            *pull_work);
+        Awh(FILE                 *fplog,
+            const t_inputrec     &inputRecord,
+            const t_commrec      *commRecord,
+            const gmx_multisim_t *multiSimRecord,
+            const AwhParams      &awhParams,
+            const std::string    &biasInitFilename,
+            pull_t               *pull_work);
 
         /*! \brief Destructor. */
         ~Awh();
@@ -242,6 +244,7 @@ class Awh
         const gmx_int64_t                seed_;                /**< Random seed for MC jumping with umbrella type bias potential. */
         const int                        nstout_;              /**< Interval in steps for writing to energy file. */
         const t_commrec                 *commRecord_;          /**< Pointer to the communication record. */
+        const gmx_multisim_t            *multiSimRecord_;      /**< Handler for multi-simulations. */
         pull_t                          *pull_;                /**< Pointer to the pull working data. */
         double                           potentialOffset_;     /**< The offset of the bias potential which changes due to bias updates. */
 };
index 4af2ee6974e89d9b208ecccc0d863821d9b3486f..9ba08eef54dd21278427aa10f3589bceb69121c5 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2016,2017, 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.
@@ -204,7 +204,7 @@ static void check_viol(FILE *log,
         while (((i+n) < disres->nr) &&
                (forceparams[forceatoms[i+n]].disres.label == label));
 
-        calc_disres_R_6(nullptr, n, &forceatoms[i],
+        calc_disres_R_6(nullptr, nullptr, n, &forceatoms[i],
                         (const rvec*)x, pbc, fcd, nullptr);
 
         if (fcd->disres.Rt_6[label] <= 0)
@@ -813,7 +813,7 @@ int gmx_disre(int argc, char *argv[])
     }
 
     ir->dr_tau = 0.0;
-    init_disres(fplog, &mtop, ir, nullptr, &fcd, nullptr, FALSE);
+    init_disres(fplog, &mtop, ir, nullptr, nullptr, &fcd, nullptr, FALSE);
 
     natoms = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box);
     snew(f, 5*natoms);
index 208dff3557be44c6bde47412e4478f488dbe1ad7..3a3257199750f9ee0bf8587e084f9445892be625 100644 (file)
 /* The source code in this file should be thread-safe.
       Please keep it that way. */
 
-void gmx_fill_commrec_from_mpi(t_commrec gmx_unused *cr)
+void gmx_fill_commrec_from_mpi(t_commrec            *cr,
+                               const gmx_multisim_t *ms)
 {
 #if !GMX_MPI
     gmx_call("gmx_fill_commrec_from_mpi");
+    GMX_UNUSED_VALUE(cr);
+    GMX_UNUSED_VALUE(ms);
 #else
     if (!gmx_mpi_initialized())
     {
@@ -76,7 +79,7 @@ void gmx_fill_commrec_from_mpi(t_commrec gmx_unused *cr)
     // all multi-node MPI cases with more than one PP rank per node,
     // with and without GPUs. By always having it available, we also
     // don't need to protect calls to mpi_comm_physicalnode, etc.
-    if (PAR(cr) || isMultiSim(cr->ms))
+    if (PAR(cr) || isMultiSim(ms))
     {
         MPI_Comm_split(MPI_COMM_WORLD, gmx_physicalnode_id_hash(), cr->nodeid, &cr->mpi_comm_physicalnode);
     }
@@ -93,11 +96,12 @@ t_commrec *init_commrec()
 
     snew(cr, 1);
 
+    cr->mpi_comm_physicalnode = MPI_COMM_NULL;
 #if GMX_LIB_MPI
-    gmx_fill_commrec_from_mpi(cr);
+    gmx_fill_commrec_from_mpi(cr, nullptr);
 #else
-    cr->mpi_comm_mysim   = nullptr;
-    cr->mpi_comm_mygroup = nullptr;
+    cr->mpi_comm_mysim   = MPI_COMM_NULL;
+    cr->mpi_comm_mygroup = MPI_COMM_NULL;
     cr->nnodes           = 1;
     cr->sim_nodeid       = 0;
     cr->nodeid           = cr->sim_nodeid;
@@ -122,7 +126,7 @@ t_commrec *init_commrec()
     return cr;
 }
 
-static void done_mpi_in_place_buf(mpi_in_place_buf_t *buf)
+void done_mpi_in_place_buf(mpi_in_place_buf_t *buf)
 {
     if (nullptr != buf)
     {
@@ -137,7 +141,7 @@ static void done_mpi_in_place_buf(mpi_in_place_buf_t *buf)
 void done_commrec(t_commrec *cr)
 {
 #if GMX_MPI
-    if (PAR(cr) || isMultiSim(cr->ms))
+    if (cr->mpi_comm_physicalnode != MPI_COMM_NULL)
     {
         MPI_Comm_free(&cr->mpi_comm_physicalnode);
     }
@@ -147,16 +151,12 @@ void done_commrec(t_commrec *cr)
         // TODO: implement
         // done_domdec(cr->dd);
     }
-    if (nullptr != cr->ms)
-    {
-        done_mpi_in_place_buf(cr->ms->mpb);
-        sfree(cr->ms);
-    }
     done_mpi_in_place_buf(cr->mpb);
     sfree(cr);
 }
 
-t_commrec *reinitialize_commrec_for_this_thread(const t_commrec gmx_unused *cro)
+t_commrec *reinitialize_commrec_for_this_thread(const t_commrec      *cro,
+                                                const gmx_multisim_t *ms)
 {
 #if GMX_THREAD_MPI
     t_commrec *cr;
@@ -168,13 +168,15 @@ t_commrec *reinitialize_commrec_for_this_thread(const t_commrec gmx_unused *cro)
     *cr = *cro;
 
     /* and we start setting our own thread-specific values for things */
-    gmx_fill_commrec_from_mpi(cr);
+    gmx_fill_commrec_from_mpi(cr, ms);
 
     // TODO cr->duty should not be initialized here
     cr->duty             = (DUTY_PP | DUTY_PME);
 
     return cr;
 #else
+    GMX_UNUSED_VALUE(cro);
+    GMX_UNUSED_VALUE(ms);
     return nullptr;
 #endif
 }
index 3297dc8d63eeef5d8b17a9c13b938a850edbe80e..95a163b2e894ed110f9fa88005c45533cd6eda47 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2016,2017, 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.
@@ -53,17 +53,20 @@ struct t_filenm;
 struct t_commrec *init_commrec(void);
 /* Allocate, initialize and return the commrec. */
 
-void done_commrec(struct t_commrec *cr);
+void done_commrec(t_commrec *cr);
 /* Free memory associated with the commrec. */
 
-struct t_commrec *reinitialize_commrec_for_this_thread(const struct t_commrec *cro);
+struct t_commrec *reinitialize_commrec_for_this_thread(const t_commrec      *cro,
+                                                       const gmx_multisim_t *ms);
+
 /* Initialize communication records for thread-parallel simulations.
    Must be called on all threads before any communication takes place by
    the individual threads. Copies the original commrec to
    thread-local versions (a small memory leak results because we don't
    deallocate the old shared version).  */
 
-void gmx_fill_commrec_from_mpi(struct t_commrec *cr);
+void gmx_fill_commrec_from_mpi(t_commrec            *cr,
+                               const gmx_multisim_t *ms);
 /* Continues t_commrec construction */
 
 void gmx_setup_nodecomm(FILE *fplog, struct t_commrec *cr);
index de3a4f2f190b8f8ae2b4b4c6b99719905c26adc4..f6f1eb6c69b60a9525b765f93b9ed594fe98a060 100644 (file)
@@ -355,6 +355,7 @@ static std::string detected_hardware_string(const gmx_hw_info_t *hwinfo,
 }
 
 void gmx_print_detected_hardware(FILE *fplog, const t_commrec *cr,
+                                 const gmx_multisim_t *ms,
                                  const gmx::MDLogger &mdlog,
                                  const gmx_hw_info_t *hwinfo)
 {
@@ -378,7 +379,7 @@ void gmx_print_detected_hardware(FILE *fplog, const t_commrec *cr,
      */
     if (cpuInfo.supportLevel() >= gmx::CpuInfo::SupportLevel::Features)
     {
-        gmx::simdCheck(static_cast<gmx::SimdType>(hwinfo->simd_suggest_min), fplog, isMasterSimMasterRank(cr->ms, cr));
+        gmx::simdCheck(static_cast<gmx::SimdType>(hwinfo->simd_suggest_min), fplog, isMasterSimMasterRank(ms, cr));
     }
 
     /* For RDTSCP we only check on our local node and skip the MPI reduction */
index 9bc77254c0828970f876cdfc918ab517ddd5838d..c70a3b7e68fe4aff1df3d01d0d2fb61facdc28d2 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2012,2013,2014,2015,2016,2017, by the GROMACS development team, led by
+ * Copyright (c) 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.
@@ -38,6 +38,7 @@
 #include <cstdio>
 
 struct gmx_hw_info_t;
+struct gmx_multisim_t;
 struct t_commrec;
 
 namespace gmx
@@ -49,6 +50,7 @@ class MDLogger;
  * and to stderr the master rank.
  */
 void gmx_print_detected_hardware(FILE *fplog, const t_commrec *cr,
+                                 const gmx_multisim_t *ms,
                                  const gmx::MDLogger &mdlog,
                                  const gmx_hw_info_t *hwinfo);
 
index 14ac9094f1cf3298a4bc1c461bf5accc96584195..2a5c4e73ca491a5b43f442b2aae82ec94eccfb86 100644 (file)
@@ -1287,6 +1287,7 @@ static void imd_check_integrator_parallel(t_inputrec *ir, t_commrec *cr)
 
 void init_IMD(t_inputrec             *ir,
               t_commrec              *cr,
+              const gmx_multisim_t   *ms,
               gmx_mtop_t             *top_global,
               FILE                   *fplog,
               int                     defnstimd,
@@ -1322,7 +1323,7 @@ void init_IMD(t_inputrec             *ir,
         if (options.wait || options.terminatable || options.pull)
         {
             /* Multiple simulations or replica exchange */
-            if (isMultiSim(cr->ms))
+            if (isMultiSim(ms))
             {
                 fprintf(stderr, "%s Cannot use IMD for multiple simulations or replica exchange.\n", IMDstr);
             }
index 089174a68a5b5d7293b50756bf09726bcf4b0f16..30e29eb16d551f4c7f794d9f23db2b486e53baf3 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2014,2015,2016,2017, by the GROMACS development team, led by
+ * Copyright (c) 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.
@@ -76,6 +76,7 @@
 struct gmx_domdec_t;
 struct gmx_enerdata_t;
 struct gmx_mtop_t;
+struct gmx_multisim_t;
 struct gmx_output_env_t;
 struct gmx_wallcycle;
 struct MdrunOptions;
@@ -129,6 +130,7 @@ void dd_make_local_IMD_atoms(gmx_bool bIMD, gmx_domdec_t *dd, t_IMD *imd);
  * \param ir           The inputrec structure containing the MD input parameters
  *                     including a pointer to the IMD data structure.
  * \param cr           Information structure for MPI communication.
+ * \param ms           Handler for multi-simulations.
  * \param top_global   The topology of the whole system.
  * \param fplog        General output file, normally md.log.
  * \param defnstimd    Default IMD update (=communication) frequency.
@@ -138,7 +140,9 @@ void dd_make_local_IMD_atoms(gmx_bool bIMD, gmx_domdec_t *dd, t_IMD *imd);
  * \param oenv         Output options.
  * \param mdrunOptions Options for mdrun.
  */
-void init_IMD(t_inputrec *ir, t_commrec *cr, gmx_mtop_t *top_global,
+void init_IMD(t_inputrec *ir, t_commrec *cr,
+              const gmx_multisim_t *ms,
+              gmx_mtop_t *top_global,
               FILE *fplog, int defnstimd, rvec x[],
               int nfile, const t_filenm fnm[], const gmx_output_env_t *oenv,
               const MdrunOptions &mdrunOptions);
index 1bbc51db70f4a17e39870a3c4fa8e15cfa1bc9f6..913ea1f24b4cd7fc5b1cda7a36a1da0d24a74a0a 100644 (file)
@@ -69,6 +69,7 @@
 
 void init_disres(FILE *fplog, const gmx_mtop_t *mtop,
                  t_inputrec *ir, const t_commrec *cr,
+                 const gmx_multisim_t *ms,
                  t_fcdata *fcd, t_state *state, gmx_bool bIsREMD)
 {
     int                  fa, nmol, npair, np;
@@ -203,7 +204,7 @@ void init_disres(FILE *fplog, const gmx_mtop_t *mtop,
     dd->Rtav_6 = &(dd->Rt_6[dd->nres]);
 
     ptr = getenv("GMX_DISRE_ENSEMBLE_SIZE");
-    if (cr && cr->ms != nullptr && ptr != nullptr && !bIsREMD)
+    if (cr && ms != nullptr && ptr != nullptr && !bIsREMD)
     {
 #if GMX_MPI
         dd->nsystems = 0;
@@ -217,7 +218,7 @@ void init_disres(FILE *fplog, const gmx_mtop_t *mtop,
          * than one processor per simulation system. */
         if (MASTER(cr))
         {
-            check_multi_int(fplog, cr->ms, dd->nsystems,
+            check_multi_int(fplog, ms, dd->nsystems,
                             "the number of systems per ensemble",
                             FALSE);
         }
@@ -227,9 +228,9 @@ void init_disres(FILE *fplog, const gmx_mtop_t *mtop,
          * of ms->nsim. But this required an extra communicator which
          * was stored in t_fcdata. This pulled in mpi.h in nearly all C files.
          */
-        if (!(cr->ms->nsim == 1 || cr->ms->nsim == dd->nsystems))
+        if (!(ms->nsim == 1 || ms->nsim == dd->nsystems))
         {
-            gmx_fatal(FARGS, "GMX_DISRE_ENSEMBLE_SIZE (%d) is not equal to 1 or the number of systems (option -multidir) %d", dd->nsystems, cr->ms->nsim);
+            gmx_fatal(FARGS, "GMX_DISRE_ENSEMBLE_SIZE (%d) is not equal to 1 or the number of systems (option -multidir) %d", dd->nsystems, ms->nsim);
         }
         if (fplog)
         {
@@ -237,7 +238,7 @@ void init_disres(FILE *fplog, const gmx_mtop_t *mtop,
             for (int i = 0; i < dd->nsystems; i++)
             {
                 fprintf(fplog, " %d",
-                        (cr->ms->sim/dd->nsystems)*dd->nsystems+i);
+                        (ms->sim/dd->nsystems)*dd->nsystems+i);
             }
             fprintf(fplog, "\n");
         }
@@ -269,9 +270,9 @@ void init_disres(FILE *fplog, const gmx_mtop_t *mtop,
          * checks from appropriate processes (since check_multi_int is
          * too broken to check whether the communication will
          * succeed...) */
-        if (cr && cr->ms && dd->nsystems > 1 && MASTER(cr))
+        if (cr && ms && dd->nsystems > 1 && MASTER(cr))
         {
-            check_multi_int(fplog, cr->ms, fcd->disres.nres,
+            check_multi_int(fplog, ms, fcd->disres.nres,
                             "the number of distance restraints",
                             FALSE);
         }
@@ -281,6 +282,7 @@ void init_disres(FILE *fplog, const gmx_mtop_t *mtop,
 }
 
 void calc_disres_R_6(const t_commrec *cr,
+                     const gmx_multisim_t *ms,
                      int nfa, const t_iatom forceatoms[],
                      const rvec x[], const t_pbc *pbc,
                      t_fcdata *fcd, history_t *hist)
@@ -380,8 +382,8 @@ void calc_disres_R_6(const t_commrec *cr,
             Rtav_6[res] *= invn;
         }
 
-        GMX_ASSERT(cr != NULL && cr->ms != NULL, "We need multisim with nsystems>1");
-        gmx_sum_sim(2*dd->nres, dd->Rt_6, cr->ms);
+        GMX_ASSERT(cr != NULL && ms != NULL, "We need multisim with nsystems>1");
+        gmx_sum_sim(2*dd->nres, dd->Rt_6, ms);
 
         if (DOMAINDECOMP(cr))
         {
index 5c798371f5324e2f8bfc1c07a45e38ecaf708101..bc95d13d0c5139399efe2af782bfba27caa5ce0e 100644 (file)
@@ -50,6 +50,7 @@
 #include "gromacs/utility/basedefinitions.h"
 
 struct gmx_mtop_t;
+struct gmx_multisim_t;
 class history_t;
 struct t_commrec;
 struct t_inputrec;
@@ -68,6 +69,7 @@ class t_state;
  */
 void init_disres(FILE *fplog, const gmx_mtop_t *mtop,
                  t_inputrec *ir, const t_commrec *cr,
+                 const gmx_multisim_t *ms,
                  t_fcdata *fcd, t_state *state, gmx_bool bIsREMD);
 
 /*! \brief
@@ -75,6 +77,7 @@ void init_disres(FILE *fplog, const gmx_mtop_t *mtop,
  * and the ensemble averaged r^-6 (inst. and time averaged) for all restraints
  */
 void calc_disres_R_6(const t_commrec *cr,
+                     const gmx_multisim_t *ms,
                      int nfa, const t_iatom *fa,
                      const rvec *x, const t_pbc *pbc,
                      t_fcdata *fcd, history_t *hist);
index 352243a4b50a94ef845c7b325488d2539a78f2bd..32a8bc97ecb4f044e94b0b3bd1788dd24b1a1a1e 100644 (file)
@@ -477,6 +477,7 @@ calcBondedForces(const t_idef     *idef,
 }
 
 void calc_listed(const t_commrec             *cr,
+                 const gmx_multisim_t *ms,
                  struct gmx_wallcycle        *wcycle,
                  const t_idef *idef,
                  const rvec x[], history_t *hist,
@@ -546,14 +547,14 @@ void calc_listed(const t_commrec             *cr,
              */
             GMX_RELEASE_ASSERT(fr->ePBC == epbcNONE || g != nullptr, "With orientation restraints molecules should be whole");
             enerd->term[F_ORIRESDEV] =
-                calc_orires_dev(cr->ms, idef->il[F_ORIRES].nr,
+                calc_orires_dev(ms, idef->il[F_ORIRES].nr,
                                 idef->il[F_ORIRES].iatoms,
                                 idef->iparams, md, x,
                                 pbc_null, fcd, hist);
         }
         if (fcd->disres.nres > 0)
         {
-            calc_disres_R_6(cr,
+            calc_disres_R_6(cr, ms,
                             idef->il[F_DISRES].nr,
                             idef->il[F_DISRES].iatoms,
                             x, pbc_null,
@@ -670,6 +671,7 @@ do_force_listed(struct gmx_wallcycle        *wcycle,
                 matrix                       box,
                 const t_lambda              *fepvals,
                 const t_commrec             *cr,
+                const gmx_multisim_t        *ms,
                 const t_idef                *idef,
                 const rvec                   x[],
                 history_t                   *hist,
@@ -699,7 +701,7 @@ do_force_listed(struct gmx_wallcycle        *wcycle,
         /* Not enough flops to bother counting */
         set_pbc(&pbc_full, fr->ePBC, box);
     }
-    calc_listed(cr, wcycle, idef, x, hist,
+    calc_listed(cr, ms, wcycle, idef, x, hist,
                 forceForUseWithShiftForces, forceWithVirial,
                 fr, pbc, &pbc_full,
                 graph, enerd, nrnb, lambda, md, fcd,
index 910128217c50e7d51ffe4aa7b067099bb7af3ad1..6fd13ac0deb0185e0a8b931a7fe616eeff7bb647 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2014,2015,2016,2017, by the GROMACS development team, led by
+ * Copyright (c) 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.
@@ -71,6 +71,7 @@
 
 struct gmx_enerdata_t;
 struct gmx_grppairener_t;
+struct gmx_multisim_t;
 class history_t;
 struct t_commrec;
 struct t_fcdata;
@@ -101,6 +102,7 @@ ftype_is_bonded_potential(int ftype);
  * Note that pbc_full is used only for position restraints, and is
  * not initialized if there are none. */
 void calc_listed(const t_commrec *cr,
+                 const gmx_multisim_t *ms,
                  struct gmx_wallcycle *wcycle,
                  const t_idef *idef,
                  const rvec x[], history_t *hist,
@@ -134,6 +136,7 @@ do_force_listed(struct gmx_wallcycle           *wcycle,
                 matrix                          box,
                 const t_lambda                 *fepvals,
                 const t_commrec                *cr,
+                const gmx_multisim_t           *ms,
                 const t_idef                   *idef,
                 const rvec                      x[],
                 history_t                      *hist,
index d4b2dce733de67b59f85503b2e35ddc6e85d6b86..8f437a31bf9310994c24921cf267d6d515fd7490 100644 (file)
 // TODO This implementation of ensemble orientation restraints is nasty because
 // a user can't just do multi-sim with single-sim orientation restraints.
 
-void init_orires(FILE             *fplog,
-                 const gmx_mtop_t *mtop,
-                 const t_inputrec *ir,
-                 const t_commrec  *cr,
-                 t_state          *globalState,
-                 t_oriresdata     *od)
+void init_orires(FILE                 *fplog,
+                 const gmx_mtop_t     *mtop,
+                 const t_inputrec     *ir,
+                 const t_commrec      *cr,
+                 const gmx_multisim_t *ms,
+                 t_state              *globalState,
+                 t_oriresdata         *od)
 {
     od->nr = gmx_mtop_ftype_count(mtop, F_ORIRES);
     if (0 == od->nr)
@@ -152,7 +153,6 @@ void init_orires(FILE             *fplog,
      */
     snew(od->Dinsl, od->nr);
 
-    const gmx_multisim_t *ms = cr->ms;
     if (ms)
     {
         snew(od->Dins, od->nr);
index c248e928804021e6cbb38eae869245483f1d0c0b..0491c9b59af5e97be2588e77b76fc7dd70319586 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2010,2014,2015,2017, by the GROMACS development team, led by
+ * Copyright (c) 2010,2014,2015,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.
@@ -66,12 +66,13 @@ class t_state;
  * on the master rank (which is the only rank, since orientation
  * restraints can not run in parallel).
  */
-void init_orires(FILE             *fplog,
-                 const gmx_mtop_t *mtop,
-                 const t_inputrec *ir,
-                 const t_commrec  *cr,
-                 t_state          *globalState,
-                 t_oriresdata     *od);
+void init_orires(FILE                 *fplog,
+                 const gmx_mtop_t     *mtop,
+                 const t_inputrec     *ir,
+                 const t_commrec      *cr,
+                 const gmx_multisim_t *ms,
+                 t_state              *globalState,
+                 t_oriresdata         *od);
 
 /*! \brief
  * Calculates the time averaged D matrices, the S matrix for each experiment.
index 4ed5320ca7ed3c04e4734ff7ebe55aea6229b343..ce37d40a8e3cce74584d84a80756c9fbd74a3306 100644 (file)
@@ -2328,6 +2328,7 @@ gmx_bool constrain_lincs(FILE *fplog, gmx_bool bLog, gmx_bool bEner,
                          gmx_int64_t step,
                          struct gmx_lincsdata *lincsd, t_mdatoms *md,
                          t_commrec *cr,
+                         const gmx_multisim_t *ms,
                          rvec *x, rvec *xprime, rvec *min_proj,
                          matrix box, t_pbc *pbc,
                          real lambda, real *dvdlambda,
@@ -2476,9 +2477,9 @@ gmx_bool constrain_lincs(FILE *fplog, gmx_bool bLog, gmx_bool bEner,
             {
                 cconerr(lincsd, xprime, pbc,
                         &ncons_loc, &p_ssd, &p_max, &p_imax);
-                if (isMultiSim(cr->ms))
+                if (isMultiSim(ms))
                 {
-                    sprintf(buf3, " in simulation %d", cr->ms->sim);
+                    sprintf(buf3, " in simulation %d", ms->sim);
                 }
                 else
                 {
index d41c33e11f0f53ec54da5b8d1b3bfb9c8d621bc7..bed36a16648e42becb3513388035c04a2e3ad1ea 100644 (file)
@@ -276,6 +276,7 @@ gmx_bool constrain(FILE *fplog, gmx_bool bLog, gmx_bool bEner,
                    struct gmx_constr *constr,
                    t_idef *idef, t_inputrec *ir,
                    t_commrec *cr,
+                   const gmx_multisim_t *ms,
                    gmx_int64_t step, int delta_step,
                    real step_scaling,
                    t_mdatoms *md,
@@ -387,7 +388,7 @@ gmx_bool constrain(FILE *fplog, gmx_bool bLog, gmx_bool bEner,
 
     if (constr->lincsd != nullptr)
     {
-        bOK = constrain_lincs(fplog, bLog, bEner, ir, step, constr->lincsd, md, cr,
+        bOK = constrain_lincs(fplog, bLog, bEner, ir, step, constr->lincsd, md, cr, ms,
                               x, xprime, min_proj,
                               box, pbc_null, lambda, dvdlambda,
                               invdt, v, vir != nullptr, vir_r_m_dr,
index fb3c8e8e4f68e465850dd7124a32ae5098982e02..738d51b9d71989d60b6cee7e06b1b1d297165d9a 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2016,2017, 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.
@@ -44,6 +44,7 @@
 #include "gromacs/topology/topology.h"
 #include "gromacs/utility/real.h"
 
+struct gmx_multisim_t;
 struct t_inputrec;
 
 /* Abstract type for LINCS that is defined only in the file that uses it */
@@ -163,7 +164,8 @@ gmx_bool constrain(FILE *log, gmx_bool bLog, gmx_bool bEner,
                    gmx_constr_t constr,
                    t_idef *idef,
                    t_inputrec *ir,
-                   struct t_commrec *cr,
+                   t_commrec *cr,
+                   const gmx_multisim_t *ms,
                    gmx_int64_t step, int delta_step,
                    real step_scaling,
                    t_mdatoms *md,
@@ -287,6 +289,7 @@ constrain_lincs(FILE *log, gmx_bool bLog, gmx_bool bEner,
                 gmx_int64_t step,
                 gmx_lincsdata_t lincsd, t_mdatoms *md,
                 struct t_commrec *cr,
+                const gmx_multisim_t *ms,
                 rvec *x, rvec *xprime, rvec *min_proj,
                 matrix box, struct t_pbc *pbc,
                 real lambda, real *dvdlambda,
index 4f21ca3cca63bc3d8b9510689ea815d50c64895f..15221b313de3c4c201ed0ba883ca1ef74a8f877b 100644 (file)
@@ -136,6 +136,7 @@ static void reduceEwaldThreadOuput(int nthreads, ewald_corr_thread_t *ewc_t)
 
 void do_force_lowlevel(t_forcerec *fr,      t_inputrec *ir,
                        t_idef     *idef,    t_commrec  *cr,
+                       const gmx_multisim_t *ms,
                        t_nrnb     *nrnb,    gmx_wallcycle_t wcycle,
                        t_mdatoms  *md,
                        rvec       x[],      history_t  *hist,
@@ -326,7 +327,7 @@ void do_force_lowlevel(t_forcerec *fr,      t_inputrec *ir,
                    TRUE, box);
     }
 
-    do_force_listed(wcycle, box, ir->fepvals, cr,
+    do_force_listed(wcycle, box, ir->fepvals, cr, ms,
                     idef, (const rvec *) x, hist,
                     forceForUseWithShiftForces, forceWithVirial,
                     fr, &pbc, graph, enerd, nrnb, lambda, md, fcd,
index 6bfc66051ce9cc418ee485455c788e899d29ea18..86dcc2af4854239a5802d15f2067cc4017be61b6 100644 (file)
@@ -49,6 +49,7 @@ struct gmx_device_info_t;
 struct gmx_edsam;
 struct gmx_gpu_info_t;
 struct gmx_groups_t;
+struct gmx_multisim_t;
 struct gmx_vsite_t;
 class history_t;
 struct nonbonded_verlet_t;
@@ -151,6 +152,7 @@ void set_avcsixtwelve(FILE *fplog, t_forcerec *fr,
                       const gmx_mtop_t *mtop);
 
 void do_force(FILE *log, t_commrec *cr,
+              const gmx_multisim_t *ms,
               t_inputrec *inputrec,
               gmx_int64_t step, struct t_nrnb *nrnb, gmx_wallcycle_t wcycle,
               gmx_localtop_t *top,
@@ -192,6 +194,7 @@ void do_force_lowlevel(t_forcerec   *fr,
                        t_inputrec   *ir,
                        t_idef       *idef,
                        t_commrec    *cr,
+                       const gmx_multisim_t *ms,
                        t_nrnb       *nrnb,
                        gmx_wallcycle_t wcycle,
                        t_mdatoms    *md,
@@ -212,6 +215,7 @@ void do_force_lowlevel(t_forcerec   *fr,
 /* Call all the force routines */
 
 void free_gpu_resources(const t_forcerec            *fr,
-                        const t_commrec             *cr);
+                        const t_commrec             *cr,
+                        const gmx_multisim_t        *ms);
 
 #endif
index 6f6d28fe47b73c5965f891a5f7acad28dff23086..43f4f7dc321e38fd661ffbc979b246fae569f2b3 100644 (file)
@@ -3125,7 +3125,8 @@ void init_forcerec(FILE                    *fp,
  * that it's not needed anymore (with a shared GPU run).
  */
 void free_gpu_resources(const t_forcerec        *fr,
-                        const t_commrec         *cr)
+                        const t_commrec         *cr,
+                        const gmx_multisim_t    *ms)
 {
     bool isPPrankUsingGPU = fr && fr->nbv && fr->nbv->bUseGPU;
 
@@ -3148,7 +3149,7 @@ void free_gpu_resources(const t_forcerec        *fr,
      * 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 && (PAR(cr) || isMultiSim(cr->ms)))
+    if (GMX_THREAD_MPI && (PAR(cr) || isMultiSim(ms)))
     {
         gmx_barrier_physical_node(cr);
     }
index 272c69797e5c7a92893c02b73326c9c58ac418c2..5def900acb4d3c60db7f4e5fd7eb83ca39e6d1c7 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2015,2016,2017, by the GROMACS development team, led by
+ * Copyright (c) 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.
@@ -55,6 +55,7 @@
 class energyhistory_t;
 struct gmx_mtop_t;
 struct gmx_membed_t;
+struct gmx_multisim_t;
 struct gmx_output_env_t;
 struct MdrunOptions;
 struct ObservablesHistory;
@@ -75,6 +76,7 @@ class MDAtoms;
  *
  * \param[in] fplog               Log file for output
  * \param[in] cr                  Communication record
+ * \param[in] ms                  Handle to multi-simulation handler.
  * \param[in] mdlog               Log writer for important output
  * \param[in] nfile               Number of files
  * \param[in] fnm                 Filename structure array
@@ -96,7 +98,9 @@ class MDAtoms;
  * \param[in] membed              Membrane embedding data structure
  * \param[in] walltime_accounting More timing information
  */
-typedef double integrator_t (FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
+typedef double integrator_t (FILE *fplog, t_commrec *cr,
+                             const gmx_multisim_t *ms,
+                             const gmx::MDLogger &mdlog,
                              int nfile, const t_filenm fnm[],
                              const gmx_output_env_t *oenv,
                              const MdrunOptions &mdrunOptions,
index b26d948a2e15ddeb83a0fd3ea5c8514e361944f3..642542c0d89e325f5b9321cc3f21d11542a1e8e5 100644 (file)
@@ -239,18 +239,17 @@ void gmx_log_close(FILE *fp)
 }
 
 // TODO move this to multi-sim module
-void init_multisystem(t_commrec *cr, int nsim, char **multidirs)
+gmx_multisim_t *init_multisystem(MPI_Comm comm, int nsim, char **multidirs)
 {
     gmx_multisim_t *ms;
-    int             nnodes, nnodpersim, sim;
 #if GMX_MPI
     MPI_Group       mpi_group_world;
     int            *rank;
 #endif
 
-    if (nsim < 1)
+    if (nsim <= 1)
     {
-        return;
+        return nullptr;
     }
     if (!GMX_LIB_MPI && nsim > 1)
     {
@@ -259,33 +258,34 @@ void init_multisystem(t_commrec *cr, int nsim, char **multidirs)
     }
     GMX_RELEASE_ASSERT(multidirs, "Must have multiple directories for -multisim");
 
-    nnodes  = cr->nnodes;
-    if (nnodes % nsim != 0)
+#if GMX_MPI
+    int numRanks;
+    MPI_Comm_size(comm, &numRanks);
+    if (numRanks % nsim != 0)
     {
-        gmx_fatal(FARGS, "The number of ranks (%d) is not a multiple of the number of simulations (%d)", nnodes, nsim);
+        gmx_fatal(FARGS, "The number of ranks (%d) is not a multiple of the number of simulations (%d)", numRanks, nsim);
     }
 
-    nnodpersim = nnodes/nsim;
-    sim        = cr->nodeid/nnodpersim;
+    int numRanksPerSim = numRanks/nsim;
+    int rankWithinComm;
+    MPI_Comm_rank(comm, &rankWithinComm);
 
     if (debug)
     {
-        fprintf(debug, "We have %d simulations, %d ranks per simulation, local simulation is %d\n", nsim, nnodpersim, sim);
+        fprintf(debug, "We have %d simulations, %d ranks per simulation, local simulation is %d\n", nsim, numRanksPerSim, rankWithinComm/numRanksPerSim);
     }
 
-    snew(ms, 1);
-    cr->ms   = ms;
+    ms       = new gmx_multisim_t;
     ms->nsim = nsim;
-    ms->sim  = sim;
-#if GMX_MPI
+    ms->sim  = rankWithinComm/numRanksPerSim;
     /* Create a communicator for the master nodes */
     snew(rank, ms->nsim);
     for (int i = 0; i < ms->nsim; i++)
     {
-        rank[i] = i*nnodpersim;
+        rank[i] = i*numRanksPerSim;
     }
-    MPI_Comm_group(MPI_COMM_WORLD, &mpi_group_world);
-    MPI_Group_incl(mpi_group_world, nsim, rank, &ms->mpi_group_masters);
+    MPI_Comm_group(comm, &mpi_group_world);
+    MPI_Group_incl(mpi_group_world, ms->nsim, rank, &ms->mpi_group_masters);
     sfree(rank);
     MPI_Comm_create(MPI_COMM_WORLD, ms->mpi_group_masters,
                     &ms->mpi_comm_masters);
@@ -303,24 +303,21 @@ void init_multisystem(t_commrec *cr, int nsim, char **multidirs)
     ms->mpb->dbuf_alloc  = 0;
 #endif
 
+    // TODO This should throw upon error
+    gmx_chdir(multidirs[ms->sim]);
+#else
+    GMX_UNUSED_VALUE(comm);
+    ms = nullptr;
 #endif
 
-    /* Reduce the intra-simulation communication */
-    cr->sim_nodeid = cr->nodeid % nnodpersim;
-    cr->nnodes     = nnodpersim;
-#if GMX_MPI
-    MPI_Comm_split(MPI_COMM_WORLD, sim, cr->sim_nodeid, &cr->mpi_comm_mysim);
-    cr->mpi_comm_mygroup = cr->mpi_comm_mysim;
-    cr->nodeid           = cr->sim_nodeid;
-#endif
+    return ms;
+}
 
-    if (debug)
+void done_multisim(gmx_multisim_t *ms)
+{
+    if (nullptr != ms)
     {
-        fprintf(debug, "This is simulation %d, local number of ranks %d, local rank ID %d\n",
-                cr->ms->sim, cr->nnodes, cr->sim_nodeid);
-        fprintf(debug, "Changing to working directory %s\n", multidirs[cr->ms->sim]);
+        done_mpi_in_place_buf(ms->mpb);
+        delete ms;
     }
-
-    // TODO This should throw upon error
-    gmx_chdir(multidirs[cr->ms->sim]);
 }
index af67ef9b9cba44da8a2a5d90c7773a2d1d092f79..f7c77b87d835d945cd7b2a7abada6c5bb0761ffd 100644 (file)
@@ -40,6 +40,7 @@
 #include <stdio.h>
 
 #include "gromacs/utility/basedefinitions.h"
+#include "gromacs/utility/gmxmpi.h"
 
 struct gmx_multisim_t;
 struct t_commrec;
@@ -66,10 +67,13 @@ void check_multi_int64(FILE *log, const gmx_multisim_t *ms,
  * no output is written.
  */
 
-void init_multisystem(t_commrec *cr, int nsim, char **multidirs);
+gmx_multisim_t *init_multisystem(MPI_Comm comm, int nsim, char **multidirs);
 /* Splits the communication into nsim separate simulations
  * and creates a communication structure between the master
  * these simulations.
  */
 
+//! Cleans up multi-system handler.
+void done_multisim(gmx_multisim_t *ms);
+
 #endif
index e1814f97d8ef40bd578824f5bd52fd6420dc2bd0..7362424b0eafe7135318cb95ad03658a916786a9 100644 (file)
@@ -322,7 +322,9 @@ static void get_state_f_norm_max(t_commrec *cr,
 
 //! Initialize the energy minimization
 static void init_em(FILE *fplog, const char *title,
-                    t_commrec *cr, gmx::IMDOutputProvider *outputProvider,
+                    t_commrec *cr,
+                    const gmx_multisim_t *ms,
+                    gmx::IMDOutputProvider *outputProvider,
                     t_inputrec *ir,
                     const MdrunOptions &mdrunOptions,
                     t_state *state_global, gmx_mtop_t *top_global,
@@ -353,7 +355,7 @@ static void init_em(FILE *fplog, const char *title,
     init_nrnb(nrnb);
 
     /* Interactive molecular dynamics */
-    init_IMD(ir, cr, top_global, fplog, 1,
+    init_IMD(ir, cr, ms, top_global, fplog, 1,
              MASTER(cr) ? as_rvec_array(state_global->x.data()) : nullptr,
              nfile, fnm, nullptr, mdrunOptions);
 
@@ -440,7 +442,7 @@ static void init_em(FILE *fplog, const char *title,
             /* Constrain the starting coordinates */
             dvdl_constr = 0;
             constrain(PAR(cr) ? nullptr : fplog, TRUE, TRUE, constr, &(*top)->idef,
-                      ir, cr, -1, 0, 1.0, mdatoms,
+                      ir, cr, ms, -1, 0, 1.0, mdatoms,
                       as_rvec_array(ems->s.x.data()),
                       as_rvec_array(ems->s.x.data()),
                       nullptr,
@@ -560,7 +562,9 @@ static void write_em_traj(FILE *fplog, t_commrec *cr,
 //! \brief Do one minimization step
 //
 // \returns true when the step succeeded, false when a constraint error occurred
-static bool do_em_step(t_commrec *cr, t_inputrec *ir, t_mdatoms *md,
+static bool do_em_step(t_commrec *cr,
+                       const gmx_multisim_t *ms,
+                       t_inputrec *ir, t_mdatoms *md,
                        gmx_bool bMolPBC,
                        em_state_t *ems1, real a, const PaddedRVecVector *force,
                        em_state_t *ems2,
@@ -673,7 +677,7 @@ static bool do_em_step(t_commrec *cr, t_inputrec *ir, t_mdatoms *md,
         dvdl_constr = 0;
         validStep   =
             constrain(nullptr, TRUE, TRUE, constr, &top->idef,
-                      ir, cr, count, 0, 1.0, md,
+                      ir, cr, ms, count, 0, 1.0, md,
                       as_rvec_array(s1->x.data()), as_rvec_array(s2->x.data()),
                       nullptr, bMolPBC, s2->box,
                       s2->lambda[efptBONDED], &dvdl_constr,
@@ -710,6 +714,7 @@ static void em_dd_partition_system(FILE *fplog, int step, t_commrec *cr,
 
 //! De one energy evaluation
 static void evaluate_energy(FILE *fplog, t_commrec *cr,
+                            const gmx_multisim_t *ms,
                             gmx_mtop_t *top_global,
                             em_state_t *ems, gmx_localtop_t *top,
                             t_inputrec *inputrec,
@@ -765,7 +770,7 @@ static void evaluate_energy(FILE *fplog, t_commrec *cr,
     /* do_force always puts the charge groups in the box and shifts again
      * We do not unshift, so molecules are always whole in congrad.c
      */
-    do_force(fplog, cr, inputrec,
+    do_force(fplog, cr, ms, inputrec,
              count, nrnb, wcycle, top, &top_global->groups,
              ems->s.box, ems->s.x, &ems->s.hist,
              ems->f, force_vir, mdAtoms->mdatoms(), enerd, fcd,
@@ -816,7 +821,7 @@ static void evaluate_energy(FILE *fplog, t_commrec *cr,
         dvdl_constr = 0;
         rvec *f_rvec = as_rvec_array(ems->f.data());
         constrain(nullptr, FALSE, FALSE, constr, &top->idef,
-                  inputrec, cr, count, 0, 1.0, mdAtoms->mdatoms(),
+                  inputrec, cr, ms, count, 0, 1.0, mdAtoms->mdatoms(),
                   as_rvec_array(ems->s.x.data()), f_rvec, f_rvec,
                   fr->bMolPBC, ems->s.box,
                   ems->s.lambda[efptBONDED], &dvdl_constr,
@@ -975,7 +980,9 @@ namespace gmx
 {
 
 /*! \brief Do conjugate gradients minimization
-    \copydoc integrator_t(FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
+    \copydoc integrator_t(FILE *fplog, t_commrec *cr,
+                           const gmx_multi_sim_t *,
+                           const gmx::MDLogger &mdlog,
                            int nfile, const t_filenm fnm[],
                            const gmx_output_env_t *oenv,
                            const MdrunOptions &mdrunOptions,
@@ -992,7 +999,9 @@ namespace gmx
                            gmx_membed_t gmx_unused *membed,
                            gmx_walltime_accounting_t walltime_accounting)
  */
-double do_cg(FILE *fplog, t_commrec *cr, const gmx::MDLogger gmx_unused &mdlog,
+double do_cg(FILE *fplog, t_commrec *cr,
+             const gmx_multisim_t *ms,
+             const gmx::MDLogger gmx_unused &mdlog,
              int nfile, const t_filenm fnm[],
              const gmx_output_env_t gmx_unused *oenv,
              const MdrunOptions &mdrunOptions,
@@ -1043,7 +1052,7 @@ double do_cg(FILE *fplog, t_commrec *cr, const gmx::MDLogger gmx_unused &mdlog,
     em_state_t *s_c   = &s3;
 
     /* Init em and store the local state in s_min */
-    init_em(fplog, CG, cr, outputProvider, inputrec, mdrunOptions,
+    init_em(fplog, CG, cr, ms, outputProvider, inputrec, mdrunOptions,
             state_global, top_global, s_min, &top,
             nrnb, mu_tot, fr, &enerd, &graph, mdAtoms, &gstat,
             vsite, constr, nullptr,
@@ -1068,7 +1077,7 @@ double do_cg(FILE *fplog, t_commrec *cr, const gmx::MDLogger gmx_unused &mdlog,
     /* do_force always puts the charge groups in the box and shifts again
      * We do not unshift, so molecules are always whole in congrad.c
      */
-    evaluate_energy(fplog, cr,
+    evaluate_energy(fplog, cr, ms,
                     top_global, s_min, top,
                     inputrec, nrnb, wcycle, gstat,
                     vsite, constr, fcd, graph, mdAtoms, fr,
@@ -1241,12 +1250,12 @@ double do_cg(FILE *fplog, t_commrec *cr, const gmx::MDLogger gmx_unused &mdlog,
         }
 
         /* Take a trial step (new coords in s_c) */
-        do_em_step(cr, inputrec, mdatoms, fr->bMolPBC, s_min, c, &s_min->s.cg_p, s_c,
+        do_em_step(cr, ms, inputrec, mdatoms, fr->bMolPBC, s_min, c, &s_min->s.cg_p, s_c,
                    constr, top, nrnb, wcycle, -1);
 
         neval++;
         /* Calculate energy for the trial step */
-        evaluate_energy(fplog, cr,
+        evaluate_energy(fplog, cr, ms,
                         top_global, s_c, top,
                         inputrec, nrnb, wcycle, gstat,
                         vsite, constr, fcd, graph, mdAtoms, fr,
@@ -1350,12 +1359,12 @@ double do_cg(FILE *fplog, t_commrec *cr, const gmx::MDLogger gmx_unused &mdlog,
                 }
 
                 /* Take a trial step to this new point - new coords in s_b */
-                do_em_step(cr, inputrec, mdatoms, fr->bMolPBC, s_min, b, &s_min->s.cg_p, s_b,
+                do_em_step(cr, ms, inputrec, mdatoms, fr->bMolPBC, s_min, b, &s_min->s.cg_p, s_b,
                            constr, top, nrnb, wcycle, -1);
 
                 neval++;
                 /* Calculate energy for the trial step */
-                evaluate_energy(fplog, cr,
+                evaluate_energy(fplog, cr, ms,
                                 top_global, s_b, top,
                                 inputrec, nrnb, wcycle, gstat,
                                 vsite, constr, fcd, graph, mdAtoms, fr,
@@ -1620,7 +1629,9 @@ double do_cg(FILE *fplog, t_commrec *cr, const gmx::MDLogger gmx_unused &mdlog,
 
 
 /*! \brief Do L-BFGS conjugate gradients minimization
-    \copydoc integrator_t(FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
+    \copydoc integrator_t(FILE *fplog, t_commrec *cr,
+                          const gmx_multi_sim_t *,
+                          const gmx::MDLogger &mdlog,
                           int nfile, const t_filenm fnm[],
                           const gmx_output_env_t *oenv,
                           const MdrunOptions &mdrunOptions,
@@ -1637,7 +1648,9 @@ double do_cg(FILE *fplog, t_commrec *cr, const gmx::MDLogger gmx_unused &mdlog,
                           gmx_membed_t gmx_unused *membed,
                           gmx_walltime_accounting_t walltime_accounting)
  */
-double do_lbfgs(FILE *fplog, t_commrec *cr, const gmx::MDLogger gmx_unused &mdlog,
+double do_lbfgs(FILE *fplog, t_commrec *cr,
+                const gmx_multisim_t *ms,
+                const gmx::MDLogger gmx_unused &mdlog,
                 int nfile, const t_filenm fnm[],
                 const gmx_output_env_t gmx_unused *oenv,
                 const MdrunOptions &mdrunOptions,
@@ -1712,7 +1725,7 @@ double do_lbfgs(FILE *fplog, t_commrec *cr, const gmx::MDLogger gmx_unused &mdlo
     neval = 0;
 
     /* Init em */
-    init_em(fplog, LBFGS, cr, outputProvider, inputrec, mdrunOptions,
+    init_em(fplog, LBFGS, cr, ms, outputProvider, inputrec, mdrunOptions,
             state_global, top_global, &ems, &top,
             nrnb, mu_tot, fr, &enerd, &graph, mdAtoms, &gstat,
             vsite, constr, nullptr,
@@ -1774,7 +1787,7 @@ double do_lbfgs(FILE *fplog, t_commrec *cr, const gmx::MDLogger gmx_unused &mdlo
      * We do not unshift, so molecules are always whole
      */
     neval++;
-    evaluate_energy(fplog, cr,
+    evaluate_energy(fplog, cr, ms,
                     top_global, &ems, top,
                     inputrec, nrnb, wcycle, gstat,
                     vsite, constr, fcd, graph, mdAtoms, fr,
@@ -1980,7 +1993,7 @@ double do_lbfgs(FILE *fplog, t_commrec *cr, const gmx::MDLogger gmx_unused &mdlo
 
         neval++;
         // Calculate energy for the trial step in position C
-        evaluate_energy(fplog, cr,
+        evaluate_energy(fplog, cr, ms,
                         top_global, sc, top,
                         inputrec, nrnb, wcycle, gstat,
                         vsite, constr, fcd, graph, mdAtoms, fr,
@@ -2071,7 +2084,7 @@ double do_lbfgs(FILE *fplog, t_commrec *cr, const gmx::MDLogger gmx_unused &mdlo
 
                 neval++;
                 // Calculate energy for the trial step in point B
-                evaluate_energy(fplog, cr,
+                evaluate_energy(fplog, cr, ms,
                                 top_global, sb, top,
                                 inputrec, nrnb, wcycle, gstat,
                                 vsite, constr, fcd, graph, mdAtoms, fr,
@@ -2386,7 +2399,9 @@ double do_lbfgs(FILE *fplog, t_commrec *cr, const gmx::MDLogger gmx_unused &mdlo
 }   /* That's all folks */
 
 /*! \brief Do steepest descents minimization
-    \copydoc integrator_t(FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
+    \copydoc integrator_t(FILE *fplog, t_commrec *cr,
+                          const gmx_multi_sim_t *,
+                          const gmx::MDLogger &mdlog,
                           int nfile, const t_filenm fnm[],
                           const gmx_output_env_t *oenv,
                           const MdrunOptions &mdrunOptions,
@@ -2402,7 +2417,9 @@ double do_lbfgs(FILE *fplog, t_commrec *cr, const gmx::MDLogger gmx_unused &mdlo
                           const ReplicaExchangeParameters &replExParams,
                           gmx_walltime_accounting_t walltime_accounting)
  */
-double do_steep(FILE *fplog, t_commrec *cr, const gmx::MDLogger gmx_unused &mdlog,
+double do_steep(FILE *fplog, t_commrec *cr,
+                const gmx_multisim_t *ms,
+                const gmx::MDLogger gmx_unused &mdlog,
                 int nfile, const t_filenm fnm[],
                 const gmx_output_env_t gmx_unused *oenv,
                 const MdrunOptions &mdrunOptions,
@@ -2442,7 +2459,7 @@ double do_steep(FILE *fplog, t_commrec *cr, const gmx::MDLogger gmx_unused &mdlo
     em_state_t *s_try = &s1;
 
     /* Init em and store the local state in s_try */
-    init_em(fplog, SD, cr, outputProvider, inputrec, mdrunOptions,
+    init_em(fplog, SD, cr, ms, outputProvider, inputrec, mdrunOptions,
             state_global, top_global, s_try, &top,
             nrnb, mu_tot, fr, &enerd, &graph, mdAtoms, &gstat,
             vsite, constr, nullptr,
@@ -2488,14 +2505,14 @@ double do_steep(FILE *fplog, t_commrec *cr, const gmx::MDLogger gmx_unused &mdlo
         if (count > 0)
         {
             validStep =
-                do_em_step(cr, inputrec, mdatoms, fr->bMolPBC,
+                do_em_step(cr, ms, inputrec, mdatoms, fr->bMolPBC,
                            s_min, stepsize, &s_min->f, s_try,
                            constr, top, nrnb, wcycle, count);
         }
 
         if (validStep)
         {
-            evaluate_energy(fplog, cr,
+            evaluate_energy(fplog, cr, ms,
                             top_global, s_try, top,
                             inputrec, nrnb, wcycle, gstat,
                             vsite, constr, fcd, graph, mdAtoms, fr,
@@ -2652,7 +2669,9 @@ double do_steep(FILE *fplog, t_commrec *cr, const gmx::MDLogger gmx_unused &mdlo
 }   /* That's all folks */
 
 /*! \brief Do normal modes analysis
-    \copydoc integrator_t(FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
+    \copydoc integrator_t(FILE *fplog, t_commrec *cr,
+                          const gmx_multi_sim_t *,
+                          const gmx::MDLogger &mdlog,
                           int nfile, const t_filenm fnm[],
                           const gmx_output_env_t *oenv,
                           const MdrunOptions &mdrunOptions,
@@ -2668,7 +2687,9 @@ double do_steep(FILE *fplog, t_commrec *cr, const gmx::MDLogger gmx_unused &mdlo
                           const ReplicaExchangeParameters &replExParams,
                           gmx_walltime_accounting_t walltime_accounting)
  */
-double do_nm(FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
+double do_nm(FILE *fplog, t_commrec *cr,
+             const gmx_multisim_t *ms,
+             const gmx::MDLogger &mdlog,
              int nfile, const t_filenm fnm[],
              const gmx_output_env_t gmx_unused *oenv,
              const MdrunOptions &mdrunOptions,
@@ -2717,7 +2738,7 @@ double do_nm(FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
     em_state_t     state_work {};
 
     /* Init em and store the local state in state_minimum */
-    init_em(fplog, NM, cr, outputProvider, inputrec, mdrunOptions,
+    init_em(fplog, NM, cr, ms, outputProvider, inputrec, mdrunOptions,
             state_global, top_global, &state_work, &top,
             nrnb, mu_tot, fr, &enerd, &graph, mdAtoms, &gstat,
             vsite, constr, &shellfc,
@@ -2796,7 +2817,7 @@ double do_nm(FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
 
     /* Make evaluate_energy do a single node force calculation */
     cr->nnodes = 1;
-    evaluate_energy(fplog, cr,
+    evaluate_energy(fplog, cr, ms,
                     top_global, &state_work, top,
                     inputrec, nrnb, wcycle, gstat,
                     vsite, constr, fcd, graph, mdAtoms, fr,
@@ -2854,7 +2875,7 @@ double do_nm(FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
                 if (shellfc)
                 {
                     /* Now is the time to relax the shells */
-                    (void) relax_shell_flexcon(fplog, cr, mdrunOptions.verbose, step,
+                    (void) relax_shell_flexcon(fplog, cr, ms, mdrunOptions.verbose, step,
                                                inputrec, bNS, force_flags,
                                                top,
                                                constr, enerd, fcd,
@@ -2869,7 +2890,7 @@ double do_nm(FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
                 }
                 else
                 {
-                    evaluate_energy(fplog, cr,
+                    evaluate_energy(fplog, cr, ms,
                                     top_global, &state_work, top,
                                     inputrec, nrnb, wcycle, gstat,
                                     vsite, constr, fcd, graph, mdAtoms, fr,
index 83b7273f527870fd9e6ed0eccbf3f6236ec77ad6..82fc85b380a38660a738f89ce2bcec3dd11c7a50 100644 (file)
@@ -893,7 +893,9 @@ static void dump_shells(FILE *fp, gmx::ArrayRef<gmx::RVec> x, gmx::ArrayRef<gmx:
 
 static void init_adir(FILE *log, gmx_shellfc_t *shfc,
                       gmx_constr_t constr, t_idef *idef, t_inputrec *ir,
-                      t_commrec *cr, int dd_ac1,
+                      t_commrec *cr,
+                      const gmx_multisim_t *ms,
+                      int dd_ac1,
                       gmx_int64_t step, t_mdatoms *md, int end,
                       rvec *x_old, rvec *x_init, rvec *x,
                       rvec *f, rvec *acc_dir,
@@ -946,11 +948,11 @@ static void init_adir(FILE *log, gmx_shellfc_t *shfc,
             }
         }
     }
-    constrain(log, FALSE, FALSE, constr, idef, ir, cr, step, 0, 1.0, md,
+    constrain(log, FALSE, FALSE, constr, idef, ir, cr, ms, step, 0, 1.0, md,
               x, xnold, nullptr, bMolPBC, box,
               lambda[efptBONDED], &(dvdlambda[efptBONDED]),
               nullptr, nullptr, nrnb, econqCoord);
-    constrain(log, FALSE, FALSE, constr, idef, ir, cr, step, 0, 1.0, md,
+    constrain(log, FALSE, FALSE, constr, idef, ir, cr, ms, step, 0, 1.0, md,
               x, xnew, nullptr, bMolPBC, box,
               lambda[efptBONDED], &(dvdlambda[efptBONDED]),
               nullptr, nullptr, nrnb, econqCoord);
@@ -967,13 +969,15 @@ static void init_adir(FILE *log, gmx_shellfc_t *shfc,
     }
 
     /* Project the acceleration on the old bond directions */
-    constrain(log, FALSE, FALSE, constr, idef, ir, cr, step, 0, 1.0, md,
+    constrain(log, FALSE, FALSE, constr, idef, ir, cr, ms, step, 0, 1.0, md,
               x_old, xnew, acc_dir, bMolPBC, box,
               lambda[efptBONDED], &(dvdlambda[efptBONDED]),
               nullptr, nullptr, nrnb, econqDeriv_FlexCon);
 }
 
-void relax_shell_flexcon(FILE *fplog, t_commrec *cr, gmx_bool bVerbose,
+void relax_shell_flexcon(FILE *fplog, t_commrec *cr,
+                         const gmx_multisim_t *ms,
+                         gmx_bool bVerbose,
                          gmx_int64_t mdstep, t_inputrec *inputrec,
                          gmx_bool bDoNS, int force_flags,
                          gmx_localtop_t *top,
@@ -1116,7 +1120,7 @@ void relax_shell_flexcon(FILE *fplog, t_commrec *cr, gmx_bool bVerbose,
     {
         pr_rvecs(debug, 0, "x b4 do_force", as_rvec_array(state->x.data()), homenr);
     }
-    do_force(fplog, cr, inputrec, mdstep, nrnb, wcycle, top, groups,
+    do_force(fplog, cr, ms, inputrec, mdstep, nrnb, wcycle, top, groups,
              state->box, state->x, &state->hist,
              force[Min], force_vir, md, enerd, fcd,
              state->lambda, graph,
@@ -1128,7 +1132,7 @@ void relax_shell_flexcon(FILE *fplog, t_commrec *cr, gmx_bool bVerbose,
     if (nflexcon)
     {
         init_adir(fplog, shfc,
-                  constr, idef, inputrec, cr, dd_ac1, mdstep, md, end,
+                  constr, idef, inputrec, cr, ms, dd_ac1, mdstep, md, end,
                   shfc->x_old, as_rvec_array(state->x.data()), as_rvec_array(state->x.data()), as_rvec_array(force[Min].data()),
                   shfc->acc_dir,
                   fr->bMolPBC, state->box, state->lambda, &dum, nrnb);
@@ -1197,7 +1201,7 @@ void relax_shell_flexcon(FILE *fplog, t_commrec *cr, gmx_bool bVerbose,
         if (nflexcon)
         {
             init_adir(fplog, shfc,
-                      constr, idef, inputrec, cr, dd_ac1, mdstep, md, end,
+                      constr, idef, inputrec, cr, ms, dd_ac1, mdstep, md, end,
                       x_old, as_rvec_array(state->x.data()), as_rvec_array(pos[Min].data()), as_rvec_array(force[Min].data()), acc_dir,
                       fr->bMolPBC, state->box, state->lambda, &dum, nrnb);
 
@@ -1219,7 +1223,7 @@ void relax_shell_flexcon(FILE *fplog, t_commrec *cr, gmx_bool bVerbose,
             pr_rvecs(debug, 0, "RELAX: pos[Try]  ", as_rvec_array(pos[Try].data()), homenr);
         }
         /* Try the new positions */
-        do_force(fplog, cr, inputrec, 1, nrnb, wcycle,
+        do_force(fplog, cr, ms, inputrec, 1, nrnb, wcycle,
                  top, groups, state->box, pos[Try], &state->hist,
                  force[Try], force_vir,
                  md, enerd, fcd, state->lambda, graph,
@@ -1236,7 +1240,7 @@ void relax_shell_flexcon(FILE *fplog, t_commrec *cr, gmx_bool bVerbose,
         if (nflexcon)
         {
             init_adir(fplog, shfc,
-                      constr, idef, inputrec, cr, dd_ac1, mdstep, md, end,
+                      constr, idef, inputrec, cr, ms, dd_ac1, mdstep, md, end,
                       x_old, as_rvec_array(state->x.data()), as_rvec_array(pos[Try].data()), as_rvec_array(force[Try].data()), acc_dir,
                       fr->bMolPBC, state->box, state->lambda, &dum, nrnb);
 
index 73831831b7562bf9ec054382f88e111248e16fc8..b8ddae55338efc67a6d593fa84392a2c7001cd68 100644 (file)
@@ -47,6 +47,7 @@
 struct gmx_constr;
 struct gmx_enerdata_t;
 struct gmx_groups_t;
+struct gmx_multisim_t;
 struct gmx_shellfc_t;
 struct gmx_mtop_t;
 struct t_forcerec;
@@ -67,7 +68,9 @@ void make_local_shells(t_commrec *cr, t_mdatoms *md,
                        gmx_shellfc_t *shfc);
 
 /* Optimize shell positions */
-void relax_shell_flexcon(FILE *log, t_commrec *cr, gmx_bool bVerbose,
+void relax_shell_flexcon(FILE *log, t_commrec *cr,
+                         const gmx_multisim_t *ms,
+                         gmx_bool bVerbose,
                          gmx_int64_t mdstep, t_inputrec *inputrec,
                          gmx_bool bDoNS, int force_flags,
                          gmx_localtop_t *top,
index 483f10e0637469247fdfd91267c0dc87fa701519..4413195c3f4a1a483bae68d944c44a197670d758 100644 (file)
@@ -1033,6 +1033,7 @@ static inline void launchGpuRollingPruning(const t_commrec          *cr,
 }
 
 static void do_force_cutsVERLET(FILE *fplog, t_commrec *cr,
+                                const gmx_multisim_t *ms,
                                 t_inputrec *inputrec,
                                 gmx_int64_t step, t_nrnb *nrnb, gmx_wallcycle_t wcycle,
                                 gmx_localtop_t *top,
@@ -1515,7 +1516,7 @@ static void do_force_cutsVERLET(FILE *fplog, t_commrec *cr,
 
     /* Compute the bonded and non-bonded energies and optionally forces */
     do_force_lowlevel(fr, inputrec, &(top->idef),
-                      cr, nrnb, wcycle, mdatoms,
+                      cr, ms, nrnb, wcycle, mdatoms,
                       as_rvec_array(x.data()), hist, f, &forceWithVirial, enerd, fcd,
                       box, inputrec->fepvals, lambda, graph, &(top->excls), fr->mu_tot,
                       flags, &cycles_pme);
@@ -1716,6 +1717,7 @@ static void do_force_cutsVERLET(FILE *fplog, t_commrec *cr,
 }
 
 static void do_force_cutsGROUP(FILE *fplog, t_commrec *cr,
+                               const gmx_multisim_t *ms,
                                t_inputrec *inputrec,
                                gmx_int64_t step, t_nrnb *nrnb, gmx_wallcycle_t wcycle,
                                gmx_localtop_t *top,
@@ -1947,7 +1949,7 @@ static void do_force_cutsGROUP(FILE *fplog, t_commrec *cr,
 
     /* Compute the bonded and non-bonded energies and optionally forces */
     do_force_lowlevel(fr, inputrec, &(top->idef),
-                      cr, nrnb, wcycle, mdatoms,
+                      cr, ms, nrnb, wcycle, mdatoms,
                       as_rvec_array(x.data()), hist, f, &forceWithVirial, enerd, fcd,
                       box, inputrec->fepvals, lambda,
                       graph, &(top->excls), fr->mu_tot,
@@ -2038,6 +2040,7 @@ static void do_force_cutsGROUP(FILE *fplog, t_commrec *cr,
 }
 
 void do_force(FILE *fplog, t_commrec *cr,
+              const gmx_multisim_t *ms,
               t_inputrec *inputrec,
               gmx_int64_t step, t_nrnb *nrnb, gmx_wallcycle_t wcycle,
               gmx_localtop_t *top,
@@ -2067,7 +2070,7 @@ void do_force(FILE *fplog, t_commrec *cr,
     switch (inputrec->cutoff_scheme)
     {
         case ecutsVERLET:
-            do_force_cutsVERLET(fplog, cr, inputrec,
+            do_force_cutsVERLET(fplog, cr, ms, inputrec,
                                 step, nrnb, wcycle,
                                 top,
                                 groups,
@@ -2084,7 +2087,7 @@ void do_force(FILE *fplog, t_commrec *cr,
                                 ddCloseBalanceRegion);
             break;
         case ecutsGROUP:
-            do_force_cutsGROUP(fplog, cr, inputrec,
+            do_force_cutsGROUP(fplog, cr, ms, inputrec,
                                step, nrnb, wcycle,
                                top,
                                groups,
@@ -2118,7 +2121,9 @@ void do_force(FILE *fplog, t_commrec *cr,
 
 void do_constrain_first(FILE *fplog, gmx_constr_t constr,
                         t_inputrec *ir, t_mdatoms *md,
-                        t_state *state, t_commrec *cr, t_nrnb *nrnb,
+                        t_state *state, t_commrec *cr,
+                        const gmx_multisim_t *ms,
+                        t_nrnb *nrnb,
                         t_forcerec *fr, gmx_localtop_t *top)
 {
     int             i, m, start, end;
@@ -2152,7 +2157,7 @@ void do_constrain_first(FILE *fplog, gmx_constr_t constr,
 
     /* constrain the current position */
     constrain(nullptr, TRUE, FALSE, constr, &(top->idef),
-              ir, cr, step, 0, 1.0, md,
+              ir, cr, ms, step, 0, 1.0, md,
               as_rvec_array(state->x.data()), as_rvec_array(state->x.data()), nullptr,
               fr->bMolPBC, state->box,
               state->lambda[efptBONDED], &dvdl_dum,
@@ -2162,7 +2167,7 @@ void do_constrain_first(FILE *fplog, gmx_constr_t constr,
         /* constrain the inital velocity, and save it */
         /* also may be useful if we need the ekin from the halfstep for velocity verlet */
         constrain(nullptr, TRUE, FALSE, constr, &(top->idef),
-                  ir, cr, step, 0, 1.0, md,
+                  ir, cr, ms, step, 0, 1.0, md,
                   as_rvec_array(state->x.data()), as_rvec_array(state->v.data()), as_rvec_array(state->v.data()),
                   fr->bMolPBC, state->box,
                   state->lambda[efptBONDED], &dvdl_dum,
@@ -2192,7 +2197,7 @@ void do_constrain_first(FILE *fplog, gmx_constr_t constr,
         }
         dvdl_dum = 0;
         constrain(nullptr, TRUE, FALSE, constr, &(top->idef),
-                  ir, cr, step, -1, 1.0, md,
+                  ir, cr, ms, step, -1, 1.0, md,
                   as_rvec_array(state->x.data()), savex, nullptr,
                   fr->bMolPBC, state->box,
                   state->lambda[efptBONDED], &dvdl_dum,
index 92ba77015f6f156276b814d98dc99b4c38895c8d..bb28aa0f2e0d1cb5918615b8a8849565520b38e8 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2016,2017, 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.
@@ -47,6 +47,7 @@
 
 struct gmx_constr;
 struct gmx_localtop_t;
+struct gmx_multisim_t;
 struct gmx_output_env_t;
 struct gmx_update_t;
 struct MdrunOptions;
@@ -138,7 +139,9 @@ void initialize_lambdas(FILE *fplog, t_inputrec *ir, int *fep_state, gmx::ArrayR
 
 void do_constrain_first(FILE *log, gmx_constr *constr,
                         t_inputrec *inputrec, t_mdatoms *md,
-                        t_state *state, t_commrec *cr, t_nrnb *nrnb,
+                        t_state *state, t_commrec *cr,
+                        const gmx_multisim_t *ms,
+                        t_nrnb *nrnb,
                         t_forcerec *fr, gmx_localtop_t *top);
 
 void init_md(FILE *fplog,
index 37f659955bae8b8300417878dacca5efe86c4d6e..aa0a63f137b39747d18f9db8681a640722e0deeb 100644 (file)
 namespace gmx
 {
 
-SimulationSignaller::SimulationSignaller(SimulationSignals *signals,
-                                         const t_commrec   *cr,
-                                         bool               doInterSim,
-                                         bool               doIntraSim)
-    : signals_(signals), cr_(cr),
+SimulationSignaller::SimulationSignaller(SimulationSignals    *signals,
+                                         const t_commrec      *cr,
+                                         const gmx_multisim_t *ms,
+                                         bool                  doInterSim,
+                                         bool                  doIntraSim)
+    : signals_(signals), cr_(cr), ms_(ms),
       doInterSim_(doInterSim),
       doIntraSim_(doInterSim || doIntraSim),
       mpiBuffer_ {}
@@ -102,11 +103,11 @@ SimulationSignaller::signalInterSim()
     // multi-simulation begin active should already have issued an
     // error at mdrun time in release mode, so there's no need for a
     // release-mode assertion.
-    GMX_ASSERT(isMultiSim(cr_->ms), "Cannot do inter-simulation signalling without a multi-simulation");
+    GMX_ASSERT(isMultiSim(ms_), "Cannot do inter-simulation signalling without a multi-simulation");
     if (MASTER(cr_))
     {
         // Communicate the signals between the simulations.
-        gmx_sum_sim(eglsNR, mpiBuffer_.data(), cr_->ms);
+        gmx_sum_sim(eglsNR, mpiBuffer_.data(), ms_);
     }
     // Communicate the signals from the master to the others.
     gmx_bcast(eglsNR*sizeof(mpiBuffer_[0]), mpiBuffer_.data(), cr_);
index 794908c98091e2bede8a6d6bd9e9d2b9610a9503..151a0d68b327217c6e4ce5ed157f528d51389df4 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2011,2014,2015,2016, by the GROMACS development team, led by
+ * Copyright (c) 2011,2014,2015,2016,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.
@@ -56,6 +56,7 @@
 
 #include "gromacs/utility/real.h"
 
+struct gmx_multisim_t;
 struct t_commrec;
 
 //! Kinds of simulation conditions to signal about.
@@ -113,10 +114,11 @@ class SimulationSignaller
 {
     public:
         //! Constructor
-        SimulationSignaller(SimulationSignals *signals,
-                            const t_commrec   *cr,
-                            bool               doInterSim,
-                            bool               doIntraSim);
+        SimulationSignaller(SimulationSignals    *signals,
+                            const t_commrec      *cr,
+                            const gmx_multisim_t *ms,
+                            bool                  doInterSim,
+                            bool                  doIntraSim);
         /*! \brief Return a reference to an array of signal values to communicate.
          *
          * \return If intra-sim signalling will take place, fill and
@@ -147,6 +149,8 @@ class SimulationSignaller
         SimulationSignals       *signals_;
         //! Communication object.
         const t_commrec         *cr_;
+        //! Multi-sim handler.
+        const gmx_multisim_t    *ms_;
         //! Do inter-sim communication at this step.
         bool                     doInterSim_;
         //! Do intra-sim communication at this step.
index d3fb7ce6fb90e83643be61fc63d0c584ed50e96d..591a701d9f89d3f1524b589a3a47d6a778286e4b 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2016, by the GROMACS development team, led by
+ * Copyright (c) 2016,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.
@@ -56,7 +56,7 @@ namespace test
 //! Check that a null signaller can be called without problems
 TEST(NullSignalTest, NullSignallerWorks)
 {
-    SimulationSignaller signaller(nullptr, nullptr, false, false);
+    SimulationSignaller signaller(nullptr, nullptr, nullptr, false, false);
     EXPECT_EQ(0, signaller.getCommunicationBuffer().size());
     signaller.finalizeSignals();
 }
@@ -77,7 +77,7 @@ class SignalTest : public ::testing::Test
 
 TEST_F(SignalTest, NoSignalPropagatesIfNoSignallingTakesPlace)
 {
-    SimulationSignaller signaller(&signals_, nullptr, false, false);
+    SimulationSignaller signaller(&signals_, nullptr, nullptr, false, false);
     EXPECT_EQ(0, signaller.getCommunicationBuffer().size());
     signaller.finalizeSignals();
     EXPECT_EQ(1, signals_[0].sig);
@@ -90,7 +90,7 @@ TEST_F(SignalTest, NoSignalPropagatesIfNoSignallingTakesPlace)
 
 TEST_F(SignalTest, LocalIntraSimSignalPropagatesWhenIntraSimSignalTakesPlace)
 {
-    SimulationSignaller signaller(&signals_, nullptr, false, true);
+    SimulationSignaller signaller(&signals_, nullptr, nullptr, false, true);
     EXPECT_NE(0, signaller.getCommunicationBuffer().size());
     signaller.finalizeSignals();
     EXPECT_EQ(0, signals_[0].sig);
@@ -103,7 +103,7 @@ TEST_F(SignalTest, LocalIntraSimSignalPropagatesWhenIntraSimSignalTakesPlace)
 
 TEST_F(SignalTest, LocalIntraSimSignalPropagatesWhenInterSimTakesPlace)
 {
-    SimulationSignaller signaller(&signals_, nullptr, true, false);
+    SimulationSignaller signaller(&signals_, nullptr, nullptr, true, false);
     EXPECT_NE(0, signaller.getCommunicationBuffer().size());
     // Can't call finalizeSignals without a full commrec
     signaller.setSignals();
@@ -117,7 +117,7 @@ TEST_F(SignalTest, LocalIntraSimSignalPropagatesWhenInterSimTakesPlace)
 
 TEST_F(SignalTest, LocalIntraSimSignalPropagatesWhenBothTakePlace)
 {
-    SimulationSignaller signaller(&signals_, nullptr, true, true);
+    SimulationSignaller signaller(&signals_, nullptr, nullptr, true, true);
     EXPECT_NE(0, signaller.getCommunicationBuffer().size());
     // Can't call finalizeSignals without a full commrec
     signaller.setSignals();
@@ -132,7 +132,7 @@ TEST_F(SignalTest, LocalIntraSimSignalPropagatesWhenBothTakePlace)
 TEST_F(SignalTest, NonLocalSignalDoesntPropagateWhenIntraSimSignalTakesPlace)
 {
     signals_[0].isLocal = false;
-    SimulationSignaller signaller(&signals_, nullptr, false, true);
+    SimulationSignaller signaller(&signals_, nullptr, nullptr, false, true);
     EXPECT_NE(0, signaller.getCommunicationBuffer().size());
     signaller.finalizeSignals();
     EXPECT_EQ(1, signals_[0].sig);
@@ -146,7 +146,7 @@ TEST_F(SignalTest, NonLocalSignalDoesntPropagateWhenIntraSimSignalTakesPlace)
 TEST_F(SignalTest, NonLocalSignalPropagatesWhenInterSimSignalTakesPlace)
 {
     signals_[0].isLocal = false;
-    SimulationSignaller signaller(&signals_, nullptr, true, false);
+    SimulationSignaller signaller(&signals_, nullptr, nullptr, true, false);
     EXPECT_NE(0, signaller.getCommunicationBuffer().size());
     // Can't call finalizeSignals without a full commrec
     signaller.setSignals();
@@ -161,7 +161,7 @@ TEST_F(SignalTest, NonLocalSignalPropagatesWhenInterSimSignalTakesPlace)
 TEST_F(SignalTest, NonLocalSignalPropagatesWhenBothTakePlace)
 {
     signals_[0].isLocal = false;
-    SimulationSignaller signaller(&signals_, nullptr, true, true);
+    SimulationSignaller signaller(&signals_, nullptr, nullptr, true, true);
     EXPECT_NE(0, signaller.getCommunicationBuffer().size());
     // Can't call finalizeSignals without a full commrec
     signaller.setSignals();
index eae59c1a7069267c73784e43b650deac02b38b94..97a882c2d491a5e6a33453ddfc51be5092e43b2a 100644 (file)
@@ -127,7 +127,9 @@ namespace gmx
 {
 
 /*! \brief Do test particle insertion.
-    \copydoc integrator_t (FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
+    \copydoc integrator_t (FILE *fplog, t_commrec *cr,
+                           const gmx_multi_sim_t *,
+                           const gmx::MDLogger &mdlog,
                            int nfile, const t_filenm fnm[],
                            const gmx_output_env_t *oenv,
                            const MdrunOptions &mdrunOptions,
@@ -144,7 +146,9 @@ namespace gmx
                            gmx_membed_t gmx_unused *membed,
                            gmx_walltime_accounting_t walltime_accounting)
  */
-double do_tpi(FILE *fplog, t_commrec *cr, const gmx::MDLogger gmx_unused &mdlog,
+double do_tpi(FILE *fplog, t_commrec *cr,
+              const gmx_multisim_t *ms,
+              const gmx::MDLogger gmx_unused &mdlog,
               int nfile, const t_filenm fnm[],
               const gmx_output_env_t *oenv,
               const MdrunOptions &mdrunOptions,
@@ -659,7 +663,7 @@ double do_tpi(FILE *fplog, t_commrec *cr, const gmx::MDLogger gmx_unused &mdlog,
              * out of the box. */
             /* Make do_force do a single node force calculation */
             cr->nnodes = 1;
-            do_force(fplog, cr, inputrec,
+            do_force(fplog, cr, ms, inputrec,
                      step, nrnb, wcycle, top, &top_global->groups,
                      state_global->box, state_global->x, &state_global->hist,
                      f, force_vir, mdatoms, enerd, fcd,
index 6fc8aa4bbf8e0f181b1f8bf9e563e6b55a721af6..1cab82b2695e1726920a1e8ebdcbe6787d0eca3c 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2016,2017, 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.
@@ -1553,6 +1553,7 @@ void update_constraints(FILE                          *fplog,
                         t_idef                        *idef,
                         tensor                         vir_part,
                         t_commrec                     *cr,
+                        const gmx_multisim_t          *ms,
                         t_nrnb                        *nrnb,
                         gmx_wallcycle_t                wcycle,
                         gmx_update_t                  *upd,
@@ -1611,7 +1612,7 @@ void update_constraints(FILE                          *fplog,
         if (EI_VV(inputrec->eI) && bFirstHalf)
         {
             constrain(nullptr, bLog, bEner, constr, idef,
-                      inputrec, cr, step, 1, 1.0, md,
+                      inputrec, cr, ms, step, 1, 1.0, md,
                       as_rvec_array(state->x.data()), as_rvec_array(state->v.data()), as_rvec_array(state->v.data()),
                       bMolPBC, state->box,
                       state->lambda[efptBONDED], dvdlambda,
@@ -1620,7 +1621,7 @@ void update_constraints(FILE                          *fplog,
         else
         {
             constrain(nullptr, bLog, bEner, constr, idef,
-                      inputrec, cr, step, 1, 1.0, md,
+                      inputrec, cr, ms, step, 1, 1.0, md,
                       as_rvec_array(state->x.data()), as_rvec_array(upd->xp.data()), nullptr,
                       bMolPBC, state->box,
                       state->lambda[efptBONDED], dvdlambda,
@@ -1681,7 +1682,7 @@ void update_constraints(FILE                          *fplog,
             wallcycle_start(wcycle, ewcCONSTR);
 
             constrain(nullptr, bLog, bEner, constr, idef,
-                      inputrec, cr, step, 1, 0.5, md,
+                      inputrec, cr, ms, step, 1, 0.5, md,
                       as_rvec_array(state->x.data()), as_rvec_array(upd->xp.data()), nullptr,
                       bMolPBC, state->box,
                       state->lambda[efptBONDED], dvdlambda,
index 742ec58e823e735f078e7ab2e877fbaf7a0d92ab..d29ec47f52f0088ac66654580fc4fb10c2155166 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2016,2017, 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.
@@ -48,6 +48,7 @@ class ekinstate_t;
 struct gmx_constr;
 struct gmx_ekindata_t;
 struct gmx_enerdata_t;
+struct gmx_multisim_t;
 struct t_extmass;
 struct t_fcdata;
 struct t_graph;
@@ -144,6 +145,7 @@ void update_constraints(FILE                    *fplog,
                         t_idef                  *idef,
                         tensor                   vir_part,
                         t_commrec               *cr,
+                        const gmx_multisim_t    *ms,
                         t_nrnb                  *nrnb,
                         gmx_wallcycle_t          wcycle,
                         gmx_update_t            *upd,
index 114c5b2f7afae0a7bbf4fc64daef504b8df3e750..91db3478f25e5439a178930c6ef228aa4d1e55d0 100644 (file)
@@ -231,12 +231,13 @@ read_checkpoint_data(const char *filename, int *simulation_part,
 
 /* This routine cannot print tons of data, since it is called before the log file is opened. */
 void
-handleRestart(t_commrec *cr,
-              gmx_bool   bTryToAppendFiles,
-              const int  NFILE,
-              t_filenm   fnm[],
-              bool      *bDoAppendFiles,
-              bool      *bStartFromCpt)
+handleRestart(t_commrec            *cr,
+              const gmx_multisim_t *ms,
+              gmx_bool              bTryToAppendFiles,
+              const int             NFILE,
+              t_filenm              fnm[],
+              bool                 *bDoAppendFiles,
+              bool                 *bStartFromCpt)
 {
     gmx_bool        bAddPart;
     int             sim_part, sim_part_fn;
@@ -255,7 +256,7 @@ handleRestart(t_commrec *cr,
                              &sim_part_fn, cr,
                              bTryToAppendFiles, NFILE, fnm,
                              part_suffix, &bAddPart, bDoAppendFiles);
-        if (sim_part_fn == 0 && isMasterSimMasterRank(cr->ms, cr))
+        if (sim_part_fn == 0 && isMasterSimMasterRank(ms, cr))
         {
             fprintf(stdout, "No previous checkpoint file present with -cpi option, assuming this is a new run.\n");
         }
@@ -267,10 +268,10 @@ handleRestart(t_commrec *cr,
         // Master ranks of multi simulations should check that the
         // simulation part number is consistent across the
         // simulations.
-        if (isMultiSim(cr->ms) && MASTER(cr))
+        if (isMultiSim(ms) && MASTER(cr))
         {
             // Only the master simulation should report on problems.
-            if (isMasterSimMasterRank(cr->ms, cr))
+            if (isMasterSimMasterRank(ms, cr))
             {
                 /* Log file is not yet available, so if there's a
                  * problem we can only write to stderr. */
@@ -280,7 +281,7 @@ handleRestart(t_commrec *cr,
             {
                 fpmulti = nullptr;
             }
-            check_multi_int(fpmulti, cr->ms, sim_part, "simulation part", TRUE);
+            check_multi_int(fpmulti, ms, sim_part, "simulation part", TRUE);
         }
     }
     else
@@ -305,7 +306,7 @@ handleRestart(t_commrec *cr,
         sprintf(suffix, "%s%04d", part_suffix, sim_part_fn);
 
         add_suffix_to_output_names(fnm, NFILE, suffix);
-        if (isMasterSimMasterRank(cr->ms, cr))
+        if (isMasterSimMasterRank(ms, cr))
         {
             fprintf(stdout, "Checkpoint file is from part %d, new output files will be suffixed '%s'.\n", sim_part-1, suffix);
         }
index 8a93c8cb1e4bbbc7a0853e8eddae854c8715a7e3..dd6a3b350dd24448fe222beef0bb5445c429ba0c 100644 (file)
@@ -60,6 +60,7 @@
 
 #include "gromacs/utility/basedefinitions.h"
 
+struct gmx_multisim_t;
 struct t_commrec;
 struct t_filenm;
 
@@ -80,6 +81,7 @@ struct t_filenm;
  * and/or simulations.
  *
  * \param[in]    cr                 Communication structure
+ * \param[in]    ms                 Handles multi-simulations.
  * \param[in]    bTryToAppendFiles  Whether appending is requested (from mdrun)
  * \param[in]    NFILE              Size of fnm struct
  * \param[inout] fnm                Filename parameters to mdrun
@@ -90,11 +92,12 @@ struct t_filenm;
  * \param[out]   bStartFromCpt      True on return if we found the checkpoint
  *                                  and will use it to restart.
  */
-void handleRestart(t_commrec *cr,
-                   gmx_bool   bTryToAppendFiles,
-                   const int  NFILE,
-                   t_filenm   fnm[],
-                   bool      *bDoAppendFiles,
-                   bool      *bStartFromCpt);
+void handleRestart(t_commrec            *cr,
+                   const gmx_multisim_t *ms,
+                   gmx_bool              bTryToAppendFiles,
+                   const int             NFILE,
+                   t_filenm              fnm[],
+                   bool                 *bDoAppendFiles,
+                   bool                 *bStartFromCpt);
 
 #endif
index baccfbfa785013511a2456b1bbf4b78e1f3bb9bb..e3d78db24f651d409ce5b123650ec42bc2570b05 100644 (file)
@@ -172,7 +172,7 @@ class ThreadAffinityTestHelper
                 setLogicalProcessorCount(1);
             }
             int numThreadsOnThisNode, indexWithinNodeOfFirstThreadOnThisRank;
-            analyzeThreadsOnThisNode(cr_, &affinityAccess_,
+            analyzeThreadsOnThisNode(cr_, nullptr, &affinityAccess_,
                                      numThreadsOnThisRank,
                                      &numThreadsOnThisNode,
                                      &indexWithinNodeOfFirstThreadOnThisRank);
index 25ef279bec2bdf8a96c2fa41033ab68c1590ae4e..b316c4aa00e639b8c8f7b1558c2c7530b74f2fdd 100644 (file)
@@ -355,6 +355,7 @@ static bool set_affinity(const t_commrec *cr, int nthread_local, int intraNodeTh
 }
 
 void analyzeThreadsOnThisNode(const t_commrec            *cr,
+                              const gmx_multisim_t       *ms,
                               gmx::IThreadAffinityAccess *affinityAccess,
                               int                         numThreadsOnThisRank,
                               int                        *numThreadsOnThisNode,
@@ -363,7 +364,7 @@ void analyzeThreadsOnThisNode(const t_commrec            *cr,
     *intraNodeThreadOffset                  = 0;
     *numThreadsOnThisNode                   = numThreadsOnThisRank;
 #if GMX_MPI
-    if (PAR(cr) || isMultiSim(cr->ms))
+    if (PAR(cr) || isMultiSim(ms))
     {
         if (affinityAccess == nullptr)
         {
@@ -387,6 +388,7 @@ void analyzeThreadsOnThisNode(const t_commrec            *cr,
     }
 #else
     GMX_UNUSED_VALUE(cr);
+    GMX_UNUSED_VALUE(ms);
     GMX_UNUSED_VALUE(affinityAccess);
 #endif
 
index e3468958e8f658d08220c0ee3317a031ae2b4368..499aecb52e3c5b466eead7e2ecfb38f04334fd26 100644 (file)
@@ -47,6 +47,7 @@
 #include "gromacs/utility/basedefinitions.h"
 
 struct gmx_hw_opt_t;
+struct gmx_multisim_t;
 struct t_commrec;
 
 namespace gmx
@@ -74,6 +75,7 @@ class IThreadAffinityAccess
  * See gmx_set_thread_affinity(), which consumes this output.
  *
  * \param[in]  cr                     Communication handler.
+ * \param[in]  ms                     Multi-simulation handler.
  * \param[in]  affinityAccess         Interface for low-level access to affinity details.
  * \param[in]  numThreadsOnThisRank   The number of threads on this rank.
  * \param[out] numThreadsOnThisNode   On exit, the number of threads on all ranks of this node.
@@ -81,6 +83,7 @@ class IThreadAffinityAccess
  *   in the set of all the threads of all MPI ranks within a node (ordered by MPI rank ID).
  */
 void analyzeThreadsOnThisNode(const t_commrec            *cr,
+                              const gmx_multisim_t       *ms,
                               gmx::IThreadAffinityAccess *affinityAccess,
                               int                         numThreadsOnThisRank,
                               int                        *numThreadsOnThisNode,
index e40c0e8e374e31d38acb549709a5ee2971ddeeea..15fdd97fd00dad3d17d9f7e2aa3c58612ae8fece 100644 (file)
@@ -63,14 +63,17 @@ typedef struct {
     int              dbuf_alloc;
 } mpi_in_place_buf_t;
 
-struct gmx_multisim_t {
-    int       nsim;
-    int       sim;
-    MPI_Group mpi_group_masters;
-    MPI_Comm  mpi_comm_masters;
+void done_mpi_in_place_buf(mpi_in_place_buf_t *buf);
+
+struct gmx_multisim_t
+{
+    int       nsim              = 1;
+    int       sim               = 0;
+    MPI_Group mpi_group_masters = MPI_GROUP_NULL;
+    MPI_Comm  mpi_comm_masters  = MPI_COMM_NULL;
     /* these buffers are used as destination buffers if MPI_IN_PLACE isn't
        supported.*/
-    mpi_in_place_buf_t *mpb;
+    mpi_in_place_buf_t *mpb = nullptr;
 };
 
 #define DUTY_PP  (1<<0)
@@ -121,8 +124,6 @@ struct t_commrec {
      */
     int                    duty;
 
-    gmx_multisim_t        *ms;
-
     /* these buffers are used as destination buffers if MPI_IN_PLACE isn't
        supported.*/
     mpi_in_place_buf_t *mpb;
index 3d33e5e8eae65b2f32cbae47ba4bc85d247b911a..add2f55c7c3fb6c18f0ff8430e67101268313fca 100644 (file)
@@ -793,11 +793,12 @@ void check_and_update_hw_opt_2(gmx_hw_opt_t *hw_opt,
     }
 }
 
-void checkAndUpdateRequestedNumOpenmpThreads(gmx_hw_opt_t        *hw_opt,
-                                             const gmx_hw_info_t &hwinfo,
-                                             const t_commrec     *cr,
-                                             PmeRunMode           pmeRunMode,
-                                             const gmx_mtop_t    &mtop)
+void checkAndUpdateRequestedNumOpenmpThreads(gmx_hw_opt_t         *hw_opt,
+                                             const gmx_hw_info_t  &hwinfo,
+                                             const t_commrec      *cr,
+                                             const gmx_multisim_t *ms,
+                                             PmeRunMode            pmeRunMode,
+                                             const gmx_mtop_t     &mtop)
 {
 #if GMX_THREAD_MPI
     GMX_RELEASE_ASSERT(hw_opt->nthreads_tmpi >= 1, "Must have at least one thread-MPI rank");
@@ -850,7 +851,7 @@ void checkAndUpdateRequestedNumOpenmpThreads(gmx_hw_opt_t        *hw_opt,
          * all detected ncore_tot physical cores. We are currently not
          * checking for that here.
          */
-        int numRanksTot     = cr->nnodes*(isMultiSim(cr->ms) ? cr->ms->nsim : 1);
+        int numRanksTot     = cr->nnodes*(isMultiSim(ms) ? ms->nsim : 1);
         int numAtomsPerRank = mtop.natoms/cr->nnodes;
         int numCoresPerRank = hwinfo.ncore_tot/numRanksTot;
         if (numAtomsPerRank < c_numAtomsPerCoreSquaredSmtThreshold*gmx::square(numCoresPerRank))
@@ -878,6 +879,7 @@ void checkAndUpdateRequestedNumOpenmpThreads(gmx_hw_opt_t        *hw_opt,
 void checkHardwareOversubscription(int                          numThreadsOnThisRank,
                                    const gmx::HardwareTopology &hwTop,
                                    const t_commrec             *cr,
+                                   const gmx_multisim_t        *ms,
                                    const gmx::MDLogger         &mdlog)
 {
     if (hwTop.supportLevel() < gmx::HardwareTopology::SupportLevel::LogicalProcessorCount)
@@ -889,12 +891,14 @@ void checkHardwareOversubscription(int                          numThreadsOnThis
     int numRanksOnThisNode   = 1;
     int numThreadsOnThisNode = numThreadsOnThisRank;
 #if GMX_MPI
-    if (PAR(cr) || isMultiSim(cr->ms))
+    if (PAR(cr) || isMultiSim(ms))
     {
         /* Count the threads within this physical node */
         MPI_Comm_size(cr->mpi_comm_physicalnode, &numRanksOnThisNode);
         MPI_Allreduce(&numThreadsOnThisRank, &numThreadsOnThisNode, 1, MPI_INT, MPI_SUM, cr->mpi_comm_physicalnode);
     }
+#else
+    GMX_UNUSED_VALUE(ms);
 #endif
 
     if (numThreadsOnThisNode > hwTop.machine().logicalProcessorCount)
index d972c559eeb1fcb671c9de746d1b061d79086248..4bd2447d9c1af76cf3df4d3751dbd2e5839eb9df 100644 (file)
@@ -54,6 +54,7 @@
 struct gmx_hw_info_t;
 struct gmx_hw_opt_t;
 struct gmx_mtop_t;
+struct gmx_multisim_t;
 struct t_commrec;
 struct t_inputrec;
 
@@ -108,17 +109,19 @@ void check_and_update_hw_opt_2(gmx_hw_opt_t *hw_opt,
  *
  * Should be called when we know the MPI rank count and PME run mode.
  */
-void checkAndUpdateRequestedNumOpenmpThreads(gmx_hw_opt_t        *hw_opt,
-                                             const gmx_hw_info_t &hwinfo,
-                                             const t_commrec     *cr,
-                                             PmeRunMode           pmeRunMode,
-                                             const gmx_mtop_t    &mtop);
+void checkAndUpdateRequestedNumOpenmpThreads(gmx_hw_opt_t         *hw_opt,
+                                             const gmx_hw_info_t  &hwinfo,
+                                             const t_commrec      *cr,
+                                             const gmx_multisim_t *ms,
+                                             PmeRunMode            pmeRunMode,
+                                             const gmx_mtop_t     &mtop);
 
 /*! \brief Warns for oversubscribing the hardware threads, when that is the case
  */
 void checkHardwareOversubscription(int                          numThreadsOnThisRank,
                                    const gmx::HardwareTopology &hwTop,
                                    const t_commrec             *cr,
+                                   const gmx_multisim_t        *ms,
                                    const gmx::MDLogger         &mdlog);
 
 #endif
index 770ac7f5913cb6039838a02fe2a95a519e1f770a..f9862902042b317c4616030f1a39ef8867a0f1f5 100644 (file)
@@ -187,6 +187,7 @@ runTaskAssignment(const std::vector<int>     &gpuIdsToUse,
                   const gmx_hw_info_t        &hardwareInfo,
                   const MDLogger             &mdlog,
                   const t_commrec            *cr,
+                  const gmx_multisim_t       *ms,
                   const std::vector<GpuTask> &gpuTasksOnThisRank)
 {
     /* Communicate among ranks on this node to find each task that can
@@ -294,10 +295,10 @@ runTaskAssignment(const std::vector<int>     &gpuIdsToUse,
             MPI_Barrier(cr->mpi_comm_mysim);
 #endif
         }
-        if (isMultiSim(cr->ms))
+        if (isMultiSim(ms))
         {
 #if GMX_MPI
-            MPI_Barrier(cr->ms->mpi_comm_masters);
+            MPI_Barrier(ms->mpi_comm_masters);
 #endif
         }
 
index 62123e082405d0935ecf228398de2552584a02c2..53936362c1b3f907ccdbed4f6733b4e7b2fe36ba 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2017, by the GROMACS development team, led by
+ * Copyright (c) 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.
@@ -53,6 +53,7 @@
 #include <vector>
 
 struct gmx_hw_info_t;
+struct gmx_multisim_t;
 struct t_commrec;
 
 namespace gmx
@@ -102,6 +103,7 @@ using GpuTaskAssignments = std::vector<GpuTaskAssignment>;
  * \param[in]  hardwareInfo               The detected hardware
  * \param[in]  mdlog                      Logging object to write to.
  * \param[in]  cr                         Communication object.
+ * \param[in]  ms                         Handles multi-simulations.
  * \param[in]  gpuTasksOnThisRank         Information about what GPU tasks
  *                                        exist on this rank.
  *
@@ -116,6 +118,7 @@ runTaskAssignment(const std::vector<int>     &gpuIdsToUse,
                   const gmx_hw_info_t        &hardwareInfo,
                   const MDLogger             &mdlog,
                   const t_commrec            *cr,
+                  const gmx_multisim_t       *ms,
                   const std::vector<GpuTask> &gpuTasksOnThisRank);
 
 //! Function for whether the task of \c mapping has value \c TaskType.
index 8897aecff3d533ca66de4943cd160977c2121d28..bf22d4c66f0fc6e6a6cb72baf27bdf183dab667e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2013,2014,2016,2017, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,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.
@@ -83,6 +83,8 @@ typedef void* MPI_Request;
 typedef void* MPI_Status;
 typedef void* MPI_Group;
 #define MPI_COMM_NULL NULL
+#define MPI_GROUP_NULL NULL
+#define MPI_COMM_WORLD NULL
 #endif
 #endif
 //! \endcond
index add69850754014f5fb7cbdf0a4742eba54bed71c..d302c1f425b37a62b3eb352e2802eb867e46dedb 100644 (file)
@@ -280,7 +280,9 @@ static void prepareRerunState(const t_trxframe  &rerunFrame,
 }
 
 /*! \libinternal
-    \copydoc integrator_t (FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
+    \copydoc integrator_t (FILE *fplog, t_commrec *cr,
+                           const gmx_multisim_t *ms,
+                           const gmx::MDLogger &mdlog,
                            int nfile, const t_filenm fnm[],
                            const gmx_output_env_t *oenv,
                            const MdrunOptions &mdrunOptions,
@@ -296,7 +298,9 @@ static void prepareRerunState(const t_trxframe  &rerunFrame,
                            gmx_membed_t *membed,
                            gmx_walltime_accounting_t walltime_accounting)
  */
-double gmx::do_md(FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
+double gmx::do_md(FILE *fplog, t_commrec *cr,
+                  const gmx_multisim_t *ms,
+                  const gmx::MDLogger &mdlog,
                   int nfile, const t_filenm fnm[],
                   const gmx_output_env_t *oenv,
                   const MdrunOptions &mdrunOptions,
@@ -389,7 +393,7 @@ double gmx::do_md(FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
     SimulationSignals signals;
     // Most global communnication stages don't propagate mdrun
     // signals, and will use this object to achieve that.
-    SimulationSignaller nullSignaller(nullptr, nullptr, false, false);
+    SimulationSignaller nullSignaller(nullptr, nullptr, nullptr, false, false);
 
     if (!mdrunOptions.writeConfout)
     {
@@ -549,7 +553,8 @@ double gmx::do_md(FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
     }
 
     /* Set up interactive MD (IMD) */
-    init_IMD(ir, cr, top_global, fplog, ir->nstcalcenergy, MASTER(cr) ? as_rvec_array(state_global->x.data()) : nullptr,
+    init_IMD(ir, cr, ms, top_global, fplog, ir->nstcalcenergy,
+             MASTER(cr) ? as_rvec_array(state_global->x.data()) : nullptr,
              nfile, fnm, oenv, mdrunOptions);
 
     if (DOMAINDECOMP(cr))
@@ -616,7 +621,7 @@ double gmx::do_md(FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
     /* Initialize AWH and restore state from history in checkpoint if needed. */
     if (ir->bDoAwh)
     {
-        ir->awh = new gmx::Awh(fplog, *ir, cr, *ir->awhParams, opt2fn("-awh", nfile, fnm), ir->pull_work);
+        ir->awh = new gmx::Awh(fplog, *ir, cr, ms, *ir->awhParams, opt2fn("-awh", nfile, fnm), ir->pull_work);
 
         if (startingFromCheckpoint)
         {
@@ -633,7 +638,7 @@ double gmx::do_md(FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
     const bool useReplicaExchange = (replExParams.exchangeInterval > 0);
     if (useReplicaExchange && MASTER(cr))
     {
-        repl_ex = init_replica_exchange(fplog, cr->ms, top_global->natoms, ir,
+        repl_ex = init_replica_exchange(fplog, ms, top_global->natoms, ir,
                                         replExParams);
     }
 
@@ -678,7 +683,7 @@ double gmx::do_md(FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
         {
             /* Constrain the initial coordinates and velocities */
             do_constrain_first(fplog, constr, ir, mdatoms, state,
-                               cr, nrnb, fr, top);
+                               cr, ms, nrnb, fr, top);
         }
         if (vsite)
         {
@@ -916,7 +921,7 @@ double gmx::do_md(FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
     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) || (cr->ms && fcd->orires.nr);
+    bUsingEnsembleRestraints = (fcd->disres.nsystems > 1) || (ms && fcd->orires.nr);
 
     {
         // Replica exchange and ensemble restraints need all
@@ -939,15 +944,15 @@ double gmx::do_md(FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
     step_rel = 0;
 
     // TODO extract this to new multi-simulation module
-    if (MASTER(cr) && isMultiSim(cr->ms) && !useReplicaExchange)
+    if (MASTER(cr) && isMultiSim(ms) && !useReplicaExchange)
     {
-        if (!multisim_int_all_are_equal(cr->ms, ir->nsteps))
+        if (!multisim_int_all_are_equal(ms, ir->nsteps))
         {
             GMX_LOG(mdlog.warning).appendText(
                     "Note: The number of steps is not consistent across multi simulations,\n"
                     "but we are proceeding anyway!");
         }
-        if (!multisim_int_all_are_equal(cr->ms, ir->init_step))
+        if (!multisim_int_all_are_equal(ms, ir->init_step))
         {
             GMX_LOG(mdlog.warning).appendText(
                     "Note: The initial step is not consistent across multi simulations,\n"
@@ -1195,7 +1200,7 @@ double gmx::do_md(FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
         if (shellfc)
         {
             /* Now is the time to relax the shells */
-            relax_shell_flexcon(fplog, cr, mdrunOptions.verbose, step,
+            relax_shell_flexcon(fplog, cr, ms, mdrunOptions.verbose, step,
                                 ir, bNS, force_flags, top,
                                 constr, enerd, fcd,
                                 state, &f, force_vir, mdatoms,
@@ -1224,7 +1229,7 @@ double gmx::do_md(FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
              * This is parallellized as well, and does communication too.
              * Check comments in sim_util.c
              */
-            do_force(fplog, cr, ir, step, nrnb, wcycle, top, groups,
+            do_force(fplog, cr, ms, ir, step, nrnb, wcycle, top, groups,
                      state->box, state->x, &state->hist,
                      f, force_vir, mdatoms, enerd, fcd,
                      state->lambda, graph,
@@ -1266,7 +1271,7 @@ double gmx::do_md(FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
                 update_constraints(fplog, step, nullptr, ir, mdatoms,
                                    state, fr->bMolPBC, graph, f,
                                    &top->idef, shake_vir,
-                                   cr, nrnb, wcycle, upd, constr,
+                                   cr, ms, nrnb, wcycle, upd, constr,
                                    TRUE, bCalcVir);
                 wallcycle_start(wcycle, ewcUPDATE);
             }
@@ -1521,7 +1526,7 @@ double gmx::do_md(FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
                 update_constraints(fplog, step, nullptr, ir, mdatoms,
                                    state, fr->bMolPBC, graph, f,
                                    &top->idef, tmp_vir,
-                                   cr, nrnb, wcycle, upd, constr,
+                                   cr, ms, nrnb, wcycle, upd, constr,
                                    TRUE, bCalcVir);
             }
         }
@@ -1586,7 +1591,7 @@ double gmx::do_md(FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
             update_constraints(fplog, step, &dvdl_constr, ir, mdatoms, state,
                                fr->bMolPBC, graph, f,
                                &top->idef, shake_vir,
-                               cr, nrnb, wcycle, upd, constr,
+                               cr, ms, nrnb, wcycle, upd, constr,
                                FALSE, bCalcVir);
 
             if (ir->eI == eiVVAK)
@@ -1616,7 +1621,7 @@ double gmx::do_md(FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
                 update_constraints(fplog, step, nullptr, ir, mdatoms,
                                    state, fr->bMolPBC, graph, f,
                                    &top->idef, tmp_vir,
-                                   cr, nrnb, wcycle, upd, nullptr,
+                                   cr, ms, nrnb, wcycle, upd, nullptr,
                                    FALSE, bCalcVir);
             }
             if (EI_VV(ir->eI))
@@ -1686,7 +1691,7 @@ double gmx::do_md(FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
                 // situation where e.g. checkpointing can't be
                 // signalled.
                 bool                doIntraSimSignal = true;
-                SimulationSignaller signaller(&signals, cr, doInterSimSignal, doIntraSimSignal);
+                SimulationSignaller signaller(&signals, cr, ms, doInterSimSignal, doIntraSimSignal);
 
                 compute_globals(fplog, gstat, cr, ir, fr, ekind, state, mdatoms, nrnb, vcm,
                                 wcycle, enerd, force_vir, shake_vir, total_vir, pres, mu_tot,
@@ -1812,7 +1817,7 @@ double gmx::do_md(FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
             state->fep_state = lamnew;
         }
         /* Print the remaining wall clock time for the run */
-        if (isMasterSimMasterRank(cr->ms, cr) &&
+        if (isMasterSimMasterRank(ms, cr) &&
             (do_verbose || gmx_got_usr_signal()) &&
             !bPMETunePrinting)
         {
@@ -1846,7 +1851,7 @@ double gmx::do_md(FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
         bExchanged = FALSE;
         if (bDoReplEx)
         {
-            bExchanged = replica_exchange(fplog, cr, repl_ex,
+            bExchanged = replica_exchange(fplog, cr, ms, repl_ex,
                                           state_global, enerd,
                                           state, step, t);
         }
index 608c5001b1d2e27dae47fe37d9f405eb830043a8..7f86acafbbdeebcd77088ebf15a86cbfdb0d46fe 100644 (file)
@@ -52,6 +52,8 @@
  */
 #include "gmxpre.h"
 
+#include "config.h"
+
 #include <cstdio>
 #include <cstdlib>
 #include <cstring>
@@ -430,7 +432,7 @@ int Mdrunner::mainFunction(int argc, char *argv[])
     hw_opt.thread_affinity = nenum(thread_aff_opt_choices);
 
     // now check for a multi-simulation
-    int nmultisim = 0;
+    int nmultisim = 1;
     if (opt2bSet("-multidir", nfile, fnm))
     {
         nmultisim = opt2fns(&multidir, "-multidir", nfile, fnm);
@@ -447,7 +449,21 @@ int Mdrunner::mainFunction(int argc, char *argv[])
         gmx_fatal(FARGS, "Replica exchange number of exchanges needs to be positive");
     }
 
-    init_multisystem(cr, nmultisim, multidir);
+    ms = init_multisystem(MPI_COMM_WORLD, nmultisim, multidir);
+
+    /* Prepare the intra-simulation communication */
+    // TODO consolidate this with init_commrec, after changing the
+    // relative ordering of init_commrec and init_multisystem
+#if GMX_MPI
+    if (ms != nullptr)
+    {
+        cr->nnodes = cr->nnodes / nmultisim;
+        MPI_Comm_split(MPI_COMM_WORLD, ms->sim, cr->sim_nodeid, &cr->mpi_comm_mysim);
+        cr->mpi_comm_mygroup = cr->mpi_comm_mysim;
+        MPI_Comm_rank(cr->mpi_comm_mysim, &cr->sim_nodeid);
+        MPI_Comm_rank(cr->mpi_comm_mygroup, &cr->nodeid);
+    }
+#endif
 
     if (!opt2bSet("-cpi", nfile, fnm))
     {
@@ -469,7 +485,7 @@ int Mdrunner::mainFunction(int argc, char *argv[])
 
     continuationOptions.appendFilesOptionSet = opt2parg_bSet("-append", asize(pa), pa);
 
-    handleRestart(cr, bTryToAppendFiles, nfile, fnm, &continuationOptions.appendFiles, &continuationOptions.startedFromCheckpoint);
+    handleRestart(cr, ms, bTryToAppendFiles, nfile, fnm, &continuationOptions.appendFiles, &continuationOptions.startedFromCheckpoint);
 
     mdrunOptions.rerun            = opt2bSet("-rerun", nfile, fnm);
     mdrunOptions.ntompOptionIsSet = opt2parg_bSet("-ntomp", asize(pa), pa);
@@ -502,11 +518,16 @@ int Mdrunner::mainFunction(int argc, char *argv[])
 
     /* Log file has to be closed in mdrunner if we are appending to it
        (fplog not set here) */
-    if (MASTER(cr) && !continuationOptions.appendFiles)
+    if (fplog != nullptr)
     {
         gmx_log_close(fplog);
     }
 
+    if (GMX_LIB_MPI)
+    {
+        done_commrec(cr);
+    }
+    done_multisim(ms);
     return rc;
 }
 
index a1a815b70438d8b81082107a34292b7482f122f5..87dfdb600ad559517aed99a4cce103cea36800bd 100644 (file)
@@ -173,7 +173,7 @@ init_replica_exchange(FILE                            *fplog,
     {
         gmx_fatal(FARGS, "Replica exchange is only supported by dynamical simulations");
         /* Note that PAR(cr) is defined by cr->nnodes > 1, which is
-         * distinct from isMultiSim(cr->ms). A multi-simulation only runs
+         * distinct from isMultiSim(ms). A multi-simulation only runs
          * with real MPI parallelism, but this does not imply PAR(cr)
          * is true!
          *
@@ -1212,7 +1212,8 @@ prepare_to_do_exchange(struct gmx_repl_ex *re,
     }
 }
 
-gmx_bool replica_exchange(FILE *fplog, const t_commrec *cr, struct gmx_repl_ex *re,
+gmx_bool replica_exchange(FILE *fplog, const t_commrec *cr,
+                          const gmx_multisim_t *ms, struct gmx_repl_ex *re,
                           t_state *state, const gmx_enerdata_t *enerd,
                           t_state *state_local, gmx_int64_t step, real time)
 {
@@ -1229,7 +1230,7 @@ gmx_bool replica_exchange(FILE *fplog, const t_commrec *cr, struct gmx_repl_ex *
     if (MASTER(cr))
     {
         replica_id  = re->repl;
-        test_for_replica_exchange(fplog, cr->ms, re, enerd, det(state_local->box), step, time);
+        test_for_replica_exchange(fplog, ms, re, enerd, det(state_local->box), step, time);
         prepare_to_do_exchange(re, replica_id, &maxswap, &bThisReplicaExchanged);
     }
     /* Do intra-simulation broadcast so all processors belonging to
@@ -1274,7 +1275,7 @@ gmx_bool replica_exchange(FILE *fplog, const t_commrec *cr, struct gmx_repl_ex *
                     {
                         fprintf(debug, "Exchanging %d with %d\n", replica_id, exchange_partner);
                     }
-                    exchange_state(cr->ms, exchange_partner, state);
+                    exchange_state(ms, exchange_partner, state);
                 }
             }
             /* For temperature-type replica exchange, we need to scale
index 30c75258cb94373e4a08dba8f16cda339060e599..81e6de3ad3f53484476486158932f1f5c27fc9d7 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2011,2012,2013,2014,2015,2017, by the GROMACS development team, led by
+ * Copyright (c) 2011,2012,2013,2014,2015,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.
@@ -77,6 +77,7 @@ init_replica_exchange(FILE                            *fplog,
 
 gmx_bool replica_exchange(FILE *fplog,
                           const t_commrec *cr,
+                          const gmx_multisim_t *ms,
                           gmx_repl_ex_t re,
                           t_state *state, const gmx_enerdata_t *enerd,
                           t_state *state_local,
index efd4f9f3d7f1fa09a2c8f6f9840c39e840370c5c..2ad74e10be2e663094ba8ce2fd3a5fa6e16831db 100644 (file)
@@ -150,7 +150,7 @@ void Mdrunner::reinitializeOnSpawnedThread()
     // Mdrunner.
     fnm = dup_tfn(nfile, fnm);
 
-    cr  = reinitialize_commrec_for_this_thread(cr);
+    cr  = reinitialize_commrec_for_this_thread(cr, ms);
 
     if (!MASTER(cr))
     {
@@ -217,7 +217,7 @@ t_commrec *Mdrunner::spawnThreads(int numThreadsToLaunch)
     GMX_UNUSED_VALUE(mdrunner_start_fn);
 #endif
 
-    return reinitialize_commrec_for_this_thread(cr);
+    return reinitialize_commrec_for_this_thread(cr, ms);
 }
 
 }      // namespace
@@ -498,7 +498,7 @@ int Mdrunner::mdrunner()
 
     hwinfo = gmx_detect_hardware(mdlog);
 
-    gmx_print_detected_hardware(fplog, cr, mdlog, hwinfo);
+    gmx_print_detected_hardware(fplog, cr, ms, mdlog, hwinfo);
 
     std::vector<int> gpuIdsToUse;
     auto             compatibleGpus = getCompatibleGpus(hwinfo->gpu_info);
@@ -790,9 +790,9 @@ int Mdrunner::mdrunner()
     snew(fcd, 1);
 
     /* This needs to be called before read_checkpoint to extend the state */
-    init_disres(fplog, mtop, inputrec, cr, fcd, globalState.get(), replExParams.exchangeInterval > 0);
+    init_disres(fplog, mtop, inputrec, cr, ms, fcd, globalState.get(), replExParams.exchangeInterval > 0);
 
-    init_orires(fplog, mtop, inputrec, cr, globalState.get(), &(fcd->orires));
+    init_orires(fplog, mtop, inputrec, cr, ms, globalState.get(), &(fcd->orires));
 
     if (inputrecDeform(inputrec))
     {
@@ -914,12 +914,12 @@ int Mdrunner::mdrunner()
     /* Initialize per-physical-node MPI process/thread ID and counters. */
     gmx_init_intranode_counters(cr);
 #if GMX_MPI
-    if (isMultiSim(cr->ms))
+    if (isMultiSim(ms))
     {
         GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted(
                 "This is simulation %d out of %d running as a composite GROMACS\n"
                 "multi-simulation job. Setup for this simulation:\n",
-                cr->ms->sim, cr->ms->nsim);
+                ms->sim, ms->nsim);
     }
     GMX_LOG(mdlog.warning).appendTextFormatted(
             "Using %d MPI %s\n",
@@ -937,7 +937,7 @@ int Mdrunner::mdrunner()
     check_and_update_hw_opt_2(&hw_opt, inputrec->cutoff_scheme);
 
     /* Check and update the number of OpenMP threads requested */
-    checkAndUpdateRequestedNumOpenmpThreads(&hw_opt, *hwinfo, cr, pmeRunMode, *mtop);
+    checkAndUpdateRequestedNumOpenmpThreads(&hw_opt, *hwinfo, cr, ms, pmeRunMode, *mtop);
 
     gmx_omp_nthreads_init(mdlog, cr,
                           hwinfo->nthreads_hw_avail,
@@ -1017,7 +1017,7 @@ int Mdrunner::mdrunner()
     {
         // Produce the task assignment for this rank.
         gpuTaskAssignment = runTaskAssignment(gpuIdsToUse, userGpuTaskAssignment, *hwinfo,
-                                              mdlog, cr, gpuTasksOnThisRank);
+                                              mdlog, cr, ms, gpuTasksOnThisRank);
     }
     GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
 
@@ -1034,9 +1034,9 @@ int Mdrunner::mdrunner()
     {
         MPI_Barrier(cr->mpi_comm_mysim);
     }
-    if (isMultiSim(cr->ms))
+    if (isMultiSim(ms))
     {
-        MPI_Barrier(cr->ms->mpi_comm_masters);
+        MPI_Barrier(ms->mpi_comm_masters);
     }
 #endif
 
@@ -1094,7 +1094,7 @@ int Mdrunner::mdrunner()
 
     checkHardwareOversubscription(numThreadsOnThisRank,
                                   *hwinfo->hardwareTopology,
-                                  cr, mdlog);
+                                  cr, ms, mdlog);
 
     if (hw_opt.thread_affinity != threadaffOFF)
     {
@@ -1106,7 +1106,7 @@ int Mdrunner::mdrunner()
                                       &hw_opt, hwinfo->nthreads_hw_avail, TRUE);
 
         int numThreadsOnThisNode, intraNodeThreadOffset;
-        analyzeThreadsOnThisNode(cr, nullptr, numThreadsOnThisRank, &numThreadsOnThisNode,
+        analyzeThreadsOnThisNode(cr, ms, nullptr, numThreadsOnThisRank, &numThreadsOnThisNode,
                                  &intraNodeThreadOffset);
 
         /* Set the CPU affinity */
@@ -1320,7 +1320,7 @@ int Mdrunner::mdrunner()
         }
 
         /* Now do whatever the user wants us to do (how flexible...) */
-        my_integrator(inputrec->eI) (fplog, cr, mdlog, nfile, fnm,
+        my_integrator(inputrec->eI) (fplog, cr, ms, mdlog, nfile, fnm,
                                      oenv,
                                      mdrunOptions,
                                      vsite, constr,
@@ -1362,7 +1362,7 @@ int Mdrunner::mdrunner()
                inputrec, nrnb, wcycle, walltime_accounting,
                fr ? fr->nbv : nullptr,
                pmedata,
-               EI_DYNAMICS(inputrec->eI) && !isMultiSim(cr->ms));
+               EI_DYNAMICS(inputrec->eI) && !isMultiSim(ms));
 
     // Free PME data
     if (pmedata)
@@ -1380,7 +1380,7 @@ int Mdrunner::mdrunner()
     mdModules.reset(nullptr);   // destruct force providers here as they might also use the GPU
 
     /* Free GPU memory and set a physical node tMPI barrier (which should eventually go away) */
-    free_gpu_resources(fr, cr);
+    free_gpu_resources(fr, cr, ms);
     free_gpu(nonbondedDeviceInfo);
     free_gpu(pmeDeviceInfo);
 
@@ -1399,6 +1399,7 @@ int Mdrunner::mdrunner()
     if (MASTER(cr) && continuationOptions.appendFiles)
     {
         gmx_log_close(fplog);
+        fplog = nullptr;
     }
 
     rc = (int)gmx_get_stop_condition();
@@ -1409,6 +1410,7 @@ int Mdrunner::mdrunner()
        wait for that. */
     if (PAR(cr) && MASTER(cr))
     {
+        done_commrec(cr);
         tMPI_Finalize();
     }
 #endif
index a95c36863e8499cfccd77cc97483cf7f87f042ff..6778e89b781e806d58bc7884c2bc815c663b6267 100644 (file)
@@ -154,6 +154,8 @@ class Mdrunner
         FILE                            *fplog;
         //! Handle to communication data structure.
         t_commrec                       *cr;
+        //! Handle to multi-simulation handler.
+        gmx_multisim_t                  *ms;
 
     public:
         /*! \brief Defaulted constructor.