Preparation for de-duplicating mdrun setup
[gromacs.git] / src / gromacs / mdrun / runner.h
blob75ee32f51b7c3696c41579e99a71d685b57d77a3
1 /*
2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2015,2017,2018, 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 /*! \libinternal \file
37 * \brief Declares the routine running the inetgrators.
39 * \author David van der Spoel <david.vanderspoel@icm.uu.se>
40 * \ingroup module_mdrun
42 #ifndef GMX_MDRUN_RUNNER_H
43 #define GMX_MDRUN_RUNNER_H
45 #include <cstdio>
47 #include <array>
48 #include <memory>
50 #include "gromacs/commandline/filenm.h"
51 #include "gromacs/compat/pointers.h"
52 #include "gromacs/domdec/domdec.h"
53 #include "gromacs/hardware/hw_info.h"
54 #include "gromacs/math/vec.h"
55 #include "gromacs/mdlib/mdrun.h"
56 #include "gromacs/utility/basedefinitions.h"
57 #include "gromacs/utility/real.h"
59 #include "replicaexchange.h"
61 struct gmx_output_env_t;
62 struct ReplicaExchangeParameters;
63 struct t_commrec;
64 struct t_fileio;
66 namespace gmx
69 // Todo: move to forward declaration headers...
70 class MDModules;
71 class IRestraintPotential; // defined in restraint/restraintpotential.h
72 class RestraintManager;
73 class SimulationContext;
74 class StopHandlerBuilder;
76 //! Work-around for GCC bug 58265
77 constexpr bool BUGFREE_NOEXCEPT_STRING = std::is_nothrow_move_assignable<std::string>::value;
79 /*! \libinternal \brief Runner object for supporting setup and execution of mdrun.
81 * This class has responsibility for the lifetime of data structures
82 * that exist for the life of the simulation, e.g. for logging and
83 * communication.
85 * It is also responsible for initializing data members that
86 * e.g. correspond to values potentially set by commmand-line
87 * options. Later these will be obtained directly from modules, and
88 * the results of command-line option handling returned directly to
89 * the modules, rather than propagated to them by data members of this
90 * class.
92 * \todo Most of the attributes should be declared by specific modules
93 * as command-line options. Accordingly, they do not conform to the
94 * naming scheme, because that would make for a lot of noise in the
95 * diff, only to have it change again when the options move to their
96 * modules.
98 * \todo Preparing logging and MPI contexts could probably be a
99 * higher-level responsibility, so that an Mdrunner would get made
100 * without needing to re-initialize these components (as currently
101 * happens always for the master rank, and differently for the spawned
102 * ranks with thread-MPI).
104 * \ingroup module_mdrun
106 class Mdrunner
108 public:
109 /*! \brief Builder class to manage object creation.
111 * This class is a member of gmx::Mdrunner so that it can initialize
112 * private members of gmx::Mdrunner.
114 * It is non-trivial to establish an initialized gmx::Mdrunner invariant,
115 * so objects can be obtained by clients using a Builder or a move.
116 * Clients cannot default initialize or copy gmx::Mdrunner.
118 class BuilderImplementation;
120 ~Mdrunner();
123 * \brief Copy not allowed.
125 * An Mdrunner has unique resources and it is not clear whether any of
126 * one of those resources should be duplicated or shared unless the
127 * specific use case is known. Either build a fresh runner or use a
128 * helper function for clearly indicated behavior. API clarification may
129 * allow unambiguous initialization by copy in future versions.
131 * \{
133 Mdrunner(const Mdrunner &) = delete;
134 Mdrunner &operator=(const Mdrunner &) = delete;
135 /* \} */
138 * \brief Mdrunner objects can be passed by value via move semantics.
140 * \param handle runner instance to be moved from.
141 * \{
143 Mdrunner(Mdrunner &&handle) noexcept;
144 //NOLINTNEXTLINE(performance-noexcept-move-constructor) working around GCC bug 58265
145 Mdrunner &operator=(Mdrunner &&handle) noexcept(BUGFREE_NOEXCEPT_STRING);
146 /* \} */
148 /*! \brief Driver routine, that calls the different simulation methods. */
150 * Currently, thread-MPI does not spawn threads until during mdrunner() and parallelism
151 * is not initialized until some time during this call...
153 int mdrunner();
156 * \brief Add a potential to be evaluated during MD integration.
158 * \param restraint MD restraint potential to apply
159 * \param name User-friendly plain-text name to uniquely identify the puller
161 * This implementation attaches an object providing the gmx::IRestraintPotential
162 * interface.
163 * \todo Mdrunner should fetch such resources from the SimulationContext
164 * rather than offering this public interface.
166 void addPotential(std::shared_ptr<IRestraintPotential> restraint,
167 std::string name);
169 //! Called when thread-MPI spawns threads.
170 t_commrec *spawnThreads(int numThreadsToLaunch) const;
172 /*! \brief Initializes a new Mdrunner from the master.
174 * Run this method in a new thread from a master runner to get additional
175 * workers on spawned threads.
177 * \returns New Mdrunner instance suitable for thread-MPI work on new ranks.
179 * \internal
180 * \todo clarify (multiple) invariants during MD runner start-up.
181 * The runner state before and after launching threads is distinct enough that
182 * it should be codified in the invariants of different classes. That would
183 * mean that the object returned by this method would be of a different type
184 * than the object held by the client up to the point of call, and its name
185 * would be changed to "launchOnSpawnedThread" or something not including the
186 * word "clone".
188 Mdrunner cloneOnSpawnedThread() const;
190 private:
191 /*! \brief Constructor.
193 * Note that when member variables are not present in the constructor
194 * member initialization list (which is true for the default constructor),
195 * then they are initialized with any default member initializer specified
196 * when they were declared, or default initialized. */
197 Mdrunner() = default;
199 //! Parallelism-related user options.
200 gmx_hw_opt_t hw_opt;
202 //! Filenames and properties from command-line argument values.
203 ArrayRef<const t_filenm> filenames;
205 /*! \brief Output context for writing text files
207 * \internal
208 * \todo push this data member down when the information can be queried from an encapsulated resource.
210 gmx_output_env_t *oenv = nullptr;
211 //! Ongoing collection of mdrun options
212 MdrunOptions mdrunOptions;
213 //! Options for the domain decomposition.
214 DomdecOptions domdecOptions;
216 /*! \brief Target short-range interations for "cpu", "gpu", or "auto". Default is "auto".
218 * \internal
219 * \todo replace with string or enum class and initialize with sensible value.
221 const char *nbpu_opt = nullptr;
223 /*! \brief Target long-range interactions for "cpu", "gpu", or "auto". Default is "auto".
225 * \internal
226 * \todo replace with string or enum class and initialize with sensible value.
228 const char *pme_opt = nullptr;
230 /*! \brief Target long-range interactions FFT/solve stages for "cpu", "gpu", or "auto". Default is "auto".
232 * \internal
233 * \todo replace with string or enum class and initialize with sensible value.
235 const char *pme_fft_opt = nullptr;
236 //! Command-line override for the duration of a neighbor list with the Verlet scheme.
237 int nstlist_cmdline = 0;
238 //! Parameters for replica-exchange simulations.
239 ReplicaExchangeParameters replExParams;
240 //! Print a warning if any force is larger than this (in kJ/mol nm).
241 real pforce = -1;
243 //! \brief Non-owning handle to file used for logging.
244 t_fileio *logFileHandle = nullptr;
246 //! \brief Non-owning handle to communication data structure.
247 t_commrec *cr = nullptr;
249 //! \brief Non-owning handle to multi-simulation handler.
250 gmx_multisim_t *ms = nullptr;
253 * \brief Handle to restraints manager for the current process.
255 * \internal
256 * Use opaque pointer for this implementation detail.
258 std::unique_ptr<RestraintManager> restraintManager_;
261 * \brief Builder for stop signal handler
263 * Optionally provided through MdrunnerBuilder. Client may create a
264 * StopHandlerBuilder and register any number of signal providers before
265 * launching the Mdrunner.
267 * Default is an empty signal handler that will have local signal issuers
268 * added after being passed into the integrator.
270 * \internal
271 * We do not need a full type specification here, so we use an opaque pointer.
273 std::unique_ptr<StopHandlerBuilder> stopHandlerBuilder_;
276 /*! \libinternal
277 * \brief Build a gmx::Mdrunner.
279 * Client code (such as `gmx mdrun`) uses this builder to get an initialized Mdrunner.
281 * A builder allows the library to ensure that client code cannot obtain an
282 * uninitialized or partially initialized runner by refusing to build() if the
283 * client has not provided sufficient or self-consistent direction. Director
284 * code can be implemented for different user interfaces, encapsulating any
285 * run-time functionality that does not belong in the library MD code, such
286 * as command-line option processing or interfacing to external libraries.
288 * \ingroup module_mdrun
290 * \internal
292 * The initial Builder implementation is neither extensible at run time nor
293 * at compile time. Future implementations should evolve to compose the runner,
294 * rather than just consolidating the parameters for initialization, but there
295 * is not yet a firm design for how flexibly module code will be coupled to
296 * the builder and how much of the client interface will be in this Builder
297 * versus Builders provided by the various modules.
299 * The named components for the initial builder implementation are descriptive
300 * of the state of mdrun at the time, and are not intended to be prescriptive of
301 * future design.
302 * The probable course of GROMACS development is for the modular components that
303 * support MD simulation to independently express their input parameters (required
304 * and optional) and to provide some sort of help to the UI for input preparation.
305 * If each module provides or aids the instantiation of a Director
306 * for the client code, the Directors could be constructed with a handle to this
307 * Builder and it would not need a public interface.
309 * As the modules are more clearly encapsulated, each module can provide its own
310 * builder, user interface helpers, and/or composable Director code.
311 * The runner and client code will also have to be updated as appropriate
312 * default behavior is clarified for
313 * (a) default behavior of client when user does not provide input,
314 * (b) default behavior of builder when client does not provide input, and
315 * (c) default behavior of runner when builder does not provide input.
317 class MdrunnerBuilder final
319 public:
321 * \brief Constructor requires a handle to a SimulationContext to share.
323 * \param context handle to run-time resources and execution environment details.
325 * The calling code must guarantee that the
326 * pointer remains valid for the lifetime of the builder, and that the
327 * resources retrieved from the context remain valid for the lifetime of
328 * the runner produced.
330 * \internal
331 * \todo Find and implement appropriate abstraction layers for SimulationContext.
332 * At some point this parameter should become a constant reference or value
333 * instead of a pointer.
334 * Ref e.g. https://redmine.gromacs.org/issues/2587
336 explicit MdrunnerBuilder(compat::not_null<SimulationContext*> context);
338 //! \cond
339 MdrunnerBuilder() = delete;
340 MdrunnerBuilder(const MdrunnerBuilder&) = delete;
341 MdrunnerBuilder &operator=(const MdrunnerBuilder &) = delete;
342 //! \endcond
344 /*! \brief Allow transfer of ownership with move semantics.
346 * \param builder source object to transfer.
348 * \{
350 MdrunnerBuilder(MdrunnerBuilder && builder) noexcept;
351 MdrunnerBuilder &operator=(MdrunnerBuilder &&builder) noexcept;
352 //! \}
355 * \brief Get ownership of an initialized gmx::Mdrunner.
357 * After build() is called, the Builder object should not be used
358 * again. It is an error to call build without first calling all builder
359 * methods described as "required."
361 * \return A new Mdrunner.
363 * \throws APIError if a required component has not been added before calling build().
365 Mdrunner build();
368 * \brief Set up non-bonded short-range force calculations.
370 * Required. Director code must provide valid options for the non-bonded
371 * interaction code. The builder does not apply any defaults.
373 * \param nbpu_opt Target short-range interactions for "cpu", "gpu", or "auto".
375 * Calling must guarantee that the pointed-to C string is valid through
376 * simulation launch.
378 * \internal
379 * \todo Replace with string or enum that we can have sensible defaults for.
380 * \todo Either the Builder or modular Director code should provide sensible defaults.
382 MdrunnerBuilder &addNonBonded(const char* nbpu_opt);
385 * \brief Set up long-range electrostatics calculations.
387 * Required. Director code should provide valid options for PME electrostatics,
388 * whether or not PME electrostatics are used. The builder does not apply
389 * any defaults, so client code should be prepared to provide (e.g.) "auto"
390 * in the event no user input or logic provides an alternative argument.
392 * \param pme_opt Target long-range interactions for "cpu", "gpu", or "auto".
393 * \param pme_fft_opt Target long-range interactions FFT/solve stages for "cpu", "gpu", or "auto".
395 * Calling must guarantee that the pointed-to C strings are valid through
396 * simulation launch.
398 * \internal
399 * The arguments are passed as references to elements of arrays of C strings.
400 * \todo Replace with modern strings or (better) enum classes.
401 * \todo Make optional and/or encapsulate into electrostatics module.
403 MdrunnerBuilder &addElectrostatics(const char* pme_opt,
404 const char* pme_fft_opt);
407 * \brief Provide access to the multisim communicator to use.
409 * \param multisim borrowed handle to multisim record.
411 * Required. Client should get a `gmx_multisim_t*` value from init_multisystem().
412 * Client is responsible for calling done_multisim() on the handle after
413 * simulation.
415 * \internal Pointer is copied, but calling code retains ownership and
416 * responsibility for multisim. Mdrunner must not do anything that would
417 * invalidate the original copied-from pointer.
419 * \todo Clarify semantics of specifying optional multisim work
420 * \todo Clarify ownership and management of multisim resources.
422 MdrunnerBuilder &addMultiSim(gmx_multisim_t* multisim);
425 * \brief Set MD options not owned by some other module.
427 * Optional. Override simulation parameters
429 * \param options structure to copy
430 * \param forceWarningThreshold Print a warning if any force is larger than this (in kJ/mol nm) (default -1)
432 * \internal
433 * \todo Map these parameters to more appropriate encapsulating types.
434 * Find a better way to indicate "unspecified" than a magic value of the parameter type.
436 MdrunnerBuilder &addSimulationMethod(const MdrunOptions &options,
437 real forceWarningThreshold);
440 * \brief Set the domain decomposition module.
442 * Optional. Overrides default constructed DomdecOptions if provided.
444 * \param options options with which to construct domain decomposition.
446 * \internal
447 * \todo revisit whether we should be passing this parameter struct or a higher-level handle of some sort.
449 MdrunnerBuilder &addDomainDecomposition(const DomdecOptions &options);
452 * \brief Set Verlet list manager.
454 * Optional. Neighbor list existence, type, and parameters are mostly determined
455 * by the simulation parameters loaded elsewhere. This is just an override.
457 * \param rebuildInterval override for the duration of a neighbor list with the Verlet scheme.
459 MdrunnerBuilder &addNeighborList(int rebuildInterval);
462 * \brief Set replica exchange manager.
464 * Optional. For guidance on preparing a valid ReplicaExchangeParameters
465 * value, refer to the details in mdrun.cpp, the `t_pargs pa[]` defined there,
466 * and the action of parse_common_args() with regards to that structure.
467 * If not provided by client, a default constructed ReplicaExchangeParameters
468 * is used.
470 * \param params parameters with which to set up replica exchange.
472 * \internal
473 * \todo revisit whether we should be passing this parameter struct or a higher-level handle of some sort.
475 MdrunnerBuilder &addReplicaExchange(const ReplicaExchangeParameters &params);
478 * \brief Specify parameters determining hardware resource allocation.
480 * Optional. If not provided, default-constructed gmx_hw_opt_t will be used.
482 * \param hardwareOptions Parallelism-related user options.
484 MdrunnerBuilder &addHardwareOptions(const gmx_hw_opt_t &hardwareOptions);
487 * \brief Provide the filenames options structure with option values chosen
489 * Required. The object is assumed to have been updated by
490 * parse_common_args or equivalent.
492 * \param filenames Filenames and properties from command-line argument values or defaults.
494 * \internal
495 * \todo Modules should manage their own filename options and defaults.
497 MdrunnerBuilder &addFilenames(ArrayRef<const t_filenm> filenames);
500 * \brief Provide parameters for setting up output environment.
502 * Required. Handle is assumed to have been produced by output_env_init
503 * as in parse_common_args.
505 * \param outputEnvironment Output context for writing text files.
507 * \internal
508 * \todo Allow client code to set up output environment and provide as a resource.
509 * This parameter is used to set up resources that are dependent on the execution
510 * environment and API context. Such resources should be retrieved by the simulator
511 * from a client-provided resource, but currently the resources are only fully
512 * initialized in Mdrunner.
514 MdrunnerBuilder &addOutputEnvironment(gmx_output_env_t* outputEnvironment);
517 * \brief Provide the filehandle pointer to be used for the MD log.
519 * Required. Either nullptr if no log should be written, or
520 * valid and open reading for writing.
522 * \param logFileHandle Non-owning handle to file used for logging.
523 * \internal
525 MdrunnerBuilder &addLogFile(t_fileio *logFileHandle);
528 * \brief Provide a StopHandlerBuilder for the MD stop signal handling.
530 * Optional. Defaults to empty.
532 * Client may provide additional (non-default) issuers of simulation stop
533 * signals by preconfiguring the StopHandlerBuilder used later when the
534 * simulation runs.
536 * \param builder
538 MdrunnerBuilder &addStopHandlerBuilder(std::unique_ptr<StopHandlerBuilder> builder);
540 ~MdrunnerBuilder();
542 private:
543 std::unique_ptr<Mdrunner::BuilderImplementation> impl_;
546 } // namespace gmx
548 #endif // GMX_MDRUN_RUNNER_H