2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2019, 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.
35 /*! \defgroup module_modularsimulator The modular simulator
36 * \ingroup group_mdrun
38 * The modular simulator improves extensibility, adds Monte Carlo capabilities,
39 * promotes data locality and communication via interfaces, supports
40 * multi-stepping integrators, and paves the way for some task parallelism.
42 * For more information, see page_modularsimulator
43 * \todo Can we link to `docs/doxygen/lib/modularsimulator.md`?
45 * \author Pascal Merz <pascal.merz@me.com>
47 /*! \libinternal \file
49 * Declares the main interfaces used by the modular simulator
51 * \author Pascal Merz <pascal.merz@me.com>
52 * \ingroup module_modularsimulator
54 #ifndef GMX_MODULARSIMULATOR_MODULARSIMULATORINTERFACES_H
55 #define GMX_MODULARSIMULATOR_MODULARSIMULATORINTERFACES_H
60 #include "gromacs/utility/basedefinitions.h"
62 struct gmx_localtop_t;
68 template<class Signaller>
69 class SignallerBuilder;
70 class NeighborSearchSignaller;
71 class LastStepSignaller;
72 class LoggingSignaller;
73 class EnergySignaller;
75 //! \addtogroup module_modularsimulator
78 // This will make signatures more legible
84 //! The function type that can be scheduled to be run during the simulator run
85 typedef std::function<void()> SimulatorRunFunction;
86 //! Pointer to the function type that can be scheduled to be run during the simulator run
87 typedef std::unique_ptr<SimulatorRunFunction> SimulatorRunFunctionPtr;
89 //! The function type that allows to register run functions
90 typedef std::function<void(SimulatorRunFunctionPtr)> RegisterRunFunction;
91 //! Pointer to the function type that allows to register run functions
92 typedef std::unique_ptr<RegisterRunFunction> RegisterRunFunctionPtr;
95 * \brief The general interface for elements of the modular simulator
97 * Setup and teardown are run once at the beginning of the simulation
98 * (after all elements were set up, before the first step) and at the
99 * end of the simulation (after the last step, before elements are
100 * destructed), respectively. `registerRun` is periodically called
101 * during the run, at which point elements can decide to register one
102 * or more run functions to be run at a specific time / step. Registering
103 * more than one function is especially valuable for collective elements
104 * consisting of more than one single element.
106 class ISimulatorElement
109 /*! \brief Query whether element wants to run at step / time
111 * Element can register one or more functions to be run at that step through
112 * the registration pointer.
114 virtual void scheduleTask(Step, Time, const RegisterRunFunctionPtr&) = 0;
115 //! Method guaranteed to be called after construction, before simulator run
116 virtual void elementSetup() = 0;
117 //! Method guaranteed to be called after simulator run, before deconstruction
118 virtual void elementTeardown() = 0;
119 //! Standard virtual destructor
120 virtual ~ISimulatorElement() = default;
124 * \brief The general Signaller interface
126 * Signallers are run at the beginning of Simulator steps, informing
127 * their clients about the upcoming step. This allows clients to
128 * decide if they need to be activated at this time step, and what
129 * functions they will have to run. Examples for signallers
130 * include the neighbor-search signaller (informs its clients when a
131 * neighbor-searching step is about to happen) or the logging
132 * signaller (informs its clients when a logging step is about to
135 * We expect all signallers to accept registration from clients, but
136 * different signallers might handle that differently, so we don't
137 * include this in the interface.
142 //! Function run before every step of scheduling
143 virtual void signal(Step, Time) = 0;
144 //! Method guaranteed to be called after construction, before simulator run
145 virtual void signallerSetup() = 0;
146 //! Standard virtual destructor
147 virtual ~ISignaller() = default;
150 //! The function type that can be registered to signallers for callback
151 typedef std::function<void(Step, Time)> SignallerCallback;
152 //! Pointer to the function type that can be registered to signallers for callback
153 typedef std::unique_ptr<SignallerCallback> SignallerCallbackPtr;
156 * \brief Interface for clients of the NeighborSearchSignaller
158 * Defining registerNSCallback allows clients to register an arbitrary callback
159 * for notification by the signaller.
161 class INeighborSearchSignallerClient
165 // (doxygen doesn't like these...)
166 //! Allow builder of NeighborSearchSignaller to ask for callback registration
167 friend class SignallerBuilder<NeighborSearchSignaller>;
169 //! Standard virtual destructor
170 virtual ~INeighborSearchSignallerClient() = default;
173 //! Return callback to NeighborSearchSignaller
174 virtual SignallerCallbackPtr registerNSCallback() = 0;
178 * \brief Interface for clients of the LastStepSignaller
180 * Defining registerLastStepCallback allows clients to register an arbitrary callback
181 * for notification by the signaller.
183 class ILastStepSignallerClient
187 // (doxygen doesn't like these...)
188 //! Allow builder of LastStepSignaller to ask for callback registration
189 friend class SignallerBuilder<LastStepSignaller>;
191 //! Standard virtual destructor
192 virtual ~ILastStepSignallerClient() = default;
195 //! Return callback to LastStepSignaller
196 virtual SignallerCallbackPtr registerLastStepCallback() = 0;
200 * \brief Interface for clients of the LoggingSignaller
202 * Defining registerLoggingCallback allows clients to register an arbitrary callback
203 * for notification by the signaller.
205 class ILoggingSignallerClient
209 // (doxygen doesn't like these...)
210 //! Allow builder of LoggingSignaller to ask for callback registration
211 friend class SignallerBuilder<LoggingSignaller>;
213 //! Standard virtual destructor
214 virtual ~ILoggingSignallerClient() = default;
217 //! Return callback to LoggingSignaller
218 virtual SignallerCallbackPtr registerLoggingCallback() = 0;
221 //! The energy events signalled by the EnergySignaller
222 enum class EnergySignallerEvent
224 EnergyCalculationStep,
225 VirialCalculationStep,
226 FreeEnergyCalculationStep
230 * \brief Interface for clients of the EnergySignaller
232 * Defining registerEnergyCallback allows clients to register an arbitrary callback
233 * for notification by the signaller for every EnergySignallerEvent separately.
235 class IEnergySignallerClient
239 // (doxygen doesn't like these...)
240 //! Allow builder of EnergySignaller to ask for callback registration
241 friend class SignallerBuilder<EnergySignaller>;
243 //! Standard virtual destructor
244 virtual ~IEnergySignallerClient() = default;
247 //! Return callback to EnergySignaller
248 virtual SignallerCallbackPtr registerEnergyCallback(EnergySignallerEvent) = 0;
251 //! The trajectory writing events
252 enum class TrajectoryEvent
259 * \brief Interface for signaller clients of the TrajectoryElement
261 * Defining registerTrajectorySignallerCallback allows clients to register an arbitrary
262 * callback for notification by the signaller for every TrajectoryEvent separately.
264 class ITrajectorySignallerClient
268 // (doxygen doesn't like these...)
269 //! Allow builder of TrajectoryElement to ask for callback registration
270 friend class TrajectoryElementBuilder;
272 //! Standard virtual destructor
273 virtual ~ITrajectorySignallerClient() = default;
276 //! Return callback to TrajectoryElement
277 virtual SignallerCallbackPtr registerTrajectorySignallerCallback(TrajectoryEvent) = 0;
280 /* Trajectory writing clients are handed a pointer to the output file handler,
281 * allowing them to write their own trajectory contribution.
283 * As trajectory writing and log writing cannot currently be separated for the
284 * energy, clients also get informed whether this is a trajectory-writing step
285 * and / or a log-writing step.
287 //! Function type for trajectory writing clients
288 typedef std::function<void(gmx_mdoutf*, Step, Time, bool, bool)> ITrajectoryWriterCallback;
289 //! Pointer to the function type for trajectory writing clients
290 typedef std::unique_ptr<ITrajectoryWriterCallback> ITrajectoryWriterCallbackPtr;
293 * \brief Interface for writer clients of the TrajectoryElement
295 * Defining registerTrajectoryWriterCallback allows clients to register an arbitrary
296 * callback called by the TrajectoryElement when trajectory writing happens.
298 * Setup and teardown methods allow clients to perform tasks with a valid output pointer.
299 * These functions have a standard implementation to allow clients not to implement
300 * them if no setup / teardown is needed.
302 class ITrajectoryWriterClient
306 // (doxygen doesn't like these...)
307 //! Allow TrajectoryElement to ask for callback registration
308 friend class TrajectoryElement;
310 //! Standard virtual destructor
311 virtual ~ITrajectoryWriterClient() = default;
314 //! Setup method with valid output pointer.
315 virtual void trajectoryWriterSetup(gmx_mdoutf* outf) = 0;
316 //! Teardown method with valid output pointer.
317 virtual void trajectoryWriterTeardown(gmx_mdoutf* outf) = 0;
319 //! Return callback to TrajectoryElement
320 virtual ITrajectoryWriterCallbackPtr registerTrajectoryWriterCallback(TrajectoryEvent) = 0;
324 * \brief Client requiring read access to the local topology
327 class ITopologyHolderClient
331 // (doxygen doesn't like these...)
332 //! Allow TopologyHolder to set new topology
333 friend class TopologyHolder;
335 //! Standard virtual destructor
336 virtual ~ITopologyHolderClient() = default;
339 //! Pass pointer to new local topology
340 virtual void setTopology(const gmx_localtop_t*) = 0;
344 * \brief Client that needs to store data during checkpointing
346 * The current checkpointing helper uses the legacy t_state object to collect
347 * the data to be checkpointed. Clients get queried for their contributions
348 * using pointers to t_state objects.
349 * \todo Add checkpoint reading
350 * \todo Evolve this to a model in which the checkpoint helper passes a file
351 * pointer rather than a t_state object, and the clients are responsible
354 class ICheckpointHelperClient
358 // (doxygen doesn't like these...)
359 //! Allow CheckpointHelper to interact
360 friend class CheckpointHelper;
362 //! Standard virtual destructor
363 virtual ~ICheckpointHelperClient() = default;
367 virtual void writeCheckpoint(t_state* localState, t_state* globalState) = 0;
372 #endif // GMX_MODULARSIMULATOR_MODULARSIMULATORINTERFACES_H