Introduce plumbing for ObservablesReducer
authorMark Abraham <mark.j.abraham@gmail.com>
Tue, 7 Sep 2021 17:38:29 +0000 (17:38 +0000)
committerJoe Jordan <ejjordan12@gmail.com>
Tue, 7 Sep 2021 17:38:29 +0000 (17:38 +0000)
41 files changed:
src/gromacs/mdlib/md_support.cpp
src/gromacs/mdlib/md_support.h
src/gromacs/mdlib/stat.cpp
src/gromacs/mdlib/stat.h
src/gromacs/mdlib/update_vv.cpp
src/gromacs/mdlib/update_vv.h
src/gromacs/mdrun/isimulator.h
src/gromacs/mdrun/md.cpp
src/gromacs/mdrun/mimic.cpp
src/gromacs/mdrun/minimize.cpp
src/gromacs/mdrun/rerun.cpp
src/gromacs/mdrun/runner.cpp
src/gromacs/mdrun/simulatorbuilder.cpp
src/gromacs/mdrun/simulatorbuilder.h
src/gromacs/modularsimulator/andersentemperaturecoupling.cpp
src/gromacs/modularsimulator/andersentemperaturecoupling.h
src/gromacs/modularsimulator/computeglobalselement.cpp
src/gromacs/modularsimulator/computeglobalselement.h
src/gromacs/modularsimulator/constraintelement.cpp
src/gromacs/modularsimulator/constraintelement.h
src/gromacs/modularsimulator/energydata.cpp
src/gromacs/modularsimulator/energydata.h
src/gromacs/modularsimulator/firstorderpressurecoupling.cpp
src/gromacs/modularsimulator/firstorderpressurecoupling.h
src/gromacs/modularsimulator/forceelement.cpp
src/gromacs/modularsimulator/forceelement.h
src/gromacs/modularsimulator/modularsimulator.h
src/gromacs/modularsimulator/mttk.cpp
src/gromacs/modularsimulator/mttk.h
src/gromacs/modularsimulator/nosehooverchains.cpp
src/gromacs/modularsimulator/nosehooverchains.h
src/gromacs/modularsimulator/parrinellorahmanbarostat.cpp
src/gromacs/modularsimulator/parrinellorahmanbarostat.h
src/gromacs/modularsimulator/propagator.cpp
src/gromacs/modularsimulator/propagator.h
src/gromacs/modularsimulator/simulatoralgorithm.cpp
src/gromacs/modularsimulator/simulatoralgorithm.h
src/gromacs/modularsimulator/statepropagatordata.cpp
src/gromacs/modularsimulator/statepropagatordata.h
src/gromacs/modularsimulator/velocityscalingtemperaturecoupling.cpp
src/gromacs/modularsimulator/velocityscalingtemperaturecoupling.h

index 31ba183021bba8eac1d6fa9b5b51f5c76fafe8b1..46ebb11617187e02736905a240e3b500fbe864e6 100644 (file)
@@ -67,6 +67,7 @@
 #include "gromacs/mdtypes/inputrec.h"
 #include "gromacs/mdtypes/md_enums.h"
 #include "gromacs/mdtypes/mdatom.h"
+#include "gromacs/mdtypes/observablesreducer.h"
 #include "gromacs/mdtypes/state.h"
 #include "gromacs/pbcutil/pbc.h"
 #include "gromacs/pulling/pull.h"
@@ -302,7 +303,9 @@ void compute_globals(gmx_global_stat*               gstat,
                      gmx::SimulationSignaller*      signalCoordinator,
                      const matrix                   lastbox,
                      gmx_bool*                      bSumEkinhOld,
-                     const int                      flags)
+                     const int                      flags,
+                     int64_t                        step,
+                     gmx::ObservablesReducer*       observablesReducer)
 {
     gmx_bool bEner, bPres, bTemp;
     gmx_bool bStopCM, bGStat, bReadEkin, bEkinAveVel, bScaleEkin, bConstrain;
@@ -345,7 +348,8 @@ void compute_globals(gmx_global_stat*               gstat,
         calc_vcm_grp(*mdatoms, x, v, vcm);
     }
 
-    if (bTemp || bStopCM || bPres || bEner || bConstrain || bCheckNumberOfBondedInteractions)
+    if (bTemp || bStopCM || bPres || bEner || bConstrain || bCheckNumberOfBondedInteractions
+        || !observablesReducer->communicationBuffer().empty())
     {
         if (!bGStat)
         {
@@ -371,7 +375,9 @@ void compute_globals(gmx_global_stat*               gstat,
                             bStopCM ? vcm : nullptr,
                             signalBuffer,
                             *bSumEkinhOld,
-                            flags);
+                            flags,
+                            step,
+                            observablesReducer);
                 wallcycle_stop(wcycle, WallCycleCounter::MoveE);
             }
             signalCoordinator->finalizeSignals();
index da949e10d1165f0e573936a14e59f7f06c28093f..e43260a5cf2e933a672453005807c4921bb55122 100644 (file)
@@ -38,6 +38,8 @@
 #ifndef GMX_MDLIB_MD_SUPPORT_H
 #define GMX_MDLIB_MD_SUPPORT_H
 
+#include <cstdint>
+
 #include "gromacs/mdlib/vcm.h"
 #include "gromacs/mdtypes/md_enums.h"
 #include "gromacs/timing/wallcycle.h"
@@ -60,6 +62,7 @@ template<typename T>
 class ArrayRef;
 class Constraints;
 class MDLogger;
+class ObservablesReducer;
 class SimulationSignaller;
 } // namespace gmx
 
@@ -133,6 +136,8 @@ void compute_globals(gmx_global_stat*               gstat,
                      gmx::SimulationSignaller*      signalCoordinator,
                      const matrix                   lastbox,
                      gmx_bool*                      bSumEkinhOld,
-                     int                            flags);
+                     int                            flags,
+                     int64_t                        step,
+                     gmx::ObservablesReducer*       observablesReducer);
 
 #endif
index c7e47c267f87d76ca3ecbbf96483228a7a30cc23..6be1c9d2cff94bdfdaf23c22f3e92a25a41339d9 100644 (file)
@@ -59,6 +59,7 @@
 #include "gromacs/mdtypes/group.h"
 #include "gromacs/mdtypes/inputrec.h"
 #include "gromacs/mdtypes/md_enums.h"
+#include "gromacs/mdtypes/observablesreducer.h"
 #include "gromacs/utility/fatalerror.h"
 #include "gromacs/utility/futil.h"
 #include "gromacs/utility/smalloc.h"
@@ -141,18 +142,20 @@ static int filter_enerdterm(const real* afrom, gmx_bool bToBuffer, real* ato, gm
     return to;
 }
 
-void global_stat(const gmx_global_stat& gs,
-                 const t_commrec*       cr,
-                 gmx_enerdata_t*        enerd,
-                 tensor                 fvir,
-                 tensor                 svir,
-                 const t_inputrec&      inputrec,
-                 gmx_ekindata_t*        ekind,
-                 gmx::ArrayRef<real>    constraintsRmsdData,
-                 t_vcm*                 vcm,
-                 gmx::ArrayRef<real>    sig,
-                 bool                   bSumEkinhOld,
-                 int                    flags)
+void global_stat(const gmx_global_stat&   gs,
+                 const t_commrec*         cr,
+                 gmx_enerdata_t*          enerd,
+                 tensor                   fvir,
+                 tensor                   svir,
+                 const t_inputrec&        inputrec,
+                 gmx_ekindata_t*          ekind,
+                 gmx::ArrayRef<real>      constraintsRmsdData,
+                 t_vcm*                   vcm,
+                 gmx::ArrayRef<real>      sig,
+                 bool                     bSumEkinhOld,
+                 int                      flags,
+                 int64_t                  step,
+                 gmx::ObservablesReducer* observablesReducer)
 /* instead of current system, gmx_booleans for summing virial, kinetic energy, and other terms */
 {
     int ie = 0, ifv = 0, isv = 0, irmsd = 0;
@@ -170,6 +173,12 @@ void global_stat(const gmx_global_stat& gs,
                         || (inputrec.eI == IntegrationAlgorithm::VVAK && bPres));
     bool bReadEkin                       = ((flags & CGLO_READEKIN) != 0);
 
+    // This structure implements something akin to a vector. As
+    // modules add their data into it with add_bin[rd], they save the
+    // index it returns, which allows them to look up their data later
+    // after the reduction with extract_bin[rd]. The various index
+    // variables are mostly named following the pattern
+    // "i<abbreviation for module>".
     t_bin* rb   = gs.rb;
     int*   itc0 = gs.itc0;
     int*   itc1 = gs.itc1;
@@ -284,6 +293,14 @@ void global_stat(const gmx_global_stat& gs,
         isig = add_binr(rb, sig);
     }
 
+    gmx::ArrayRef<double> observablesReducerBuffer = observablesReducer->communicationBuffer();
+    int                   tbinIndexForObservablesReducer = 0;
+    if (!observablesReducerBuffer.empty())
+    {
+        tbinIndexForObservablesReducer =
+                add_bind(rb, observablesReducerBuffer.ssize(), observablesReducerBuffer.data());
+    }
+
     sum_bin(rb, cr);
 
     /* Extract all the data locally */
@@ -381,4 +398,13 @@ void global_stat(const gmx_global_stat& gs,
     {
         extract_binr(rb, isig, sig);
     }
+
+    if (!observablesReducerBuffer.empty())
+    {
+        extract_bind(rb,
+                     tbinIndexForObservablesReducer,
+                     observablesReducerBuffer.ssize(),
+                     observablesReducerBuffer.data());
+        observablesReducer->reductionComplete(step);
+    }
 }
index 8001bf0d39605ea27d69fff2864f3f4bfe075441..eb48f9d665182e656ef6ef89323fdd98682aa9ca 100644 (file)
@@ -54,6 +54,7 @@ namespace gmx
 template<typename T>
 class ArrayRef;
 class Constraints;
+class ObservablesReducer;
 } // namespace gmx
 
 typedef struct gmx_global_stat* gmx_global_stat_t;
@@ -63,18 +64,20 @@ gmx_global_stat_t global_stat_init(const t_inputrec* ir);
 void global_stat_destroy(gmx_global_stat_t gs);
 
 /*! \brief All-reduce energy-like quantities over cr->mpi_comm_mysim  */
-void global_stat(const gmx_global_stat& gs,
-                 const t_commrec*       cr,
-                 gmx_enerdata_t*        enerd,
-                 tensor                 fvir,
-                 tensor                 svir,
-                 const t_inputrec&      inputrec,
-                 gmx_ekindata_t*        ekind,
-                 gmx::ArrayRef<real>    constraintsRmsdData,
-                 t_vcm*                 vcm,
-                 gmx::ArrayRef<real>    sig,
-                 bool                   bSumEkinhOld,
-                 int                    flags);
+void global_stat(const gmx_global_stat&   gs,
+                 const t_commrec*         cr,
+                 gmx_enerdata_t*          enerd,
+                 tensor                   fvir,
+                 tensor                   svir,
+                 const t_inputrec&        inputrec,
+                 gmx_ekindata_t*          ekind,
+                 gmx::ArrayRef<real>      constraintsRmsdData,
+                 t_vcm*                   vcm,
+                 gmx::ArrayRef<real>      sig,
+                 bool                     bSumEkinhOld,
+                 int                      flags,
+                 int64_t                  step,
+                 gmx::ObservablesReducer* observablesReducer);
 
 /*! \brief Returns TRUE if io should be done */
 inline bool do_per_step(int64_t step, int64_t nstep)
index a5a9797a60c999d217a4fbb981dd8273877d96f2..279e77c8957be1982090aa7ad6c65845767d1638 100644 (file)
@@ -84,6 +84,7 @@ void integrateVVFirstStep(int64_t                   step,
                           t_vcm*                    vcm,
                           const gmx_localtop_t&     top,
                           gmx_enerdata_t*           enerd,
+                          gmx::ObservablesReducer*  observablesReducer,
                           gmx_ekindata_t*           ekind,
                           gmx_global_stat*          gstat,
                           real*                     last_ekin,
@@ -215,7 +216,9 @@ void integrateVVFirstStep(int64_t                   step,
                             nullSignaller,
                             state->box,
                             bSumEkinhOld,
-                            cglo_flags);
+                            cglo_flags,
+                            step,
+                            observablesReducer);
             /* explanation of above:
                 a) We compute Ekin at the full time step
                 if 1) we are using the AveVel Ekin, and it's not the
@@ -300,7 +303,9 @@ void integrateVVFirstStep(int64_t                   step,
                                 nullSignaller,
                                 state->box,
                                 bSumEkinhOld,
-                                CGLO_GSTAT | CGLO_TEMPERATURE);
+                                CGLO_GSTAT | CGLO_TEMPERATURE,
+                                step,
+                                observablesReducer);
                 wallcycle_start(wcycle, WallCycleCounter::Update);
             }
         }
@@ -331,36 +336,37 @@ void integrateVVFirstStep(int64_t                   step,
     }
 }
 
-void integrateVVSecondStep(int64_t                                                  step,
-                           const t_inputrec*                                        ir,
-                           t_forcerec*                                              fr,
-                           t_commrec*                                               cr,
-                           t_state*                                                 state,
-                           t_mdatoms*                                               mdatoms,
-                           t_fcdata*                                                fcdata,
-                           t_extmass*                                               MassQ,
-                           t_vcm*                                                   vcm,
-                           pull_t*                                                  pull_work,
-                           gmx_enerdata_t*                                          enerd,
-                           gmx_ekindata_t*                                          ekind,
-                           gmx_global_stat*                                         gstat,
-                           real*                                                    dvdl_constr,
-                           bool                                                     bCalcVir,
-                           tensor                                                   total_vir,
-                           tensor                                                   shake_vir,
-                           tensor                                                   force_vir,
-                           tensor                                                   pres,
-                           matrix                                                   M,
-                           matrix                                                   lastbox,
-                           bool                                                     do_log,
-                           bool                                                     do_ene,
-                           bool                                                     bGStat,
-                           bool*                                                    bSumEkinhOld,
-                           gmx::ForceBuffers*                                       f,
-                           std::vector<gmx::RVec>*                                  cbuf,
-                           gmx::Update*                                             upd,
-                           gmx::Constraints*                                        constr,
-                           gmx::SimulationSignaller*                                nullSignaller,
+void integrateVVSecondStep(int64_t                   step,
+                           const t_inputrec*         ir,
+                           t_forcerec*               fr,
+                           t_commrec*                cr,
+                           t_state*                  state,
+                           t_mdatoms*                mdatoms,
+                           t_fcdata*                 fcdata,
+                           t_extmass*                MassQ,
+                           t_vcm*                    vcm,
+                           pull_t*                   pull_work,
+                           gmx_enerdata_t*           enerd,
+                           gmx::ObservablesReducer*  observablesReducer,
+                           gmx_ekindata_t*           ekind,
+                           gmx_global_stat*          gstat,
+                           real*                     dvdl_constr,
+                           bool                      bCalcVir,
+                           tensor                    total_vir,
+                           tensor                    shake_vir,
+                           tensor                    force_vir,
+                           tensor                    pres,
+                           matrix                    M,
+                           matrix                    lastbox,
+                           bool                      do_log,
+                           bool                      do_ene,
+                           bool                      bGStat,
+                           bool*                     bSumEkinhOld,
+                           gmx::ForceBuffers*        f,
+                           std::vector<gmx::RVec>*   cbuf,
+                           gmx::Update*              upd,
+                           gmx::Constraints*         constr,
+                           gmx::SimulationSignaller* nullSignaller,
                            gmx::EnumerationArray<TrotterSequence, std::vector<int>> trotter_seq,
                            t_nrnb*                                                  nrnb,
                            gmx_wallcycle*                                           wcycle)
@@ -461,7 +467,9 @@ void integrateVVSecondStep(int64_t
                         nullSignaller,
                         lastbox,
                         bSumEkinhOld,
-                        (bGStat ? CGLO_GSTAT : 0) | CGLO_TEMPERATURE);
+                        (bGStat ? CGLO_GSTAT : 0) | CGLO_TEMPERATURE,
+                        step,
+                        observablesReducer);
         wallcycle_start(wcycle, WallCycleCounter::Update);
         trotter_update(ir,
                        step,
index bc4307d681b0668f16ecbad268ddfdd3be2d558c..9cc7bdb391b0f48fd69882b7f9988a22091557a2 100644 (file)
@@ -69,6 +69,7 @@ namespace gmx
 class Constraints;
 class ForceBuffers;
 class MDLogger;
+class ObservablesReducer;
 class SimulationSignaller;
 class Update;
 enum class StartingBehavior : int;
@@ -91,6 +92,7 @@ enum class StartingBehavior : int;
  * \param[in]  vcm               Center of mass motion removal.
  * \param[in]  top               Local topology.
  * \param[in]  enerd             Energy data.
+ * \param[in]  observablesReducer Pointer to the \c ObservablesReducer object
  * \param[in]  ekind             Kinetic energy data.
  * \param[in]  gstat             Storage of thermodynamic parameters data.
  * \param[out] last_ekin         Kinetic energies of the last step.
@@ -133,6 +135,7 @@ void integrateVVFirstStep(int64_t                   step,
                           t_vcm*                    vcm,
                           const gmx_localtop_t&     top,
                           gmx_enerdata_t*           enerd,
+                          gmx::ObservablesReducer*  observablesReducer,
                           gmx_ekindata_t*           ekind,
                           gmx_global_stat*          gstat,
                           real*                     last_ekin,
@@ -174,6 +177,7 @@ void integrateVVFirstStep(int64_t                   step,
  * \param[in]  vcm               Center of mass motion removal.
  * \param[in]  pull_work         Pulling data.
  * \param[in]  enerd             Energy data.
+ * \param[in]  observablesReducer Pointer to the \c ObservablesReducer object
  * \param[in]  ekind             Kinetic energy data.
  * \param[in]  gstat             Storage of thermodynamic parameters data.
  * \param[out] dvdl_constr       FEP data for constraints.
@@ -197,36 +201,37 @@ void integrateVVFirstStep(int64_t                   step,
  * \param[in]  nrnb              Cycle counters.
  * \param[in]  wcycle            Wall-clock cycle counter.
  */
-void integrateVVSecondStep(int64_t                                                  step,
-                           const t_inputrec*                                        ir,
-                           t_forcerec*                                              fr,
-                           t_commrec*                                               cr,
-                           t_state*                                                 state,
-                           t_mdatoms*                                               mdatoms,
-                           t_fcdata*                                                fcdata,
-                           t_extmass*                                               MassQ,
-                           t_vcm*                                                   vcm,
-                           pull_t*                                                  pull_work,
-                           gmx_enerdata_t*                                          enerd,
-                           gmx_ekindata_t*                                          ekind,
-                           gmx_global_stat*                                         gstat,
-                           real*                                                    dvdl_constr,
-                           bool                                                     bCalcVir,
-                           tensor                                                   total_vir,
-                           tensor                                                   shake_vir,
-                           tensor                                                   force_vir,
-                           tensor                                                   pres,
-                           matrix                                                   M,
-                           matrix                                                   lastbox,
-                           bool                                                     do_log,
-                           bool                                                     do_ene,
-                           bool                                                     bGStat,
-                           bool*                                                    bSumEkinhOld,
-                           gmx::ForceBuffers*                                       f,
-                           std::vector<gmx::RVec>*                                  cbuf,
-                           gmx::Update*                                             upd,
-                           gmx::Constraints*                                        constr,
-                           gmx::SimulationSignaller*                                nullSignaller,
+void integrateVVSecondStep(int64_t                   step,
+                           const t_inputrec*         ir,
+                           t_forcerec*               fr,
+                           t_commrec*                cr,
+                           t_state*                  state,
+                           t_mdatoms*                mdatoms,
+                           t_fcdata*                 fcdata,
+                           t_extmass*                MassQ,
+                           t_vcm*                    vcm,
+                           pull_t*                   pull_work,
+                           gmx_enerdata_t*           enerd,
+                           gmx::ObservablesReducer*  observablesReducer,
+                           gmx_ekindata_t*           ekind,
+                           gmx_global_stat*          gstat,
+                           real*                     dvdl_constr,
+                           bool                      bCalcVir,
+                           tensor                    total_vir,
+                           tensor                    shake_vir,
+                           tensor                    force_vir,
+                           tensor                    pres,
+                           matrix                    M,
+                           matrix                    lastbox,
+                           bool                      do_log,
+                           bool                      do_ene,
+                           bool                      bGStat,
+                           bool*                     bSumEkinhOld,
+                           gmx::ForceBuffers*        f,
+                           std::vector<gmx::RVec>*   cbuf,
+                           gmx::Update*              upd,
+                           gmx::Constraints*         constr,
+                           gmx::SimulationSignaller* nullSignaller,
                            gmx::EnumerationArray<TrotterSequence, std::vector<int>> trotter_seq,
                            t_nrnb*                                                  nrnb,
                            gmx_wallcycle*                                           wcycle);
index 37ffb33742438a4d9abdaf09ebc772ef369f19bb..e7cf49b8301b1b6287ab55c3b8bee686859eadfe 100644 (file)
@@ -75,6 +75,7 @@ struct MDModulesNotifiers;
 class ImdSession;
 class MDLogger;
 class MDAtoms;
+class ObservablesReducerBuilder;
 class StopHandlerBuilder;
 struct MdrunOptions;
 class VirtualSitesHandler;
@@ -136,6 +137,7 @@ public:
                         gmx_wallcycle*                      wcycle,
                         t_forcerec*                         fr,
                         gmx_enerdata_t*                     enerd,
+                        ObservablesReducerBuilder*          observablesReducerBuilder,
                         gmx_ekindata_t*                     ekind,
                         MdrunScheduleWorkload*              runScheduleWork,
                         const ReplicaExchangeParameters&    replExParams,
@@ -170,6 +172,7 @@ public:
         wcycle(wcycle),
         fr(fr),
         enerd(enerd),
+        observablesReducerBuilder(observablesReducerBuilder),
         ekind(ekind),
         runScheduleWork(runScheduleWork),
         replExParams(replExParams),
@@ -234,6 +237,8 @@ public:
     t_forcerec* fr;
     //! Data for energy output.
     gmx_enerdata_t* enerd;
+    //! Builder for coordinator of reduction for observables
+    ObservablesReducerBuilder* observablesReducerBuilder;
     //! Kinetic energy data.
     gmx_ekindata_t* ekind;
     //! Schedule of work for each MD step for this task.
index 11ae4fab7baf53d91d1fb4e532109b810c5f52c2..7caa1dc7085974e96ab24c936eb9ca5d4c344d84 100644 (file)
 #include "gromacs/mdtypes/mdrunoptions.h"
 #include "gromacs/mdtypes/multipletimestepping.h"
 #include "gromacs/mdtypes/observableshistory.h"
+#include "gromacs/mdtypes/observablesreducer.h"
 #include "gromacs/mdtypes/pullhistory.h"
 #include "gromacs/mdtypes/simulation_workload.h"
 #include "gromacs/mdtypes/state.h"
@@ -360,7 +361,8 @@ void gmx::LegacySimulator::do_md()
     std::unique_ptr<t_state> stateInstance;
     t_state*                 state;
 
-    gmx_localtop_t top(top_global.ffparams);
+    gmx_localtop_t     top(top_global.ffparams);
+    ObservablesReducer observablesReducer = observablesReducerBuilder->build();
 
     ForceBuffers     f(simulationWork.useMts,
                    ((useGpuForNonbonded && useGpuForBufferOps) || useGpuForUpdate)
@@ -632,6 +634,9 @@ void gmx::LegacySimulator::do_md()
     t_vcm vcm(top_global.groups, *ir);
     reportComRemovalInfo(fplog, vcm);
 
+    int64_t step     = ir->init_step;
+    int64_t step_rel = 0;
+
     /* To minimize communication, compute_globals computes the COM velocity
      * and the kinetic energy for the velocities without COM motion removed.
      * Thus to get the kinetic energy without the COM contribution, we need
@@ -671,7 +676,9 @@ void gmx::LegacySimulator::do_md()
                         &nullSignaller,
                         state->box,
                         &bSumEkinhOld,
-                        cglo_flags_iteration);
+                        cglo_flags_iteration,
+                        step,
+                        &observablesReducer);
         if (cglo_flags_iteration & CGLO_STOPCM)
         {
             /* At initialization, do not pass x with acceleration-correction mode
@@ -718,7 +725,9 @@ void gmx::LegacySimulator::do_md()
                         &nullSignaller,
                         state->box,
                         &bSumEkinhOld,
-                        cglo_flags & ~CGLO_PRESSURE);
+                        cglo_flags & ~CGLO_PRESSURE,
+                        step,
+                        &observablesReducer);
     }
 
     /* Calculate the initial half step temperature, and save the ekinh_old */
@@ -801,9 +810,6 @@ void gmx::LegacySimulator::do_md()
     bExchanged       = FALSE;
     bNeedRepartition = FALSE;
 
-    int64_t step     = ir->init_step;
-    int64_t step_rel = 0;
-
     auto stopHandler = stopHandlerBuilder->getStopHandlerMD(
             compat::not_null<SimulationSignal*>(&signals[eglsSTOPCOND]),
             simulationsShareState,
@@ -1066,7 +1072,9 @@ void gmx::LegacySimulator::do_md()
                             &nullSignaller,
                             state->box,
                             &bSumEkinhOld,
-                            cglo_flags);
+                            cglo_flags,
+                            step,
+                            &observablesReducer);
             if (DOMAINDECOMP(cr))
             {
                 dd_localTopologyChecker(cr->dd)->checkNumberOfBondedInteractions(
@@ -1223,6 +1231,7 @@ void gmx::LegacySimulator::do_md()
                                  &vcm,
                                  top,
                                  enerd,
+                                 &observablesReducer,
                                  ekind,
                                  gstat,
                                  &last_ekin,
@@ -1471,6 +1480,7 @@ void gmx::LegacySimulator::do_md()
                                   &vcm,
                                   pull_work,
                                   enerd,
+                                  &observablesReducer,
                                   ekind,
                                   gstat,
                                   &dvdl_constr,
@@ -1700,7 +1710,9 @@ void gmx::LegacySimulator::do_md()
                                 | (!EI_VV(ir->eI) ? CGLO_PRESSURE : 0) | CGLO_CONSTRAINT
                                 | (DOMAINDECOMP(cr) && dd_localTopologyChecker(*cr->dd).shouldCheckNumberOfBondedInteractions()
                                            ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS
-                                           : 0));
+                                           : 0),
+                        step,
+                        &observablesReducer);
                 if (DOMAINDECOMP(cr))
                 {
                     dd_localTopologyChecker(cr->dd)->checkNumberOfBondedInteractions(
index ec45896922dd22979027284079bc81093d39847b..29b74e0d8bdd4fc5c0e37326a4fa232794ec8375 100644 (file)
 #include "gromacs/mdtypes/mdatom.h"
 #include "gromacs/mdtypes/mdrunoptions.h"
 #include "gromacs/mdtypes/observableshistory.h"
+#include "gromacs/mdtypes/observablesreducer.h"
 #include "gromacs/mdtypes/simulation_workload.h"
 #include "gromacs/mdtypes/state.h"
 #include "gromacs/mimic/communicator.h"
@@ -206,6 +207,8 @@ void gmx::LegacySimulator::do_mimic()
     int        nstglobalcomm = 1;
     const bool bNS           = true;
 
+    ObservablesReducer observablesReducer = observablesReducerBuilder->build();
+
     if (MASTER(cr))
     {
         MimicCommunicator::init();
@@ -339,6 +342,9 @@ void gmx::LegacySimulator::do_mimic()
         doFreeEnergyPerturbation = true;
     }
 
+    int64_t step     = ir->init_step;
+    int64_t step_rel = 0;
+
     {
         int cglo_flags = CGLO_GSTAT;
         if (DOMAINDECOMP(cr) && dd_localTopologyChecker(*cr->dd).shouldCheckNumberOfBondedInteractions())
@@ -368,7 +374,9 @@ void gmx::LegacySimulator::do_mimic()
                         &nullSignaller,
                         state->box,
                         &bSumEkinhOld,
-                        cglo_flags);
+                        cglo_flags,
+                        step,
+                        &observablesReducer);
         if (DOMAINDECOMP(cr))
         {
             dd_localTopologyChecker(cr->dd)->checkNumberOfBondedInteractions(
@@ -414,9 +422,6 @@ void gmx::LegacySimulator::do_mimic()
                     "MiMiC does not report kinetic energy, total energy, temperature, virial and "
                     "pressure.");
 
-    int64_t step     = ir->init_step;
-    int64_t step_rel = 0;
-
     auto stopHandler = stopHandlerBuilder->getStopHandlerMD(
             compat::not_null<SimulationSignal*>(&signals[eglsSTOPCOND]),
             false,
@@ -655,7 +660,9 @@ void gmx::LegacySimulator::do_mimic()
                             &signaller,
                             state->box,
                             &bSumEkinhOld,
-                            cglo_flags);
+                            cglo_flags,
+                            step,
+                            &observablesReducer);
             if (DOMAINDECOMP(cr))
             {
                 dd_localTopologyChecker(cr->dd)->checkNumberOfBondedInteractions(
index 6784cfeb0bad3d855a3f78f5c75b635f7c151d6b..d055c942e662f9483f3b4b1de618f019d129d502 100644 (file)
 #include "gromacs/mdtypes/md_enums.h"
 #include "gromacs/mdtypes/mdatom.h"
 #include "gromacs/mdtypes/mdrunoptions.h"
+#include "gromacs/mdtypes/observablesreducer.h"
 #include "gromacs/mdtypes/state.h"
 #include "gromacs/pbcutil/pbc.h"
 #include "gromacs/timing/wallcycle.h"
@@ -901,7 +902,7 @@ public:
      * unsuited for aggregate initialization. When the types
      * improve, the call signature of this method can be reduced.
      */
-    void run(em_state_t* ems, rvec mu_tot, tensor vir, tensor pres, int64_t count, gmx_bool bFirst);
+    void run(em_state_t* ems, rvec mu_tot, tensor vir, tensor pres, int64_t count, gmx_bool bFirst, int64_t step);
     //! Handles logging (deprecated).
     FILE* fplog;
     //! Handles logging.
@@ -924,8 +925,10 @@ public:
     t_nrnb* nrnb;
     //! Manages wall cycle accounting.
     gmx_wallcycle* wcycle;
-    //! Coordinates global reduction.
+    //! Legacy coordinator of global reduction.
     gmx_global_stat_t gstat;
+    //! Coordinates reduction for observables
+    gmx::ObservablesReducer* observablesReducer;
     //! Handles virtual sites.
     VirtualSitesHandler* vsite;
     //! Handles constraints.
@@ -944,7 +947,7 @@ public:
     std::vector<RVec> pairSearchCoordinates;
 };
 
-void EnergyEvaluator::run(em_state_t* ems, rvec mu_tot, tensor vir, tensor pres, int64_t count, gmx_bool bFirst)
+void EnergyEvaluator::run(em_state_t* ems, rvec mu_tot, tensor vir, tensor pres, int64_t count, gmx_bool bFirst, int64_t step)
 {
     real     t;
     gmx_bool bNS;
@@ -1047,7 +1050,9 @@ void EnergyEvaluator::run(em_state_t* ems, rvec mu_tot, tensor vir, tensor pres,
                     nullptr,
                     std::vector<real>(1, terminate),
                     FALSE,
-                    CGLO_ENERGY | CGLO_PRESSURE | CGLO_CONSTRAINT);
+                    CGLO_ENERGY | CGLO_PRESSURE | CGLO_CONSTRAINT,
+                    step,
+                    observablesReducer);
 
         wallcycle_stop(wcycle, WallCycleCounter::MoveE);
     }
@@ -1285,6 +1290,8 @@ void LegacySimulator::do_cg()
     em_state_t* s_b   = &s2;
     em_state_t* s_c   = &s3;
 
+    ObservablesReducer observablesReducer = observablesReducerBuilder->build();
+
     /* Init em and store the local state in s_min */
     init_em(fplog,
             mdlog,
@@ -1344,15 +1351,32 @@ void LegacySimulator::do_cg()
         sp_header(fplog, CG, inputrec->em_tol, number_steps);
     }
 
-    EnergyEvaluator energyEvaluator{ fplog,  mdlog,           cr,         ms,        top_global,
-                                     &top,   inputrec,        imdSession, pull_work, nrnb,
-                                     wcycle, gstat,           vsite,      constr,    mdAtoms,
-                                     fr,     runScheduleWork, enerd,      -1,        {} };
+    EnergyEvaluator energyEvaluator{ fplog,
+                                     mdlog,
+                                     cr,
+                                     ms,
+                                     top_global,
+                                     &top,
+                                     inputrec,
+                                     imdSession,
+                                     pull_work,
+                                     nrnb,
+                                     wcycle,
+                                     gstat,
+                                     &observablesReducer,
+                                     vsite,
+                                     constr,
+                                     mdAtoms,
+                                     fr,
+                                     runScheduleWork,
+                                     enerd,
+                                     -1,
+                                     {} };
     /* Call the force routine and some auxiliary (neighboursearching etc.) */
     /* 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
      */
-    energyEvaluator.run(s_min, mu_tot, vir, pres, -1, TRUE);
+    energyEvaluator.run(s_min, mu_tot, vir, pres, -1, TRUE, step);
 
     if (MASTER(cr))
     {
@@ -1545,7 +1569,7 @@ void LegacySimulator::do_cg()
 
         neval++;
         /* Calculate energy for the trial step */
-        energyEvaluator.run(s_c, mu_tot, vir, pres, -1, FALSE);
+        energyEvaluator.run(s_c, mu_tot, vir, pres, -1, FALSE, step);
 
         /* Calc derivative along line */
         const rvec*                    pc  = s_c->s.cg_p.rvec_array();
@@ -1660,7 +1684,7 @@ void LegacySimulator::do_cg()
 
                 neval++;
                 /* Calculate energy for the trial step */
-                energyEvaluator.run(s_b, mu_tot, vir, pres, -1, FALSE);
+                energyEvaluator.run(s_b, mu_tot, vir, pres, -1, FALSE, step);
 
                 /* p does not change within a step, but since the domain decomposition
                  * might change, we have to use cg_p of s_b here.
@@ -1984,6 +2008,8 @@ void LegacySimulator::do_lbfgs()
     int step  = 0;
     int neval = 0;
 
+    ObservablesReducer observablesReducer = observablesReducerBuilder->build();
+
     /* Init em */
     init_em(fplog,
             mdlog,
@@ -2081,13 +2107,29 @@ void LegacySimulator::do_lbfgs()
      * We do not unshift, so molecules are always whole
      */
     neval++;
-    EnergyEvaluator energyEvaluator{ fplog,    mdlog,      cr,        ms,   top_global,      &top,
-                                     inputrec, imdSession, pull_work, nrnb, wcycle,          gstat,
-                                     vsite,    constr,     mdAtoms,   fr,   runScheduleWork, enerd };
+    EnergyEvaluator energyEvaluator{ fplog,
+                                     mdlog,
+                                     cr,
+                                     ms,
+                                     top_global,
+                                     &top,
+                                     inputrec,
+                                     imdSession,
+                                     pull_work,
+                                     nrnb,
+                                     wcycle,
+                                     gstat,
+                                     &observablesReducer,
+                                     vsite,
+                                     constr,
+                                     mdAtoms,
+                                     fr,
+                                     runScheduleWork,
+                                     enerd };
     rvec            mu_tot;
     tensor          vir;
     tensor          pres;
-    energyEvaluator.run(&ems, mu_tot, vir, pres, -1, TRUE);
+    energyEvaluator.run(&ems, mu_tot, vir, pres, -1, TRUE, step);
 
     if (MASTER(cr))
     {
@@ -2317,7 +2359,7 @@ void LegacySimulator::do_lbfgs()
 
         neval++;
         // Calculate energy for the trial step in position C
-        energyEvaluator.run(sc, mu_tot, vir, pres, step, FALSE);
+        energyEvaluator.run(sc, mu_tot, vir, pres, step, FALSE, step);
 
         // Calc line gradient in position C
         real*  fc  = static_cast<real*>(sc->f.view().force()[0]);
@@ -2401,7 +2443,7 @@ void LegacySimulator::do_lbfgs()
 
                 neval++;
                 // Calculate energy for the trial step in point B
-                energyEvaluator.run(sb, mu_tot, vir, pres, step, FALSE);
+                energyEvaluator.run(sb, mu_tot, vir, pres, step, FALSE, step);
                 fnorm = sb->fnorm;
 
                 // Calculate gradient in point B
@@ -2761,6 +2803,8 @@ void LegacySimulator::do_steep()
     em_state_t* s_min = &s0;
     em_state_t* s_try = &s1;
 
+    ObservablesReducer observablesReducer = observablesReducerBuilder->build();
+
     /* Init em and store the local state in s_try */
     init_em(fplog,
             mdlog,
@@ -2826,9 +2870,25 @@ void LegacySimulator::do_steep()
     {
         sp_header(fplog, SD, inputrec->em_tol, nsteps);
     }
-    EnergyEvaluator energyEvaluator{ fplog,    mdlog,      cr,        ms,   top_global,      &top,
-                                     inputrec, imdSession, pull_work, nrnb, wcycle,          gstat,
-                                     vsite,    constr,     mdAtoms,   fr,   runScheduleWork, enerd };
+    EnergyEvaluator energyEvaluator{ fplog,
+                                     mdlog,
+                                     cr,
+                                     ms,
+                                     top_global,
+                                     &top,
+                                     inputrec,
+                                     imdSession,
+                                     pull_work,
+                                     nrnb,
+                                     wcycle,
+                                     gstat,
+                                     &observablesReducer,
+                                     vsite,
+                                     constr,
+                                     mdAtoms,
+                                     fr,
+                                     runScheduleWork,
+                                     enerd };
 
     /**** HERE STARTS THE LOOP ****
      * count is the counter for the number of steps
@@ -2853,7 +2913,7 @@ void LegacySimulator::do_steep()
 
         if (validStep)
         {
-            energyEvaluator.run(s_try, mu_tot, vir, pres, count, count == 0);
+            energyEvaluator.run(s_try, mu_tot, vir, pres, count, count == 0, count);
         }
         else
         {
@@ -3087,6 +3147,8 @@ void LegacySimulator::do_nm()
 
     em_state_t state_work{};
 
+    ObservablesReducer observablesReducer = observablesReducerBuilder->build();
+
     /* Init em and store the local state in state_minimum */
     init_em(fplog,
             mdlog,
@@ -3199,10 +3261,26 @@ void LegacySimulator::do_nm()
 
     /* Make evaluate_energy do a single node force calculation */
     cr->nnodes = 1;
-    EnergyEvaluator energyEvaluator{ fplog,    mdlog,      cr,        ms,   top_global,      &top,
-                                     inputrec, imdSession, pull_work, nrnb, wcycle,          gstat,
-                                     vsite,    constr,     mdAtoms,   fr,   runScheduleWork, enerd };
-    energyEvaluator.run(&state_work, mu_tot, vir, pres, -1, TRUE);
+    EnergyEvaluator energyEvaluator{ fplog,
+                                     mdlog,
+                                     cr,
+                                     ms,
+                                     top_global,
+                                     &top,
+                                     inputrec,
+                                     imdSession,
+                                     pull_work,
+                                     nrnb,
+                                     wcycle,
+                                     gstat,
+                                     &observablesReducer,
+                                     vsite,
+                                     constr,
+                                     mdAtoms,
+                                     fr,
+                                     runScheduleWork,
+                                     enerd };
+    energyEvaluator.run(&state_work, mu_tot, vir, pres, -1, TRUE, 0);
     cr->nnodes = nnodes;
 
     /* if forces are not small, warn user */
@@ -3296,7 +3374,7 @@ void LegacySimulator::do_nm()
                 }
                 else
                 {
-                    energyEvaluator.run(&state_work, mu_tot, vir, pres, aid * 2 + dx, FALSE);
+                    energyEvaluator.run(&state_work, mu_tot, vir, pres, aid * 2 + dx, FALSE, step);
                 }
 
                 cr->nnodes = nnodes;
index cd648a504e98e7b9723bc6f5a010d7dc6c25a250..877f73dddc384aba42e540eff445893f50f8b8a0 100644 (file)
 #include "gromacs/mdtypes/mdatom.h"
 #include "gromacs/mdtypes/mdrunoptions.h"
 #include "gromacs/mdtypes/observableshistory.h"
+#include "gromacs/mdtypes/observablesreducer.h"
 #include "gromacs/mdtypes/simulation_workload.h"
 #include "gromacs/mdtypes/state.h"
 #include "gromacs/mimic/utilities.h"
@@ -268,6 +269,8 @@ void gmx::LegacySimulator::do_rerun()
     int        nstglobalcomm = 1;
     const bool bNS           = true;
 
+    ObservablesReducer observablesReducer = observablesReducerBuilder->build();
+
     const SimulationGroups* groups = &top_global.groups;
     if (ir->eI == IntegrationAlgorithm::Mimic)
     {
@@ -384,6 +387,9 @@ void gmx::LegacySimulator::do_rerun()
         doFreeEnergyPerturbation = true;
     }
 
+    int64_t step     = ir->init_step;
+    int64_t step_rel = 0;
+
     {
         int cglo_flags = CGLO_GSTAT;
         if (DOMAINDECOMP(cr) && dd_localTopologyChecker(*cr->dd).shouldCheckNumberOfBondedInteractions())
@@ -413,7 +419,9 @@ void gmx::LegacySimulator::do_rerun()
                         &nullSignaller,
                         state->box,
                         &bSumEkinhOld,
-                        cglo_flags);
+                        cglo_flags,
+                        step,
+                        &observablesReducer);
         if (DOMAINDECOMP(cr))
         {
             dd_localTopologyChecker(cr->dd)->checkNumberOfBondedInteractions(
@@ -510,9 +518,6 @@ void gmx::LegacySimulator::do_rerun()
         calc_shifts(rerun_fr.box, fr->shift_vec);
     }
 
-    int64_t step     = ir->init_step;
-    int64_t step_rel = 0;
-
     auto stopHandler = stopHandlerBuilder->getStopHandlerMD(
             compat::not_null<SimulationSignal*>(&signals[eglsSTOPCOND]),
             false,
@@ -766,7 +771,9 @@ void gmx::LegacySimulator::do_rerun()
                             &signaller,
                             state->box,
                             &bSumEkinhOld,
-                            cglo_flags);
+                            cglo_flags,
+                            step,
+                            &observablesReducer);
             if (DOMAINDECOMP(cr))
             {
                 dd_localTopologyChecker(cr->dd)->checkNumberOfBondedInteractions(
index 765398cca5c780195292b3646a5aeb36d80f29f5..09964ee8b7c9b42f56c07c5042a01fe151cd30ac 100644 (file)
 #include "gromacs/mdtypes/mdatom.h"
 #include "gromacs/mdtypes/mdrunoptions.h"
 #include "gromacs/mdtypes/observableshistory.h"
+#include "gromacs/mdtypes/observablesreducer.h"
 #include "gromacs/mdtypes/simulation_workload.h"
 #include "gromacs/mdtypes/state.h"
 #include "gromacs/mdtypes/state_propagator_data_gpu.h"
@@ -1034,6 +1035,8 @@ int Mdrunner::mdrunner()
                                                               doEssentialDynamics,
                                                               membedHolder.doMembed());
 
+    ObservablesReducerBuilder observablesReducerBuilder;
+
     // Build restraints.
     // TODO: hide restraint implementation details from Mdrunner.
     // There is nothing unique about restraints at this point as far as the
@@ -2016,7 +2019,7 @@ int Mdrunner::mdrunner()
         simulatorBuilder.add(SimulatorConfig(mdrunOptions, startingBehavior, &runScheduleWork));
 
 
-        simulatorBuilder.add(SimulatorEnv(fplog, cr, ms, mdlog, oenv));
+        simulatorBuilder.add(SimulatorEnv(fplog, cr, ms, mdlog, oenv, &observablesReducerBuilder));
         simulatorBuilder.add(Profiling(&nrnb, walltime_accounting, wcycle.get()));
         simulatorBuilder.add(ConstraintsParam(
                 constr.get(), enforcedRotation ? enforcedRotation->getLegacyEnfrot() : nullptr, vsite.get()));
index 90b87f703d6b119a1ef4225180c44c8b5d1277f5..87cab10cfe618f9492b7eab65470a4bec6e253c6 100644 (file)
@@ -155,6 +155,7 @@ std::unique_ptr<ISimulator> SimulatorBuilder::build(bool useModularSimulator)
                                                       profiling_->wallCycle,
                                                       legacyInput_->forceRec,
                                                       simulatorStateData_->enerdata_p,
+                                                      simulatorEnv_->observablesReducerBuilder_,
                                                       simulatorStateData_->ekindata_p,
                                                       simulatorConfig_->runScheduleWork_,
                                                       *replicaExchangeParameters_,
@@ -192,6 +193,7 @@ std::unique_ptr<ISimulator> SimulatorBuilder::build(bool useModularSimulator)
                                                                 profiling_->wallCycle,
                                                                 legacyInput_->forceRec,
                                                                 simulatorStateData_->enerdata_p,
+                                                                simulatorEnv_->observablesReducerBuilder_,
                                                                 simulatorStateData_->ekindata_p,
                                                                 simulatorConfig_->runScheduleWork_,
                                                                 *replicaExchangeParameters_,
index 5d03dbb050c46e8c8d27c2fc5e2ab4d5675da377..5ab848fa808e9edc55752b32abe28bd984376fbc 100644 (file)
@@ -77,6 +77,7 @@ class MDAtoms;
 class MDLogger;
 struct MDModulesNotifiers;
 struct MdrunOptions;
+class ObservablesReducerBuilder;
 class ReadCheckpointDataHolder;
 enum class StartingBehavior;
 class StopHandlerBuilder;
@@ -148,12 +149,13 @@ class SimulatorEnv
 {
 public:
     //! Build from current simulation environment.
-    SimulatorEnv(FILE*             fplog,
-                 t_commrec*        commRec,
-                 gmx_multisim_t*   multisimCommRec,
-                 const MDLogger&   logger,
-                 gmx_output_env_t* outputEnv) :
-        fplog_{ fplog }, commRec_{ commRec }, multisimCommRec_{ multisimCommRec }, logger_{ logger }, outputEnv_{ outputEnv }
+    SimulatorEnv(FILE*                      fplog,
+                 t_commrec*                 commRec,
+                 gmx_multisim_t*            multisimCommRec,
+                 const MDLogger&            logger,
+                 gmx_output_env_t*          outputEnv,
+                 ObservablesReducerBuilder* observablesReducerBuilder) :
+        fplog_{ fplog }, commRec_{ commRec }, multisimCommRec_{ multisimCommRec }, logger_{ logger }, outputEnv_{ outputEnv }, observablesReducerBuilder_{ observablesReducerBuilder }
     {
     }
 
@@ -167,6 +169,8 @@ public:
     const MDLogger& logger_;
     //! Handle to file output handling.
     const gmx_output_env_t* outputEnv_;
+    //! Builder for coordinator of reduction for observables
+    ObservablesReducerBuilder* observablesReducerBuilder_;
 };
 
 /*! \brief
index c404b03534170888be1fb38adc7b21ef0ad069d7..cf5743bc40f1a4f1659b8414c173ae1cadd3da20 100644 (file)
@@ -153,7 +153,8 @@ ISimulatorElement* AndersenTemperatureCoupling::getElementPointerImpl(
         StatePropagatorData*                    statePropagatorData,
         EnergyData*                             energyData,
         FreeEnergyPerturbationData*             freeEnergyPerturbationData,
-        GlobalCommunicationHelper gmx_unused* globalCommunicationHelper)
+        GlobalCommunicationHelper gmx_unused* globalCommunicationHelper,
+        ObservablesReducer gmx_unused* observablesReducer)
 {
     GMX_RELEASE_ASSERT(legacySimulatorData->inputrec->etc == TemperatureCoupling::Andersen
                                || legacySimulatorData->inputrec->etc == TemperatureCoupling::AndersenMassive,
index cba4b56f9595efbfed1e40a74ca5339c30acc437..6cab2cad2844dec2a829e1be42d3c411f0ab0db0 100644 (file)
@@ -92,7 +92,8 @@ public:
      * \param statePropagatorData  Pointer to the \c StatePropagatorData object
      * \param energyData  Pointer to the \c EnergyData object
      * \param freeEnergyPerturbationData  Pointer to the \c FreeEnergyPerturbationData object
-     * \param globalCommunicationHelper  Pointer to the \c GlobalCommunicationHelper object
+     * \param globalCommunicationHelper   Pointer to the \c GlobalCommunicationHelper object
+     * \param observablesReducer          Pointer to the \c ObservablesReducer object
      *
      * \return  Pointer to the element to be added. Element needs to have been stored using \c storeElement
      */
@@ -101,7 +102,8 @@ public:
                                                     StatePropagatorData*        statePropagatorData,
                                                     EnergyData*                 energyData,
                                                     FreeEnergyPerturbationData* freeEnergyPerturbationData,
-                                                    GlobalCommunicationHelper* globalCommunicationHelper);
+                                                    GlobalCommunicationHelper* globalCommunicationHelper,
+                                                    ObservablesReducer*        observablesReducer);
 
     //! Returns the frequency at which temperature coupling is performed
     [[nodiscard]] int frequency() const;
index 3bf736748de755e3fc389e2af2ed74543b68c6fd..f54747211f71a58335f0277f5dbc7ac7a387544e 100644 (file)
@@ -70,18 +70,19 @@ template<ComputeGlobalsAlgorithm algorithm>
 ComputeGlobalsElement<algorithm>::ComputeGlobalsElement(StatePropagatorData* statePropagatorData,
                                                         EnergyData*          energyData,
                                                         FreeEnergyPerturbationData* freeEnergyPerturbationData,
-                                                        SimulationSignals* signals,
-                                                        int                nstglobalcomm,
-                                                        FILE*              fplog,
-                                                        const MDLogger&    mdlog,
-                                                        t_commrec*         cr,
-                                                        const t_inputrec*  inputrec,
-                                                        const MDAtoms*     mdAtoms,
-                                                        t_nrnb*            nrnb,
-                                                        gmx_wallcycle*     wcycle,
-                                                        t_forcerec*        fr,
-                                                        const gmx_mtop_t&  global_top,
-                                                        Constraints*       constr) :
+                                                        SimulationSignals*  signals,
+                                                        int                 nstglobalcomm,
+                                                        FILE*               fplog,
+                                                        const MDLogger&     mdlog,
+                                                        t_commrec*          cr,
+                                                        const t_inputrec*   inputrec,
+                                                        const MDAtoms*      mdAtoms,
+                                                        t_nrnb*             nrnb,
+                                                        gmx_wallcycle*      wcycle,
+                                                        t_forcerec*         fr,
+                                                        const gmx_mtop_t&   global_top,
+                                                        Constraints*        constr,
+                                                        ObservablesReducer* observablesReducer) :
     energyReductionStep_(-1),
     virialReductionStep_(-1),
     vvSchedulingStep_(-1),
@@ -106,7 +107,8 @@ ComputeGlobalsElement<algorithm>::ComputeGlobalsElement(StatePropagatorData* sta
     constr_(constr),
     nrnb_(nrnb),
     wcycle_(wcycle),
-    fr_(fr)
+    fr_(fr),
+    observablesReducer_(observablesReducer)
 {
     reportComRemovalInfo(fplog, vcm_);
     gstat_ = global_stat_init(inputrec_);
@@ -310,7 +312,9 @@ void ComputeGlobalsElement<algorithm>::compute(gmx::Step            step,
                     signaller,
                     lastbox,
                     energyData_->needToSumEkinhOld(),
-                    flags);
+                    flags,
+                    step,
+                    observablesReducer_);
     if (DOMAINDECOMP(cr_))
     {
         dd_localTopologyChecker(cr_->dd)->checkNumberOfBondedInteractions(localTopology_, x, box);
@@ -366,7 +370,8 @@ ISimulatorElement* ComputeGlobalsElement<ComputeGlobalsAlgorithm::LeapFrog>::get
         StatePropagatorData*                    statePropagatorData,
         EnergyData*                             energyData,
         FreeEnergyPerturbationData*             freeEnergyPerturbationData,
-        GlobalCommunicationHelper*              globalCommunicationHelper)
+        GlobalCommunicationHelper*              globalCommunicationHelper,
+        ObservablesReducer*                     observablesReducer)
 {
     auto* element = builderHelper->storeElement(
             std::make_unique<ComputeGlobalsElement<ComputeGlobalsAlgorithm::LeapFrog>>(
@@ -384,7 +389,8 @@ ISimulatorElement* ComputeGlobalsElement<ComputeGlobalsAlgorithm::LeapFrog>::get
                     legacySimulatorData->wcycle,
                     legacySimulatorData->fr,
                     legacySimulatorData->top_global,
-                    legacySimulatorData->constr));
+                    legacySimulatorData->constr,
+                    observablesReducer));
 
     return element;
 }
@@ -396,7 +402,8 @@ ISimulatorElement* ComputeGlobalsElement<ComputeGlobalsAlgorithm::VelocityVerlet
         StatePropagatorData*                    statePropagatorData,
         EnergyData*                             energyData,
         FreeEnergyPerturbationData*             freeEnergyPerturbationData,
-        GlobalCommunicationHelper*              globalCommunicationHelper)
+        GlobalCommunicationHelper*              globalCommunicationHelper,
+        ObservablesReducer*                     observablesReducer)
 {
     // We allow this element to be added multiple times to the call list, but we only want one
     // actual element built
@@ -426,7 +433,8 @@ ISimulatorElement* ComputeGlobalsElement<ComputeGlobalsAlgorithm::VelocityVerlet
                         simulator->wcycle,
                         simulator->fr,
                         simulator->top_global,
-                        simulator->constr));
+                        simulator->constr,
+                        observablesReducer));
         builderHelper->storeBuilderData(key, vvComputeGlobalsElement);
         return vvComputeGlobalsElement;
     }
index 2ae60fa09605a4ce935e21d477b793340904c975..f6905f20c747a31fa50ab2005c3170594d4c24b7 100644 (file)
@@ -62,6 +62,7 @@ class FreeEnergyPerturbationData;
 class LegacySimulatorData;
 class MDAtoms;
 class MDLogger;
+class ObservablesReducer;
 
 //! \addtogroup module_modularsimulator
 //! \{
@@ -119,7 +120,8 @@ public:
                           gmx_wallcycle*              wcycle,
                           t_forcerec*                 fr,
                           const gmx_mtop_t&           global_top,
-                          Constraints*                constr);
+                          Constraints*                constr,
+                          ObservablesReducer*         observablesReducer);
 
     //! Destructor
     ~ComputeGlobalsElement() override;
@@ -152,7 +154,8 @@ public:
      * \param statePropagatorData  Pointer to the \c StatePropagatorData object
      * \param energyData  Pointer to the \c EnergyData object
      * \param freeEnergyPerturbationData  Pointer to the \c FreeEnergyPerturbationData object
-     * \param globalCommunicationHelper  Pointer to the \c GlobalCommunicationHelper object
+     * \param globalCommunicationHelper   Pointer to the \c GlobalCommunicationHelper object
+     * \param observablesReducer          Pointer to the \c ObservablesReducer object
      *
      * \throws std::bad_any_cast  on internal error in VelocityVerlet algorithm builder.
      * \throws std::bad_alloc  when out of memory.
@@ -164,7 +167,8 @@ public:
                                                     StatePropagatorData*        statePropagatorData,
                                                     EnergyData*                 energyData,
                                                     FreeEnergyPerturbationData* freeEnergyPerturbationData,
-                                                    GlobalCommunicationHelper* globalCommunicationHelper);
+                                                    GlobalCommunicationHelper* globalCommunicationHelper,
+                                                    ObservablesReducer*        observablesReducer);
 
 private:
     //! ITopologyClient implementation
@@ -263,6 +267,8 @@ private:
     gmx_wallcycle* wcycle_;
     //! Parameters for force calculations.
     t_forcerec* fr_;
+    //! Coordinates reduction for observables
+    ObservablesReducer* observablesReducer_;
 };
 
 //! \}
index cbf914d09c2702b5d597c9cf8c87018e0208bcc4..5c5f8813576c2c3f00e17e6cbeb6778ed0264111 100644 (file)
@@ -238,7 +238,8 @@ ISimulatorElement* ConstraintsElement<variable>::getElementPointerImpl(
         StatePropagatorData*                    statePropagatorData,
         EnergyData*                             energyData,
         FreeEnergyPerturbationData*             freeEnergyPerturbationData,
-        GlobalCommunicationHelper gmx_unused* globalCommunicationHelper)
+        GlobalCommunicationHelper gmx_unused* globalCommunicationHelper,
+        ObservablesReducer* /*observablesReducer*/)
 {
     return builderHelper->storeElement(
             std::make_unique<ConstraintsElement<variable>>(legacySimulatorData->constr,
index d5564ba1b5277000c0f71561b88458cb567c2246..c8600dd689ec759ee7329345ef0bce7b61f0ebde 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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 @@ class FreeEnergyPerturbationData;
 class GlobalCommunicationHelper;
 class LegacySimulatorData;
 class ModularSimulatorAlgorithmBuilderHelper;
+class ObservablesReducer;
 class StatePropagatorData;
 
 /*! \internal
@@ -115,7 +116,8 @@ public:
      * \param statePropagatorData  Pointer to the \c StatePropagatorData object
      * \param energyData  Pointer to the \c EnergyData object
      * \param freeEnergyPerturbationData  Pointer to the \c FreeEnergyPerturbationData object
-     * \param globalCommunicationHelper  Pointer to the \c GlobalCommunicationHelper object
+     * \param globalCommunicationHelper   Pointer to the \c GlobalCommunicationHelper object
+     * \param observablesReducer          Pointer to the \c ObservablesReducer object
      *
      * \return  Pointer to the element to be added. Element needs to have been stored using \c storeElement
      */
@@ -124,7 +126,8 @@ public:
                                                     StatePropagatorData*        statePropagatorData,
                                                     EnergyData*                 energyData,
                                                     FreeEnergyPerturbationData* freeEnergyPerturbationData,
-                                                    GlobalCommunicationHelper* globalCommunicationHelper);
+                                                    GlobalCommunicationHelper* globalCommunicationHelper,
+                                                    ObservablesReducer*        observablesReducer);
 
 private:
     //! The actual constraining computation
index 5553ec2b8d7d02eeac5628617ad5fb8e76878b63..f2a58538cbc993bc795a66814c7c3e5669ef9bc8 100644 (file)
@@ -552,7 +552,8 @@ ISimulatorElement* EnergyData::Element::getElementPointerImpl(
         StatePropagatorData gmx_unused* statePropagatorData,
         EnergyData*                     energyData,
         FreeEnergyPerturbationData gmx_unused* freeEnergyPerturbationData,
-        GlobalCommunicationHelper gmx_unused* globalCommunicationHelper)
+        GlobalCommunicationHelper gmx_unused* globalCommunicationHelper,
+        ObservablesReducer* /*observablesReducer*/)
 {
     return energyData->element();
 }
index b4f2635acf760568e64f530a5d5406f7e7b1e342..9f6411c1f02610276d15f9bbaae43f0320fa879e 100644 (file)
@@ -66,6 +66,7 @@ class GlobalCommunicationHelper;
 class LegacySimulatorData;
 class MDAtoms;
 class ModularSimulatorAlgorithmBuilderHelper;
+class ObservablesReducer;
 class ParrinelloRahmanBarostat;
 class StatePropagatorData;
 class VelocityScalingTemperatureCoupling;
@@ -392,7 +393,8 @@ public:
      * \param statePropagatorData  Pointer to the \c StatePropagatorData object
      * \param energyData  Pointer to the \c EnergyData object
      * \param freeEnergyPerturbationData  Pointer to the \c FreeEnergyPerturbationData object
-     * \param globalCommunicationHelper  Pointer to the \c GlobalCommunicationHelper object
+     * \param globalCommunicationHelper   Pointer to the \c GlobalCommunicationHelper object
+     * \param observablesReducer          Pointer to the \c ObservablesReducer object
      *
      * \return  Pointer to the element to be added. Element needs to have been stored using \c storeElement
      */
@@ -401,7 +403,8 @@ public:
                                                     StatePropagatorData*        statePropagatorData,
                                                     EnergyData*                 energyData,
                                                     FreeEnergyPerturbationData* freeEnergyPerturbationData,
-                                                    GlobalCommunicationHelper* globalCommunicationHelper);
+                                                    GlobalCommunicationHelper* globalCommunicationHelper,
+                                                    ObservablesReducer*        observablesReducer);
 
 private:
     EnergyData* energyData_;
index c1ecee52b9e4ebd41561feaaf489a76031ae737a..ed9363d8ec5e05e8781acff8eff514ff21d6e3ae 100644 (file)
@@ -239,8 +239,9 @@ ISimulatorElement* FirstOrderPressureCoupling::getElementPointerImpl(
         EnergyData*                             energyData,
         FreeEnergyPerturbationData gmx_unused* freeEnergyPerturbationData,
         GlobalCommunicationHelper gmx_unused* globalCommunicationHelper,
-        int                                   offset,
-        ReportPreviousStepConservedEnergy     reportPreviousStepConservedEnergy)
+        ObservablesReducer* /*observablesReducer*/,
+        int                               offset,
+        ReportPreviousStepConservedEnergy reportPreviousStepConservedEnergy)
 {
     return builderHelper->storeElement(std::make_unique<FirstOrderPressureCoupling>(
             legacySimulatorData->inputrec->nstpcouple,
index 78c9e9a1668131baafefb198ed15a704fd53224d..489c8a4cbd7237b5e07cecdcb3a077c722541520 100644 (file)
@@ -59,6 +59,7 @@ class GlobalCommunicationHelper;
 class LegacySimulatorData;
 class MDAtoms;
 class ModularSimulatorAlgorithmBuilderHelper;
+class ObservablesReducer;
 class StatePropagatorData;
 
 /*! \internal
@@ -102,7 +103,8 @@ public:
      * \param statePropagatorData  Pointer to the \c StatePropagatorData object
      * \param energyData  Pointer to the \c EnergyData object
      * \param freeEnergyPerturbationData  Pointer to the \c FreeEnergyPerturbationData object
-     * \param globalCommunicationHelper  Pointer to the \c GlobalCommunicationHelper object
+     * \param globalCommunicationHelper   Pointer to the \c GlobalCommunicationHelper object
+     * \param observablesReducer          Pointer to the \c ObservablesReducer object
      * \param offset  The step offset at which the barostat is applied
      * \param reportPreviousStepConservedEnergy  Report the previous or the current step conserved energy
      *
@@ -115,6 +117,7 @@ public:
                           EnergyData*                             energyData,
                           FreeEnergyPerturbationData gmx_unused* freeEnergyPerturbationData,
                           GlobalCommunicationHelper gmx_unused* globalCommunicationHelper,
+                          ObservablesReducer*                   observablesReducer,
                           int                                   offset,
                           ReportPreviousStepConservedEnergy     reportPreviousStepConservedEnergy);
 
index 77565e161c3f83475c1e4854d3f87b72ba43f5fd..586e1bc2beb07640fee6c1334a990200afdc1408 100644 (file)
@@ -171,7 +171,7 @@ void ForceElement::run(Step step, Time time, unsigned int flags)
     {
         // TODO: Correcting the box is done in DomDecHelper (if using DD) or here (non-DD simulations).
         //       Think about unifying this responsibility, could this be done in one place?
-        auto box = statePropagatorData_->box();
+        auto* box = statePropagatorData_->box();
         correct_box(fplog_, step, box);
     }
 
@@ -180,10 +180,10 @@ void ForceElement::run(Step step, Time time, unsigned int flags)
      * This is parallelized as well, and does communication too.
      * Check comments in sim_util.c
      */
-    auto       x      = statePropagatorData_->positionsView();
-    auto&      forces = statePropagatorData_->forcesView();
-    auto       box    = statePropagatorData_->constBox();
-    history_t* hist   = nullptr; // disabled
+    auto        x      = statePropagatorData_->positionsView();
+    auto&       forces = statePropagatorData_->forcesView();
+    const auto* box    = statePropagatorData_->constBox();
+    history_t*  hist   = nullptr; // disabled
 
     tensor force_vir = { { 0 } };
     // TODO: Make lambda const (needs some adjustments in lower force routines)
@@ -307,7 +307,8 @@ ForceElement::getElementPointerImpl(LegacySimulatorData*                    lega
                                     StatePropagatorData*                    statePropagatorData,
                                     EnergyData*                             energyData,
                                     FreeEnergyPerturbationData* freeEnergyPerturbationData,
-                                    GlobalCommunicationHelper gmx_unused* globalCommunicationHelper)
+                                    GlobalCommunicationHelper gmx_unused* globalCommunicationHelper,
+                                    ObservablesReducer* /*observablesReducer*/)
 {
     const bool isVerbose    = legacySimulatorData->mdrunOptions.verbose;
     const bool isDynamicBox = inputrecDynamicBox(legacySimulatorData->inputrec);
index 27ba90a665d07590c3701ec5b17106d87923a8c1..c778d37be9025736cea5712c62ae0f876af7758d 100644 (file)
@@ -74,6 +74,7 @@ class LegacySimulatorData;
 class MDAtoms;
 class MdrunScheduleWorkload;
 class ModularSimulatorAlgorithmBuilderHelper;
+class ObservablesReducer;
 class StatePropagatorData;
 class VirtualSitesHandler;
 
@@ -132,7 +133,8 @@ public:
      * \param statePropagatorData  Pointer to the \c StatePropagatorData object
      * \param energyData  Pointer to the \c EnergyData object
      * \param freeEnergyPerturbationData  Pointer to the \c FreeEnergyPerturbationData object
-     * \param globalCommunicationHelper  Pointer to the \c GlobalCommunicationHelper object
+     * \param globalCommunicationHelper   Pointer to the \c GlobalCommunicationHelper object
+     * \param observablesReducer          Pointer to the \c ObservablesReducer object
      *
      * \return  Pointer to the element to be added. Element needs to have been stored using \c storeElement
      */
@@ -141,7 +143,8 @@ public:
                                                     StatePropagatorData*        statePropagatorData,
                                                     EnergyData*                 energyData,
                                                     FreeEnergyPerturbationData* freeEnergyPerturbationData,
-                                                    GlobalCommunicationHelper* globalCommunicationHelper);
+                                                    GlobalCommunicationHelper* globalCommunicationHelper,
+                                                    ObservablesReducer*        observablesReducer);
 
 private:
     //! ITopologyHolderClient implementation
index 42d170e2e7ce0c2414b333f36f7c7ff8fc1dbb27..82d6068a8fb132e339993cc308e2fe3c1161dc18 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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.
index 524519038d6344dfdb8b2bc7192b6705cbf22876..22517e52380c4c22f3b43646c9f5255a7037684a 100644 (file)
@@ -594,7 +594,8 @@ ISimulatorElement* MttkElement::getElementPointerImpl(
         StatePropagatorData gmx_unused* statePropagatorData,
         EnergyData*                     energyData,
         FreeEnergyPerturbationData gmx_unused* freeEnergyPerturbationData,
-        GlobalCommunicationHelper gmx_unused*  globalCommunicationHelper,
+        GlobalCommunicationHelper gmx_unused* globalCommunicationHelper,
+        ObservablesReducer gmx_unused*         observablesReducer,
         Offset                                 offset,
         ScheduleOnInitStep                     scheduleOnInitStep,
         const MttkPropagatorConnectionDetails& mttkPropagatorConnectionDetails)
@@ -665,7 +666,8 @@ ISimulatorElement* MttkBoxScaling::getElementPointerImpl(
         StatePropagatorData*                    statePropagatorData,
         EnergyData*                             energyData,
         FreeEnergyPerturbationData gmx_unused* freeEnergyPerturbationData,
-        GlobalCommunicationHelper gmx_unused*  globalCommunicationHelper,
+        GlobalCommunicationHelper gmx_unused* globalCommunicationHelper,
+        ObservablesReducer gmx_unused*         observablesReducer,
         const MttkPropagatorConnectionDetails& mttkPropagatorConnectionDetails)
 {
     // Data is now owned by the caller of this method, who will handle lifetime (see ModularSimulatorAlgorithm)
index a9549fe3e5aec77b85c0365ff2b92871ca8f3bce..fa03a8dde7fd94f9c3532744a7a49f71b981c04f 100644 (file)
@@ -319,10 +319,10 @@ public:
      * \param energyData  Pointer to the \c EnergyData object
      * \param freeEnergyPerturbationData  Pointer to the \c FreeEnergyPerturbationData object
      * \param globalCommunicationHelper  Pointer to the \c GlobalCommunicationHelper object
+     * \param observablesReducer  Pointer to the \c ObservablesReducer object
      * \param offset  The step offset at which the thermostat is applied
      * \param scheduleOnInitStep  Whether the element is scheduled on the initial step
      * \param mttkPropagatorConnectionDetails  Reference to the \c MttkPropagatorConnectionDetails object containing propagator tags and offsets
-
      *
      * \return  Pointer to the element to be added. Element needs to have been stored using \c storeElement
      */
@@ -333,6 +333,7 @@ public:
                           EnergyData*                             energyData,
                           FreeEnergyPerturbationData*             freeEnergyPerturbationData,
                           GlobalCommunicationHelper*              globalCommunicationHelper,
+                          ObservablesReducer*                     observablesReducer,
                           Offset                                  offset,
                           ScheduleOnInitStep                      scheduleOnInitStep,
                           const MttkPropagatorConnectionDetails&  mttkPropagatorConnectionDetails);
@@ -397,7 +398,8 @@ public:
      * \param statePropagatorData  Pointer to the \c StatePropagatorData object
      * \param energyData  Pointer to the \c EnergyData object
      * \param freeEnergyPerturbationData  Pointer to the \c FreeEnergyPerturbationData object
-     * \param globalCommunicationHelper  Pointer to the \c GlobalCommunicationHelper object
+     * \param globalCommunicationHelper   Pointer to the \c GlobalCommunicationHelper object
+     * \param observablesReducer          Pointer to the \c ObservablesReducer object
      * \param mttkPropagatorConnectionDetails  Reference to the \c MttkPropagatorConnectionDetails object containing propagator tags and offsets
      *
      * \return  Pointer to the element to be added. Element needs to have been stored using \c storeElement
@@ -409,6 +411,7 @@ public:
                           EnergyData*                             energyData,
                           FreeEnergyPerturbationData*             freeEnergyPerturbationData,
                           GlobalCommunicationHelper*              globalCommunicationHelper,
+                          ObservablesReducer*                     observablesReducer,
                           const MttkPropagatorConnectionDetails&  mttkPropagatorConnectionDetails);
 
 private:
index da1ecbd2d7f13bdd5063cb72adb9a2f8cf3785c8..60826edc88255339eef54fd8a6de0caef34b1e42 100644 (file)
@@ -712,6 +712,7 @@ ISimulatorElement* NoseHooverChainsElement::getElementPointerImpl(
         EnergyData*                     energyData,
         FreeEnergyPerturbationData gmx_unused* freeEnergyPerturbationData,
         GlobalCommunicationHelper gmx_unused*  globalCommunicationHelper,
+        ObservablesReducer*                    observablesReducer,
         NhcUsage                               nhcUsage,
         Offset                                 offset,
         UseFullStepKE                          useFullStepKE,
@@ -729,6 +730,7 @@ ISimulatorElement* NoseHooverChainsElement::getElementPointerImpl(
                                  energyData,
                                  freeEnergyPerturbationData,
                                  globalCommunicationHelper,
+                                 observablesReducer,
                                  nhcUsage,
                                  offset,
                                  useFullStepKE,
@@ -743,11 +745,12 @@ ISimulatorElement* NoseHooverChainsElement::getElementPointerImpl(
         EnergyData*                     energyData,
         FreeEnergyPerturbationData gmx_unused* freeEnergyPerturbationData,
         GlobalCommunicationHelper gmx_unused* globalCommunicationHelper,
-        NhcUsage                              nhcUsage,
-        Offset                                offset,
-        UseFullStepKE                         useFullStepKE,
-        ScheduleOnInitStep                    scheduleOnInitStep,
-        const PropagatorTag&                  propagatorTag)
+        ObservablesReducer gmx_unused* observablesReducer,
+        NhcUsage                       nhcUsage,
+        Offset                         offset,
+        UseFullStepKE                  useFullStepKE,
+        ScheduleOnInitStep             scheduleOnInitStep,
+        const PropagatorTag&           propagatorTag)
 {
     if (!builderHelper->simulationData<NoseHooverChainsData>(NoseHooverChainsData::dataID(nhcUsage)))
     {
index 75c97b7f779ec9fbd3d60f8bfe8c4f187ef64266..0abf32d0c243f69bf8c3280ad17b260b1c307e94 100644 (file)
@@ -60,6 +60,7 @@ class ModularSimulatorAlgorithmBuilderHelper;
 struct MttkPropagatorConnectionDetails;
 class MttkData;
 class NoseHooverGroup;
+class ObservablesReducer;
 class StatePropagatorData;
 enum class UseFullStepKE;
 
@@ -207,7 +208,8 @@ public:
      * \param statePropagatorData  Pointer to the \c StatePropagatorData object
      * \param energyData  Pointer to the \c EnergyData object
      * \param freeEnergyPerturbationData  Pointer to the \c FreeEnergyPerturbationData object
-     * \param globalCommunicationHelper  Pointer to the \c GlobalCommunicationHelper object
+     * \param globalCommunicationHelper   Pointer to the \c GlobalCommunicationHelper object
+     * \param observablesReducer          Pointer to the \c ObservablesReducer object
      * \param nhcUsage  What the NHC is connected to - system or barostat
      * \param offset  The step offset at which the thermostat is applied
      * \param useFullStepKE  Whether full step or half step KE is used
@@ -223,6 +225,7 @@ public:
                           EnergyData*                             energyData,
                           FreeEnergyPerturbationData*             freeEnergyPerturbationData,
                           GlobalCommunicationHelper*              globalCommunicationHelper,
+                          ObservablesReducer*                     observablesReducer,
                           NhcUsage                                nhcUsage,
                           Offset                                  offset,
                           UseFullStepKE                           useFullStepKE,
@@ -236,7 +239,8 @@ public:
      * \param statePropagatorData  Pointer to the \c StatePropagatorData object
      * \param energyData  Pointer to the \c EnergyData object
      * \param freeEnergyPerturbationData  Pointer to the \c FreeEnergyPerturbationData object
-     * \param globalCommunicationHelper  Pointer to the \c GlobalCommunicationHelper object
+     * \param globalCommunicationHelper   Pointer to the \c GlobalCommunicationHelper object
+     * \param observablesReducer          Pointer to the \c ObservablesReducer object
      * \param nhcUsage  What the NHC is connected to - system or barostat
      * \param offset  The step offset at which the thermostat is applied
      * \param useFullStepKE  Whether full step or half step KE is used
@@ -251,6 +255,7 @@ public:
                                                     EnergyData*                 energyData,
                                                     FreeEnergyPerturbationData* freeEnergyPerturbationData,
                                                     GlobalCommunicationHelper* globalCommunicationHelper,
+                                                    ObservablesReducer*        observablesReducer,
                                                     NhcUsage                   nhcUsage,
                                                     Offset                     offset,
                                                     UseFullStepKE              useFullStepKE,
index 95a6150088f437db7c526775182c641d661beb7d..d38f669fb55ddaee51b1ff198a8801aa4cd4fbbc 100644 (file)
@@ -331,8 +331,9 @@ ISimulatorElement* ParrinelloRahmanBarostat::getElementPointerImpl(
         EnergyData*                             energyData,
         FreeEnergyPerturbationData gmx_unused* freeEnergyPerturbationData,
         GlobalCommunicationHelper gmx_unused* globalCommunicationHelper,
-        Offset                                offset,
-        const PropagatorTag&                  propagatorTag)
+        ObservablesReducer* /*observablesReducer*/,
+        Offset               offset,
+        const PropagatorTag& propagatorTag)
 {
     auto* element  = builderHelper->storeElement(std::make_unique<ParrinelloRahmanBarostat>(
             legacySimulatorData->inputrec->nstpcouple,
index b49ba6de17e129bdd5199971780219ed2a9925fd..0e08fb5406f58e1913ed020c6daaf0622ab54dea 100644 (file)
@@ -58,6 +58,7 @@ enum class CheckpointDataOperation;
 class EnergyData;
 class LegacySimulatorData;
 class MDAtoms;
+class ObservablesReducer;
 class StatePropagatorData;
 
 /*! \internal
@@ -118,7 +119,8 @@ public:
      * \param statePropagatorData  Pointer to the \c StatePropagatorData object
      * \param energyData  Pointer to the \c EnergyData object
      * \param freeEnergyPerturbationData  Pointer to the \c FreeEnergyPerturbationData object
-     * \param globalCommunicationHelper  Pointer to the \c GlobalCommunicationHelper object
+     * \param globalCommunicationHelper   Pointer to the \c GlobalCommunicationHelper object
+     * \param observablesReducer          Pointer to the \c ObservablesReducer object
      * \param propagatorTag  Tag of the propagator to connect to
      * \param offset  The step offset at which the barostat is applied
      *
@@ -131,6 +133,7 @@ public:
                           EnergyData*                             energyData,
                           FreeEnergyPerturbationData gmx_unused* freeEnergyPerturbationData,
                           GlobalCommunicationHelper gmx_unused* globalCommunicationHelper,
+                          ObservablesReducer*                   observablesReducer,
                           Offset                                offset,
                           const PropagatorTag&                  propagatorTag);
 
index bf819fb323fcacd5b4b31cbe044296a063030368..5b2e020889aea258c66318624e95b46db4d13d6c 100644 (file)
@@ -915,19 +915,19 @@ static PropagatorConnection getConnection(Propagator<integrationStage> gmx_unuse
             return propagator->velocityScalingCallback();
         };
     }
-    if constexpr (hasStartVelocityScaling<integrationStage>())
+    if constexpr (hasStartVelocityScaling<integrationStage>()) // NOLINT(readability-misleading-indentation)
     {
         propagatorConnection.getViewOnStartVelocityScaling = [propagator]() {
             return propagator->viewOnStartVelocityScaling();
         };
     }
-    if constexpr (hasEndVelocityScaling<integrationStage>())
+    if constexpr (hasEndVelocityScaling<integrationStage>()) // NOLINT(readability-misleading-indentation)
     {
         propagatorConnection.getViewOnEndVelocityScaling = [propagator]() {
             return propagator->viewOnEndVelocityScaling();
         };
     }
-    if constexpr (hasPositionScaling<integrationStage>())
+    if constexpr (hasPositionScaling<integrationStage>()) // NOLINT(readability-misleading-indentation)
     {
         propagatorConnection.setNumPositionScalingVariables = [propagator](int num) {
             propagator->setNumPositionScalingVariables(num);
@@ -939,7 +939,7 @@ static PropagatorConnection getConnection(Propagator<integrationStage> gmx_unuse
             return propagator->positionScalingCallback();
         };
     }
-    if constexpr (hasParrinelloRahmanScaling<integrationStage>())
+    if constexpr (hasParrinelloRahmanScaling<integrationStage>()) // NOLINT(readability-misleading-indentation)
     {
         propagatorConnection.getViewOnPRScalingMatrix = [propagator]() {
             return propagator->viewOnPRScalingMatrix();
@@ -949,7 +949,7 @@ static PropagatorConnection getConnection(Propagator<integrationStage> gmx_unuse
         };
     }
 
-    return propagatorConnection;
+    return propagatorConnection; // NOLINT(readability-misleading-indentation)
 }
 
 // doxygen is confused by the two definitions
@@ -962,8 +962,9 @@ ISimulatorElement* Propagator<integrationStage>::getElementPointerImpl(
         EnergyData gmx_unused*     energyData,
         FreeEnergyPerturbationData gmx_unused* freeEnergyPerturbationData,
         GlobalCommunicationHelper gmx_unused* globalCommunicationHelper,
-        const PropagatorTag&                  propagatorTag,
-        TimeStep                              timestep)
+        ObservablesReducer* /* observablesReducer */,
+        const PropagatorTag& propagatorTag,
+        TimeStep             timestep)
 {
     GMX_RELEASE_ASSERT(!(integrationStage == IntegrationStage::ScaleVelocities
                          || integrationStage == IntegrationStage::ScalePositions)
@@ -984,6 +985,7 @@ ISimulatorElement* Propagator<integrationStage>::getElementPointerImpl(
         EnergyData*                             energyData,
         FreeEnergyPerturbationData*             freeEnergyPerturbationData,
         GlobalCommunicationHelper*              globalCommunicationHelper,
+        ObservablesReducer*                     observablesReducer,
         const PropagatorTag&                    propagatorTag)
 {
     GMX_RELEASE_ASSERT(
@@ -996,6 +998,7 @@ ISimulatorElement* Propagator<integrationStage>::getElementPointerImpl(
                                  energyData,
                                  freeEnergyPerturbationData,
                                  globalCommunicationHelper,
+                                 observablesReducer,
                                  propagatorTag,
                                  TimeStep(0.0));
 }
index 631a98f133782fface5d4f07495e118585b1a6b1..02c32ede8371385893458435012aec5154b40268 100644 (file)
@@ -62,6 +62,7 @@ class GlobalCommunicationHelper;
 class LegacySimulatorData;
 class MDAtoms;
 class ModularSimulatorAlgorithmBuilderHelper;
+class ObservablesReducer;
 class StatePropagatorData;
 
 //! \addtogroup module_modularsimulator
@@ -178,7 +179,8 @@ public:
      * \param statePropagatorData  Pointer to the \c StatePropagatorData object
      * \param energyData  Pointer to the \c EnergyData object
      * \param freeEnergyPerturbationData  Pointer to the \c FreeEnergyPerturbationData object
-     * \param globalCommunicationHelper  Pointer to the \c GlobalCommunicationHelper object
+     * \param globalCommunicationHelper   Pointer to the \c GlobalCommunicationHelper object
+     * \param observablesReducer          Pointer to the \c ObservablesReducer object
      * \param propagatorTag  The name of the propagator to simplify connection
      * \param timestep  The time step the propagator uses
      *
@@ -190,6 +192,7 @@ public:
                                                     EnergyData*                 energyData,
                                                     FreeEnergyPerturbationData* freeEnergyPerturbationData,
                                                     GlobalCommunicationHelper* globalCommunicationHelper,
+                                                    ObservablesReducer*        observablesReducer,
                                                     const PropagatorTag&       propagatorTag,
                                                     TimeStep                   timestep);
 
@@ -202,7 +205,8 @@ public:
      * \param statePropagatorData  Pointer to the \c StatePropagatorData object
      * \param energyData  Pointer to the \c EnergyData object
      * \param freeEnergyPerturbationData  Pointer to the \c FreeEnergyPerturbationData object
-     * \param globalCommunicationHelper  Pointer to the \c GlobalCommunicationHelper object
+     * \param globalCommunicationHelper   Pointer to the \c GlobalCommunicationHelper object
+     * \param observablesReducer          Pointer to the \c ObservablesReducer object
      * \param propagatorTag  The name of the propagator to simplify connection
      *
      * \return  Pointer to the element to be added. Element needs to have been stored using \c storeElement
@@ -213,6 +217,7 @@ public:
                                                     EnergyData*                 energyData,
                                                     FreeEnergyPerturbationData* freeEnergyPerturbationData,
                                                     GlobalCommunicationHelper* globalCommunicationHelper,
+                                                    ObservablesReducer*        observablesReducer,
                                                     const PropagatorTag&       propagatorTag);
 
 private:
index f4abbf7add149a2f94e26e64f0c9bd6eee23c3cd..4b035d12ae74a32e11628862b80177f119cc3cc9 100644 (file)
@@ -411,6 +411,7 @@ ModularSimulatorAlgorithmBuilder::ModularSimulatorAlgorithmBuilder(
                                                                 legacySimulatorData->inputrec,
                                                                 legacySimulatorData->cr),
                                signals_.get()),
+    observablesReducer_(legacySimulatorData->observablesReducerBuilder->build()),
     checkpointHelperBuilder_(std::move(checkpointDataHolder),
                              legacySimulatorData->startingBehavior,
                              legacySimulatorData->cr)
index eb559245a4acf553231ce51caa9354120770d6d0..1c6daaa0beeb536f3b8dde7c6ee19d3a140d7c6c 100644 (file)
@@ -55,6 +55,7 @@
 #include <typeinfo>
 
 #include "gromacs/mdrun/isimulator.h"
+#include "gromacs/mdtypes/observablesreducer.h"
 #include "gromacs/mdtypes/state.h"
 #include "gromacs/utility/exceptions.h"
 
@@ -287,7 +288,7 @@ private:
  *
  * This includes data that needs to be shared between elements involved in
  * global communication. This will become obsolete as soon as global
- * communication is moved to a client system (#3421).
+ * communication is moved to a client system (#3421 and #3887).
  */
 class GlobalCommunicationHelper
 {
@@ -438,8 +439,10 @@ private:
     std::unique_ptr<SimulationSignals> signals_;
     //! Helper object passed to element factory functions
     ModularSimulatorAlgorithmBuilderHelper elementAdditionHelper_;
-    //! Container for global computation data
+    //! Container for minor aspects of global computation data
     GlobalCommunicationHelper globalCommunicationHelper_;
+    //! Coordinates reduction for observables
+    ObservablesReducer observablesReducer_;
 
     /*! \brief Set arbitrary data in the ModularSimulatorAlgorithm
      *
@@ -565,7 +568,8 @@ private:
  *             StatePropagatorData*                    statePropagatorData,
  *             EnergyData*                             energyData,
  *             FreeEnergyPerturbationData*             freeEnergyPerturbationData,
- *             GlobalCommunicationHelper*              globalCommunicationHelper)
+ *             GlobalCommunicationHelper*              globalCommunicationHelper,
+ *             ObservablesReducer*                     observablesReducer)
  *
  * This function may also accept additional parameters which are passed using the variadic
  * template parameter pack forwarded in getElementPointer.
@@ -595,7 +599,8 @@ private:
  * \param statePropagatorData  Pointer to the \c StatePropagatorData object
  * \param energyData  Pointer to the \c EnergyData object
  * \param freeEnergyPerturbationData  Pointer to the \c FreeEnergyPerturbationData object
- * \param globalCommunicationHelper  Pointer to the \c GlobalCommunicationHelper object
+ * \param globalCommunicationHelper   Pointer to the \c GlobalCommunicationHelper object
+ * \param observablesReducer          Pointer to the \c ObservablesReducer object
  * \param args  Variable number of additional parameters to be forwarded
  *
  * \return  Pointer to the element to be added. Element needs to have been stored using \c storeElement
@@ -607,6 +612,7 @@ ISimulatorElement* getElementPointer(LegacySimulatorData*                    leg
                                      EnergyData*                             energyData,
                                      FreeEnergyPerturbationData* freeEnergyPerturbationData,
                                      GlobalCommunicationHelper*  globalCommunicationHelper,
+                                     ObservablesReducer*         observablesReducer,
                                      Args&&... args)
 {
     return Element::getElementPointerImpl(legacySimulatorData,
@@ -615,6 +621,7 @@ ISimulatorElement* getElementPointer(LegacySimulatorData*                    leg
                                           energyData,
                                           freeEnergyPerturbationData,
                                           globalCommunicationHelper,
+                                          observablesReducer,
                                           std::forward<Args>(args)...);
 }
 
@@ -634,6 +641,7 @@ void ModularSimulatorAlgorithmBuilder::add(Args&&... args)
                                                                      energyData_.get(),
                                                                      freeEnergyPerturbationData_.get(),
                                                                      &globalCommunicationHelper_,
+                                                                     &observablesReducer_,
                                                                      std::forward<Args>(args)...));
 
     // Make sure returned element pointer is owned by *this
index c9f72964099d40a2f2f8b19893ff2d0ab26c11e7..a0177f43c9ebdec912b89e10196b575207b72b44 100644 (file)
@@ -796,7 +796,8 @@ ISimulatorElement* StatePropagatorData::Element::getElementPointerImpl(
         StatePropagatorData*                               statePropagatorData,
         EnergyData gmx_unused*      energyData,
         FreeEnergyPerturbationData* freeEnergyPerturbationData,
-        GlobalCommunicationHelper gmx_unused* globalCommunicationHelper)
+        GlobalCommunicationHelper gmx_unused* globalCommunicationHelper,
+        ObservablesReducer* /*observablesReducer*/)
 {
     statePropagatorData->element()->setFreeEnergyPerturbationData(freeEnergyPerturbationData);
     return statePropagatorData->element();
index 78007403d50b0f083d3e268baba1f548329fd84d..d0f49027658ab58d5911ab100c7b0157af8de359 100644 (file)
@@ -71,6 +71,7 @@ class FreeEnergyPerturbationData;
 class GlobalCommunicationHelper;
 class LegacySimulatorData;
 class ModularSimulatorAlgorithmBuilderHelper;
+class ObservablesReducer;
 
 /*! \internal
  * \ingroup module_modularsimulator
@@ -333,7 +334,8 @@ public:
      * \param statePropagatorData  Pointer to the \c StatePropagatorData object
      * \param energyData  Pointer to the \c EnergyData object
      * \param freeEnergyPerturbationData  Pointer to the \c FreeEnergyPerturbationData object
-     * \param globalCommunicationHelper  Pointer to the \c GlobalCommunicationHelper object
+     * \param globalCommunicationHelper   Pointer to the \c GlobalCommunicationHelper object
+     * \param observablesReducer          Pointer to the \c ObservablesReducer object
      *
      * \return  Pointer to the element to be added. Element needs to have been stored using \c storeElement
      */
@@ -342,7 +344,8 @@ public:
                                                     StatePropagatorData*        statePropagatorData,
                                                     EnergyData*                 energyData,
                                                     FreeEnergyPerturbationData* freeEnergyPerturbationData,
-                                                    GlobalCommunicationHelper* globalCommunicationHelper);
+                                                    GlobalCommunicationHelper* globalCommunicationHelper,
+                                                    ObservablesReducer*        observablesReducer);
 
 private:
     //! Pointer to the associated StatePropagatorData
index 847bb15a8f2f88848a82363dcc0fe2258df06472..47df3fc82abcca8a7ebef784aa7aa5800650c1dd 100644 (file)
@@ -741,10 +741,11 @@ ISimulatorElement* VelocityScalingTemperatureCoupling::getElementPointerImpl(
         EnergyData*                     energyData,
         FreeEnergyPerturbationData gmx_unused* freeEnergyPerturbationData,
         GlobalCommunicationHelper gmx_unused* globalCommunicationHelper,
-        Offset                                offset,
-        UseFullStepKE                         useFullStepKE,
-        ReportPreviousStepConservedEnergy     reportPreviousStepConservedEnergy,
-        const PropagatorTag&                  propagatorTag)
+        ObservablesReducer* /*observablesReducer*/,
+        Offset                            offset,
+        UseFullStepKE                     useFullStepKE,
+        ReportPreviousStepConservedEnergy reportPreviousStepConservedEnergy,
+        const PropagatorTag&              propagatorTag)
 {
     // Element is now owned by the caller of this method, who will handle lifetime (see ModularSimulatorAlgorithm)
     auto* element = builderHelper->storeElement(std::make_unique<VelocityScalingTemperatureCoupling>(
index 9bd04b9e46b87078ccfd596bbbb7341ffd3fb3a1..6054ae71da3f077d4e5d8fdb4256e7bfbb0fe1df 100644 (file)
@@ -57,6 +57,7 @@ namespace gmx
 {
 class ITemperatureCouplingImpl;
 class LegacySimulatorData;
+class ObservablesReducer;
 struct TemperatureCouplingData;
 
 //! Enum describing whether the thermostat is using full or half step kinetic energy
@@ -129,7 +130,8 @@ public:
      * \param statePropagatorData  Pointer to the \c StatePropagatorData object
      * \param energyData  Pointer to the \c EnergyData object
      * \param freeEnergyPerturbationData  Pointer to the \c FreeEnergyPerturbationData object
-     * \param globalCommunicationHelper  Pointer to the \c GlobalCommunicationHelper object
+     * \param globalCommunicationHelper   Pointer to the \c GlobalCommunicationHelper object
+     * \param observablesReducer          Pointer to the \c ObservablesReducer object
      * \param propagatorTag  Tag of the propagator to connect to
      * \param offset  The step offset at which the thermostat is applied
      * \param useFullStepKE  Whether full step or half step KE is used
@@ -144,6 +146,7 @@ public:
                           EnergyData*                             energyData,
                           FreeEnergyPerturbationData*             freeEnergyPerturbationData,
                           GlobalCommunicationHelper*              globalCommunicationHelper,
+                          ObservablesReducer*                     observablesReducer,
                           Offset                                  offset,
                           UseFullStepKE                           useFullStepKE,
                           ReportPreviousStepConservedEnergy       reportPreviousStepConservedEnergy,