Annotate modular simulator headers with exposure level
[gromacs.git] / src / gromacs / modularsimulator / modularsimulatorinterfaces.h
blob85c37d94d1a53d83c66f438bf14690a15b3d2dca
1 /*
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
37 * \brief
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 /*! \internal \file
48 * \brief
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
59 #include <functional>
60 #include <memory>
62 #include "gromacs/utility/basedefinitions.h"
64 struct gmx_localtop_t;
65 struct gmx_mdoutf;
66 class t_state;
68 namespace gmx
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
79 //! \{
81 // This will make signatures more legible
82 //! Step number
83 using Step = int64_t;
84 //! Simulation time
85 using Time = double;
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;
97 /*! \internal
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
111 public:
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;
126 /*! \internal
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
136 * happen).
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.
142 class ISignaller
144 public:
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;
158 /*! \internal
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
166 public:
167 //! @cond
168 // (doxygen doesn't like these...)
169 //! Allow builder of NeighborSearchSignaller to ask for callback registration
170 friend class SignallerBuilder<NeighborSearchSignaller>;
171 //! @endcond
172 //! Standard virtual destructor
173 virtual ~INeighborSearchSignallerClient() = default;
175 protected:
176 //! Return callback to NeighborSearchSignaller
177 virtual SignallerCallbackPtr registerNSCallback() = 0;
180 /*! \internal
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
188 public:
189 //! @cond
190 // (doxygen doesn't like these...)
191 //! Allow builder of LastStepSignaller to ask for callback registration
192 friend class SignallerBuilder<LastStepSignaller>;
193 //! @endcond
194 //! Standard virtual destructor
195 virtual ~ILastStepSignallerClient() = default;
197 protected:
198 //! Return callback to LastStepSignaller
199 virtual SignallerCallbackPtr registerLastStepCallback() = 0;
202 /*! \internal
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
210 public:
211 //! @cond
212 // (doxygen doesn't like these...)
213 //! Allow builder of LoggingSignaller to ask for callback registration
214 friend class SignallerBuilder<LoggingSignaller>;
215 //! @endcond
216 //! Standard virtual destructor
217 virtual ~ILoggingSignallerClient() = default;
219 protected:
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
232 /*! \internal
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
240 public:
241 //! @cond
242 // (doxygen doesn't like these...)
243 //! Allow builder of EnergySignaller to ask for callback registration
244 friend class SignallerBuilder<EnergySignaller>;
245 //! @endcond
246 //! Standard virtual destructor
247 virtual ~IEnergySignallerClient() = default;
249 protected:
250 //! Return callback to EnergySignaller
251 virtual SignallerCallbackPtr registerEnergyCallback(EnergySignallerEvent) = 0;
254 //! The trajectory writing events
255 enum class TrajectoryEvent
257 StateWritingStep,
258 EnergyWritingStep
261 /*! \internal
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
269 public:
270 //! @cond
271 // (doxygen doesn't like these...)
272 //! Allow builder of TrajectorySignaller to ask for callback registration
273 friend class SignallerBuilder<TrajectorySignaller>;
274 //! @endcond
275 //! Standard virtual destructor
276 virtual ~ITrajectorySignallerClient() = default;
278 protected:
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;
295 /*! \internal
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
305 public:
306 //! @cond
307 // (doxygen doesn't like these...)
308 //! Allow TrajectoryElement to ask for callback registration
309 friend class TrajectoryElement;
310 //! @endcond
311 //! Standard virtual destructor
312 virtual ~ITrajectoryWriterClient() = default;
314 protected:
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;
324 /*! \internal
325 * \brief Client requiring read access to the local topology
328 class ITopologyHolderClient
330 public:
331 //! @cond
332 // (doxygen doesn't like these...)
333 //! Allow TopologyHolder to set new topology
334 friend class TopologyHolder;
335 //! @endcond
336 //! Standard virtual destructor
337 virtual ~ITopologyHolderClient() = default;
339 protected:
340 //! Pass pointer to new local topology
341 virtual void setTopology(const gmx_localtop_t*) = 0;
344 /*! \internal
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
353 * to read / write.
355 class ICheckpointHelperClient
357 public:
358 //! @cond
359 // (doxygen doesn't like these...)
360 //! Allow CheckpointHelper to interact
361 friend class CheckpointHelper;
362 //! @endcond
363 //! Standard virtual destructor
364 virtual ~ICheckpointHelperClient() = default;
366 protected:
367 //! Write checkpoint
368 virtual void writeCheckpoint(t_state* localState, t_state* globalState) = 0;
370 //! /}
371 } // namespace gmx
373 #endif // GMX_MODULARSIMULATOR_MODULARSIMULATORINTERFACES_H