SimulationInput abstraction
MD simulation initialization has deeply-embedded dependencies on the TPR file and on the checkpoint file. This means there is not a clear seam for features like Monte Carlo state restoration or for decoupling replica exchange (and other multi-sim modes) from the core simulation. More generally, API features for simulation input preparation are blocked by missing abstractions from which simulator invariants can be established.
This is a proposal for a SimulationInput abstraction that
- reduces coupling between Mdrunner initialization code and file-based input
- encapsulates the aggregate of input that includes contributions from both TPR and checkpoint files
- conveys all information needed to start a simulation run (except run time parameters that do not affect the meaning of the results).
The goal is to create an object which represents the entire simulation input, and is sufficient to start a simulation. In a first approach, it will simply be created from the TPR and checkpoint files, but it will later allow creation and manipulation of input independently from these files (e.g. through the API). It would add a layer of abstraction between the reading of input files and the creation of objects used throughout the simulation (such as t_state, inputrec, mtop), simplifying changes on either side of this layer.
Characteristics
SimulationInput is an opaque type that can be used to parameterize factories or Directors in use cases where read_tpx_state() and load_checkpoint() currently appear.
A SimulationInput handle is obtained by client code and provided to the gmx::Mdrunner. Previous design discussions have established a preference for a fully defined type that can be instantiated (as a stack object) on either side of the API boundary. (It's pointed-to implementation member can be passed across the API boundary in a unique_ptr as long as we provide a custom deleter.) The contents of the holder (the SimulationInput) are as opaque as possible in initial implementations.
The invariant of a SimulationInput is its ability to define the starting point of a trajectory segment. SimulationInput objects are logically immutable (implementation details may warrant internal statefulness).
Resolution
Reviewers have requested one merge request each for
-
Initial factoring to remove TPR/CPT filename arguments from Mdrunner. (!454 (merged)) -
Public API supporting client ownership of encapsulated SimulationInput. (!465 (merged))
Implementation details
A design review meeting (@cblau , @ejjordan , @ptmerz , @kanduri ) accepted
that an initial implementation should simply capture the relevant filename
arguments from LegacyMdrunOptions to allow read_tpx_state
and load_checkpoint
to be replaced with operations on a SimulationInput object.
While we figure out what the public or object-oriented interface should look like, free function utilities handle existing use cases.
Client code provides a SimulationInput when building the Mdrunner.
Initially, client code can create a SimulationInput from a LegacyMdrunOptions.
In the simulation runner, calls to read_tpx_state
and load_checkpoint
are replaced with
calls that use the SimulationInput handle.
See !454 (merged) for additional design notes.
Public interface
To facilitate development in the next cycle without crippling maintainability, the 2021 release needs to
- rely on a SimulationInput object instead of
-s
and-cpi
, and - allow client code to own a SimulationInput object.
The proposal defines a holder that allows SimulationInput to remain minimally specified, but safely allocated and deallocated on either side of the API boundary now and into the future.
Design notes have been moved to !465 (merged)
Future work
- Allow a SimulationInput to be used to prototype the builder for a new SimulationInput, and use as the basis for gmxapi.modify_input / gmx_convert-tpr
- Produce sufficient information from gmx::Mdrunner (or gmx::Mdrunner::mdrunner()) to build a new SimulationInput, corresponding to the final simulator state.
- Define the composition of a SimulationInput. Define less opaque representations of SimulationInput components that can be extracted from or built into a SimulationInput.
- adapters to write files out from a SimulationInput
- serialization/deserialization?
See also #3379 (closed) and #3652 (closed)
Expansion of builder protocol
makeSimulationInput() can be extended or replaced as a SimulationInput can be composed in multiple ways.
/*! \brief Direct the construction of a SimulationInput.
*
* Example:
* // mdrun command implementation.
* SimulationInputBuilder builder;
* auto director = simulationInputDirector(options);
* director.construct(&builder);
* auto inputHandle = builder.build();
*
* //
*/
SimulationInputDirector simulationInputDirector(const LegacyMdrunOptions&);
Additionally, it is probably appropriate to refactor handleRestart as a step in directing the construction of the SimulationInput let startingBehavior be extracted from SimulationInput.
Deferred
This proposal is intended to support and complement other efforts that are explicitly beyond the scope of the present issue, such as
- Define SimulationState.
- Unify tpr and cpt file formats to a single simulation input / continuation file format.
- Relations:
- relates #2901 (closed)
- parent #3379 (closed)