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.
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>
49 * Declares the main interfaces used by the modular simulator
51 * \author Pascal Merz <pascal.merz@me.com>
52 * \ingroup module_modularsimulator
54 * This header is only used within the modular simulator module
56 #ifndef GMX_MODULARSIMULATOR_MODULARSIMULATORINTERFACES_H
57 #define GMX_MODULARSIMULATOR_MODULARSIMULATORINTERFACES_H
62 #include "gromacs/utility/basedefinitions.h"
64 struct gmx_localtop_t
;
70 template<class Signaller
>
71 class SignallerBuilder
;
72 class NeighborSearchSignaller
;
73 class LastStepSignaller
;
74 class LoggingSignaller
;
75 class TrajectorySignaller
;
76 class EnergySignaller
;
78 //! \addtogroup module_modularsimulator
81 // This will make signatures more legible
87 //! The function type that can be scheduled to be run during the simulator run
88 typedef std::function
<void()> SimulatorRunFunction
;
89 //! Pointer to the function type that can be scheduled to be run during the simulator run
90 typedef std::unique_ptr
<SimulatorRunFunction
> SimulatorRunFunctionPtr
;
92 //! The function type that allows to register run functions
93 typedef std::function
<void(SimulatorRunFunctionPtr
)> RegisterRunFunction
;
94 //! Pointer to the function type that allows to register run functions
95 typedef std::unique_ptr
<RegisterRunFunction
> RegisterRunFunctionPtr
;
98 * \brief The general interface for elements of the modular simulator
100 * Setup and teardown are run once at the beginning of the simulation
101 * (after all elements were set up, before the first step) and at the
102 * end of the simulation (after the last step, before elements are
103 * destructed), respectively. `registerRun` is periodically called
104 * during the run, at which point elements can decide to register one
105 * or more run functions to be run at a specific time / step. Registering
106 * more than one function is especially valuable for collective elements
107 * consisting of more than one single element.
109 class ISimulatorElement
112 /*! \brief Query whether element wants to run at step / time
114 * Element can register one or more functions to be run at that step through
115 * the registration pointer.
117 virtual void scheduleTask(Step
, Time
, const RegisterRunFunctionPtr
&) = 0;
118 //! Method guaranteed to be called after construction, before simulator run
119 virtual void elementSetup() = 0;
120 //! Method guaranteed to be called after simulator run, before deconstruction
121 virtual void elementTeardown() = 0;
122 //! Standard virtual destructor
123 virtual ~ISimulatorElement() = default;
127 * \brief The general Signaller interface
129 * Signallers are run at the beginning of Simulator steps, informing
130 * their clients about the upcoming step. This allows clients to
131 * decide if they need to be activated at this time step, and what
132 * functions they will have to run. Examples for signallers
133 * include the neighbor-search signaller (informs its clients when a
134 * neighbor-searching step is about to happen) or the logging
135 * signaller (informs its clients when a logging step is about to
138 * We expect all signallers to accept registration from clients, but
139 * different signallers might handle that differently, so we don't
140 * include this in the interface.
145 //! Function run before every step of scheduling
146 virtual void signal(Step
, Time
) = 0;
147 //! Method guaranteed to be called after construction, before simulator run
148 virtual void setup() = 0;
149 //! Standard virtual destructor
150 virtual ~ISignaller() = default;
153 //! The function type that can be registered to signallers for callback
154 typedef std::function
<void(Step
, Time
)> SignallerCallback
;
155 //! Pointer to the function type that can be registered to signallers for callback
156 typedef std::unique_ptr
<SignallerCallback
> SignallerCallbackPtr
;
159 * \brief Interface for clients of the NeighborSearchSignaller
161 * Defining registerNSCallback allows clients to register an arbitrary callback
162 * for notification by the signaller.
164 class INeighborSearchSignallerClient
168 // (doxygen doesn't like these...)
169 //! Allow builder of NeighborSearchSignaller to ask for callback registration
170 friend class SignallerBuilder
<NeighborSearchSignaller
>;
172 //! Standard virtual destructor
173 virtual ~INeighborSearchSignallerClient() = default;
176 //! Return callback to NeighborSearchSignaller
177 virtual SignallerCallbackPtr
registerNSCallback() = 0;
181 * \brief Interface for clients of the LastStepSignaller
183 * Defining registerLastStepCallback allows clients to register an arbitrary callback
184 * for notification by the signaller.
186 class ILastStepSignallerClient
190 // (doxygen doesn't like these...)
191 //! Allow builder of LastStepSignaller to ask for callback registration
192 friend class SignallerBuilder
<LastStepSignaller
>;
194 //! Standard virtual destructor
195 virtual ~ILastStepSignallerClient() = default;
198 //! Return callback to LastStepSignaller
199 virtual SignallerCallbackPtr
registerLastStepCallback() = 0;
203 * \brief Interface for clients of the LoggingSignaller
205 * Defining registerLoggingCallback allows clients to register an arbitrary callback
206 * for notification by the signaller.
208 class ILoggingSignallerClient
212 // (doxygen doesn't like these...)
213 //! Allow builder of LoggingSignaller to ask for callback registration
214 friend class SignallerBuilder
<LoggingSignaller
>;
216 //! Standard virtual destructor
217 virtual ~ILoggingSignallerClient() = default;
220 //! Return callback to LoggingSignaller
221 virtual SignallerCallbackPtr
registerLoggingCallback() = 0;
224 //! The energy events signalled by the EnergySignaller
225 enum class EnergySignallerEvent
227 EnergyCalculationStep
,
228 VirialCalculationStep
,
229 FreeEnergyCalculationStep
233 * \brief Interface for clients of the EnergySignaller
235 * Defining registerEnergyCallback allows clients to register an arbitrary callback
236 * for notification by the signaller for every EnergySignallerEvent separately.
238 class IEnergySignallerClient
242 // (doxygen doesn't like these...)
243 //! Allow builder of EnergySignaller to ask for callback registration
244 friend class SignallerBuilder
<EnergySignaller
>;
246 //! Standard virtual destructor
247 virtual ~IEnergySignallerClient() = default;
250 //! Return callback to EnergySignaller
251 virtual SignallerCallbackPtr
registerEnergyCallback(EnergySignallerEvent
) = 0;
254 //! The trajectory writing events
255 enum class TrajectoryEvent
262 * \brief Interface for signaller clients of the TrajectoryElement
264 * Defining registerTrajectorySignallerCallback allows clients to register an arbitrary
265 * callback for notification by the signaller for every TrajectoryEvent separately.
267 class ITrajectorySignallerClient
271 // (doxygen doesn't like these...)
272 //! Allow builder of TrajectorySignaller to ask for callback registration
273 friend class SignallerBuilder
<TrajectorySignaller
>;
275 //! Standard virtual destructor
276 virtual ~ITrajectorySignallerClient() = default;
279 //! Return callback to TrajectoryElement
280 virtual SignallerCallbackPtr
registerTrajectorySignallerCallback(TrajectoryEvent
) = 0;
283 /* Trajectory writing clients are handed a pointer to the output file handler,
284 * allowing them to write their own trajectory contribution.
286 * As trajectory writing and log writing cannot currently be separated for the
287 * energy, clients also get informed whether this is a trajectory-writing step
288 * and / or a log-writing step.
290 //! Function type for trajectory writing clients
291 typedef std::function
<void(gmx_mdoutf
*, Step
, Time
, bool, bool)> ITrajectoryWriterCallback
;
292 //! Pointer to the function type for trajectory writing clients
293 typedef std::unique_ptr
<ITrajectoryWriterCallback
> ITrajectoryWriterCallbackPtr
;
296 * \brief Interface for writer clients of the TrajectoryElement
298 * Defining registerTrajectoryWriterCallback allows clients to register an arbitrary
299 * callback called by the TrajectoryElement when trajectory writing happens.
301 * Setup and teardown methods allow clients to perform tasks with a valid output pointer.
303 class ITrajectoryWriterClient
307 // (doxygen doesn't like these...)
308 //! Allow TrajectoryElement to ask for callback registration
309 friend class TrajectoryElement
;
311 //! Standard virtual destructor
312 virtual ~ITrajectoryWriterClient() = default;
315 //! Setup method with valid output pointer.
316 virtual void trajectoryWriterSetup(gmx_mdoutf
* outf
) = 0;
317 //! Teardown method with valid output pointer.
318 virtual void trajectoryWriterTeardown(gmx_mdoutf
* outf
) = 0;
320 //! Return callback to TrajectoryElement
321 virtual ITrajectoryWriterCallbackPtr
registerTrajectoryWriterCallback(TrajectoryEvent
) = 0;
325 * \brief Client requiring read access to the local topology
328 class ITopologyHolderClient
332 // (doxygen doesn't like these...)
333 //! Allow TopologyHolder to set new topology
334 friend class TopologyHolder
;
336 //! Standard virtual destructor
337 virtual ~ITopologyHolderClient() = default;
340 //! Pass pointer to new local topology
341 virtual void setTopology(const gmx_localtop_t
*) = 0;
345 * \brief Client that needs to store data during checkpointing
347 * The current checkpointing helper uses the legacy t_state object to collect
348 * the data to be checkpointed. Clients get queried for their contributions
349 * using pointers to t_state objects.
350 * \todo Add checkpoint reading
351 * \todo Evolve this to a model in which the checkpoint helper passes a file
352 * pointer rather than a t_state object, and the clients are responsible
355 class ICheckpointHelperClient
359 // (doxygen doesn't like these...)
360 //! Allow CheckpointHelper to interact
361 friend class CheckpointHelper
;
363 //! Standard virtual destructor
364 virtual ~ICheckpointHelperClient() = default;
368 virtual void writeCheckpoint(t_state
* localState
, t_state
* globalState
) = 0;
373 #endif // GMX_MODULARSIMULATOR_MODULARSIMULATORINTERFACES_H