Move mdrun signalling code
authorMark Abraham <mark.j.abraham@gmail.com>
Tue, 25 Nov 2014 20:23:37 +0000 (21:23 +0100)
committerMark Abraham <mark.j.abraham@gmail.com>
Tue, 3 Mar 2015 12:07:58 +0000 (13:07 +0100)
No functionality changes here, I just put some related functionality
into functions in their own source file to
* simplify later removing inter-simulation signalling, and
* prepare for further encapsulation later.

Updated struct name and usage for new style. Updated include guards.
Removed now-useless C++-compilation guard from header file. Added
basic Doxygen.

Change-Id: I3ea1e2f77a1cdb6608bba38f08a430cc3b8d7c9a

src/gromacs/legacyheaders/md_support.h
src/gromacs/legacyheaders/mdrun.h
src/gromacs/legacyheaders/types/globsig.h [deleted file]
src/gromacs/mdlib/md_support.cpp
src/gromacs/mdlib/mdrun_signalling.cpp [new file with mode: 0644]
src/gromacs/mdlib/mdrun_signalling.h [new file with mode: 0644]
src/programs/mdrun/md.cpp

index eb7cc5907c5a98ae6dd2fde711660a11ffe50102..8653d08597e014ced7c7113a8a9971e21f8e0258 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, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, 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.
 #include "gromacs/legacyheaders/sim_util.h"
 #include "gromacs/legacyheaders/typedefs.h"
 #include "gromacs/legacyheaders/vcm.h"
-#include "gromacs/legacyheaders/types/globsig.h"
 #include "gromacs/timing/wallcycle.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+struct gmx_signalling_t;
+
 /* Define a number of flags to better control the information
  * passed to compute_globals in md.c and global_stat.
  */
@@ -107,10 +108,6 @@ int multisim_nstsimsync(const t_commrec *cr,
                         const t_inputrec *ir, int repl_ex_nst);
 /* Determine the interval for inter-simulation communication */
 
-void init_global_signals(globsig_t *gs, const t_commrec *cr,
-                         const t_inputrec *ir, int repl_ex_nst);
-/* Constructor for globsig_t */
-
 void copy_coupling_state(t_state *statea, t_state *stateb,
                          gmx_ekindata_t *ekinda, gmx_ekindata_t *ekindb, t_grpopts* opts);
 /* Copy stuff from state A to state B */
@@ -121,7 +118,7 @@ void compute_globals(FILE *fplog, gmx_global_stat_t gstat, t_commrec *cr, t_inpu
                      t_nrnb *nrnb, t_vcm *vcm, gmx_wallcycle_t wcycle,
                      gmx_enerdata_t *enerd, tensor force_vir, tensor shake_vir, tensor total_vir,
                      tensor pres, rvec mu_tot, gmx_constr_t constr,
-                     globsig_t *gs, gmx_bool bInterSimGS,
+                     struct gmx_signalling_t *gs, gmx_bool bInterSimGS,
                      matrix box, gmx_mtop_t *top_global, gmx_bool *bSumEkinhOld, int flags);
 /* Compute global variables during integration */
 
index 473a5af2fb3da20cbad2fe77f49b40de7026a870..86e9b116f349c350006a91559260c127e760c6cf 100644 (file)
@@ -50,7 +50,6 @@
 #include "gromacs/legacyheaders/update.h"
 #include "gromacs/legacyheaders/vcm.h"
 #include "gromacs/legacyheaders/vsite.h"
-#include "gromacs/legacyheaders/types/globsig.h"
 #include "gromacs/legacyheaders/types/membedt.h"
 #include "gromacs/timing/wallcycle.h"
 
diff --git a/src/gromacs/legacyheaders/types/globsig.h b/src/gromacs/legacyheaders/types/globsig.h
deleted file mode 100644 (file)
index 2c515ec..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2011,2014, 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.
- *
- * GROMACS is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * GROMACS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with GROMACS; if not, see
- * http://www.gnu.org/licenses, or write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
- *
- * If you want to redistribute modifications to GROMACS, please
- * consider that scientific software is very special. Version
- * control is crucial - bugs must be traceable. We will be happy to
- * consider code for inclusion in the official distribution, but
- * derived work must not be called official GROMACS. Details are found
- * in the README & COPYING files - if they are missing, get the
- * official version at http://www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org.
- */
-#ifndef _globsig_h
-#define _globsig_h
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if 0
-}
-/* Hack to make automatic indenting work */
-#endif
-
-/* simulation conditions to transmit. Keep in mind that they are
-   transmitted to other nodes through an MPI_Reduce after
-   casting them to a real (so the signals can be sent together with other
-   data). This means that the only meaningful values are positive,
-   negative or zero. */
-enum {
-    eglsCHKPT, eglsSTOPCOND, eglsRESETCOUNTERS, eglsNR
-};
-
-typedef struct {
-    int nstms;       /* The frequency for intersimulation communication */
-    int sig[eglsNR]; /* The signal set by one process in do_md */
-    int set[eglsNR]; /* The communicated signal, equal for all processes */
-} globsig_t;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
index 00bce0b9b330c9565a84c9cd5ee688dd2758e8dc..713d3a732284f90b257c75b052038f19f9c3bc94 100644 (file)
 #include "gromacs/legacyheaders/vcm.h"
 #include "gromacs/legacyheaders/types/commrec.h"
 #include "gromacs/math/vec.h"
+#include "gromacs/mdlib/mdrun_signalling.h"
 #include "gromacs/timing/wallcycle.h"
 #include "gromacs/topology/mtop_util.h"
+#include "gromacs/utility/arrayref.h"
 #include "gromacs/utility/cstringutil.h"
 #include "gromacs/utility/smalloc.h"
 #include "gromacs/utility/snprintf.h"
 
-/* Is the signal in one simulation independent of other simulations? */
-gmx_bool gs_simlocal[eglsNR] = { FALSE, FALSE, TRUE };
-
 /* check which of the multisim simulations has the shortest number of
    steps and return that number of nsteps */
 gmx_int64_t get_multisim_nsteps(const t_commrec *cr,
@@ -174,31 +173,6 @@ int multisim_nstsimsync(const t_commrec *cr,
     return nmin;
 }
 
-void init_global_signals(globsig_t *gs, const t_commrec *cr,
-                         const t_inputrec *ir, int repl_ex_nst)
-{
-    int i;
-
-    if (MULTISIM(cr))
-    {
-        gs->nstms = multisim_nstsimsync(cr, ir, repl_ex_nst);
-        if (debug)
-        {
-            fprintf(debug, "Syncing simulations for checkpointing and termination every %d steps\n", gs->nstms);
-        }
-    }
-    else
-    {
-        gs->nstms = 1;
-    }
-
-    for (i = 0; i < eglsNR; i++)
-    {
-        gs->sig[i] = 0;
-        gs->set[i] = 0;
-    }
-}
-
 void copy_coupling_state(t_state *statea, t_state *stateb,
                          gmx_ekindata_t *ekinda, gmx_ekindata_t *ekindb, t_grpopts* opts)
 {
@@ -289,12 +263,10 @@ void compute_globals(FILE *fplog, gmx_global_stat_t gstat, t_commrec *cr, t_inpu
                      t_nrnb *nrnb, t_vcm *vcm, gmx_wallcycle_t wcycle,
                      gmx_enerdata_t *enerd, tensor force_vir, tensor shake_vir, tensor total_vir,
                      tensor pres, rvec mu_tot, gmx_constr_t constr,
-                     globsig_t *gs, gmx_bool bInterSimGS,
+                     struct gmx_signalling_t *gs, gmx_bool bInterSimGS,
                      matrix box, gmx_mtop_t *top_global,
                      gmx_bool *bSumEkinhOld, int flags)
 {
-    int      i, gsi;
-    real     gs_buf[eglsNR];
     tensor   corr_vir, corr_pres;
     gmx_bool bEner, bPres, bTemp;
     gmx_bool bStopCM, bGStat,
@@ -363,54 +335,18 @@ void compute_globals(FILE *fplog, gmx_global_stat_t gstat, t_commrec *cr, t_inpu
         }
         else
         {
-            if (gs != NULL)
-            {
-                for (i = 0; i < eglsNR; i++)
-                {
-                    gs_buf[i] = gs->sig[i];
-                }
-            }
+            gmx::ArrayRef<real> signalBuffer = prepareSignalBuffer(gs);
             if (PAR(cr))
             {
                 wallcycle_start(wcycle, ewcMoveE);
                 global_stat(fplog, gstat, cr, enerd, force_vir, shake_vir, mu_tot,
                             ir, ekind, constr, bStopCM ? vcm : NULL,
-                            gs != NULL ? eglsNR : 0, gs_buf,
+                            signalBuffer.size(), signalBuffer.data(),
                             top_global, state,
                             *bSumEkinhOld, flags);
                 wallcycle_stop(wcycle, ewcMoveE);
             }
-            if (gs != NULL)
-            {
-                if (MULTISIM(cr) && bInterSimGS)
-                {
-                    if (MASTER(cr))
-                    {
-                        /* Communicate the signals between the simulations */
-                        gmx_sum_sim(eglsNR, gs_buf, cr->ms);
-                    }
-                    /* Communicate the signals form the master to the others */
-                    gmx_bcast(eglsNR*sizeof(gs_buf[0]), gs_buf, cr);
-                }
-                for (i = 0; i < eglsNR; i++)
-                {
-                    if (bInterSimGS || gs_simlocal[i])
-                    {
-                        /* Set the communicated signal only when it is non-zero,
-                         * since signals might not be processed at each MD step.
-                         */
-                        gsi = (gs_buf[i] >= 0 ?
-                               (int)(gs_buf[i] + 0.5) :
-                               (int)(gs_buf[i] - 0.5));
-                        if (gsi != 0)
-                        {
-                            gs->set[i] = gsi;
-                        }
-                        /* Turn off the local signal */
-                        gs->sig[i] = 0;
-                    }
-                }
-            }
+            handleSignals(gs, cr, bInterSimGS);
             *bSumEkinhOld = FALSE;
         }
     }
diff --git a/src/gromacs/mdlib/mdrun_signalling.cpp b/src/gromacs/mdlib/mdrun_signalling.cpp
new file mode 100644 (file)
index 0000000..c76c4f7
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2004, The GROMACS development team.
+ * Copyright (c) 2013,2014,2015, 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.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \internal \file
+ *
+ * \brief This file defines functions for inter-rank signalling by mdrun.
+ *
+ * This handles details of responding to termination conditions,
+ * coordinating checkpoints, and coordinating multi-simulations.
+ *
+ * \author Berk Hess <hess@kth.se>
+ * \author Mark Abraham <mark.j.abraham@gmail.com>
+ * \ingroup module_mdlib
+ */
+
+#include "gmxpre.h"
+
+#include "mdrun_signalling.h"
+
+#include <algorithm>
+
+#include "gromacs/legacyheaders/md_support.h"
+#include "gromacs/legacyheaders/types/commrec.h"
+#include "gromacs/legacyheaders/types/inputrec.h"
+#include "gromacs/utility/arrayref.h"
+#include "gromacs/utility/real.h"
+
+void init_global_signals(struct gmx_signalling_t *gs, const t_commrec *cr,
+                         const t_inputrec *ir, int repl_ex_nst)
+{
+    int i;
+
+    if (MULTISIM(cr))
+    {
+        gs->nstms = multisim_nstsimsync(cr, ir, repl_ex_nst);
+        if (debug)
+        {
+            fprintf(debug, "Syncing simulations for checkpointing and termination every %d steps\n", gs->nstms);
+        }
+    }
+    else
+    {
+        gs->nstms = 1;
+    }
+
+    for (i = 0; i < eglsNR; i++)
+    {
+        gs->sig[i] = 0;
+        gs->set[i] = 0;
+    }
+}
+
+gmx::ArrayRef<real>
+prepareSignalBuffer(struct gmx_signalling_t *gs)
+{
+    if (gs)
+    {
+        gmx::ArrayRef<int>  signal(gs->sig);
+        gmx::ArrayRef<real> temp(gs->mpiBuffer);
+
+        std::copy(signal.begin(), signal.end(), temp.begin());
+        return temp;
+    }
+    else
+    {
+        return gmx::EmptyArrayRef();
+    }
+}
+
+void
+handleSignals(struct gmx_signalling_t  *gs,
+              const t_commrec          *cr,
+              bool                      bInterSimGS)
+{
+    /* Is the signal in one simulation independent of other simulations? */
+    bool bIsSignalLocal[eglsNR] = { false, false, true };
+
+    if (!gs)
+    {
+        return;
+    }
+
+    if (MULTISIM(cr) && bInterSimGS)
+    {
+        if (MASTER(cr))
+        {
+            /* Communicate the signals between the simulations */
+            gmx_sum_sim(eglsNR, gs->mpiBuffer, cr->ms);
+        }
+        /* Communicate the signals from the master to the others */
+        gmx_bcast(eglsNR*sizeof(gs->mpiBuffer), gs->mpiBuffer, cr);
+    }
+    for (int i = 0; i < eglsNR; i++)
+    {
+        if (bInterSimGS || bIsSignalLocal[i])
+        {
+            /* Set the communicated signal only when it is non-zero,
+             * since signals might not be processed at each MD step.
+             */
+            int gsi = (gs->mpiBuffer[i] >= 0.0 ?
+                       (int)(gs->mpiBuffer[i] + 0.5) :
+                       (int)(gs->mpiBuffer[i] - 0.5));
+            if (gsi != 0)
+            {
+                gs->set[i] = gsi;
+            }
+            /* Turn off the local signal */
+            gs->sig[i] = 0;
+        }
+    }
+}
diff --git a/src/gromacs/mdlib/mdrun_signalling.h b/src/gromacs/mdlib/mdrun_signalling.h
new file mode 100644 (file)
index 0000000..2fdde5d
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2004, The GROMACS development team.
+ * Copyright (c) 2011,2014,2015, 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.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \libinternal \file
+ *
+ * \brief This file declares functions for inter-rank signalling by mdrun
+ *
+ * This handles details of responding to termination conditions,
+ * coordinating checkpoints, and coordinating multi-simulations.
+ *
+ * \author Berk Hess <hess@kth.se>
+ * \author Mark Abraham <mark.j.abraham@gmail.com>
+ * \inlibraryapi
+ * \ingroup module_mdlib
+ */
+#ifndef GMX_MDLIB_MDRUN_SIGNALLING_H
+#define GMX_MDLIB_MDRUN_SIGNALLING_H
+
+#include "gromacs/legacyheaders/types/inputrec.h"
+#include "gromacs/utility/real.h"
+
+struct t_commrec;
+
+namespace gmx
+{
+
+template <typename T>
+class ArrayRef;
+
+}
+
+/*! \brief Simulation conditions to transmit.
+ *
+ * Keep in mind that they are transmitted to other ranks through an
+ * MPI_Reduce after casting them to a real (so the signals can be sent
+ * together with other data). This means that the only meaningful
+ * values are positive, negative or zero. */
+enum {
+    eglsCHKPT, eglsSTOPCOND, eglsRESETCOUNTERS, eglsNR
+};
+
+/*! \internal \brief Object used by mdrun ranks to signal to each other */
+struct gmx_signalling_t {
+    int  nstms;             /**< The frequency for inter-simulation communication */
+    int  sig[eglsNR];       /**< The signal set by this rank in do_md */
+    int  set[eglsNR];       /**< The communicated signal, equal for all ranks once communication has occurred */
+    real mpiBuffer[eglsNR]; /**< Buffer for communication */
+};
+
+/*! \brief Construct a struct gmx_signalling_t */
+void init_global_signals(struct gmx_signalling_t *gs,
+                         const t_commrec         *cr,
+                         const t_inputrec        *ir,
+                         int                      repl_ex_nst);
+
+/*! \brief Fill the array of reals in which inter- and
+ * intra-simulation signals will be communicated
+ * with the signal values to be sent. */
+gmx::ArrayRef<real>
+prepareSignalBuffer(struct gmx_signalling_t *gs);
+
+/*! \brief Handle intra- and inter-simulation signals recieved
+ *
+ * If a multi-simulation signal should be handled, communicate between
+ * simulation-master ranks, then propagate from the masters to the
+ * rest of the ranks for each simulation.
+ *
+ * Then, set the flags that mdrun will use to respond to the signals
+ * received. */
+void
+handleSignals(struct gmx_signalling_t  *gs,
+              const t_commrec          *cr,
+              bool                      bInterSimGS);
+
+#endif
index ff5af6d6491a7268f52d40410ff602c20d2020c3..f5168fc2f0e359ae1689c92e77a93d25cd135adc 100644 (file)
@@ -79,7 +79,6 @@
 #include "gromacs/legacyheaders/types/fcdata.h"
 #include "gromacs/legacyheaders/types/force_flags.h"
 #include "gromacs/legacyheaders/types/forcerec.h"
-#include "gromacs/legacyheaders/types/globsig.h"
 #include "gromacs/legacyheaders/types/group.h"
 #include "gromacs/legacyheaders/types/inputrec.h"
 #include "gromacs/legacyheaders/types/interaction_const.h"
@@ -94,6 +93,7 @@
 #include "gromacs/math/vec.h"
 #include "gromacs/math/vectypes.h"
 #include "gromacs/mdlib/compute_io.h"
+#include "gromacs/mdlib/mdrun_signalling.h"
 #include "gromacs/mdlib/nb_verlet.h"
 #include "gromacs/mdlib/nbnxn_cuda/nbnxn_cuda_data_mgmt.h"
 #include "gromacs/pbcutil/mshift.h"
@@ -199,7 +199,7 @@ double do_md(FILE *fplog, t_commrec *cr, int nfile, const t_filenm fnm[],
     gmx_global_stat_t gstat;
     gmx_update_t      upd   = NULL;
     t_graph          *graph = NULL;
-    globsig_t         gs;
+    gmx_signalling_t  gs;
     gmx_groups_t     *groups;
     gmx_ekindata_t   *ekind, *ekind_save;
     gmx_shellfc_t     shellfc;