2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2019,2020, by the GROMACS development team, led by
5 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 * and including many others, as listed in the AUTHORS file in the
7 * top-level source directory and at http://www.gromacs.org.
9 * GROMACS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * GROMACS is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with GROMACS; if not, see
21 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * If you want to redistribute modifications to GROMACS, please
25 * consider that scientific software is very special. Version
26 * control is crucial - bugs must be traceable. We will be happy to
27 * consider code for inclusion in the official distribution, but
28 * derived work must not be called official GROMACS. Details are found
29 * in the README & COPYING files - if they are missing, get the
30 * official version at http://www.gromacs.org.
32 * To help us fund GROMACS development, we humbly ask that you cite
33 * the research papers on the package. Check out http://www.gromacs.org.
36 * \brief Declares the checkpoint helper for the modular simulator
38 * \author Pascal Merz <pascal.merz@me.com>
39 * \ingroup module_modularsimulator
41 * This header is only used within the modular simulator module
44 #ifndef GMX_MODULARSIMULATOR_CHECKPOINTHELPER_H
45 #define GMX_MODULARSIMULATOR_CHECKPOINTHELPER_H
50 #include "gromacs/mdlib/checkpointhandler.h"
51 #include "gromacs/mdrunutility/handlerestart.h"
53 #include "modularsimulatorinterfaces.h"
55 struct gmx_walltime_accounting;
56 struct ObservablesHistory;
60 class KeyValueTreeObject;
62 class TrajectoryElement;
65 * \ingroup module_modularsimulator
66 * \brief Checkpoint helper
68 * The `CheckpointHelper` is responsible to write checkpoints. In the
69 * longer term, it will also be responsible to read checkpoints, but this
70 * is not yet implemented.
72 * Writing checkpoints is done just before neighbor-searching (NS) steps,
73 * or after the last step. Checkpointing occurs periodically (by default,
74 * every 15 minutes), and needs two NS steps to take effect - on the first
75 * NS step, the checkpoint helper on master rank signals to all other ranks
76 * that checkpointing is about to occur. At the next NS step, the checkpoint
77 * is written. On the last step, checkpointing happens immediately after the
78 * step (no signalling). To be able to react to last step being signalled,
79 * the CheckpointHelper does also implement the `ISimulatorElement` interface,
80 * but does only register a function if the last step has been called. It
81 * should be placed on top of the simulator loop.
83 * Checkpointing happens at the end of a simulation step, which gives a
84 * straightforward re-entry point at the top of the simulator loop.
86 * Checkpoint writing is done by passing sub-objects of a
87 * WriteCheckpointDataHolder object to the clients. Checkpoint reading is
88 * done by passing sub-objects of a ReadCheckpointDataHolder object (passed
89 * in from runner level) do the clients.
91 * \see ReadCheckpointDataHolder
92 * \see WriteCheckpointDataHolder
95 class CheckpointHelper final : public ILastStepSignallerClient, public ISimulatorElement
99 CheckpointHelper(std::vector<std::tuple<std::string, ICheckpointHelperClient*>>&& clients,
100 std::unique_ptr<CheckpointHandler> checkpointHandler,
102 TrajectoryElement* trajectoryElement,
105 ObservablesHistory* observablesHistory,
106 gmx_walltime_accounting* walltime_accounting,
107 t_state* state_global,
108 bool writeFinalCheckpoint);
110 /*! \brief Run checkpointing
112 * Sets signal and / or performs checkpointing at neighbor searching steps
114 * \param step The step number
115 * \param time The time
117 void run(Step step, Time time);
119 /*! \brief Register run function for step / time
121 * Performs checkpointing at the last step. This is part of the element call
122 * list, as the checkpoint helper need to be able to react to the last step
125 * \param step The step number
126 * \param time The time
127 * \param registerRunFunction Function allowing to register a run function
129 void scheduleTask(Step step, Time time, const RegisterRunFunction& registerRunFunction) override;
131 //! No element setup needed
132 void elementSetup() override {}
133 //! No element teardown needed
134 void elementTeardown() override {}
137 //! List of checkpoint clients
138 std::vector<std::tuple<std::string, ICheckpointHelperClient*>> clients_;
140 //! The checkpoint handler
141 std::unique_ptr<CheckpointHandler> checkpointHandler_;
143 //! The first step of the simulation
144 const Step initStep_;
145 //! The last step of the simulation
147 //! Whether a checkpoint is written on the last step
148 const bool writeFinalCheckpoint_;
150 //! ILastStepSignallerClient implementation
151 std::optional<SignallerCallback> registerLastStepCallback() override;
153 //! The actual checkpoint writing function
154 void writeCheckpoint(Step step, Time time);
156 //! Pointer to the trajectory element - to use file pointer
157 TrajectoryElement* trajectoryElement_;
159 // Access to ISimulator data
162 //! Handles communication.
164 //! History of simulation observables.
165 ObservablesHistory* observablesHistory_;
166 //! Manages wall time accounting.
167 gmx_walltime_accounting* walltime_accounting_;
168 //! Full simulation state (only non-nullptr on master rank).
169 t_state* state_global_;
173 * \ingroup module_modularsimulator
174 * \brief Builder for the checkpoint helper
176 class CheckpointHelperBuilder
180 CheckpointHelperBuilder(std::unique_ptr<ReadCheckpointDataHolder> checkpointDataHolder,
181 StartingBehavior startingBehavior,
184 //! Register checkpointing client
185 void registerClient(ICheckpointHelperClient* client);
187 //! Set CheckpointHandler
188 void setCheckpointHandler(std::unique_ptr<CheckpointHandler> checkpointHandler);
190 //! Return CheckpointHelper
191 template<typename... Args>
192 std::unique_ptr<CheckpointHelper> build(Args&&... args);
195 //! Map of checkpoint clients
196 std::map<std::string, ICheckpointHelperClient*> clientsMap_;
197 //! Whether we are resetting from checkpoint
198 const bool resetFromCheckpoint_;
199 //! The input checkpoint data
200 std::unique_ptr<ReadCheckpointDataHolder> checkpointDataHolder_;
201 //! The checkpoint handler
202 std::unique_ptr<CheckpointHandler> checkpointHandler_;
203 //! Handles communication.
205 //! Whether the builder accepts registrations.
206 ModularSimulatorBuilderState state_;
209 template<typename... Args>
210 std::unique_ptr<CheckpointHelper> CheckpointHelperBuilder::build(Args&&... args)
212 state_ = ModularSimulatorBuilderState::NotAcceptingClientRegistrations;
213 // Make sure that we don't have unused entries in checkpoint
214 if (resetFromCheckpoint_)
216 for (const auto& key : checkpointDataHolder_->keys())
218 if (clientsMap_.count(key) == 0)
220 // We have an entry in checkpointDataHolder_ which has no matching client
221 throw CheckpointError("Checkpoint entry " + key + " was not read. This "
222 "likely means that you are not using the same algorithm "
223 "that was used to create the checkpoint file.");
228 std::vector<std::tuple<std::string, ICheckpointHelperClient*>>&& clients = { clientsMap_.begin(),
230 return std::make_unique<CheckpointHelper>(std::move(clients), std::move(checkpointHandler_),
231 std::forward<Args>(args)...);
236 #endif // GMX_MODULARSIMULATOR_CHECKPOINTHELPER_H