Allow Mdrunner to accept a handle to SimulationInput from the client.
This change adds an input method to the MdRunner builder to provide
access to resources provided through the new SimulationInput module.
Refs #3374
filename = mdNode->params();
}
- /* As default behavior, automatically extend trajectories from the checkpoint file.
+ /* Mock up the argv interface used by option processing infrastructure.
+ *
+ * As default behavior, automatically extend trajectories from the checkpoint file.
* In the future, our API for objects used to initialize a simulation needs to address the fact that currently a
* microstate requires data from both the TPR and checkpoint file to be fully specified. Put another way,
* current
* GROMACS simulations can take a "configuration" as input that does not constitute a complete microstate in
* terms of hidden degrees of freedom (integrator/thermostat/barostat/PRNG state), but we want a clear notion of
* a microstate for gmxapi interfaces.
+ *
+ * TODO: Remove `-s` and `-cpi` arguments.
+ * Ref: https://gitlab.com/gromacs/gromacs/-/issues/3652
*/
// Set input TPR name
builder.addReplicaExchange(options_.replExParams);
// Need to establish run-time values from various inputs to provide a resource handle to Mdrunner
builder.addHardwareOptions(options_.hw_opt);
+
// \todo File names are parameters that should be managed modularly through further factoring.
builder.addFilenames(options_.filenames);
+ // TODO: Remove `s` and `-cpi` from LegacyMdrunOptions before launch(). #3652
+ auto simulationInput = makeSimulationInput(options_);
+ builder.addInput(simulationInput);
+
// Note: The gmx_output_env_t life time is not managed after the call to parse_common_args.
// \todo Implement lifetime management for gmx_output_env_t.
// \todo Output environment should be configured outside of Mdrunner and provided as a resource.
std::move(simulationContext), std::move(logFileGuard));
// Clean up argv once builder is no longer in use
+ // TODO: Remove long-lived references to argv so this is no longer necessary.
+ // Ref https://gitlab.com/gromacs/gromacs/-/issues/2877
for (auto&& string : argv)
{
if (string != nullptr)
shellfc.cpp
simulationcontext.cpp
simulationinput.cpp
- simulationinpututility.cpp
+ simulationinputhandle.cpp
simulatorbuilder.cpp
tpi.cpp
)
+# TODO: Find a home for this header and a scheme for installation.
+# This header straddles the installed libraries and is a transitive interface
+# from libgromacs to libgmxapi to libgmxapi clients. Near term efforts are
+# planned to consolidate these libraries and refine the public interface.
+# In the mean time, this is kept out of the gmxapi to avoid circular dependencies
+# between the libraries. It can be moved to a separate interface-only target,
+# but that is beyond the scope of issue #3379, which introduces the header.
+# Ref #3152 and #3652
+install(FILES simulationinputhandle.h
+ DESTINATION include/gromacs/mdrun)
+
if (BUILD_TESTING)
# TODO import this from src/programs/mdrun/tests
# add_subdirectory(tests)
#include "gromacs/mdlib/vsite.h"
#include "gromacs/mdrun/mdmodules.h"
#include "gromacs/mdrun/simulationcontext.h"
+#include "gromacs/mdrun/simulationinput.h"
+#include "gromacs/mdrun/simulationinputhandle.h"
#include "gromacs/mdrunutility/handlerestart.h"
#include "gromacs/mdrunutility/logging.h"
#include "gromacs/mdrunutility/multisim.h"
#include "isimulator.h"
#include "membedholder.h"
#include "replicaexchange.h"
-#include "simulationinput.h"
-#include "simulationinpututility.h"
#include "simulatorbuilder.h"
#if GMX_FAHCORE
newRunner.ms = ms;
newRunner.startingBehavior = startingBehavior;
newRunner.stopHandlerBuilder_ = std::make_unique<StopHandlerBuilder>(*stopHandlerBuilder_);
+ newRunner.inputHolder_ = inputHolder_;
threadMpiMdrunnerAccessBarrier();
// 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<t_inputrec> inputrec;
/* Read (nearly) all data required for the simulation
* and keep the partly serialized tpr contents to send to other ranks later
*/
- applyGlobalSimulationState(*simulationInput.object_, partialDeserializedTpr.get(),
+ applyGlobalSimulationState(*inputHolder_.get(), partialDeserializedTpr.get(),
globalState.get(), inputrec.get(), &mtop);
}
// 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,
+ applyLocalState(*inputHolder_.get(), logFileHandle, cr, domdecOptions.numCells,
inputrec.get(), globalState.get(), &observablesHistory,
mdrunOptions.reproducible, mdModules_->notifier(),
modularSimulatorCheckpointData.get(), useModularSimulator);
void addDomdec(const DomdecOptions& options);
+ void addInput(SimulationInputHandle inputHolder);
+
void addVerletList(int nstlist);
void addReplicaExchange(const ReplicaExchangeParameters& params);
* \brief Builder for simulation stop signal handler.
*/
std::unique_ptr<StopHandlerBuilder> stopHandlerBuilder_ = nullptr;
+
+ SimulationInputHandle inputHolder_;
};
Mdrunner::BuilderImplementation::BuilderImplementation(std::unique_ptr<MDModules> mdModules,
// nullptr is a valid value for the multisim handle
newRunner.ms = multiSimulation_;
+ if (inputHolder_)
+ {
+ newRunner.inputHolder_ = std::move(inputHolder_);
+ }
+ else
+ {
+ GMX_THROW(gmx::APIError("MdrunnerBuilder::addInput() is required before build()."));
+ }
+
// \todo Clarify ownership and lifetime management for gmx_output_env_t
// \todo Update sanity checking when output environment has clearly specified invariants.
// Initialization and default values for oenv are not well specified in the current version.
stopHandlerBuilder_ = std::move(builder);
}
+void Mdrunner::BuilderImplementation::addInput(SimulationInputHandle inputHolder)
+{
+ inputHolder_ = std::move(inputHolder);
+}
+
MdrunnerBuilder::MdrunnerBuilder(std::unique_ptr<MDModules> mdModules,
compat::not_null<SimulationContext*> context) :
impl_{ std::make_unique<Mdrunner::BuilderImplementation>(std::move(mdModules), context) }
return *this;
}
+MdrunnerBuilder& MdrunnerBuilder::addInput(SimulationInputHandle input)
+{
+ impl_->addInput(std::move(input));
+ return *this;
+}
+
MdrunnerBuilder::MdrunnerBuilder(MdrunnerBuilder&&) noexcept = default;
MdrunnerBuilder& MdrunnerBuilder::operator=(MdrunnerBuilder&&) noexcept = default;
#include "gromacs/hardware/hw_info.h"
#include "gromacs/math/vec.h"
#include "gromacs/mdrun/mdmodules.h"
+#include "gromacs/mdrun/simulationinputhandle.h"
#include "gromacs/mdrunutility/handlerestart.h"
#include "gromacs/mdtypes/mdrunoptions.h"
#include "gromacs/utility/arrayref.h"
std::unique_ptr<StopHandlerBuilder> stopHandlerBuilder_;
//! The modules that comprise mdrun.
std::unique_ptr<MDModules> mdModules_;
+
+ /*!
+ * \brief Holds simulation input specification provided by client, if any.
+ *
+ * If present on any instance (rank) of a simulation runner, an identical
+ * (or compatible) SimulationInput must be held on all cooperating instances.
+ */
+ SimulationInputHandle inputHolder_;
};
/*! \libinternal
*/
MdrunnerBuilder& addStopHandlerBuilder(std::unique_ptr<StopHandlerBuilder> builder);
+ /*!
+ * \brief Acquire a handle to the SimulationInput.
+ *
+ * Required. SimulationInput will be taking responsibility for some of the
+ * input provided through other methods, such as addFilenames.
+ *
+ * See also issue https://gitlab.com/gromacs/gromacs/-/issues/3374
+ *
+ * \param input Shared ownership of a SimulationInput.
+ */
+ MdrunnerBuilder& addInput(SimulationInputHandle input);
+
~MdrunnerBuilder();
private:
#include "simulationinput.h"
-#include <utility>
-
-#include "simulationinput_impl.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"
namespace gmx
{
-struct MdModulesNotifier;
-
-SimulationInput::SimulationInput(const char* tprFilename, const char* cpiFilename) :
- tprFilename_(tprFilename),
- cpiFilename_(cpiFilename)
+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);
}
-SimulationInputHolder::SimulationInputHolder() = default;
-
-SimulationInputHolder::~SimulationInputHolder() = default;
-
-namespace detail
+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)
{
-
-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<SimulationInput>(tprFilename, cpiFilename);
-
- SimulationInputHolder holder;
- holder.object_ = std::move(simulationInput);
- return holder;
+ load_checkpoint(simulationInput.cpiFilename_.c_str(), logfio, cr, dd_nc, inputRecord, state,
+ observablesHistory, reproducibilityRequested, mdModulesNotifier,
+ modularSimulatorCheckpointData, useModularSimulator);
}
-} // end namespace detail
-
} // end namespace gmx
* 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.
+/*! \libinternal \file
+ * \brief Utilities for interacting with SimulationInput.
*
* \author M. Eric Irrgang <ericirrgang@gmail.com>
* \ingroup module_mdrun
+ * \inlibraryapi
*/
#ifndef GMX_MDRUN_SIMULATIONINPUT_H
#define GMX_MDRUN_SIMULATIONINPUT_H
#include <memory>
+#include <string>
-namespace gmx
-{
+#include "gromacs/mdrun/simulationinputhandle.h"
+#include "gromacs/mdtypes/checkpointdata.h"
+#include "gromacs/utility/mdmodulenotification.h"
// Forward declarations for types from other modules that are opaque to the public API.
-class LegacyMdrunOptions;
+// 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 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().
+ * 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
*
- * See also https://gitlab.com/gromacs/gromacs/-/issues/3379 for design and development road map.
- */
-class SimulationInput;
-
-/*!
- * \brief Owning handle to a SimulationInput object.
+ * Clients should use the utility functions defined in simulationinpututility.h
*
- * SimulationInput has no public API. Acquire a SimulationInputHolder with makeSimulationInput().
- * See https://gitlab.com/gromacs/gromacs/-/issues/3374
+ * 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 SimulationInputHolder
+class SimulationInput
{
public:
- SimulationInputHolder();
- ~SimulationInputHolder();
-
- SimulationInputHolder(SimulationInputHolder&&) noexcept = default;
- SimulationInputHolder& operator=(SimulationInputHolder&&) noexcept = default;
+ SimulationInput(const char* tprFilename, const char* cpiFilename);
- std::unique_ptr<SimulationInput> object_;
+ std::string tprFilename_;
+ std::string cpiFilename_;
};
-namespace detail
-{
-
-/*! \brief Get a SimulationInput.
+/*! \brief Get the global simulation input.
*
- * \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.
+ * 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:
- * // After preparing a LegacyMdrunOptions and calling handleRestart()...
- * SimulationInputBuilder builder;
- * auto simulationInputHandle = makeSimulationInput(options, &builder);
+ * if (SIMMASTER(cr))
+ * {
+ * // Only the master rank has the global state
+ * globalState = globalSimulationState(simulationInput);
*
- * // In addition to MdrunnerBuilder::addFiles(),
- * mdrunnerBuilder.addInput(simulationInputHandle.get());
+ * // 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.
+ *
+ * \{
*/
-SimulationInputHolder makeSimulationInput(const char* tprFilename, const char* cpiFilename);
+// 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<t_state> globalSimulationState(const SimulationInput&);
+void applyGlobalInputRecord(const SimulationInput&, t_inputrec*);
+void applyGlobalTopology(const SimulationInput&, gmx_mtop_t*);
+//! \}
-} // end namespace detail
+/*! \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
+++ /dev/null
-/*
- * 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 <string>
-
-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
--- /dev/null
+/*
+ * 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 "simulationinputhandle.h"
+
+#include <utility>
+
+#include "gromacs/mdrun/legacymdrunoptions.h"
+
+namespace gmx
+{
+
+/*! \cond
+ * SimulationInput needs much more discussion and refinement before it should be used directly.
+ * Use the interface defined in the headers and refer to #3652 for updates.
+ *
+ * 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) :
+ tprFilename_(tprFilename),
+ cpiFilename_(cpiFilename)
+ {
+ }
+
+ std::string tprFilename_;
+ std::string cpiFilename_;
+};
+/*! \endcond */
+
+class detail::SimulationInputHandleImpl final
+{
+public:
+ explicit SimulationInputHandleImpl(std::shared_ptr<SimulationInput> input) :
+ simulationInput_{ std::move(input) }
+ {
+ }
+
+ SimulationInputHandleImpl(const SimulationInputHandleImpl&) = default;
+ SimulationInputHandleImpl& operator=(const SimulationInputHandleImpl&) = default;
+ SimulationInputHandleImpl(SimulationInputHandleImpl&&) noexcept = default;
+ SimulationInputHandleImpl& operator=(SimulationInputHandleImpl&&) noexcept = default;
+
+ [[nodiscard]] SimulationInput* simulationInput() const { return simulationInput_.get(); }
+
+ /*! \brief Boolean interpretation checks for presence of payload.
+ *
+ * \return true if handle has a SimulationInput, else false.
+ */
+ operator bool() const { return bool(simulationInput_); }
+
+private:
+ // Note that we should not need to worry about managing the SimulationInput
+ // Deleter as long as we manage the SimulationInputHolderImpl Deleter and
+ // SimulationInputHolderImpl is the only way to own a SimulationInput.
+ // BUT these semantics may change, and we should try to be responsible about
+ // consistent Allocator implementation.
+ std::shared_ptr<SimulationInput> simulationInput_;
+};
+
+/*! \cond
+ * TODO: Improve doxygen source scoping.
+ * It seems surprising that doxygen should be looking at this source file, but we
+ * need to exclude the following definitions to avoid warnings.
+ * Possibly related to https://gitlab.com/gromacs/gromacs/-/issues/3402
+ */
+detail::SimulationInputHandleImplDeleter::SimulationInputHandleImplDeleter() = default;
+
+detail::SimulationInputHandleImplDeleter::SimulationInputHandleImplDeleter(
+ const SimulationInputHandleImplDeleter&) noexcept = default;
+
+detail::SimulationInputHandleImplDeleter::SimulationInputHandleImplDeleter(
+ SimulationInputHandleImplDeleter&&) noexcept = default;
+
+detail::SimulationInputHandleImplDeleter& detail::SimulationInputHandleImplDeleter::
+ operator=(const SimulationInputHandleImplDeleter&) noexcept = default;
+
+detail::SimulationInputHandleImplDeleter& detail::SimulationInputHandleImplDeleter::
+ operator=(SimulationInputHandleImplDeleter&&) noexcept = default;
+
+void detail::SimulationInputHandleImplDeleter::operator()(SimulationInputHandleImpl* impl) const
+{
+ delete impl;
+}
+
+SimulationInputHandle::SimulationInputHandle() = default;
+
+SimulationInputHandle::~SimulationInputHandle() = default;
+
+SimulationInputHandle::SimulationInputHandle(std::unique_ptr<detail::SimulationInputHandleImpl> impl) :
+ impl_(impl.release())
+{
+}
+
+SimulationInputHandle::SimulationInputHandle(const SimulationInputHandle& source)
+{
+ // Dynamically allocate a new holder implementation object using the copy constructor.
+ // Note that make_unique does not provide for custom deleters, and there is no default
+ // overload to move construct/assign from basic unique_ptr to one with custom deleter,
+ // but more elaborate creation functions for SimulationInputHolderImpl seem like
+ // overkill at this point. Still, we use make_unique to confine constructor errors
+ // to the following exception-safe line.
+ auto impl = std::make_unique<detail::SimulationInputHandleImpl>(*source.impl_);
+ // Move ownership of the heap object to the handle with a custom deleter.
+ impl_.reset(impl.release());
+}
+
+SimulationInputHandle& SimulationInputHandle::operator=(const SimulationInputHandle& source)
+{
+ if (this != &source)
+ {
+ // Dynamically allocate a new holder implementation object using the copy constructor.
+ // Note that make_unique does not provide for custom deleters, and there is no default
+ // overload to move construct/assign from basic unique_ptr to one with custom deleter,
+ // but more elaborate creation functions for SimulationInputHolderImpl seem like
+ // overkill at this point. Still, we use make_unique to confine constructor errors
+ // to the following exception-safe line.
+ auto impl = std::make_unique<detail::SimulationInputHandleImpl>(*source.impl_);
+ // Move ownership of the heap object to the handle with a custom deleter.
+ impl_.reset(impl.release());
+ }
+ return *this;
+}
+/*! \endcond */
+
+SimulationInput* SimulationInputHandle::get() const noexcept
+{
+ if (!impl_)
+ {
+ return nullptr;
+ }
+ return impl_->simulationInput();
+}
+
+SimulationInputHandle::operator bool() const
+{
+ if (impl_)
+ {
+ return bool(*impl_);
+ }
+ return false;
+}
+
+SimulationInputHandle makeSimulationInput(const LegacyMdrunOptions& options)
+{
+ // 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.
+ const auto* const tprFilename = ftp2fn(efTPR, options.filenames.size(), options.filenames.data());
+ const auto* const cpiFilename = opt2fn("-cpi", options.filenames.size(), options.filenames.data());
+ auto simulationInput = std::make_unique<SimulationInput>(tprFilename, cpiFilename);
+ auto impl = std::make_unique<detail::SimulationInputHandleImpl>(std::move(simulationInput));
+
+ return SimulationInputHandle(std::move(impl));
+}
+
+} // end namespace gmx
--- /dev/null
+/*
+ * 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 <ericirrgang@gmail.com>
+ * \ingroup module_mdrun
+ * \inpublicapi
+ */
+
+#ifndef GMX_MDRUN_SIMULATIONINPUTHANDLE_H
+#define GMX_MDRUN_SIMULATIONINPUTHANDLE_H
+
+#include <memory>
+
+namespace gmx
+{
+
+// Forward declarations for types from other modules that are opaque to the public API.
+class LegacyMdrunOptions;
+
+/*!
+ * \brief Prescription for molecular simulation.
+ *
+ * Represent the complete and unique information needed to generate a simulation
+ * trajectory segment. SimulationInput objects are opaque to the public API.
+ * Ownership can be managed with SimulationInputHolder objects. Clients can
+ * acquire owning references to SimulationInput objects (as SimulationInputHolder)
+ * through makeSimulationInput() or from other SimulationInputHolders.
+ *
+ * A SimulationInput object represents an immutable source of data, and is safe
+ * to share. A SimulationInput object may have internal state to support
+ * performance optimizations when shared by multiple SimulationInputHolders.
+ * The SimulationInput is guaranteed to live at least as long as any associated
+ * SimulationInputHolders. The API does not specify whether it may persist
+ * longer internally or be reused for later equivalent requests.
+ *
+ * \see SimulationInputHandle
+ * \see makeSimulationInput()
+ *
+ * \internal
+ * SimulationInput has no public interface yet, but we need a forward declaration for the
+ * library symbol. Library interface provided through simulationinput.h
+ * See also https://gitlab.com/gromacs/gromacs/-/issues/3379 for design and development road map.
+ */
+class SimulationInput;
+
+/*! \cond internal
+ * Client software developers do not interact directly with the contents of gmx::detail,
+ * but some declarations and definitions are necessary in the public headers, such as
+ * forward declarations of implementation classes and definitions of custom deleters.
+ */
+namespace detail
+{
+/*!
+ * \brief Private implementation class;
+ */
+class SimulationInputHandleImpl;
+
+/*!
+ * \brief Explicit deleter details for SimulationInputHolderImpl.
+ *
+ * SimulationInputHolderImpl objects are created by the GROMACS library, but
+ * are destroyed when the SimulationInputHolder goes out of scope in the client
+ * code, which may be linked to a different allocator.
+ * We want to make sure that objects are allocated and deallocated with the same
+ * allocator, so we avoid the default deleter in unique_ptrs and compile allocation
+ * and deallocation code in the same translation unit.
+ *
+ * Note that this does not solve potential ABI incompatibilities between the
+ * unique_ptr implementations themselves, but we need to consider ABI
+ * compatibility goals and challenges as well as supported use cases and
+ * ownership semantics.
+ */
+struct SimulationInputHandleImplDeleter
+{
+ /*! \cond */
+ SimulationInputHandleImplDeleter();
+ SimulationInputHandleImplDeleter(const SimulationInputHandleImplDeleter& deleter) noexcept;
+ SimulationInputHandleImplDeleter(SimulationInputHandleImplDeleter&& deleter) noexcept;
+ SimulationInputHandleImplDeleter& operator=(const SimulationInputHandleImplDeleter& deleter) noexcept;
+ SimulationInputHandleImplDeleter& operator=(SimulationInputHandleImplDeleter&& deleter) noexcept;
+ void operator()(SimulationInputHandleImpl* impl) const;
+ /*! \endcond */
+};
+} // end namespace detail
+/*! \endcond internal */
+
+/*!
+ * \brief Owning handle to a SimulationInput object.
+ *
+ * SimulationInput objects are logically immutable, so ownership may be shared
+ * by multiple SimulationInputHolders.
+ *
+ * Acquire a SimulationInputHolder with makeSimulationInput() and pass to (e.g.)
+ * gmx::MdrunnerBuilder::addInput()
+ *
+ * SimulationInput has no public API yet.
+ * \see https://gitlab.com/gromacs/gromacs/-/issues/3379
+ */
+class SimulationInputHandle
+{
+public:
+ /*! \cond internal */
+ SimulationInputHandle();
+ ~SimulationInputHandle();
+
+ SimulationInputHandle(const SimulationInputHandle& source);
+ SimulationInputHandle(SimulationInputHandle&&) noexcept = default;
+
+ SimulationInputHandle& operator=(const SimulationInputHandle& rhs);
+ SimulationInputHandle& operator=(SimulationInputHandle&&) noexcept = default;
+
+ /*!
+ * \brief Take ownership of private implementation object to produce a new public holder.
+ */
+ explicit SimulationInputHandle(std::unique_ptr<detail::SimulationInputHandleImpl> impl);
+ /*! \endcond */
+
+ /*!
+ * \brief Access opaque SimulationInput pointer.
+ *
+ * \return Borrowed access to the SimulationInput, if present.
+ */
+ [[nodiscard]] SimulationInput* get() const noexcept;
+
+ /*!
+ * \brief Boolean context returns true if an input is held, else false.
+ */
+ operator bool() const;
+
+private:
+ std::unique_ptr<detail::SimulationInputHandleImpl, detail::SimulationInputHandleImplDeleter> impl_;
+};
+
+/*! \brief Direct the construction of a SimulationInput.
+ *
+ * \warning Creation methods for SimulationInput resources are under rapid development.
+ * Reference https://gitlab.com/gromacs/gromacs/-/issues/3652
+ *
+ * \param options library-internal container holding partially processed user input.
+ *
+ * \ingroup module_mdrun
+ *
+ * \internal
+ * This isn't really a public API function until its arguments are obtainable
+ * through the public API.
+ *
+ * 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());
+ *
+ */
+SimulationInputHandle makeSimulationInput(const LegacyMdrunOptions& options);
+
+} // end namespace gmx
+
+#endif // GMX_MDRUN_SIMULATIONINPUTHANDLE_H
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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 <ericirrgang@gmail.com>
- * \ingroup module_mdrun
- */
-
-#ifndef GMX_MDRUN_SIMULATIONINPUTUTILITY_H
-#define GMX_MDRUN_SIMULATIONINPUTUTILITY_H
-
-#include <memory>
-
-#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<t_state> 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
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2011-2019, by the GROMACS development team, led by
+ * Copyright (c) 2011-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.
builder.addHardwareOptions(options.hw_opt);
// \todo File names are parameters that should be managed modularly through further factoring.
builder.addFilenames(options.filenames);
+ builder.addInput(makeSimulationInput(options));
// Note: The gmx_output_env_t life time is not managed after the call to parse_common_args.
// \todo Implement lifetime management for gmx_output_env_t.
// \todo Output environment should be configured outside of Mdrunner and provided as a resource.