From: Mark Abraham Date: Mon, 12 Apr 2021 17:00:34 +0000 (+0000) Subject: Improve docs and naming for MdModulesNotifiers X-Git-Url: http://biod.pnpi.spb.ru/gitweb/?a=commitdiff_plain;h=d359c91dd5f8f3c556e4baadf97c6fab424324b4;p=alexxy%2Fgromacs.git Improve docs and naming for MdModulesNotifiers --- diff --git a/docs/doxygen/lib/mdmodules.md b/docs/doxygen/lib/mdmodules.md index 9d6ea6bf9c..f0f36441d6 100644 --- a/docs/doxygen/lib/mdmodules.md +++ b/docs/doxygen/lib/mdmodules.md @@ -162,17 +162,17 @@ and local atom sets by subscribing to callback functions. To include a notification for your module * Add the function signature for the callback function to the - `MdModulesNotifier` in `mdmodulenotification.h`, + `MDModulesNotifiers` in `mdmodulenotification.h`, ```C++ - registerMdModulesNotification<..., + BuildMDModulesNotifier<..., YourCallbackSignature, ..., ``` (keep alphabetical order for ease of git merge) -* Hand the notifier_ member of the MdModules Implementation class to your +* Hand the notifier_ member of the MDModules Implementation class to your builder createYourModule(¬ifier_) * Add the function you want to subscribe with in the builder, diff --git a/docs/doxygen/lib/modularsimulator.md b/docs/doxygen/lib/modularsimulator.md index d4776d3ec4..60615ef38f 100644 --- a/docs/doxygen/lib/modularsimulator.md +++ b/docs/doxygen/lib/modularsimulator.md @@ -725,7 +725,7 @@ with the XDR library. The alternative would be to write an entirely new data structure, changing the function signature of all checkpoint-related functions, and write a corresponding low-level routine interacting with the XDR library. -**The MdModule approach:** To allow for modules to write checkpoints, the legacy +**The MDModule approach:** To allow for modules to write checkpoints, the legacy checkpoint was extended by a KVTree. When writing to checkpoint, this tree gets filled (via callbacks) by the single modules, and then serialized. When reading, the KVTree gets deserialized, and then distributed to the modules which can read @@ -733,7 +733,7 @@ back the data previously stored. ##### Modular simulator design -The MdModule checks off almost all requirements to a modularized checkpointing format. +The MDModule checks off almost all requirements to a modularized checkpointing format. The proposed design is therefore an evolved form of this approach. Notably, two improvements include * Hide the implementation details of the data structure holding the data (currently, @@ -793,13 +793,13 @@ if clients write self-consistent read and write code, this should never be neede Checking for key existence seems rather to be a lazy way to circumvent versioning, and is therefore discouraged. -**Callback method:** The modular simulator and MdModules don't use the exact same +**Callback method:** The modular simulator and MDModules don't use the exact same way of communicating with clients. The two methods could be unified if needed. The only _fundamental_ difference is that modular simulator clients need to identify -with a unique key to receive their dedicated sub-data, while MdModules all read from -and write to the same KV-tree. MdModules could be adapted to that by either requiring +with a unique key to receive their dedicated sub-data, while MDModules all read from +and write to the same KV-tree. MDModules could be adapted to that by either requiring a unique key from the modules, or by using the same `CheckpointData` for all modules -and using a single unique key (something like "MdModules") to register that object +and using a single unique key (something like "MDModules") to register that object with the global checkpoint. **Performance:** One of the major differences between the new approach and the legacy diff --git a/src/gromacs/applied_forces/densityfitting/densityfitting.cpp b/src/gromacs/applied_forces/densityfitting/densityfitting.cpp index a891dfcf99..ed14140132 100644 --- a/src/gromacs/applied_forces/densityfitting/densityfitting.cpp +++ b/src/gromacs/applied_forces/densityfitting/densityfitting.cpp @@ -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. @@ -81,7 +81,7 @@ namespace * the DensityFitting class needs access to parameters that become available * only during simulation setup. * - * This class collects these parameters via MdModuleNotifications in the + * This class collects these parameters via MDModulesNotifiers in the * simulation setup phase and provides a check if all necessary parameters have * been provided. */ @@ -170,10 +170,10 @@ public: referenceDensityVoxel /= sumOfDensityData; } } - /*! \brief Set the periodic boundary condition via MdModuleNotifier. + /*! \brief Set the periodic boundary condition via MDModuleNotifier. * * The pbc type is wrapped in PeriodicBoundaryConditionType to - * allow the MdModuleNotifier to statically distinguish the callback + * allow the MDModuleNotifier to statically distinguish the callback * function type from other 'int' function callbacks. * * \param[in] pbcType enumerates the periodic boundary condition. @@ -230,7 +230,7 @@ public: /*! \brief Request to be notified during pre-processing. * - * \param[in] notifier allows the module to subscribe to notifications from MdModules. + * \param[in] notifiers allows the module to subscribe to notifications from MDModules. * * The density fitting code subscribes to these notifications: * - setting atom group indices in the densityFittingOptions_ from an @@ -239,9 +239,9 @@ public: * key-value-tree during pre-processing by a function taking a * KeyValueTreeObjectBuilder as parameter */ - void subscribeToPreProcessingNotifications(MdModulesNotifier* notifier) override + void subscribeToPreProcessingNotifications(MDModulesNotifiers* notifiers) override { - // Callbacks for several kinds of MdModuleNotification are created + // Callbacks for several kinds of MDModulesNotifier are created // and subscribed, and will be dispatched correctly at run time // based on the type of the parameter required by the lambda. @@ -254,20 +254,20 @@ public: const auto setFitGroupIndicesFunction = [this](const IndexGroupsAndNames& indexGroupsAndNames) { densityFittingOptions_.setFitGroupIndices(indexGroupsAndNames); }; - notifier->preProcessingNotifications_.subscribe(setFitGroupIndicesFunction); + notifiers->preProcessingNotifier_.subscribe(setFitGroupIndicesFunction); // Writing internal parameters during pre-processing const auto writeInternalParametersFunction = [this](KeyValueTreeObjectBuilder treeBuilder) { densityFittingOptions_.writeInternalParametersToKvt(treeBuilder); }; - notifier->preProcessingNotifications_.subscribe(writeInternalParametersFunction); + notifiers->preProcessingNotifier_.subscribe(writeInternalParametersFunction); // Checking for consistency with all .mdp options const auto checkEnergyCaluclationFrequencyFunction = [this](EnergyCalculationFrequencyErrors* energyCalculationFrequencyErrors) { densityFittingOptions_.checkEnergyCaluclationFrequency(energyCalculationFrequencyErrors); }; - notifier->preProcessingNotifications_.subscribe(checkEnergyCaluclationFrequencyFunction); + notifiers->preProcessingNotifier_.subscribe(checkEnergyCaluclationFrequencyFunction); } /*! \brief Request to be notified. @@ -279,13 +279,13 @@ public: * - the type of periodic boundary conditions that are used * by taking a PeriodicBoundaryConditionType as parameter * - the writing of checkpoint data - * by taking a MdModulesWriteCheckpointData as parameter + * by taking a MDModulesWriteCheckpointData as parameter * - the reading of checkpoint data - * by taking a MdModulesCheckpointReadingDataOnMaster as parameter + * by taking a MDModulesCheckpointReadingDataOnMaster as parameter * - the broadcasting of checkpoint data - * by taking MdModulesCheckpointReadingBroadcast as parameter + * by taking MDModulesCheckpointReadingBroadcast as parameter */ - void subscribeToSimulationSetupNotifications(MdModulesNotifier* notifier) override + void subscribeToSimulationSetupNotifications(MDModulesNotifiers* notifiers) override { if (!densityFittingOptions_.active()) { @@ -296,51 +296,51 @@ public: const auto readInternalParametersFunction = [this](const KeyValueTreeObject& tree) { densityFittingOptions_.readInternalParametersFromKvt(tree); }; - notifier->simulationSetupNotifications_.subscribe(readInternalParametersFunction); + notifiers->simulationSetupNotifier_.subscribe(readInternalParametersFunction); // constructing local atom sets during simulation setup const auto setLocalAtomSetFunction = [this](LocalAtomSetManager* localAtomSetManager) { this->constructLocalAtomSet(localAtomSetManager); }; - notifier->simulationSetupNotifications_.subscribe(setLocalAtomSetFunction); + notifiers->simulationSetupNotifier_.subscribe(setLocalAtomSetFunction); // constructing local atom sets during simulation setup const auto setPeriodicBoundaryContionsFunction = [this](const PbcType& pbc) { this->densityFittingSimulationParameters_.setPeriodicBoundaryConditionType(pbc); }; - notifier->simulationSetupNotifications_.subscribe(setPeriodicBoundaryContionsFunction); + notifiers->simulationSetupNotifier_.subscribe(setPeriodicBoundaryContionsFunction); // setting the simulation time step const auto setSimulationTimeStepFunction = [this](const SimulationTimeStep& simulationTimeStep) { this->densityFittingSimulationParameters_.setSimulationTimeStep(simulationTimeStep.delta_t); }; - notifier->simulationSetupNotifications_.subscribe(setSimulationTimeStepFunction); + notifiers->simulationSetupNotifier_.subscribe(setSimulationTimeStepFunction); // adding output to energy file const auto requestEnergyOutput = - [this](MdModulesEnergyOutputToDensityFittingRequestChecker* energyOutputRequest) { + [this](MDModulesEnergyOutputToDensityFittingRequestChecker* energyOutputRequest) { this->setEnergyOutputRequest(energyOutputRequest); }; - notifier->simulationSetupNotifications_.subscribe(requestEnergyOutput); + notifiers->simulationSetupNotifier_.subscribe(requestEnergyOutput); // writing checkpoint data - const auto checkpointDataWriting = [this](MdModulesWriteCheckpointData checkpointData) { + const auto checkpointDataWriting = [this](MDModulesWriteCheckpointData checkpointData) { forceProvider_->writeCheckpointData(checkpointData, DensityFittingModuleInfo::name_); }; - notifier->checkpointingNotifications_.subscribe(checkpointDataWriting); + notifiers->checkpointingNotifier_.subscribe(checkpointDataWriting); // reading checkpoint data - const auto checkpointDataReading = [this](MdModulesCheckpointReadingDataOnMaster checkpointData) { + const auto checkpointDataReading = [this](MDModulesCheckpointReadingDataOnMaster checkpointData) { densityFittingState_.readState(checkpointData.checkpointedData_, DensityFittingModuleInfo::name_); }; - notifier->checkpointingNotifications_.subscribe(checkpointDataReading); + notifiers->checkpointingNotifier_.subscribe(checkpointDataReading); // broadcasting checkpoint data - const auto checkpointDataBroadcast = [this](MdModulesCheckpointReadingBroadcast checkpointData) { + const auto checkpointDataBroadcast = [this](MDModulesCheckpointReadingBroadcast checkpointData) { densityFittingState_.broadcastState(checkpointData.communicator_, checkpointData.isParallelRun_); }; - notifier->checkpointingNotifications_.subscribe(checkpointDataBroadcast); + notifiers->checkpointingNotifier_.subscribe(checkpointDataBroadcast); } //! From IMDModule @@ -375,7 +375,7 @@ public: /*! \brief Set up the local atom sets that are used by this module. * - * \note When density fitting is set up with MdModuleNotification in + * \note When density fitting is set up with MDModulesNotifier in * the constructor, this function is called back. * * \param[in] localAtomSetManager the manager to add local atom sets. @@ -388,7 +388,7 @@ public: /*! \brief Request energy output to energy file during simulation. */ - void setEnergyOutputRequest(MdModulesEnergyOutputToDensityFittingRequestChecker* energyOutputRequest) + void setEnergyOutputRequest(MDModulesEnergyOutputToDensityFittingRequestChecker* energyOutputRequest) { energyOutputRequest->energyOutputToDensityFitting_ = densityFittingOptions_.active(); } diff --git a/src/gromacs/applied_forces/densityfitting/densityfittingforceprovider.cpp b/src/gromacs/applied_forces/densityfitting/densityfittingforceprovider.cpp index eec0e3c8b4..9a4f5d7e86 100644 --- a/src/gromacs/applied_forces/densityfitting/densityfittingforceprovider.cpp +++ b/src/gromacs/applied_forces/densityfitting/densityfittingforceprovider.cpp @@ -417,7 +417,7 @@ void DensityFittingForceProvider::calculateForces(const ForceProviderInput& forc impl_->calculateForces(forceProviderInput, forceProviderOutput); } -void DensityFittingForceProvider::writeCheckpointData(MdModulesWriteCheckpointData checkpointWriting, +void DensityFittingForceProvider::writeCheckpointData(MDModulesWriteCheckpointData checkpointWriting, const std::string& moduleName) { impl_->stateToCheckpoint().writeState(checkpointWriting.builder_, moduleName); diff --git a/src/gromacs/applied_forces/densityfitting/densityfittingforceprovider.h b/src/gromacs/applied_forces/densityfitting/densityfittingforceprovider.h index 5896218156..c31d1a694d 100644 --- a/src/gromacs/applied_forces/densityfitting/densityfittingforceprovider.h +++ b/src/gromacs/applied_forces/densityfitting/densityfittingforceprovider.h @@ -142,7 +142,7 @@ public: * \note The provided state to checkpoint has to change if checkpointing * is moved before the force provider call in the MD-loop. */ - void writeCheckpointData(MdModulesWriteCheckpointData checkpointWriting, const std::string& moduleName); + void writeCheckpointData(MDModulesWriteCheckpointData checkpointWriting, const std::string& moduleName); private: class Impl; diff --git a/src/gromacs/applied_forces/electricfield.cpp b/src/gromacs/applied_forces/electricfield.cpp index 2140b62263..6d4a45a34b 100644 --- a/src/gromacs/applied_forces/electricfield.cpp +++ b/src/gromacs/applied_forces/electricfield.cpp @@ -171,8 +171,8 @@ public: void calculateForces(const ForceProviderInput& forceProviderInput, ForceProviderOutput* forceProviderOutput) override; - void subscribeToSimulationSetupNotifications(MdModulesNotifier* /* notifier */) override {} - void subscribeToPreProcessingNotifications(MdModulesNotifier* /* notifier */) override {} + void subscribeToSimulationSetupNotifications(MDModulesNotifiers* /* notifiers */) override {} + void subscribeToPreProcessingNotifications(MDModulesNotifiers* /* notifiers */) override {} private: //! Return whether or not to apply a field diff --git a/src/gromacs/fileio/checkpoint.cpp b/src/gromacs/fileio/checkpoint.cpp index 0bbe5657d0..18dc33422e 100644 --- a/src/gromacs/fileio/checkpoint.cpp +++ b/src/gromacs/fileio/checkpoint.cpp @@ -158,7 +158,7 @@ enum cptv cptv_RemoveBuildMachineInformation, /**< remove functionality that makes mdrun builds non-reproducible */ cptv_ComPrevStepAsPullGroupReference, /**< Allow using COM of previous step as pull group PBC reference */ cptv_PullAverage, /**< Added possibility to output average pull force and position */ - cptv_MdModules, /**< Added checkpointing for MdModules */ + cptv_MDModules, /**< Added checkpointing for MDModules */ cptv_ModularSimulator, /**< Added checkpointing for modular simulator */ cptv_Count /**< the total number of cptv versions */ }; @@ -2193,12 +2193,12 @@ static int do_cpt_awh(XDR* xd, gmx_bool bRead, int fflags, gmx::AwhHistory* awhH return ret; } -static void do_cpt_mdmodules(int fileVersion, - t_fileio* checkpointFileHandle, - const gmx::MdModulesNotifier& mdModulesNotifier, - FILE* outputFile) +static void do_cpt_mdmodules(int fileVersion, + t_fileio* checkpointFileHandle, + const gmx::MDModulesNotifiers& mdModulesNotifiers, + FILE* outputFile) { - if (fileVersion >= cptv_MdModules) + if (fileVersion >= cptv_MDModules) { gmx::FileIOXdrSerializer serializer(checkpointFileHandle); gmx::KeyValueTreeObject mdModuleCheckpointParameterTree = @@ -2208,10 +2208,10 @@ static void do_cpt_mdmodules(int fileVersion, gmx::TextWriter textWriter(outputFile); gmx::dumpKeyValueTree(&textWriter, mdModuleCheckpointParameterTree); } - gmx::MdModulesCheckpointReadingDataOnMaster mdModuleCheckpointReadingDataOnMaster = { + gmx::MDModulesCheckpointReadingDataOnMaster mdModuleCheckpointReadingDataOnMaster = { mdModuleCheckpointParameterTree, fileVersion }; - mdModulesNotifier.checkpointingNotifications_.notify(mdModuleCheckpointReadingDataOnMaster); + mdModulesNotifiers.checkpointingNotifier_.notify(mdModuleCheckpointReadingDataOnMaster); } } @@ -2304,7 +2304,7 @@ void write_checkpoint_data(t_fileio* fp, LambdaWeightCalculation elamstats, t_state* state, ObservablesHistory* observablesHistory, - const gmx::MdModulesNotifier& mdModulesNotifier, + const gmx::MDModulesNotifiers& mdModulesNotifiers, std::vector* outputfiles, gmx::WriteCheckpointDataHolder* modularSimulatorCheckpointData) { @@ -2423,12 +2423,12 @@ void write_checkpoint_data(t_fileio* fp, gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?"); } - // Checkpointing MdModules + // Checkpointing MDModules { gmx::KeyValueTreeBuilder builder; - gmx::MdModulesWriteCheckpointData mdModulesWriteCheckpoint = { builder.rootObject(), + gmx::MDModulesWriteCheckpointData mdModulesWriteCheckpoint = { builder.rootObject(), headerContents.file_version }; - mdModulesNotifier.checkpointingNotifications_.notify(mdModulesWriteCheckpoint); + mdModulesNotifiers.checkpointingNotifier_.notify(mdModulesWriteCheckpoint); auto tree = builder.build(); gmx::FileIOXdrSerializer serializer(fp); gmx::serializeKeyValueTree(tree, &serializer); @@ -2605,7 +2605,7 @@ static void read_checkpoint(const char* fn, t_state* state, ObservablesHistory* observablesHistory, gmx_bool reproducibilityRequested, - const gmx::MdModulesNotifier& mdModulesNotifier, + const gmx::MDModulesNotifiers& mdModulesNotifiers, gmx::ReadCheckpointDataHolder* modularSimulatorCheckpointData, bool useModularSimulator) { @@ -2817,7 +2817,7 @@ static void read_checkpoint(const char* fn, { cp_error(); } - do_cpt_mdmodules(headerContents->file_version, fp, mdModulesNotifier, nullptr); + do_cpt_mdmodules(headerContents->file_version, fp, mdModulesNotifiers, nullptr); if (headerContents->file_version >= cptv_ModularSimulator) { gmx::FileIOXdrSerializer serializer(fp); @@ -2843,7 +2843,7 @@ void load_checkpoint(const char* fn, t_state* state, ObservablesHistory* observablesHistory, gmx_bool reproducibilityRequested, - const gmx::MdModulesNotifier& mdModulesNotifier, + const gmx::MDModulesNotifiers& mdModulesNotifiers, gmx::ReadCheckpointDataHolder* modularSimulatorCheckpointData, bool useModularSimulator) { @@ -2861,17 +2861,17 @@ void load_checkpoint(const char* fn, state, observablesHistory, reproducibilityRequested, - mdModulesNotifier, + mdModulesNotifiers, modularSimulatorCheckpointData, useModularSimulator); } if (PAR(cr)) { gmx_bcast(sizeof(headerContents.step), &headerContents.step, cr->mpiDefaultCommunicator); - gmx::MdModulesCheckpointReadingBroadcast broadcastCheckPointData = { + gmx::MDModulesCheckpointReadingBroadcast broadcastCheckPointData = { cr->mpiDefaultCommunicator, PAR(cr), headerContents.file_version }; - mdModulesNotifier.checkpointingNotifications_.notify(broadcastCheckPointData); + mdModulesNotifiers.checkpointingNotifier_.notify(broadcastCheckPointData); } ir->bContinuation = TRUE; if (ir->nsteps >= 0) @@ -2992,8 +2992,8 @@ static CheckpointHeaderContents read_checkpoint_data(t_fileio* { cp_error(); } - gmx::MdModulesNotifier mdModuleNotifier; - do_cpt_mdmodules(headerContents.file_version, fp, mdModuleNotifier, nullptr); + gmx::MDModulesNotifiers mdModuleNotifiers; + do_cpt_mdmodules(headerContents.file_version, fp, mdModuleNotifiers, nullptr); if (headerContents.file_version >= cptv_ModularSimulator) { // Store modular checkpoint data into modularSimulatorCheckpointData @@ -3111,8 +3111,8 @@ void list_checkpoint(const char* fn, FILE* out) std::vector outputfiles; ret = do_cpt_files(gmx_fio_getxdr(fp), TRUE, &outputfiles, out, headerContents.file_version); } - gmx::MdModulesNotifier mdModuleNotifier; - do_cpt_mdmodules(headerContents.file_version, fp, mdModuleNotifier, out); + gmx::MDModulesNotifiers mdModuleNotifiers; + do_cpt_mdmodules(headerContents.file_version, fp, mdModuleNotifiers, out); if (headerContents.file_version >= cptv_ModularSimulator) { gmx::FileIOXdrSerializer serializer(fp); diff --git a/src/gromacs/fileio/checkpoint.h b/src/gromacs/fileio/checkpoint.h index 49cc0fe77b..f2c35b8c53 100644 --- a/src/gromacs/fileio/checkpoint.h +++ b/src/gromacs/fileio/checkpoint.h @@ -64,7 +64,7 @@ enum class LambdaWeightCalculation : int; namespace gmx { -struct MdModulesNotifier; +struct MDModulesNotifiers; class KeyValueTreeObject; class ReadCheckpointDataHolder; class WriteCheckpointDataHolder; @@ -125,20 +125,20 @@ extern template void writeKvtCheckpointValue(const real& value, KeyValueTreeObjectBuilder kvtBuilder); /*! \libinternal - * \brief Provides the MdModules with the checkpointed data on the master rank. + * \brief Provides the MDModules with the checkpointed data on the master rank. */ -struct MdModulesCheckpointReadingDataOnMaster +struct MDModulesCheckpointReadingDataOnMaster { - //! The data of the MdModules that is stored in the checkpoint file + //! The data of the MDModules that is stored in the checkpoint file const KeyValueTreeObject& checkpointedData_; //! The version of the read ceckpoint file int checkpointFileVersion_; }; /*! \libinternal - * \brief Provides the MdModules with the communication record to broadcast. + * \brief Provides the MDModules with the communication record to broadcast. */ -struct MdModulesCheckpointReadingBroadcast +struct MDModulesCheckpointReadingBroadcast { //! The communicator MPI_Comm communicator_; @@ -148,11 +148,11 @@ struct MdModulesCheckpointReadingBroadcast int checkpointFileVersion_; }; -/*! \libinternal \brief Writing the MdModules data to a checkpoint file. +/*! \libinternal \brief Writing the MDModules data to a checkpoint file. */ -struct MdModulesWriteCheckpointData +struct MDModulesWriteCheckpointData { - //! Builder for the Key-Value-Tree to store the MdModule checkpoint data + //! Builder for the Key-Value-Tree to store the MDModule checkpoint data KeyValueTreeObjectBuilder builder_; //! The version of the read file version int checkpointFileVersion_; @@ -252,7 +252,7 @@ void write_checkpoint_data(t_fileio* fp, LambdaWeightCalculation elamstats, t_state* state, ObservablesHistory* observablesHistory, - const gmx::MdModulesNotifier& notifier, + const gmx::MDModulesNotifiers& mdModulesNotifiers, std::vector* outputfiles, gmx::WriteCheckpointDataHolder* modularSimulatorCheckpointData); @@ -271,7 +271,7 @@ void load_checkpoint(const char* fn, t_state* state, ObservablesHistory* observablesHistory, gmx_bool reproducibilityRequested, - const gmx::MdModulesNotifier& mdModulesNotifier, + const gmx::MDModulesNotifiers& mdModulesNotifiers, gmx::ReadCheckpointDataHolder* modularSimulatorCheckpointData, bool useModularSimulator); diff --git a/src/gromacs/gmxpreprocess/grompp.cpp b/src/gromacs/gmxpreprocess/grompp.cpp index 85f6e376cc..2f10d3b364 100644 --- a/src/gromacs/gmxpreprocess/grompp.cpp +++ b/src/gromacs/gmxpreprocess/grompp.cpp @@ -1926,7 +1926,7 @@ int gmx_grompp(int argc, char* argv[]) } GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR - // Now that the MdModules have their options assigned from get_ir, subscribe + // Now that the MDModules have their options assigned from get_ir, subscribe // to eventual notifications during pre-processing their data mdModules.subscribeToPreProcessingNotifications(); @@ -1937,7 +1937,7 @@ int gmx_grompp(int argc, char* argv[]) .asParagraph() .appendTextFormatted("checking input for internal consistency..."); } - check_ir(mdparin, mdModules.notifier(), ir, opts, wi); + check_ir(mdparin, mdModules.notifiers(), ir, opts, wi); if (ir->ld_seed == -1) { @@ -2201,7 +2201,7 @@ int gmx_grompp(int argc, char* argv[]) { GMX_LOG(logger.info).asParagraph().appendTextFormatted("initialising group options..."); } - do_index(mdparin, ftp2fn_null(efNDX, NFILE, fnm), &sys, bVerbose, mdModules.notifier(), ir, wi); + do_index(mdparin, ftp2fn_null(efNDX, NFILE, fnm), &sys, bVerbose, mdModules.notifiers(), ir, wi); if (ir->cutoff_scheme == CutoffScheme::Verlet && ir->verletbuf_tol > 0) { @@ -2488,7 +2488,7 @@ int gmx_grompp(int argc, char* argv[]) { gmx::KeyValueTreeBuilder internalParameterBuilder; - mdModules.notifier().preProcessingNotifications_.notify(internalParameterBuilder.rootObject()); + mdModules.notifiers().preProcessingNotifier_.notify(internalParameterBuilder.rootObject()); ir->internalParameters = std::make_unique(internalParameterBuilder.build()); } diff --git a/src/gromacs/gmxpreprocess/readir.cpp b/src/gromacs/gmxpreprocess/readir.cpp index 426bd68d39..f1f70cb257 100644 --- a/src/gromacs/gmxpreprocess/readir.cpp +++ b/src/gromacs/gmxpreprocess/readir.cpp @@ -219,11 +219,11 @@ static void process_interaction_modifier(InteractionModifiers* eintmod) } } -void check_ir(const char* mdparin, - const gmx::MdModulesNotifier& mdModulesNotifier, - t_inputrec* ir, - t_gromppopts* opts, - warninp_t wi) +void check_ir(const char* mdparin, + const gmx::MDModulesNotifiers& mdModulesNotifiers, + t_inputrec* ir, + t_gromppopts* opts, + warninp_t wi) /* Check internal consistency. * NOTE: index groups are not set here yet, don't check things * like temperature coupling group options here, but in triple_check @@ -580,10 +580,10 @@ void check_ir(const char* mdparin, check_nst("nstcalcenergy", ir->nstcalcenergy, "nstenergy", &ir->nstenergy, wi); } - // Inquire all MdModules, if their parameters match with the energy + // Inquire all MDModules, if their parameters match with the energy // calculation frequency gmx::EnergyCalculationFrequencyErrors energyCalculationFrequencyErrors(ir->nstcalcenergy); - mdModulesNotifier.preProcessingNotifications_.notify(&energyCalculationFrequencyErrors); + mdModulesNotifiers.preProcessingNotifier_.notify(&energyCalculationFrequencyErrors); // Emit all errors from the energy calculation frequency checks for (const std::string& energyFrequencyErrorMessage : @@ -3449,13 +3449,13 @@ static void checkAndUpdateVcmFreezeGroupConsistency(SimulationGroups* groups, } } -void do_index(const char* mdparin, - const char* ndx, - gmx_mtop_t* mtop, - bool bVerbose, - const gmx::MdModulesNotifier& notifier, - t_inputrec* ir, - warninp_t wi) +void do_index(const char* mdparin, + const char* ndx, + gmx_mtop_t* mtop, + bool bVerbose, + const gmx::MDModulesNotifiers& mdModulesNotifiers, + t_inputrec* ir, + warninp_t wi) { t_blocka* defaultIndexGroups; int natoms; @@ -3868,7 +3868,7 @@ void do_index(const char* mdparin, gmx::IndexGroupsAndNames defaultIndexGroupsAndNames( *defaultIndexGroups, gmx::arrayRefFromArray(gnames, defaultIndexGroups->nr)); - notifier.preProcessingNotifications_.notify(defaultIndexGroupsAndNames); + mdModulesNotifiers.preProcessingNotifier_.notify(defaultIndexGroupsAndNames); auto freezeDims = gmx::splitString(inputrecStrings->frdim); auto freezeGroupNames = gmx::splitString(inputrecStrings->freeze); diff --git a/src/gromacs/gmxpreprocess/readir.h b/src/gromacs/gmxpreprocess/readir.h index da326072f5..9b7aa8194d 100644 --- a/src/gromacs/gmxpreprocess/readir.h +++ b/src/gromacs/gmxpreprocess/readir.h @@ -50,7 +50,7 @@ namespace gmx { class MDModules; -struct MdModulesNotifier; +struct MDModulesNotifiers; } // namespace gmx struct gmx_mtop_t; @@ -112,11 +112,11 @@ void init_inputrec_strings(); /*! \brief Clean up object that holds strings parsed from an .mdp file */ void done_inputrec_strings(); -void check_ir(const char* mdparin, - const gmx::MdModulesNotifier& mdModulesNotifier, - t_inputrec* ir, - t_gromppopts* opts, - warninp_t wi); +void check_ir(const char* mdparin, + const gmx::MDModulesNotifiers& mdModulesNotifiers, + t_inputrec* ir, + t_gromppopts* opts, + warninp_t wi); /* Validate inputrec data. * Fatal errors will be added to nerror. */ @@ -141,13 +141,13 @@ void get_ir(const char* mdparin, * function is called. Also prints the input file back to mdparout. */ -void do_index(const char* mdparin, - const char* ndx, - gmx_mtop_t* mtop, - bool bVerbose, - const gmx::MdModulesNotifier& notifier, - t_inputrec* ir, - warninp_t wi); +void do_index(const char* mdparin, + const char* ndx, + gmx_mtop_t* mtop, + bool bVerbose, + const gmx::MDModulesNotifiers& mdModulesNotifiers, + t_inputrec* ir, + warninp_t wi); /* Read the index file and assign grp numbers to atoms. */ diff --git a/src/gromacs/gmxpreprocess/tests/readir.cpp b/src/gromacs/gmxpreprocess/tests/readir.cpp index 0ad5a321f3..af1b9b967a 100644 --- a/src/gromacs/gmxpreprocess/tests/readir.cpp +++ b/src/gromacs/gmxpreprocess/tests/readir.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by + * Copyright (c) 2017,2018,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. @@ -96,7 +96,7 @@ public: get_ir(inputMdpFilename.c_str(), outputMdpFilename.c_str(), &mdModules_, &ir_, &opts_, WriteMdpHeader::no, wi_); - check_ir(inputMdpFilename.c_str(), mdModules_.notifier(), &ir_, &opts_, wi_); + check_ir(inputMdpFilename.c_str(), mdModules_.notifiers(), &ir_, &opts_, wi_); // Now check bool failure = warning_errors_exist(wi_); TestReferenceData data; diff --git a/src/gromacs/imd/imd.cpp b/src/gromacs/imd/imd.cpp index c75f8d7ce0..cf475be7cc 100644 --- a/src/gromacs/imd/imd.cpp +++ b/src/gromacs/imd/imd.cpp @@ -326,8 +326,8 @@ class InteractiveMolecularDynamics final : public IMDModule IMdpOptionProvider* mdpOptionProvider() override { return nullptr; } IMDOutputProvider* outputProvider() override { return nullptr; } void initForceProviders(ForceProviders* /* forceProviders */) override {} - void subscribeToSimulationSetupNotifications(MdModulesNotifier* /* notifier */) override {} - void subscribeToPreProcessingNotifications(MdModulesNotifier* /* notifier */) override {} + void subscribeToSimulationSetupNotifications(MDModulesNotifiers* /* notifiers */) override {} + void subscribeToPreProcessingNotifications(MDModulesNotifiers* /* notifiers */) override {} }; std::unique_ptr createInteractiveMolecularDynamicsModule() diff --git a/src/gromacs/mdlib/energyoutput.cpp b/src/gromacs/mdlib/energyoutput.cpp index 737354a93b..e736b2c5c0 100644 --- a/src/gromacs/mdlib/energyoutput.cpp +++ b/src/gromacs/mdlib/energyoutput.cpp @@ -130,15 +130,15 @@ namespace gmx * \todo Remove GMX_CONSTRAINTVIR * \todo Write free-energy output also to energy file (after adding more tests) */ -EnergyOutput::EnergyOutput(ener_file* fp_ene, - const gmx_mtop_t& mtop, - const t_inputrec& inputrec, - const pull_t* pull_work, - FILE* fp_dhdl, - bool isRerun, - const StartingBehavior startingBehavior, - const bool simulationsShareState, - const MdModulesNotifier& mdModulesNotifier) +EnergyOutput::EnergyOutput(ener_file* fp_ene, + const gmx_mtop_t& mtop, + const t_inputrec& inputrec, + const pull_t* pull_work, + FILE* fp_dhdl, + bool isRerun, + const StartingBehavior startingBehavior, + const bool simulationsShareState, + const MDModulesNotifiers& mdModulesNotifiers) { const char* ener_nm[F_NRE]; static const char* vir_nm[] = { "Vir-XX", "Vir-XY", "Vir-XZ", "Vir-YX", "Vir-YY", @@ -259,8 +259,8 @@ EnergyOutput::EnergyOutput(ener_file* fp_ene, bEner_[F_ORIRESDEV] = (gmx_mtop_ftype_count(mtop, F_ORIRES) > 0); bEner_[F_COM_PULL] = ((inputrec.bPull && pull_have_potential(*pull_work)) || inputrec.bRot); - MdModulesEnergyOutputToDensityFittingRequestChecker mdModulesAddOutputToDensityFittingFieldRequest; - mdModulesNotifier.simulationSetupNotifications_.notify(&mdModulesAddOutputToDensityFittingFieldRequest); + MDModulesEnergyOutputToDensityFittingRequestChecker mdModulesAddOutputToDensityFittingFieldRequest; + mdModulesNotifiers.simulationSetupNotifier_.notify(&mdModulesAddOutputToDensityFittingFieldRequest); bEner_[F_DENSITYFITTING] = mdModulesAddOutputToDensityFittingFieldRequest.energyOutputToDensityFitting_; diff --git a/src/gromacs/mdlib/energyoutput.h b/src/gromacs/mdlib/energyoutput.h index ea917b6e02..1adbc1c827 100644 --- a/src/gromacs/mdlib/energyoutput.h +++ b/src/gromacs/mdlib/energyoutput.h @@ -73,7 +73,7 @@ namespace gmx { class Awh; class Constraints; -struct MdModulesNotifier; +struct MDModulesNotifiers; enum class StartingBehavior; } // namespace gmx @@ -140,17 +140,17 @@ public: * \param[in] isRerun Is this is a rerun instead of the simulations. * \param[in] startingBehavior Run starting behavior. * \param[in] simulationsShareState Tells whether the physical state is shared over simulations - * \param[in] mdModulesNotifier Notifications to MD modules. + * \param[in] mdModulesNotifiers Notifications to MD modules. */ - EnergyOutput(ener_file* fp_ene, - const gmx_mtop_t& mtop, - const t_inputrec& inputrec, - const pull_t* pull_work, - FILE* fp_dhdl, - bool isRerun, - StartingBehavior startingBehavior, - bool simulationsShareState, - const MdModulesNotifier& mdModulesNotifier); + EnergyOutput(ener_file* fp_ene, + const gmx_mtop_t& mtop, + const t_inputrec& inputrec, + const pull_t* pull_work, + FILE* fp_dhdl, + bool isRerun, + StartingBehavior startingBehavior, + bool simulationsShareState, + const MDModulesNotifiers& mdModulesNotifiers); ~EnergyOutput(); diff --git a/src/gromacs/mdlib/mdoutf.cpp b/src/gromacs/mdlib/mdoutf.cpp index ee2335ddf7..8f8fd006a4 100644 --- a/src/gromacs/mdlib/mdoutf.cpp +++ b/src/gromacs/mdlib/mdoutf.cpp @@ -75,45 +75,45 @@ struct gmx_mdoutf { - t_fileio* fp_trn; - t_fileio* fp_xtc; - gmx_tng_trajectory_t tng; - gmx_tng_trajectory_t tng_low_prec; - int x_compression_precision; /* only used by XTC output */ - ener_file_t fp_ene; - const char* fn_cpt; - gmx_bool bKeepAndNumCPT; - IntegrationAlgorithm eIntegrator; - gmx_bool bExpanded; - LambdaWeightCalculation elamstats; - int simulation_part; - FILE* fp_dhdl; - int natoms_global; - int natoms_x_compressed; - const SimulationGroups* groups; /* for compressed position writing */ - gmx_wallcycle_t wcycle; - rvec* f_global; - gmx::IMDOutputProvider* outputProvider; - const gmx::MdModulesNotifier* mdModulesNotifier; - bool simulationsShareState; - MPI_Comm mastersComm; + t_fileio* fp_trn; + t_fileio* fp_xtc; + gmx_tng_trajectory_t tng; + gmx_tng_trajectory_t tng_low_prec; + int x_compression_precision; /* only used by XTC output */ + ener_file_t fp_ene; + const char* fn_cpt; + gmx_bool bKeepAndNumCPT; + IntegrationAlgorithm eIntegrator; + gmx_bool bExpanded; + LambdaWeightCalculation elamstats; + int simulation_part; + FILE* fp_dhdl; + int natoms_global; + int natoms_x_compressed; + const SimulationGroups* groups; /* for compressed position writing */ + gmx_wallcycle_t wcycle; + rvec* f_global; + gmx::IMDOutputProvider* outputProvider; + const gmx::MDModulesNotifiers* mdModulesNotifiers; + bool simulationsShareState; + MPI_Comm mastersComm; }; -gmx_mdoutf_t init_mdoutf(FILE* fplog, - int nfile, - const t_filenm fnm[], - const gmx::MdrunOptions& mdrunOptions, - const t_commrec* cr, - gmx::IMDOutputProvider* outputProvider, - const gmx::MdModulesNotifier& mdModulesNotifier, - const t_inputrec* ir, - const gmx_mtop_t& top_global, - const gmx_output_env_t* oenv, - gmx_wallcycle_t wcycle, - const gmx::StartingBehavior startingBehavior, - bool simulationsShareState, - const gmx_multisim_t* ms) +gmx_mdoutf_t init_mdoutf(FILE* fplog, + int nfile, + const t_filenm fnm[], + const gmx::MdrunOptions& mdrunOptions, + const t_commrec* cr, + gmx::IMDOutputProvider* outputProvider, + const gmx::MDModulesNotifiers& mdModulesNotifiers, + const t_inputrec* ir, + const gmx_mtop_t& top_global, + const gmx_output_env_t* oenv, + gmx_wallcycle_t wcycle, + const gmx::StartingBehavior startingBehavior, + bool simulationsShareState, + const gmx_multisim_t* ms) { gmx_mdoutf_t of; const char * appendMode = "a+", *writeMode = "w+", *filemode; @@ -220,7 +220,7 @@ gmx_mdoutf_t init_mdoutf(FILE* fplog, } outputProvider->initOutput(fplog, nfile, fnm, restartWithAppending, oenv); - of->mdModulesNotifier = &mdModulesNotifier; + of->mdModulesNotifiers = &mdModulesNotifiers; /* Set up atom counts so they can be passed to actual trajectory-writing routines later. Also, XTC writing needs @@ -297,7 +297,7 @@ static void write_checkpoint(const char* fn, double t, t_state* state, ObservablesHistory* observablesHistory, - const gmx::MdModulesNotifier& mdModulesNotifier, + const gmx::MDModulesNotifiers& mdModulesNotifiers, gmx::WriteCheckpointDataHolder* modularSimulatorCheckpointData, bool applyMpiBarrierBeforeRename, MPI_Comm mpiBarrierCommunicator) @@ -400,7 +400,7 @@ static void write_checkpoint(const char* fn, elamstats, state, observablesHistory, - mdModulesNotifier, + mdModulesNotifiers, &outputfiles, modularSimulatorCheckpointData); @@ -517,7 +517,7 @@ void mdoutf_write_checkpoint(gmx_mdoutf_t of, t, state_global, observablesHistory, - *(of->mdModulesNotifier), + *(of->mdModulesNotifiers), modularSimulatorCheckpointData, of->simulationsShareState, of->mastersComm); diff --git a/src/gromacs/mdlib/mdoutf.h b/src/gromacs/mdlib/mdoutf.h index d727d89474..6461f9c747 100644 --- a/src/gromacs/mdlib/mdoutf.h +++ b/src/gromacs/mdlib/mdoutf.h @@ -57,7 +57,7 @@ namespace gmx { enum class StartingBehavior; class IMDOutputProvider; -struct MdModulesNotifier; +struct MDModulesNotifiers; struct MdrunOptions; class WriteCheckpointDataHolder; } // namespace gmx @@ -69,20 +69,20 @@ typedef struct gmx_mdoutf* gmx_mdoutf_t; * Returns a pointer to a data structure with all output file pointers * and names required by mdrun. */ -gmx_mdoutf_t init_mdoutf(FILE* fplog, - int nfile, - const t_filenm fnm[], - const gmx::MdrunOptions& mdrunOptions, - const t_commrec* cr, - gmx::IMDOutputProvider* outputProvider, - const gmx::MdModulesNotifier& mdModulesNotifier, - const t_inputrec* ir, - const gmx_mtop_t& mtop, - const gmx_output_env_t* oenv, - gmx_wallcycle_t wcycle, - gmx::StartingBehavior startingBehavior, - bool simulationsShareState, - const gmx_multisim_t* ms); +gmx_mdoutf_t init_mdoutf(FILE* fplog, + int nfile, + const t_filenm fnm[], + const gmx::MdrunOptions& mdrunOptions, + const t_commrec* cr, + gmx::IMDOutputProvider* outputProvider, + const gmx::MDModulesNotifiers& mdModulesNotifiers, + const t_inputrec* ir, + const gmx_mtop_t& mtop, + const gmx_output_env_t* oenv, + gmx_wallcycle_t wcycle, + gmx::StartingBehavior startingBehavior, + bool simulationsShareState, + const gmx_multisim_t* ms); /*! \brief Getter for file pointer */ ener_file_t mdoutf_get_fp_ene(gmx_mdoutf_t of); diff --git a/src/gromacs/mdlib/tests/energyoutput.cpp b/src/gromacs/mdlib/tests/energyoutput.cpp index 78a4d92367..ec11ab68a8 100644 --- a/src/gromacs/mdlib/tests/energyoutput.cpp +++ b/src/gromacs/mdlib/tests/energyoutput.cpp @@ -617,7 +617,7 @@ TEST_P(EnergyOutputTest, CheckOutput) inputrec_.ref_p[YY][XX] = 1.0; } - MdModulesNotifier mdModulesNotifier; + MDModulesNotifiers mdModulesNotifiers; std::unique_ptr energyOutput = std::make_unique(energyFile_, mtop_, @@ -627,7 +627,7 @@ TEST_P(EnergyOutputTest, CheckOutput) parameters.isRerun, StartingBehavior::NewSimulation, false, - mdModulesNotifier); + mdModulesNotifiers); // Add synthetic data for a single step double testValue = 10.0; diff --git a/src/gromacs/mdrun/isimulator.h b/src/gromacs/mdrun/isimulator.h index 7ef5a99846..37ffb33742 100644 --- a/src/gromacs/mdrun/isimulator.h +++ b/src/gromacs/mdrun/isimulator.h @@ -71,7 +71,7 @@ class BoxDeformation; class Constraints; class MdrunScheduleWorkload; class IMDOutputProvider; -struct MdModulesNotifier; +struct MDModulesNotifiers; class ImdSession; class MDLogger; class MDAtoms; @@ -123,7 +123,7 @@ public: gmx_enfrot* enforcedRotation, BoxDeformation* deform, IMDOutputProvider* outputProvider, - const MdModulesNotifier& mdModulesNotifier, + const MDModulesNotifiers& mdModulesNotifiers, t_inputrec* inputrec, ImdSession* imdSession, pull_t* pull_work, @@ -157,7 +157,7 @@ public: enforcedRotation(enforcedRotation), deform(deform), outputProvider(outputProvider), - mdModulesNotifier(mdModulesNotifier), + mdModulesNotifiers(mdModulesNotifiers), inputrec(inputrec), imdSession(imdSession), pull_work(pull_work), @@ -208,8 +208,8 @@ public: BoxDeformation* deform; //! Handles writing output files. IMDOutputProvider* outputProvider; - //! Handles notifications to MdModules for checkpoint writing - const MdModulesNotifier& mdModulesNotifier; + //! Handles notifications to MDModules for checkpoint writing + const MDModulesNotifiers& mdModulesNotifiers; //! Contains user input mdp options. Note: The const-ness is casted away in a few instances, see #3854. const t_inputrec* inputrec; //! The Interactive Molecular Dynamics session. diff --git a/src/gromacs/mdrun/md.cpp b/src/gromacs/mdrun/md.cpp index a7487ff8cf..7ac685d7f2 100644 --- a/src/gromacs/mdrun/md.cpp +++ b/src/gromacs/mdrun/md.cpp @@ -308,7 +308,7 @@ void gmx::LegacySimulator::do_md() mdrunOptions, cr, outputProvider, - mdModulesNotifier, + mdModulesNotifiers, ir, top_global, oenv, @@ -324,7 +324,7 @@ void gmx::LegacySimulator::do_md() false, startingBehavior, simulationsShareState, - mdModulesNotifier); + mdModulesNotifiers); gstat = global_stat_init(ir); diff --git a/src/gromacs/mdrun/mdmodules.cpp b/src/gromacs/mdrun/mdmodules.cpp index 1014a0adde..fabeb2f4ef 100644 --- a/src/gromacs/mdrun/mdmodules.cpp +++ b/src/gromacs/mdrun/mdmodules.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2017,2018,2019,2020, by the GROMACS development team, led by + * Copyright (c) 2016,2017,2018,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. @@ -96,7 +96,7 @@ public: * \note The notifier must be constructed before the modules and shall * not be destructed before the modules are destructed. */ - MdModulesNotifier notifier_; + MDModulesNotifiers notifiers_; std::unique_ptr densityFitting_; std::unique_ptr field_; @@ -176,12 +176,12 @@ ForceProviders* MDModules::initForceProviders() void MDModules::subscribeToPreProcessingNotifications() { - impl_->densityFitting_->subscribeToPreProcessingNotifications(&impl_->notifier_); + impl_->densityFitting_->subscribeToPreProcessingNotifications(&impl_->notifiers_); } void MDModules::subscribeToSimulationSetupNotifications() { - impl_->densityFitting_->subscribeToSimulationSetupNotifications(&impl_->notifier_); + impl_->densityFitting_->subscribeToSimulationSetupNotifications(&impl_->notifiers_); } void MDModules::add(std::shared_ptr module) @@ -189,9 +189,9 @@ void MDModules::add(std::shared_ptr module) impl_->modules_.emplace_back(std::move(module)); } -const MdModulesNotifier& MDModules::notifier() +const MDModulesNotifiers& MDModules::notifiers() { - return impl_->notifier_; + return impl_->notifiers_; } } // namespace gmx diff --git a/src/gromacs/mdrun/mdmodules.h b/src/gromacs/mdrun/mdmodules.h index 5665701e33..1bd23fd237 100644 --- a/src/gromacs/mdrun/mdmodules.h +++ b/src/gromacs/mdrun/mdmodules.h @@ -58,7 +58,7 @@ class IKeyValueTreeErrorHandler; class IKeyValueTreeTransformRules; class IMDModule; class IMDOutputProvider; -struct MdModulesNotifier; +struct MDModulesNotifiers; /*! \libinternal \brief * Manages the collection of all modules used for mdrun. @@ -144,17 +144,17 @@ public: */ ForceProviders* initForceProviders(); - /*! \brief Subscribe MdModules to simulation setup notifications. + /*! \brief Subscribe MDModules to simulation setup notifications. * - * Allows MdModules to subscribe to notifications that are called back + * Allows MDModules to subscribe to notifications that are called back * during the set up of an MD simulation, after the options were * assigned to the modules. */ void subscribeToSimulationSetupNotifications(); - /*! \brief Subscribe MdModules to notifications during pre-processing. + /*! \brief Subscribe MDModules to notifications during pre-processing. * - * Allows MdModules to subscribe to notifications that are called back + * Allows MDModules to subscribe to notifications that are called back * during pre processing an MD simulation, after the options were * assigned to the modules. */ @@ -184,9 +184,9 @@ public: */ void add(std::shared_ptr module); - /*! \brief Return a handle to the callbacks. + /*! \brief Return a handle to the notifiers used for callbacks between modules. */ - const MdModulesNotifier& notifier(); + const MDModulesNotifiers& notifiers(); private: class Impl; diff --git a/src/gromacs/mdrun/mimic.cpp b/src/gromacs/mdrun/mimic.cpp index a434de0126..d5403f1945 100644 --- a/src/gromacs/mdrun/mimic.cpp +++ b/src/gromacs/mdrun/mimic.cpp @@ -242,7 +242,7 @@ void gmx::LegacySimulator::do_mimic() mdrunOptions, cr, outputProvider, - mdModulesNotifier, + mdModulesNotifiers, ir, top_global, oenv, @@ -258,7 +258,7 @@ void gmx::LegacySimulator::do_mimic() true, StartingBehavior::NewSimulation, simulationsShareState, - mdModulesNotifier); + mdModulesNotifiers); gstat = global_stat_init(ir); diff --git a/src/gromacs/mdrun/minimize.cpp b/src/gromacs/mdrun/minimize.cpp index c7da246c7c..99c20e2989 100644 --- a/src/gromacs/mdrun/minimize.cpp +++ b/src/gromacs/mdrun/minimize.cpp @@ -1240,7 +1240,7 @@ void LegacySimulator::do_cg() mdrunOptions, cr, outputProvider, - mdModulesNotifier, + mdModulesNotifiers, inputrec, top_global, nullptr, @@ -1256,7 +1256,7 @@ void LegacySimulator::do_cg() false, StartingBehavior::NewSimulation, simulationsShareState, - mdModulesNotifier); + mdModulesNotifiers); /* Print to log file */ print_em_start(fplog, cr, walltime_accounting, wcycle, CG); @@ -1942,7 +1942,7 @@ void LegacySimulator::do_lbfgs() mdrunOptions, cr, outputProvider, - mdModulesNotifier, + mdModulesNotifiers, inputrec, top_global, nullptr, @@ -1958,7 +1958,7 @@ void LegacySimulator::do_lbfgs() false, StartingBehavior::NewSimulation, simulationsShareState, - mdModulesNotifier); + mdModulesNotifiers); const int start = 0; const int end = mdatoms->homenr; @@ -2723,7 +2723,7 @@ void LegacySimulator::do_steep() mdrunOptions, cr, outputProvider, - mdModulesNotifier, + mdModulesNotifiers, inputrec, top_global, nullptr, @@ -2739,7 +2739,7 @@ void LegacySimulator::do_steep() false, StartingBehavior::NewSimulation, simulationsShareState, - mdModulesNotifier); + mdModulesNotifiers); /* Print to log file */ print_em_start(fplog, cr, walltime_accounting, wcycle, SD); @@ -3051,7 +3051,7 @@ void LegacySimulator::do_nm() mdrunOptions, cr, outputProvider, - mdModulesNotifier, + mdModulesNotifiers, inputrec, top_global, nullptr, diff --git a/src/gromacs/mdrun/rerun.cpp b/src/gromacs/mdrun/rerun.cpp index ed4ede7134..e1234ade76 100644 --- a/src/gromacs/mdrun/rerun.cpp +++ b/src/gromacs/mdrun/rerun.cpp @@ -284,7 +284,7 @@ void gmx::LegacySimulator::do_rerun() mdrunOptions, cr, outputProvider, - mdModulesNotifier, + mdModulesNotifiers, ir, top_global, oenv, @@ -300,7 +300,7 @@ void gmx::LegacySimulator::do_rerun() true, StartingBehavior::NewSimulation, simulationsShareState, - mdModulesNotifier); + mdModulesNotifiers); gstat = global_stat_init(ir); diff --git a/src/gromacs/mdrun/runner.cpp b/src/gromacs/mdrun/runner.cpp index 19fe216747..68da5a1b17 100644 --- a/src/gromacs/mdrun/runner.cpp +++ b/src/gromacs/mdrun/runner.cpp @@ -988,13 +988,13 @@ int Mdrunner::mdrunner() // TODO: Error handling mdModules_->assignOptionsToModules(*inputrec->params, nullptr); - // now that the MdModules know their options, they know which callbacks to sign up to + // now that the MDModules know their options, they know which callbacks to sign up to mdModules_->subscribeToSimulationSetupNotifications(); - const auto& mdModulesNotifier = mdModules_->notifier().simulationSetupNotifications_; + const auto& setupNotifier = mdModules_->notifiers().simulationSetupNotifier_; if (inputrec->internalParameters != nullptr) { - mdModulesNotifier.notify(*inputrec->internalParameters); + setupNotifier.notify(*inputrec->internalParameters); } if (fplog != nullptr) @@ -1069,7 +1069,7 @@ int Mdrunner::mdrunner() SeparatePmeRanksPermitted separatePmeRanksPermitted; /* Permit MDModules to notify whether they want to use PME-only ranks */ - mdModulesNotifier.notify(&separatePmeRanksPermitted); + setupNotifier.notify(&separatePmeRanksPermitted); /* If simulation is not using PME then disable PME-only ranks */ if (!(EEL_PME(inputrec->coulombtype) || EVDW_PME(inputrec->vdwtype))) @@ -1195,7 +1195,7 @@ int Mdrunner::mdrunner() globalState.get(), &observablesHistory, mdrunOptions.reproducible, - mdModules_->notifier(), + mdModules_->notifiers(), modularSimulatorCheckpointData.get(), useModularSimulator); // TODO: (#3652) Synchronize filesystem state, SimulationInput contents, and program @@ -1573,11 +1573,11 @@ int Mdrunner::mdrunner() t_nrnb nrnb; if (thisRankHasDuty(cr, DUTY_PP)) { - mdModulesNotifier.notify(*cr); - mdModulesNotifier.notify(&atomSets); - mdModulesNotifier.notify(mtop); - mdModulesNotifier.notify(inputrec->pbcType); - mdModulesNotifier.notify(SimulationTimeStep{ inputrec->delta_t }); + setupNotifier.notify(*cr); + setupNotifier.notify(&atomSets); + setupNotifier.notify(mtop); + setupNotifier.notify(inputrec->pbcType); + setupNotifier.notify(SimulationTimeStep{ inputrec->delta_t }); /* Initiate forcerecord */ fr = std::make_unique(); fr->forceProviders = mdModules_->initForceProviders(); @@ -1947,7 +1947,7 @@ int Mdrunner::mdrunner() static_cast(filenames.size()), filenames.data(), inputrec.get(), fr.get())); simulatorBuilder.add(ReplicaExchangeParameters(replExParams)); simulatorBuilder.add(InteractiveMD(imdSession.get())); - simulatorBuilder.add(SimulatorModules(mdModules_->outputProvider(), mdModules_->notifier())); + simulatorBuilder.add(SimulatorModules(mdModules_->outputProvider(), mdModules_->notifiers())); simulatorBuilder.add(CenterOfMassPulling(pull_work)); // Todo move to an MDModule simulatorBuilder.add(IonSwapping(swap)); diff --git a/src/gromacs/mdrun/simulationinput.cpp b/src/gromacs/mdrun/simulationinput.cpp index b22c7ee3ac..34ee98a100 100644 --- a/src/gromacs/mdrun/simulationinput.cpp +++ b/src/gromacs/mdrun/simulationinput.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2020, by the GROMACS development team, led by + * Copyright (c) 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. @@ -64,7 +64,7 @@ void applyLocalState(const SimulationInput& simulationInput, t_state* state, ObservablesHistory* observablesHistory, bool reproducibilityRequested, - const MdModulesNotifier& mdModulesNotifier, + const MDModulesNotifiers& mdModulesNotifiers, gmx::ReadCheckpointDataHolder* modularSimulatorCheckpointData, const bool useModularSimulator) { @@ -76,7 +76,7 @@ void applyLocalState(const SimulationInput& simulationInput, state, observablesHistory, reproducibilityRequested, - mdModulesNotifier, + mdModulesNotifiers, modularSimulatorCheckpointData, useModularSimulator); } diff --git a/src/gromacs/mdrun/simulationinput.h b/src/gromacs/mdrun/simulationinput.h index 896018219c..06d8331d10 100644 --- a/src/gromacs/mdrun/simulationinput.h +++ b/src/gromacs/mdrun/simulationinput.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2020, by the GROMACS development team, led by + * Copyright (c) 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. @@ -140,7 +140,7 @@ void applyGlobalTopology(const SimulationInput&, gmx_mtop_t* * SimulationInput implementation. * * \todo Consider refactoring to decouple the checkpoint facility from its consumers - * (state, observablesHistory, mdModulesNotifier, and parts of ir). + * (state, observablesHistory, mdModulesNotifiers, and parts of ir). * * \warning It is the caller’s responsibility to make sure that * preconditions are satisfied for the parameter objects. @@ -157,7 +157,7 @@ void applyLocalState(const SimulationInput& simulationInput, t_state* state, ObservablesHistory* observablesHistory, bool reproducibilityRequested, - const MdModulesNotifier& notifier, + const MDModulesNotifiers& notifiers, gmx::ReadCheckpointDataHolder* modularSimulatorCheckpointData, bool useModularSimulator); diff --git a/src/gromacs/mdrun/simulatorbuilder.cpp b/src/gromacs/mdrun/simulatorbuilder.cpp index 8a0e4edf1b..1f8620c32a 100644 --- a/src/gromacs/mdrun/simulatorbuilder.cpp +++ b/src/gromacs/mdrun/simulatorbuilder.cpp @@ -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. @@ -142,7 +142,7 @@ std::unique_ptr SimulatorBuilder::build(bool useModularSimulator) constraintsParam_->enforcedRotation, boxDeformation_->deform, simulatorModules_->outputProvider, - simulatorModules_->mdModulesNotifier, + simulatorModules_->mdModulesNotifiers, legacyInput_->inputrec, interactiveMD_->imdSession, centerOfMassPulling_->pull_work, @@ -179,7 +179,7 @@ std::unique_ptr SimulatorBuilder::build(bool useModularSimulator) constraintsParam_->enforcedRotation, boxDeformation_->deform, simulatorModules_->outputProvider, - simulatorModules_->mdModulesNotifier, + simulatorModules_->mdModulesNotifiers, legacyInput_->inputrec, interactiveMD_->imdSession, centerOfMassPulling_->pull_work, diff --git a/src/gromacs/mdrun/simulatorbuilder.h b/src/gromacs/mdrun/simulatorbuilder.h index 624f8d8e71..2250724078 100644 --- a/src/gromacs/mdrun/simulatorbuilder.h +++ b/src/gromacs/mdrun/simulatorbuilder.h @@ -75,7 +75,7 @@ class MdrunScheduleWorkload; class MembedHolder; class MDAtoms; class MDLogger; -struct MdModulesNotifier; +struct MDModulesNotifiers; struct MdrunOptions; class ReadCheckpointDataHolder; enum class StartingBehavior; @@ -263,14 +263,14 @@ public: class SimulatorModules { public: - SimulatorModules(IMDOutputProvider* mdOutputProvider, const MdModulesNotifier& notifier) : + SimulatorModules(IMDOutputProvider* mdOutputProvider, const MDModulesNotifiers& notifiers) : outputProvider(mdOutputProvider), - mdModulesNotifier(notifier) + mdModulesNotifiers(notifiers) { } - IMDOutputProvider* outputProvider; - const MdModulesNotifier& mdModulesNotifier; + IMDOutputProvider* outputProvider; + const MDModulesNotifiers& mdModulesNotifiers; }; class CenterOfMassPulling diff --git a/src/gromacs/mdtypes/imdmodule.h b/src/gromacs/mdtypes/imdmodule.h index 83283417b4..2f5dde528e 100644 --- a/src/gromacs/mdtypes/imdmodule.h +++ b/src/gromacs/mdtypes/imdmodule.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017,2019,2020, by the GROMACS development team, led by + * Copyright (c) 2017,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. @@ -51,7 +51,7 @@ namespace gmx class ForceProviders; class IMDOutputProvider; class IMdpOptionProvider; -struct MdModulesNotifier; +struct MDModulesNotifiers; /*! \libinternal \brief * Extension module for \Gromacs simulations. @@ -75,9 +75,9 @@ public: //! Initializes force providers from this module. virtual void initForceProviders(ForceProviders* forceProviders) = 0; //! Subscribe to simulation setup notifications - virtual void subscribeToSimulationSetupNotifications(MdModulesNotifier* notifier) = 0; + virtual void subscribeToSimulationSetupNotifications(MDModulesNotifiers* notifiers) = 0; //! Subscribe to pre processing notifications - virtual void subscribeToPreProcessingNotifications(MdModulesNotifier* notifier) = 0; + virtual void subscribeToPreProcessingNotifications(MDModulesNotifiers* notifiers) = 0; }; } // namespace gmx diff --git a/src/gromacs/modularsimulator/energydata.cpp b/src/gromacs/modularsimulator/energydata.cpp index 32e3b18922..109b160615 100644 --- a/src/gromacs/modularsimulator/energydata.cpp +++ b/src/gromacs/modularsimulator/energydata.cpp @@ -83,7 +83,7 @@ EnergyData::EnergyData(StatePropagatorData* statePropagatorData, const Constraints* constr, FILE* fplog, t_fcdata* fcd, - const MdModulesNotifier& mdModulesNotifier, + const MDModulesNotifiers& mdModulesNotifiers, bool isMasterRank, ObservablesHistory* observablesHistory, StartingBehavior startingBehavior, @@ -107,7 +107,7 @@ EnergyData::EnergyData(StatePropagatorData* statePropagatorData, constr_(constr), fplog_(fplog), fcd_(fcd), - mdModulesNotifier_(mdModulesNotifier), + mdModulesNotifiers_(mdModulesNotifiers), groups_(&globalTopology.groups), observablesHistory_(observablesHistory), simulationsShareState_(simulationsShareState) @@ -168,7 +168,7 @@ void EnergyData::setup(gmx_mdoutf* outf) false, startingBehavior_, simulationsShareState_, - mdModulesNotifier_); + mdModulesNotifiers_); if (!isMasterRank_) { diff --git a/src/gromacs/modularsimulator/energydata.h b/src/gromacs/modularsimulator/energydata.h index 1359c68bb6..90d8e59700 100644 --- a/src/gromacs/modularsimulator/energydata.h +++ b/src/gromacs/modularsimulator/energydata.h @@ -69,7 +69,7 @@ class ModularSimulatorAlgorithmBuilderHelper; class ParrinelloRahmanBarostat; class StatePropagatorData; class VelocityScalingTemperatureCoupling; -struct MdModulesNotifier; +struct MDModulesNotifiers; //! Function type for elements contributing energy using EnergyContribution = std::function; @@ -106,7 +106,7 @@ public: const Constraints* constr, FILE* fplog, t_fcdata* fcd, - const MdModulesNotifier& mdModulesNotifier, + const MDModulesNotifiers& mdModulesNotifiers, bool isMasterRank, ObservablesHistory* observablesHistory, StartingBehavior startingBehavior, @@ -312,8 +312,8 @@ private: FILE* fplog_; //! Helper struct for force calculations. t_fcdata* fcd_; - //! Notification to MD modules - const MdModulesNotifier& mdModulesNotifier_; + //! Notifiers to MD modules + const MDModulesNotifiers& mdModulesNotifiers_; //! Global topology groups const SimulationGroups* groups_; //! History of simulation observables. diff --git a/src/gromacs/modularsimulator/simulatoralgorithm.cpp b/src/gromacs/modularsimulator/simulatoralgorithm.cpp index 5c1106f1fd..afce03938b 100644 --- a/src/gromacs/modularsimulator/simulatoralgorithm.cpp +++ b/src/gromacs/modularsimulator/simulatoralgorithm.cpp @@ -436,7 +436,7 @@ ModularSimulatorAlgorithmBuilder::ModularSimulatorAlgorithmBuilder( legacySimulatorData->constr, legacySimulatorData->fplog, legacySimulatorData->fr->fcdata.get(), - legacySimulatorData->mdModulesNotifier, + legacySimulatorData->mdModulesNotifiers, MASTER(legacySimulatorData->cr), legacySimulatorData->observablesHistory, legacySimulatorData->startingBehavior, @@ -574,7 +574,7 @@ ModularSimulatorAlgorithm ModularSimulatorAlgorithmBuilder::build() legacySimulatorData_->mdrunOptions, legacySimulatorData_->cr, legacySimulatorData_->outputProvider, - legacySimulatorData_->mdModulesNotifier, + legacySimulatorData_->mdModulesNotifiers, legacySimulatorData_->inputrec, legacySimulatorData_->top_global, legacySimulatorData_->oenv, diff --git a/src/gromacs/modularsimulator/trajectoryelement.cpp b/src/gromacs/modularsimulator/trajectoryelement.cpp index 69ff938357..276d80d974 100644 --- a/src/gromacs/modularsimulator/trajectoryelement.cpp +++ b/src/gromacs/modularsimulator/trajectoryelement.cpp @@ -56,7 +56,7 @@ TrajectoryElement::TrajectoryElement(std::vector write const MdrunOptions& mdrunOptions, const t_commrec* cr, gmx::IMDOutputProvider* outputProvider, - const MdModulesNotifier& mdModulesNotifier, + const MDModulesNotifiers& mdModulesNotifiers, const t_inputrec* inputrec, const gmx_mtop_t& top_global, const gmx_output_env_t* oenv, @@ -72,7 +72,7 @@ TrajectoryElement::TrajectoryElement(std::vector write mdrunOptions, cr, outputProvider, - mdModulesNotifier, + mdModulesNotifiers, inputrec, top_global, oenv, diff --git a/src/gromacs/modularsimulator/trajectoryelement.h b/src/gromacs/modularsimulator/trajectoryelement.h index 8c93b5a881..4f8d487eac 100644 --- a/src/gromacs/modularsimulator/trajectoryelement.h +++ b/src/gromacs/modularsimulator/trajectoryelement.h @@ -60,7 +60,7 @@ struct t_inputrec; namespace gmx { class IMDOutputProvider; -struct MdModulesNotifier; +struct MDModulesNotifiers; struct MdrunOptions; enum class StartingBehavior; @@ -135,7 +135,7 @@ private: const MdrunOptions& mdrunOptions, const t_commrec* cr, IMDOutputProvider* outputProvider, - const MdModulesNotifier& mdModulesNotifier, + const MDModulesNotifiers& mdModulesNotifiers, const t_inputrec* inputrec, const gmx_mtop_t& top_global, const gmx_output_env_t* oenv, diff --git a/src/gromacs/restraint/restraintmdmodule.cpp b/src/gromacs/restraint/restraintmdmodule.cpp index 5ea9cdd07c..9f27192e47 100644 --- a/src/gromacs/restraint/restraintmdmodule.cpp +++ b/src/gromacs/restraint/restraintmdmodule.cpp @@ -194,9 +194,11 @@ std::unique_ptr RestraintMDModule::create(std::shared_ptr restraint) : diff --git a/src/gromacs/restraint/restraintmdmodule.h b/src/gromacs/restraint/restraintmdmodule.h index 9825a1b803..57fd28d282 100644 --- a/src/gromacs/restraint/restraintmdmodule.h +++ b/src/gromacs/restraint/restraintmdmodule.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by + * Copyright (c) 2018,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. @@ -53,7 +53,7 @@ namespace gmx // Forward declaration to allow opaque pointer to library internal class. class RestraintMDModuleImpl; -struct MdModulesNotifier; +struct MDModulesNotifiers; /*! \libinternal \ingroup module_restraint * \brief MDModule wrapper for Restraint implementations. @@ -115,9 +115,9 @@ public: void initForceProviders(ForceProviders* forceProviders) override; //! Subscribe to simulation setup notifications - void subscribeToSimulationSetupNotifications(MdModulesNotifier* notifier) override; + void subscribeToSimulationSetupNotifications(MDModulesNotifiers* notifiers) override; //! Subscribe to pre processing notifications - void subscribeToPreProcessingNotifications(MdModulesNotifier* notifier) override; + void subscribeToPreProcessingNotifications(MDModulesNotifiers* notifiers) override; private: /*! diff --git a/src/gromacs/swap/swapcoords.cpp b/src/gromacs/swap/swapcoords.cpp index 102f863d0e..11c152313c 100644 --- a/src/gromacs/swap/swapcoords.cpp +++ b/src/gromacs/swap/swapcoords.cpp @@ -125,8 +125,8 @@ class SwapCoordinates final : public IMDModule IMdpOptionProvider* mdpOptionProvider() override { return nullptr; } IMDOutputProvider* outputProvider() override { return nullptr; } void initForceProviders(ForceProviders* /* forceProviders */) override {} - void subscribeToSimulationSetupNotifications(MdModulesNotifier* /* notifier */) override {} - void subscribeToPreProcessingNotifications(MdModulesNotifier* /* notifier */) override {} + void subscribeToSimulationSetupNotifications(MDModulesNotifiers* /* notifiers */) override {} + void subscribeToPreProcessingNotifications(MDModulesNotifiers* /* notifiers */) override {} }; std::unique_ptr createSwapCoordinatesModule() diff --git a/src/gromacs/utility/mdmodulenotification-impl.h b/src/gromacs/utility/mdmodulenotification-impl.h index a402504670..d488132105 100644 --- a/src/gromacs/utility/mdmodulenotification-impl.h +++ b/src/gromacs/utility/mdmodulenotification-impl.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2020, by the GROMACS development team, led by + * Copyright (c) 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. @@ -34,7 +34,7 @@ */ /*! \libinternal \file * \brief - * Declares gmx::MdModuleNotification. + * Declares gmx::MDModulesNotifier. * * \author Christian Blau * \inlibraryapi @@ -50,32 +50,57 @@ namespace gmx { -/*! \libinternal \brief - * Subscribe and trigger notification functions. - * - * Extends MdModuleNotificationBase with new notification function and routine - * to subscribe new listeners. - * - * To create a class of this type that provides callbacks, e.g., for events - * EventA, and EventB use registerMdModuleNotification::type. +/*! \libinternal + * \brief Organizes notifications about an event of interest to modules. + * + * An object of this type permits modules to subscribe to the + * corresponding event. The template types of this type encode what + * information is available when the event occurs. Modules \c + * subscribe() by providing a callback function that accepts a single + * parameter of such an event type. The code that handles that event + * has the responsibilty to call \c notify() afterwards. The + * subscribed modules then receive the callback with the requested + * event type as an argument. + * + * See gmx::MDModulesNotifiers for sequence diagrams for an example. + * + * This suits scenarios where several objects are built (or re-built) + * and one or more modules need to know when one or more of such + * objects are available (or updated), so they can adapt their + * internal state accordingly. Examples include responding to loading + * input data, or to changes related to a recurring process like + * checkpointing or partitioning. The coupling between these modules + * is now expressed indirectly. This improves the modularity and + * testability of those modules. + * + * The implementation provides the necessary flexibility to be + * parameterized with multiple event types and provide \c callback() + * and \b notify() methods corresponding to each related event. This + * is done by inheriting from a series of base classes, each of which + * handles a single type of event. BuildMDModulesNotifier implements + * the details. To create a class of this type that provides two + * events with callbacks that receive respectively types TypeA and + * TypeB, use BuildMDModulesNotifier::type. * * \tparam CallParameter of the function to be notified - * \tparam MdModuleNotificationBase class to be extended with a notification + * \tparam MDModulesNotifierBase class to be extended with a notification * with CallParameter * - * \note All added subscribers are required to out-live the MdModuleNotification + * \note All added subscribers are required to out-live the MDModulesNotifier * */ -template -class MdModuleNotification : public MdModuleNotificationBase +template +class MDModulesNotifier : public MDModulesNotifierBase { public: //! Make base class notification trigger available to this class - using MdModuleNotificationBase::notify; + using MDModulesNotifierBase::notify; //! Make base class subscription available to this class - using MdModuleNotificationBase::subscribe; + using MDModulesNotifierBase::subscribe; - /*! \brief Trigger the subscribed notifications. + /*! \brief Notifies subscribers of the event described by \c + * callbackParameter. + * * \param[in] callParameter of the function to be called back */ void notify(CallParameter callParameter) const @@ -87,11 +112,9 @@ public: } /*! \brief - * Add callback function to be called when notification is triggered. - * - * Notifications are distinguished by their call signature. + * Add callback function to be called when \c notify() is called * - * \param[in] callBackFunction to be called from this class + * \param[in] callBackFunction to be called */ void subscribe(std::function callBackFunction) { @@ -103,63 +126,63 @@ private: }; /*! \internal - * \brief Aide to avoid nested MdModuleNotification definition. + * \brief Aide to avoid nested MDModulesNotifier definition. * * Instead of - * MdModuleNotification> + * MDModulesNotifier> * this allows to write - * registerMdModuleNotification::type + * BuildMDModulesNotifier::type * - * \tparam CallParameter all the event types to be registered + * \tparam CallParameter all the callback types to be registered */ template -struct registerMdModuleNotification; +struct BuildMDModulesNotifier; /*! \internal \brief Template specialization to end parameter unpacking recursion. */ template<> -struct registerMdModuleNotification<> +struct BuildMDModulesNotifier<> { /*! \internal - * \brief Do nothing but be base class of MdModuleNotification. + * \brief Do nothing but be base class of MDModulesNotifier. * - * Required so that using MdModuleNotificationBase::notify and - * MdModuleNotificationBase::subscribe are valid in derived class. + * Required so that using MDModulesNotifierBase::notify and + * MDModulesNotifierBase::subscribe are valid in derived class. */ class NoCallParameter { public: - //! Do nothing but provide MdModuleNotification::notify to derived class + //! Do nothing but provide MDModulesNotifier::notify to derived class void notify() {} - //! Do nothing but provide MdModuleNotification::subscribe to derived class + //! Do nothing but provide MDModulesNotifier::subscribe to derived class void subscribe() {} }; /*! \brief Defines a type if no notifications are managed. * - * This ensures that code works with MdModuleCallParameterManagement that + * This ensures that code works with MDModuleCallParameterManagement that * does not manage any notifications. */ using type = NoCallParameter; }; /*! \libinternal - * \brief Template specialization to assemble MdModuleNotification. + * \brief Template specialization to assemble MDModulesNotifier. * - * Assembly of MdModuleNotification is performed by recursively taking off the + * Assembly of MDModulesNotifier is performed by recursively taking off the * front of the CallParameter parameter pack and constructing the nested type - * definition of MdModuleNotification base classes. + * definition of MDModulesNotifier base classes. * * \tparam CurrentCallParameter front of the template parameter pack - * \tparam CallParameter rest of the event types + * \tparam CallParameter rest of the callback types */ template -struct registerMdModuleNotification +struct BuildMDModulesNotifier { // private: //! The next type with rest of the arguments with the front parameter removed. - using next_type = typename registerMdModuleNotification::type; - //! The type of the MdModuleNotification - using type = MdModuleNotification; + using next_type = typename BuildMDModulesNotifier::type; + //! The type of the MDModulesNotifier + using type = MDModulesNotifier; }; } // namespace gmx diff --git a/src/gromacs/utility/mdmodulenotification.h b/src/gromacs/utility/mdmodulenotification.h index aa30111cfd..88491e378e 100644 --- a/src/gromacs/utility/mdmodulenotification.h +++ b/src/gromacs/utility/mdmodulenotification.h @@ -34,7 +34,7 @@ */ /*! \libinternal \file * \brief - * Declares gmx::MdModulesNotifier. + * Declares gmx::MDModulesNotifiers. * * \author Christian Blau * \inlibraryapi @@ -61,15 +61,15 @@ class KeyValueTreeObjectBuilder; class LocalAtomSetManager; class IndexGroupsAndNames; class SeparatePmeRanksPermitted; -struct MdModulesCheckpointReadingDataOnMaster; -struct MdModulesCheckpointReadingBroadcast; -struct MdModulesWriteCheckpointData; +struct MDModulesCheckpointReadingDataOnMaster; +struct MDModulesCheckpointReadingBroadcast; +struct MDModulesWriteCheckpointData; /*! \libinternal \brief Check if module outputs energy to a specific field. * * Ensures that energy is output for this module. */ -struct MdModulesEnergyOutputToDensityFittingRequestChecker +struct MDModulesEnergyOutputToDensityFittingRequestChecker { //! Trigger output to density fitting energy field bool energyOutputToDensityFitting_ = false; @@ -119,53 +119,98 @@ struct SimulationTimeStep }; /*! \libinternal - * \brief Collection of callbacks to MDModules at differnt run-times. + * \brief Group of notifers to organize that MDModules + * can receive callbacks they subscribe to. * - * MDModules use members of this struct to sign up for callback functionality. - * - * The members of the struct represent callbacks at these run-times: - * - * When pre-processing the simulation data - * When reading and writing check-pointing data - * When setting up simulation after reading in the tpr file + * MDModules use members of this struct to subscribe to notifications + * of particular events. When the event occurs, the callback provided + * by a particular MDModule will be passed a parameter of the + * particular type they are interested in. * + * Typically, during the setup phase, modules subscribe to notifiers + * that interest them by passing callbacks that expect a single parameter + * that describes the event. These are stored for later use. See the + * sequence diagram that follows: \msc - wordwraparcs=true, - hscale="2"; - - runner [label="runner:\nMdrunner"], - CallParameter [label = "eventA:\nCallParameter"], - MOD [label = "mdModules_:\nMdModules"], - ModuleA [label="moduleA"], - ModuleB [label="moduleB"], - MdModuleNotification [label="notifier_:\nMdModuleNotification"]; - - MOD box MdModuleNotification [label = "mdModules_ owns notifier_ and moduleA/B"]; - MOD =>> ModuleA [label="instantiates(notifier_)"]; - ModuleA =>> MdModuleNotification [label="subscribe(otherfunc)"]; - ModuleA =>> MOD; - MOD =>> ModuleB [label="instantiates(notifier_)"]; - ModuleB =>> MdModuleNotification [label="subscribe(func)"]; - ModuleB =>> MOD; - runner =>> CallParameter [label="instantiate"]; - CallParameter =>> runner ; - runner =>> MOD [label="notify(eventA)"]; - MOD =>> MdModuleNotification [label="notify(eventA)"]; - MdModuleNotification =>> ModuleA [label="notify(eventA)"]; - ModuleA -> ModuleA [label="func(eventA)"]; - MdModuleNotification =>> ModuleB [label="notify(eventA)"]; - ModuleB -> ModuleB [label="otherfunc(eventA)"]; +wordwraparcs=true, +hscale="2"; + +modules [label = "mdModules:\nMDModules"], +notifiers [label="notifiers\nMDModulesNotifiers"], +notifier [label="exampleNotifier:\nBuildMDModulesNotifier\n::type"], +moduleA [label="moduleA"], +moduleB [label="moduleB"], +moduleC [label="moduleC"]; + +modules box moduleC [label = "mdModules creates and owns moduleA, moduleB, and moduleC"]; +modules =>> notifiers [label="creates"]; +notifiers =>> notifier [label="creates"]; +notifier =>> notifiers [label="returns"]; +notifiers =>> modules [label="returns"]; + +modules =>> moduleA [label="provides notifiers"]; +moduleA =>> moduleA [label="unpacks\nnotifiers.exampleNotifier"]; +moduleA =>> notifier [label="subscribes with\ncallback(EventX&)"]; +notifier =>> notifier [label="records subscription\nto EventX"]; +moduleA =>> notifier [label="subscribes with\ncallback(EventY&)"]; +notifier =>> notifier [label="records subscription\nto EventY"]; +moduleA =>> modules [label="returns"]; + +modules =>> moduleB [label="provides notifiers"]; +moduleB =>> moduleB [label="unpacks\nnotifiers.exampleNotifier"]; +moduleA =>> notifier [label="subscribes with\ncallback(EventY&)"]; +notifier =>> notifier [label="records subscription\nto EventY"]; +moduleB =>> modules [label="returns"]; + +modules =>> moduleC [label="provides notifiers"]; +moduleC =>> moduleC [label="unpacks and keeps\nnotifiers.exampleNotifier"]; +moduleC =>> modules [label="returns"]; \endmsc + + * When the event occurs later on, the stored callbacks are used to + * allow the modules to react. See the following sequence diagram, + * which assumes that exampleNotifier was configured as in the + * previous sequence diagram. + + \msc +wordwraparcs=true, +hscale="2"; + +moduleC [label="moduleC"], +notifier [label="exampleNotifier:\nBuildMDModulesNotifier\n::type"], +moduleA [label="moduleA"], +moduleB [label="moduleB"]; + +moduleC box moduleB [label = "Later, when ModuleC is doing work"]; +moduleC =>> moduleC [label="generates EventX"]; +moduleC =>> moduleC [label="generates EventY"]; +moduleC =>> notifier [label="calls notify(eventX)"]; +notifier =>> moduleA [label="calls callback(eventX)"]; +moduleA =>> moduleA [label="reacts to eventX"]; +moduleA =>> notifier [label="returns"]; + +notifier =>> moduleC [label="returns"]; +moduleC =>> notifier [label="calls notify(eventY)"]; +notifier =>> moduleA [label="calls callback(eventY)"]; +moduleA =>> moduleA [label="reacts to eventY"]; +moduleA =>> notifier [label="returns"]; +notifier =>> moduleB [label="calls callback(eventY)"]; +moduleB =>> moduleB [label="reacts to eventY"]; +moduleB =>> notifier [label="returns"]; +notifier =>> moduleC [label="returns"]; + \endmsc * - * The template arguments to the members of this struct directly reflect - * the callback function signature. Arguments passed as pointers are always - * meant to be modified, but never meant to be stored (in line with the policy + * The template arguments to the members of this struct are the + * parameters passed to the callback functions, one type per + * callback. Arguments passed as pointers are always meant to be + * modified, but never meant to be stored (in line with the policy * everywhere else). + * */ -struct MdModulesNotifier +struct MDModulesNotifiers { - /*! \brief Pre-processing callback functions. + /*! \brief Handles subscribing and calling pre-processing callback functions. * * EnergyCalculationFrequencyErrors* allows modules to check if they match * their required calculation frequency @@ -175,32 +220,31 @@ struct MdModulesNotifier * KeyValueTreeObjectBuilder enables writing of module internal data to * .tpr files. */ - registerMdModuleNotification::type preProcessingNotifications_; + BuildMDModulesNotifier::type preProcessingNotifier_; - /*! \brief Checkpointing callback functions. + /*! \brief Handles subscribing and calling checkpointing callback functions. * - * MdModulesCheckpointReadingDataOnMaster provides modules with their + * MDModulesCheckpointReadingDataOnMaster provides modules with their * checkpointed data on the master * node and checkpoint file version - * MdModulesCheckpointReadingBroadcast provides modules with a communicator + * MDModulesCheckpointReadingBroadcast provides modules with a communicator * and the checkpoint file version to * distribute their data - * MdModulesWriteCheckpointData provides the modules with a key-value-tree + * MDModulesWriteCheckpointData provides the modules with a key-value-tree * builder to store their checkpoint data and * the checkpoint file version */ - registerMdModuleNotification::type checkpointingNotifications_; + BuildMDModulesNotifier::type + checkpointingNotifier_; - /*! \brief Callbacks during simulation setup. + /*! \brief Handles subscribing and calling callbacks during simulation setup. * * const KeyValueTreeObject& provides modules with the internal data they * wrote to .tpr files * LocalAtomSetManager* enables modules to add atom indices to local atom sets * to be managed * const gmx_mtop_t& provides the topology of the system to the modules - * MdModulesEnergyOutputToDensityFittingRequestChecker* enables modules to + * MDModulesEnergyOutputToDensityFittingRequestChecker* enables modules to * report if they want to write their energy output * to the density fitting field in the energy files * SeparatePmeRanksPermitted* enables modules to report if they want @@ -213,14 +257,14 @@ struct MdModulesNotifier * const t_commrec& provides a communicator to the modules during simulation * setup */ - registerMdModuleNotification::type simulationSetupNotifications_; + BuildMDModulesNotifier::type simulationSetupNotifier_; }; } // namespace gmx diff --git a/src/gromacs/utility/tests/mdmodulenotification-impl.cpp b/src/gromacs/utility/tests/mdmodulenotification-impl.cpp index 033a5ab11b..1e7515a5b6 100644 --- a/src/gromacs/utility/tests/mdmodulenotification-impl.cpp +++ b/src/gromacs/utility/tests/mdmodulenotification-impl.cpp @@ -34,7 +34,7 @@ */ /*! \internal \file * \brief - * Tests MdModuleNotification + * Tests MDModulesNotifier * * \author Christian Blau * \ingroup module_utility @@ -95,60 +95,60 @@ private: bool notifiedEventA_ = false; }; -TEST(MDModuleNotificationTest, addConsumer) +TEST(MDModulesNotifierTest, AddConsumer) { - registerMdModuleNotification::type notifications; - EventACallee eventACallee; + BuildMDModulesNotifier::type notifier; + EventACallee eventACallee; EXPECT_FALSE(eventACallee.notifiedEventA()); - notifications.subscribe([&eventACallee](EventA eventA) { eventACallee.callback(eventA); }); - notifications.notify(EventA{}); + notifier.subscribe([&eventACallee](EventA eventA) { eventACallee.callback(eventA); }); + notifier.notify(EventA{}); EXPECT_TRUE(eventACallee.notifiedEventA()); } -TEST(MDModuleNotificationTest, addConsumerWithPointerParameter) +TEST(MDModulesNotifierTest, AddConsumerWithPointerParameter) { - registerMdModuleNotification::type notifications; - EventBCallee eventBCallee; + BuildMDModulesNotifier::type notifier; + EventBCallee eventBCallee; EXPECT_FALSE(eventBCallee.notifiedEventB()); - notifications.subscribe([&eventBCallee](EventB* eventB) { eventBCallee.callback(eventB); }); + notifier.subscribe([&eventBCallee](EventB* eventB) { eventBCallee.callback(eventB); }); EventB* eventBPointer = nullptr; - notifications.notify(eventBPointer); + notifier.notify(eventBPointer); EXPECT_TRUE(eventBCallee.notifiedEventB()); } -TEST(MDModuleNotificationTest, addTwoDifferentConsumers) +TEST(MDModulesNotifierTest, AddTwoDifferentConsumers) { - registerMdModuleNotification::type notifications; - EventBCallee eventBCallee; - EventACallee eventACallee; + BuildMDModulesNotifier::type notifier; + EventBCallee eventBCallee; + EventACallee eventACallee; EXPECT_FALSE(eventACallee.notifiedEventA()); EXPECT_FALSE(eventBCallee.notifiedEventB()); - notifications.subscribe([&eventBCallee](EventB* eventB) { eventBCallee.callback(eventB); }); - notifications.subscribe([&eventACallee](EventA eventA) { eventACallee.callback(eventA); }); + notifier.subscribe([&eventBCallee](EventB* eventB) { eventBCallee.callback(eventB); }); + notifier.subscribe([&eventACallee](EventA eventA) { eventACallee.callback(eventA); }); EventB* eventBPointer = nullptr; - notifications.notify(eventBPointer); + notifier.notify(eventBPointer); EXPECT_FALSE(eventACallee.notifiedEventA()); EXPECT_TRUE(eventBCallee.notifiedEventB()); - notifications.notify(EventA{}); + notifier.notify(EventA{}); EXPECT_TRUE(eventACallee.notifiedEventA()); EXPECT_TRUE(eventBCallee.notifiedEventB()); } -TEST(MDModuleNotificationTest, consumerOfTwoResources) +TEST(MDModulesNotifierTest, AddConsumerOfTwoResources) { - registerMdModuleNotification::type notifications; + BuildMDModulesNotifier::type notifier; EventAandBCallee callee; @@ -156,17 +156,17 @@ TEST(MDModuleNotificationTest, consumerOfTwoResources) EXPECT_FALSE(callee.notifiedEventA()); // requires a template parameter here, because call is ambiguous otherwise - notifications.subscribe([&callee](EventA msg) { callee.callback(msg); }); - notifications.subscribe([&callee](EventB* msg) { callee.notify(msg); }); + notifier.subscribe([&callee](EventA msg) { callee.callback(msg); }); + notifier.subscribe([&callee](EventB* msg) { callee.notify(msg); }); EventB* eventBp = nullptr; - notifications.notify(eventBp); + notifier.notify(eventBp); EXPECT_FALSE(callee.notifiedEventA()); EXPECT_TRUE(callee.notifiedEventB()); - notifications.notify(EventA{}); + notifier.notify(EventA{}); EXPECT_TRUE(callee.notifiedEventA()); EXPECT_TRUE(callee.notifiedEventB());