From 0bda8a13c06cf5a55d6f1b7b622a5c5e59465d2b Mon Sep 17 00:00:00 2001 From: "M. Eric Irrgang" Date: Mon, 7 Sep 2020 16:13:31 +0000 Subject: [PATCH] Replace filename-based initialization functions. Decouple Mdrunner from the details of `-s` and `-cpi` filename arguments when establishing initial simulation state. Declare gmx::SimulationInput and the library utilities needed to replace direct reference to TPR and CPT files in Mdrunner. Use SimulationInput and accompanying utilities to remove read_tpx_state and load_checkpoint from Mdrunner. Allows TPR and checkpoint file handling to be considered separately from Mdrunner initialization in future development. Refs #3374 --- src/gromacs/mdrun/CMakeLists.txt | 2 + src/gromacs/mdrun/runner.cpp | 30 +++- src/gromacs/mdrun/simulationinput.cpp | 78 ++++++++++ src/gromacs/mdrun/simulationinput.h | 107 ++++++++++++++ src/gromacs/mdrun/simulationinput_impl.h | 78 ++++++++++ src/gromacs/mdrun/simulationinpututility.cpp | 78 ++++++++++ src/gromacs/mdrun/simulationinpututility.h | 142 +++++++++++++++++++ 7 files changed, 510 insertions(+), 5 deletions(-) create mode 100644 src/gromacs/mdrun/simulationinput.cpp create mode 100644 src/gromacs/mdrun/simulationinput.h create mode 100644 src/gromacs/mdrun/simulationinput_impl.h create mode 100644 src/gromacs/mdrun/simulationinpututility.cpp create mode 100644 src/gromacs/mdrun/simulationinpututility.h diff --git a/src/gromacs/mdrun/CMakeLists.txt b/src/gromacs/mdrun/CMakeLists.txt index d0200b80cb..fac4c8ea9a 100644 --- a/src/gromacs/mdrun/CMakeLists.txt +++ b/src/gromacs/mdrun/CMakeLists.txt @@ -45,6 +45,8 @@ gmx_add_libgromacs_sources( runner.cpp shellfc.cpp simulationcontext.cpp + simulationinput.cpp + simulationinpututility.cpp simulatorbuilder.cpp tpi.cpp ) diff --git a/src/gromacs/mdrun/runner.cpp b/src/gromacs/mdrun/runner.cpp index f4938304ff..66ebd12a6a 100644 --- a/src/gromacs/mdrun/runner.cpp +++ b/src/gromacs/mdrun/runner.cpp @@ -167,6 +167,8 @@ #include "isimulator.h" #include "membedholder.h" #include "replicaexchange.h" +#include "simulationinput.h" +#include "simulationinpututility.h" #include "simulatorbuilder.h" #if GMX_FAHCORE @@ -779,6 +781,13 @@ int Mdrunner::mdrunner() // Print citation requests after all software/hardware printing pleaseCiteGromacs(fplog); + // TODO: Use SimulationInputHolder member to access SimulationInput. Issue #3374. + const auto* const tprFilename = ftp2fn(efTPR, filenames.size(), filenames.data()); + const auto* const cpiFilename = opt2fn("-cpi", filenames.size(), filenames.data()); + // Note that, as of this change, there is no public API for simulationInput or its creation. + // TODO: (#3374) Public API for providing simulationInput from client. + auto simulationInput = detail::makeSimulationInput(tprFilename, cpiFilename); + // Note: legacy program logic relies on checking whether these pointers are assigned. // Objects may or may not be allocated later. std::unique_ptr inputrec; @@ -796,8 +805,8 @@ int Mdrunner::mdrunner() /* Read (nearly) all data required for the simulation * and keep the partly serialized tpr contents to send to other ranks later */ - *partialDeserializedTpr = read_tpx_state(ftp2fn(efTPR, filenames.size(), filenames.data()), - inputrec.get(), globalState.get(), &mtop); + applyGlobalSimulationState(*simulationInput.object_, partialDeserializedTpr.get(), + globalState.get(), inputrec.get(), &mtop); } /* Check and update the hardware options for internal consistency */ @@ -1086,10 +1095,21 @@ int Mdrunner::mdrunner() inputrec->nsteps = -1; } - load_checkpoint(opt2fn_master("-cpi", filenames.size(), filenames.data(), cr), - logFileHandle, cr, domdecOptions.numCells, inputrec.get(), globalState.get(), - &observablesHistory, mdrunOptions.reproducible, mdModules_->notifier(), + // Finish applying initial simulation state information from external sources on all ranks. + // Reconcile checkpoint file data with Mdrunner state established up to this point. + applyLocalState(*simulationInput.object_, logFileHandle, cr, domdecOptions.numCells, + inputrec.get(), globalState.get(), &observablesHistory, + mdrunOptions.reproducible, mdModules_->notifier(), modularSimulatorCheckpointData.get(), useModularSimulator); + // TODO: (#3652) Synchronize filesystem state, SimulationInput contents, and program + // invariants + // on all code paths. + // Write checkpoint or provide hook to update SimulationInput. + // If there was a checkpoint file, SimulationInput contains more information + // than if there wasn't. At this point, we have synchronized the in-memory + // state with the filesystem state only for restarted simulations. We should + // be calling applyLocalState unconditionally and expect that the completeness + // of SimulationInput is not dependent on its creation method. if (startingBehavior == StartingBehavior::RestartWithAppending && logFileHandle) { diff --git a/src/gromacs/mdrun/simulationinput.cpp b/src/gromacs/mdrun/simulationinput.cpp new file mode 100644 index 0000000000..bdf2f681d3 --- /dev/null +++ b/src/gromacs/mdrun/simulationinput.cpp @@ -0,0 +1,78 @@ +/* + * This file is part of the GROMACS molecular simulation package. + * + * Copyright (c) 2020, by the GROMACS development team, led by + * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, + * and including many others, as listed in the AUTHORS file in the + * top-level source directory and at http://www.gromacs.org. + * + * GROMACS is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * GROMACS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with GROMACS; if not, see + * http://www.gnu.org/licenses, or write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * If you want to redistribute modifications to GROMACS, please + * consider that scientific software is very special. Version + * control is crucial - bugs must be traceable. We will be happy to + * consider code for inclusion in the official distribution, but + * derived work must not be called official GROMACS. Details are found + * in the README & COPYING files - if they are missing, get the + * official version at http://www.gromacs.org. + * + * To help us fund GROMACS development, we humbly ask that you cite + * the research papers on the package. Check out http://www.gromacs.org. + */ + +#include "gmxpre.h" + +#include "simulationinput.h" + +#include + +#include "simulationinput_impl.h" + +namespace gmx +{ + +struct MdModulesNotifier; + +SimulationInput::SimulationInput(const char* tprFilename, const char* cpiFilename) : + tprFilename_(tprFilename), + cpiFilename_(cpiFilename) +{ +} + +SimulationInputHolder::SimulationInputHolder() = default; + +SimulationInputHolder::~SimulationInputHolder() = default; + +namespace detail +{ + +SimulationInputHolder makeSimulationInput(const char* tprFilename, const char* cpiFilename) +{ + // Note: it seems clear that we will want a SimulationInput to be linked to + // a communications context (whether the SimulationContext or something higher level) + // so that it can encapsulate the data locality details. Otherwise, we have + // to choose whether to read the files everywhere or just to store the + // filenames until a communications context is known. + auto simulationInput = std::make_unique(tprFilename, cpiFilename); + + SimulationInputHolder holder; + holder.object_ = std::move(simulationInput); + return holder; +} + +} // end namespace detail + +} // end namespace gmx diff --git a/src/gromacs/mdrun/simulationinput.h b/src/gromacs/mdrun/simulationinput.h new file mode 100644 index 0000000000..81da8a8ab8 --- /dev/null +++ b/src/gromacs/mdrun/simulationinput.h @@ -0,0 +1,107 @@ +/* + * This file is part of the GROMACS molecular simulation package. + * + * Copyright (c) 2020, by the GROMACS development team, led by + * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, + * and including many others, as listed in the AUTHORS file in the + * top-level source directory and at http://www.gromacs.org. + * + * GROMACS is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * GROMACS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with GROMACS; if not, see + * http://www.gnu.org/licenses, or write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * If you want to redistribute modifications to GROMACS, please + * consider that scientific software is very special. Version + * control is crucial - bugs must be traceable. We will be happy to + * consider code for inclusion in the official distribution, but + * derived work must not be called official GROMACS. Details are found + * in the README & COPYING files - if they are missing, get the + * official version at http://www.gromacs.org. + * + * To help us fund GROMACS development, we humbly ask that you cite + * the research papers on the package. Check out http://www.gromacs.org. + */ +/*! \file + * \brief Public interface for SimulationInput facilities. + * + * \author M. Eric Irrgang + * \ingroup module_mdrun + */ + +#ifndef GMX_MDRUN_SIMULATIONINPUT_H +#define GMX_MDRUN_SIMULATIONINPUT_H + +#include + +namespace gmx +{ + +// Forward declarations for types from other modules that are opaque to the public API. +class LegacyMdrunOptions; + +/*! + * \brief Prescription for molecular simulation. + * + * Represents the complete and unique information needed to generate a simulation + * trajectory segment. SimulationInput objects are opaque to the public API. + * Clients can acquire SimulationInput objects through makeSimulationInput(). + * + * See also https://gitlab.com/gromacs/gromacs/-/issues/3379 for design and development road map. + */ +class SimulationInput; + +/*! + * \brief Owning handle to a SimulationInput object. + * + * SimulationInput has no public API. Acquire a SimulationInputHolder with makeSimulationInput(). + * See https://gitlab.com/gromacs/gromacs/-/issues/3374 + */ +class SimulationInputHolder +{ +public: + SimulationInputHolder(); + ~SimulationInputHolder(); + + SimulationInputHolder(SimulationInputHolder&&) noexcept = default; + SimulationInputHolder& operator=(SimulationInputHolder&&) noexcept = default; + + std::unique_ptr object_; +}; + +namespace detail +{ + +/*! \brief Get a SimulationInput. + * + * \internal + * Design notes: SimulationInput creation will warrant a builder protocol, and + * this helper can evolve into a director to apply the contents of LegacyMdrunOptions, + * while such an operation is still relevant. + * + * Example: + * // After preparing a LegacyMdrunOptions and calling handleRestart()... + * SimulationInputBuilder builder; + * auto simulationInputHandle = makeSimulationInput(options, &builder); + * + * // In addition to MdrunnerBuilder::addFiles(), + * mdrunnerBuilder.addInput(simulationInputHandle.get()); + * + */ +SimulationInputHolder makeSimulationInput(const char* tprFilename, const char* cpiFilename); + +} // end namespace detail + +} // end namespace gmx + +#endif // GMX_MDRUN_SIMULATIONINPUT_H diff --git a/src/gromacs/mdrun/simulationinput_impl.h b/src/gromacs/mdrun/simulationinput_impl.h new file mode 100644 index 0000000000..dfa5ab0f73 --- /dev/null +++ b/src/gromacs/mdrun/simulationinput_impl.h @@ -0,0 +1,78 @@ +/* + * This file is part of the GROMACS molecular simulation package. + * + * Copyright (c) 2020, by the GROMACS development team, led by + * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, + * and including many others, as listed in the AUTHORS file in the + * top-level source directory and at http://www.gromacs.org. + * + * GROMACS is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * GROMACS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with GROMACS; if not, see + * http://www.gnu.org/licenses, or write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * If you want to redistribute modifications to GROMACS, please + * consider that scientific software is very special. Version + * control is crucial - bugs must be traceable. We will be happy to + * consider code for inclusion in the official distribution, but + * derived work must not be called official GROMACS. Details are found + * in the README & COPYING files - if they are missing, get the + * official version at http://www.gromacs.org. + * + * To help us fund GROMACS development, we humbly ask that you cite + * the research papers on the package. Check out http://www.gromacs.org. + */ + +#ifndef GROMACS_SIMULATIONINPUT_IMPL_H +#define GROMACS_SIMULATIONINPUT_IMPL_H + +/*! \libinternal \file + * \brief Library interface for SimulationInput. + * + * \ingroup module_mdrun + */ + +#include + +namespace gmx +{ + +struct MdModulesNotifier; + +/* + * \brief Prescription for molecular simulation. + * + * In the first implementation, this is a POD struct to allow removal of direct + * references to TPR and CPT files from Mdrunner. The interface for SimulationInput + * should be considered to be *completely unspecified* until resolution of + * https://gitlab.com/gromacs/gromacs/-/issues/3374 + * + * Clients should use the utility functions defined in simulationinpututility.h + * + * Design note: It is probably sufficient for future versions to compose SimulationInput + * through a Builder rather than to subclass an Interface or base class. Outside of this + * translation unit, we should avoid coupling to the class definition until/unless we + * develop a much better understanding of simulation input portability. + */ +class SimulationInput +{ +public: + SimulationInput(const char* tprFilename, const char* cpiFilename); + + std::string tprFilename_; + std::string cpiFilename_; +}; + +} // end namespace gmx + +#endif // GROMACS_SIMULATIONINPUT_IMPL_H diff --git a/src/gromacs/mdrun/simulationinpututility.cpp b/src/gromacs/mdrun/simulationinpututility.cpp new file mode 100644 index 0000000000..74a050b2cd --- /dev/null +++ b/src/gromacs/mdrun/simulationinpututility.cpp @@ -0,0 +1,78 @@ +/* + * This file is part of the GROMACS molecular simulation package. + * + * Copyright (c) 2020, by the GROMACS development team, led by + * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, + * and including many others, as listed in the AUTHORS file in the + * top-level source directory and at http://www.gromacs.org. + * + * GROMACS is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * GROMACS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with GROMACS; if not, see + * http://www.gnu.org/licenses, or write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * If you want to redistribute modifications to GROMACS, please + * consider that scientific software is very special. Version + * control is crucial - bugs must be traceable. We will be happy to + * consider code for inclusion in the official distribution, but + * derived work must not be called official GROMACS. Details are found + * in the README & COPYING files - if they are missing, get the + * official version at http://www.gromacs.org. + * + * To help us fund GROMACS development, we humbly ask that you cite + * the research papers on the package. Check out http://www.gromacs.org. + */ + +#include "gmxpre.h" + +#include "simulationinpututility.h" + +#include "gromacs/fileio/checkpoint.h" +#include "gromacs/fileio/tpxio.h" +#include "gromacs/mdtypes/inputrec.h" +#include "gromacs/mdtypes/observableshistory.h" +#include "gromacs/mdtypes/state.h" + +#include "simulationinput_impl.h" + +namespace gmx +{ + +void applyGlobalSimulationState(const SimulationInput& simulationInput, + PartialDeserializedTprFile* partialDeserializedTpr, + t_state* globalState, + t_inputrec* inputRecord, + gmx_mtop_t* molecularTopology) +{ + *partialDeserializedTpr = read_tpx_state(simulationInput.tprFilename_.c_str(), inputRecord, + globalState, molecularTopology); +} + +void applyLocalState(const SimulationInput& simulationInput, + t_fileio* logfio, + const t_commrec* cr, + int* dd_nc, + t_inputrec* inputRecord, + t_state* state, + ObservablesHistory* observablesHistory, + bool reproducibilityRequested, + const MdModulesNotifier& mdModulesNotifier, + gmx::ReadCheckpointDataHolder* modularSimulatorCheckpointData, + const bool useModularSimulator) +{ + load_checkpoint(simulationInput.cpiFilename_.c_str(), logfio, cr, dd_nc, inputRecord, state, + observablesHistory, reproducibilityRequested, mdModulesNotifier, + modularSimulatorCheckpointData, useModularSimulator); +} + +} // end namespace gmx diff --git a/src/gromacs/mdrun/simulationinpututility.h b/src/gromacs/mdrun/simulationinpututility.h new file mode 100644 index 0000000000..e65a9cf09e --- /dev/null +++ b/src/gromacs/mdrun/simulationinpututility.h @@ -0,0 +1,142 @@ +/* + * This file is part of the GROMACS molecular simulation package. + * + * Copyright (c) 2020, by the GROMACS development team, led by + * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, + * and including many others, as listed in the AUTHORS file in the + * top-level source directory and at http://www.gromacs.org. + * + * GROMACS is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * GROMACS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with GROMACS; if not, see + * http://www.gnu.org/licenses, or write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * If you want to redistribute modifications to GROMACS, please + * consider that scientific software is very special. Version + * control is crucial - bugs must be traceable. We will be happy to + * consider code for inclusion in the official distribution, but + * derived work must not be called official GROMACS. Details are found + * in the README & COPYING files - if they are missing, get the + * official version at http://www.gromacs.org. + * + * To help us fund GROMACS development, we humbly ask that you cite + * the research papers on the package. Check out http://www.gromacs.org. + */ +/*! \libinternal \file + * \brief Utilities for interacting with SimulationInput. + * + * \author M. Eric Irrgang + * \ingroup module_mdrun + */ + +#ifndef GMX_MDRUN_SIMULATIONINPUTUTILITY_H +#define GMX_MDRUN_SIMULATIONINPUTUTILITY_H + +#include + +#include "gromacs/mdtypes/checkpointdata.h" +#include "gromacs/utility/mdmodulenotification.h" + +#include "simulationinput.h" + +// Forward declarations for types from other modules that are opaque to the public API. +// TODO: Document the sources of these symbols or import a (self-documenting) fwd header. +struct gmx_mtop_t; +struct t_commrec; +struct t_fileio; +struct t_inputrec; +class t_state; +struct ObservablesHistory; +struct PartialDeserializedTprFile; + +namespace gmx +{ + +/*! \brief Get the global simulation input. + * + * Acquire global simulation data structures from the SimulationInput handle. + * Note that global data is returned in the calling thread. In parallel + * computing contexts, the client is responsible for calling only where needed. + * + * Example: + * if (SIMMASTER(cr)) + * { + * // Only the master rank has the global state + * globalState = globalSimulationState(simulationInput); + * + * // Read (nearly) all data required for the simulation + * applyGlobalInputRecord(simulationInput, inputrec); + * applyGlobalTopology(simulationInput, &mtop); + * } + * + * \todo Factor the logic for global/local and master-rank-checks. + * The SimulationInput utilities should behave properly for the various distributed data scenarios. + * Consider supplying data directly to the consumers rather than exposing the + * implementation details of the legacy aggregate types. + * + * \{ + */ +// TODO: Remove this monolithic detail as member data can be separately cached and managed. (#3374) +// Note that clients still need tpxio.h for PartialDeserializedTprFile. +void applyGlobalSimulationState(const SimulationInput& simulationInput, + PartialDeserializedTprFile* partialDeserializedTpr, + t_state* globalState, + t_inputrec* inputrec, + gmx_mtop_t* globalTopology); +// TODO: Implement the following, pending further discussion re #3374. +std::unique_ptr globalSimulationState(const SimulationInput&); +void applyGlobalInputRecord(const SimulationInput&, t_inputrec*); +void applyGlobalTopology(const SimulationInput&, gmx_mtop_t*); +//! \} + +/*! \brief Initialize local stateful simulation data. + * + * Establish an invariant for the simulator at a trajectory point. + * Call on all ranks (after domain decomposition and task assignments). + * + * After this call, the simulator has all of the information it will + * receive in order to advance a trajectory from the current step. + * Checkpoint information has been applied, if applicable, and stateful + * data has been (re)initialized. + * + * \warning Mdrunner instances do not clearly distinguish between global and local + * versions of t_state. + * + * \todo Factor the distributed data aspects of simulation input data into the + * SimulationInput implementation. + * + * \todo Consider refactoring to decouple the checkpoint facility from its consumers + * (state, observablesHistory, mdModulesNotifier, and parts of ir). + * + * \warning It is the caller’s responsibility to make sure that + * preconditions are satisfied for the parameter objects. + * + * \see globalSimulationState() + * \see applyGlobalInputRecord() + * \see applyGlobalTopology() + */ +void applyLocalState(const SimulationInput& simulationInput, + t_fileio* logfio, + const t_commrec* cr, + int* dd_nc, + t_inputrec* ir, + t_state* state, + ObservablesHistory* observablesHistory, + bool reproducibilityRequested, + const MdModulesNotifier& notifier, + gmx::ReadCheckpointDataHolder* modularSimulatorCheckpointData, + bool useModularSimulator); + +} // end namespace gmx + +#endif // GMX_MDRUN_SIMULATIONINPUTUTILITY_H -- 2.22.0