Create and use SimulationInput module.
[alexxy/gromacs.git] / src / gromacs / mdrun / runner.cpp
index 3d3a1bcf38618e74bd50895af6096ad73db9ae4f..9dcfd9cd741509f0d83917731a5b5b93d2599384 100644 (file)
 #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
@@ -356,6 +356,7 @@ Mdrunner Mdrunner::cloneOnSpawnedThread() const
     newRunner.ms                  = ms;
     newRunner.startingBehavior    = startingBehavior;
     newRunner.stopHandlerBuilder_ = std::make_unique<StopHandlerBuilder>(*stopHandlerBuilder_);
+    newRunner.inputHolder_        = inputHolder_;
 
     threadMpiMdrunnerAccessBarrier();
 
@@ -782,13 +783,6 @@ 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<t_inputrec> inputrec;
@@ -806,7 +800,7 @@ int Mdrunner::mdrunner()
         /* 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);
     }
 
@@ -1098,7 +1092,7 @@ int Mdrunner::mdrunner()
 
         // 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);
@@ -1870,6 +1864,8 @@ public:
 
     void addDomdec(const DomdecOptions& options);
 
+    void addInput(SimulationInputHandle inputHolder);
+
     void addVerletList(int nstlist);
 
     void addReplicaExchange(const ReplicaExchangeParameters& params);
@@ -1954,6 +1950,8 @@ private:
      * \brief Builder for simulation stop signal handler.
      */
     std::unique_ptr<StopHandlerBuilder> stopHandlerBuilder_ = nullptr;
+
+    SimulationInputHandle inputHolder_;
 };
 
 Mdrunner::BuilderImplementation::BuilderImplementation(std::unique_ptr<MDModules> mdModules,
@@ -2016,6 +2014,15 @@ Mdrunner Mdrunner::BuilderImplementation::build()
     // 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.
@@ -2131,6 +2138,11 @@ void Mdrunner::BuilderImplementation::addStopHandlerBuilder(std::unique_ptr<Stop
     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) }
@@ -2235,6 +2247,12 @@ MdrunnerBuilder& MdrunnerBuilder::addStopHandlerBuilder(std::unique_ptr<StopHand
     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;