Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2011-2023 The plumed team
3 : (see the PEOPLE file at the root of the distribution for a list of names)
4 :
5 : See http://www.plumed.org for more information.
6 :
7 : This file is part of plumed, version 2.
8 :
9 : plumed is free software: you can redistribute it and/or modify
10 : it under the terms of the GNU Lesser General Public License as published by
11 : the Free Software Foundation, either version 3 of the License, or
12 : (at your option) any later version.
13 :
14 : plumed 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
17 : GNU Lesser General Public License for more details.
18 :
19 : You should have received a copy of the GNU Lesser General Public License
20 : along with plumed. If not, see <http://www.gnu.org/licenses/>.
21 : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
22 : #ifndef __PLUMED_core_PlumedMain_h
23 : #define __PLUMED_core_PlumedMain_h
24 :
25 : #include "WithCmd.h"
26 : #include "tools/ForwardDecl.h"
27 : #include <cstdio>
28 : #include <string>
29 : #include <vector>
30 : #include <set>
31 : #include <stack>
32 : #include <memory>
33 : #include <map>
34 : #include <atomic>
35 :
36 : // !!!!!!!!!!!!!!!!!!!!!! DANGER !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!11
37 : // THE FOLLOWING ARE DEFINITIONS WHICH ARE NECESSARY FOR DYNAMIC LOADING OF THE PLUMED KERNEL:
38 : // This section should be consistent with the Plumed.h file.
39 : // Since the Plumed.h file may be included in host MD codes, **NEVER** MODIFY THE CODE DOWN HERE
40 :
41 : /* Generic function pointer */
42 : typedef void (*plumed_function_pointer)(void);
43 :
44 : /* Holder for function pointer */
45 : typedef struct {
46 : plumed_function_pointer p;
47 : } plumed_function_holder;
48 :
49 : // END OF DANGER
50 : ////////////////////////////////////////////////////////////
51 :
52 : namespace PLMD {
53 :
54 :
55 :
56 : class ActionAtomistic;
57 : class ActionPilot;
58 : class ActionForInterface;
59 : class Log;
60 : class Atoms;
61 : class ActionSet;
62 : class DLLoader;
63 : class Communicator;
64 : class Stopwatch;
65 : class Citations;
66 : class ExchangePatterns;
67 : class FileBase;
68 : class TypesafePtr;
69 : class IFile;
70 : class Units;
71 : class Keywords;
72 : class DataPassingTools;
73 :
74 : /**
75 : Main plumed object.
76 : In MD engines this object is not manipulated directly but it is wrapped in
77 : plumed or PLMD::Plumed objects. Its main method is cmd(),
78 : which defines completely the external plumed interface.
79 : It does not contain any static data.
80 : */
81 : class PlumedMain:
82 : public WithCmd {
83 : /// Pointers to files opened in actions associated to this object.
84 : /// Notice that with the current implementation this should be at the top of this
85 : /// structure. Indeed, this should be destroyed *after* all the actions allocated
86 : /// in this PlumedMain object have been destroyed.
87 : std::set<FileBase*> files;
88 : /// Forward declaration.
89 : ForwardDecl<Communicator> comm_fwd;
90 : public:
91 : /// Communicator for plumed.
92 : /// Includes all the processors used by plumed in this replica.
93 : /// See Action::comm.
94 : Communicator&comm=*comm_fwd;
95 :
96 : private:
97 : class DeprecatedAtoms {
98 : private:
99 : PlumedMain & plumed;
100 : public:
101 809624 : explicit DeprecatedAtoms(PlumedMain& p): plumed(p) {}
102 : [[deprecated("Use Action::getKBoltzmann().")]]
103 : double getKBoltzmann() const ;
104 : [[deprecated("Use Action::getkBT() N.B. this function also reads the TEMP keyword from the input for you.")]]
105 : double getKbT() const ;
106 : [[deprecated]]
107 : int getNatoms() const ;
108 : [[deprecated("Use Action::usingNaturalUnits().")]]
109 : bool usingNaturalUnits() const ;
110 : [[deprecated]]
111 : void setCollectEnergy(bool b) const;
112 : [[deprecated]]
113 : double getEnergy() const ;
114 : };
115 : /// Forward declaration.
116 : ForwardDecl<DeprecatedAtoms> datoms_fwd;
117 : /// Object containing old bits of atoms that are used by many folks
118 : DeprecatedAtoms& datoms=*datoms_fwd;
119 : /// Forward declaration.
120 : ForwardDecl<Communicator> multi_sim_comm_fwd;
121 : public:
122 : DeprecatedAtoms& getAtoms();
123 : /// Communicator between replicas.
124 : /// Valid only on process 0 of comm; MPI_COMM_SELF elsewhere.
125 : /// See Action::multi_sim_comm.
126 : Communicator&multi_sim_comm=*multi_sim_comm_fwd;
127 :
128 : private:
129 : /// Error handler.
130 : /// Pointer to a function that is called an exception thrown within
131 : /// the library is about to leave the library.
132 : /// Can be used to remap exceptions in case the plumed wrapper was compiled
133 : /// with a different version of the C++ standard library.
134 : /// Should only be called from \ref plumed_plumedmain_cmd().
135 : typedef struct {
136 : void* ptr;
137 : void(*handler)(void* ptr,int code,const char*);
138 : } plumed_error_handler;
139 :
140 : plumed_error_handler error_handler= {NULL,NULL};
141 :
142 : bool nestedExceptions=false;
143 :
144 : /// Forward declaration.
145 : ForwardDecl<DLLoader> dlloader_fwd;
146 : DLLoader& dlloader=*dlloader_fwd;
147 :
148 : std::unique_ptr<WithCmd> cltool;
149 :
150 : std::unique_ptr<WithCmd> grex;
151 : /// Flag to avoid double initialization
152 : bool initialized=false;
153 : /// Name of MD engine
154 : std::string MDEngine{"mdcode"};
155 :
156 : /// Forward declaration.
157 : ForwardDecl<Log> log_fwd;
158 : /// Log stream
159 : Log& log=*log_fwd;
160 :
161 : /// Forward declaration.
162 : /// Should be placed after log since its constructor takes a log reference as an argument.
163 : ForwardDecl<Stopwatch> stopwatch_fwd;
164 : Stopwatch& stopwatch=*stopwatch_fwd;
165 :
166 : /// Forward declaration.
167 : ForwardDecl<Citations> citations_fwd;
168 : /// tools/Citations.holder
169 : Citations& citations=*citations_fwd;
170 :
171 : /// Present step number.
172 : long long int step=0;
173 :
174 : /// Condition for plumed to be active.
175 : /// At every step, PlumedMain is checking if there are Action's requiring some work.
176 : /// If at least one Action requires some work, this variable is set to true.
177 : bool active=false;
178 :
179 : /// Name of the input file
180 : std::string plumedDat;
181 :
182 : /// End of input file.
183 : /// Set to true to terminate reading
184 : bool endPlumed=false;
185 :
186 : /// Forward declaration.
187 : ForwardDecl<ActionSet> actionSet_fwd;
188 : /// Set of actions found in plumed.dat file
189 : ActionSet& actionSet=*actionSet_fwd;
190 :
191 : /// These are tools to pass data to PLUMED
192 : std::unique_ptr<DataPassingTools> passtools;
193 :
194 : /// Vector of actions that are passed data from the MD code
195 : std::vector<ActionForInterface*> inputs;
196 :
197 : /// Set of Pilot actions.
198 : /// These are the action the, if they are Pilot::onStep(), can trigger execution
199 : std::vector<ActionPilot*> pilots;
200 :
201 : /// Suffix string for file opening, useful for multiple simulations in the same directory
202 : std::string suffix;
203 :
204 : /// The total bias (=total energy of the restraints)
205 : double bias=0.0;
206 :
207 : /// The total work.
208 : /// This computed by accumulating the change in external potentials.
209 : double work=0.0;
210 :
211 : /// Forward declaration.
212 : ForwardDecl<ExchangePatterns> exchangePatterns_fwd;
213 : /// Class of possible exchange patterns, used for BIASEXCHANGE but also for future parallel tempering
214 : ExchangePatterns& exchangePatterns=*exchangePatterns_fwd;
215 :
216 : /// Set to true if on an exchange step
217 : bool exchangeStep=false;
218 :
219 : /// Flag for restart
220 : bool restart=false;
221 :
222 : /// Flag for checkpointig
223 : bool doCheckPoint=false;
224 :
225 : /// A string that holds the name of the action that gets the energy from the MD
226 : /// code. Set empty if energy is not used.
227 : std::string name_of_energy{""};
228 :
229 : /// This sets up the values that are set from the MD code
230 : void startStep();
231 :
232 : /// This sets up the vector that contains the interface to the MD code
233 : void setupInterfaceActions();
234 :
235 : /// Flag for parse only mode -- basically just forces restart to turn off
236 : bool doParseOnly=false;
237 :
238 : private:
239 : /// Forward declaration.
240 : ForwardDecl<TypesafePtr> stopFlag_fwd;
241 : public:
242 : /// Stuff to make plumed stop the MD code cleanly
243 : TypesafePtr& stopFlag=*stopFlag_fwd;
244 : bool stopNow=false;
245 :
246 : /// Stack for update flags.
247 : /// Store information used in class \ref generic::UpdateIf
248 : std::stack<bool> updateFlags;
249 :
250 : public:
251 : /// This determines if the user has created a value to hold the quantity that is being passed
252 : bool valueExists( const std::string& name ) const ;
253 :
254 : /// This sets the value with a particular name to the pointer to the data in the MD code
255 : void setInputValue( const std::string& name, const unsigned& start, const unsigned& stride, const TypesafePtr & val );
256 :
257 : /// This sets the forces with a particular name to the pointer to the data in the MD code
258 : void setInputForce( const std::string& name, const TypesafePtr & val );
259 :
260 : /// This updates the units of the input quantities
261 : void setUnits( const bool& natural, const Units& u );
262 :
263 : /// Flag to switch off virial calculation (for debug and MD codes with no barostat)
264 : bool novirial=false;
265 :
266 : /// Flag to switch on detailed timers
267 : bool detailedTimers=false;
268 :
269 : /// GpuDevice Identifier
270 : int gpuDeviceId=-1;
271 : /// Number of replicas, and the index of this one, as seen from every rank.
272 : /// Set by updateReplicaIdentity(); see getNumberOfReplicas().
273 : int nReplicas=1;
274 : int replicaIndex=0;
275 :
276 : /// Generic map string -> double
277 : /// intended to pass information across Actions
278 : std::map<std::string,double> passMap;
279 :
280 : /// Add a citation, returning a string containing the reference number, something like "[10]"
281 : std::string cite(const std::string&);
282 :
283 : /// Get number of threads that can be used by openmp
284 : unsigned getNumThreads()const;
285 :
286 : /// Get a reasonable number of threads so as to access to an array of size s located at x
287 : template<typename T>
288 : unsigned getGoodNumThreads(const T*x,unsigned s)const;
289 :
290 : /// Get a reasonable number of threads so as to access to vector v;
291 : template<typename T>
292 : unsigned getGoodNumThreads(const std::vector<T> & v)const;
293 :
294 : public:
295 : PlumedMain();
296 : // this is to access to WithCmd versions of cmd (allowing overloading of a virtual method)
297 : using WithCmd::cmd;
298 : /**
299 : cmd method, accessible with standard Plumed.h interface.
300 : \param key The name of the command to be executed.
301 : \param val The argument of the command to be executed.
302 : It is called as plumed_cmd() or as PLMD::Plumed::cmd()
303 : It is the interpreter for plumed commands. It basically contains the definition of the plumed interface.
304 : If you want to add a new functionality to the interface between plumed
305 : and an MD engine, this is the right place
306 : Notice that this interface should always keep retro-compatibility
307 : */
308 : void cmd(std::string_view key,const TypesafePtr & val) override;
309 : ~PlumedMain();
310 : /**
311 : Turn on parse only mode to deactivate restart in all actions.
312 : This is only used by plumed driver --parse-only
313 : */
314 : void activateParseOnlyMode();
315 : /**
316 : This checks if parse only mode is active and turns off any restart.
317 : */
318 : bool parseOnlyMode() const ;
319 : /**
320 : Read an input file.
321 : \param str name of the file
322 : */
323 : void readInputFile(const std::string & str);
324 : /**
325 : Read an input file.
326 : \param ifile
327 : */
328 : void readInputFile(IFile & ifile);
329 : /**
330 : Read an input string.
331 : \param str name of the string
332 : */
333 : void readInputWords(const std::vector<std::string> & str, const bool& before_init);
334 :
335 : /**
336 : Read an input string.
337 : \param str name of the string
338 : At variance with readInputWords(), this is splitting the string into words
339 : */
340 : void readInputLine(const std::string & str, const bool& before_init=false);
341 :
342 : /**
343 : Read an input buffer.
344 : \param str name of the string
345 : Same as readInputFile, but first write str on a temporary file and then read
346 : that files. At variance with readInputLine, it can take care of comments and
347 : continuation lines.
348 : */
349 : void readInputLines(const std::string & str);
350 :
351 : /**
352 : Initialize the object.
353 : Should be called once.
354 : */
355 : void init();
356 : /**
357 : Prepare the calculation.
358 : Here it is checked which are the active Actions and communication of the relevant atoms is initiated.
359 : Shortcut for prepareDependencies() + shareData()
360 : */
361 : void prepareCalc();
362 : /**
363 : Prepare the list of active Actions and needed atoms.
364 : Scan the Actions to see which are active and which are not, so as to prepare a list of
365 : the atoms needed at this step.
366 : */
367 : void prepareDependencies();
368 : /**
369 : Ensure that all the atoms are shared.
370 : This is used in GREX to ensure that we transfer all the positions from the MD code to PLUMED.
371 : */
372 : void shareAll();
373 : /**
374 : Share the needed atoms.
375 : In asynchronous implementations, this method sends the required atoms to all the plumed processes,
376 : without waiting for the communication to complete.
377 : */
378 : void shareData();
379 : /**
380 : Perform the calculation.
381 : Shortcut for waitData() + justCalculate() + justApply().
382 : Equivalently: waitData() + justCalculate() + backwardPropagate() + update().
383 : */
384 : void performCalc();
385 : /**
386 : Perform the calculation without update()
387 : Shortcut for: waitData() + justCalculate() + backwardPropagate()
388 : */
389 : void performCalcNoUpdate();
390 : /**
391 : Perform the calculation without backpropagation nor update()
392 : Shortcut for: waitData() + justCalculate()
393 : */
394 : void performCalcNoForces();
395 : /**
396 : Complete PLUMED calculation.
397 : Shortcut for prepareCalc() + performCalc()
398 : */
399 : void calc();
400 : /**
401 : Scatters the needed atoms.
402 : In asynchronous implementations, this method waits for the communications started in shareData()
403 : to be completed. Otherwise, just send around needed atoms.
404 : */
405 : void waitData();
406 : /**
407 : Perform the forward loop on active actions.
408 : */
409 : void justCalculate();
410 : /**
411 : Backward propagate and update.
412 : Shortcut for backwardPropagate() + update()
413 : I leave it here for backward compatibility
414 : */
415 : void justApply();
416 : /**
417 : Perform the backward loop on active actions.
418 : Needed to apply the forces back.
419 : */
420 : void backwardPropagate();
421 : /**
422 : Call the update() method.
423 : */
424 : void update();
425 : /**
426 : If there are calculations that need to be done at the very end of the calculations this
427 : makes sures they are done
428 : */
429 : /**
430 : This function does clearInputForces for the list of atoms that have a force on them. This
431 : is an optimisation to prevent calling std::fill over a large array
432 : */
433 : void resetInputs();
434 : void runJobsAtEndOfCalculation();
435 : /// Reference to the list of Action's
436 : const ActionSet & getActionSet()const;
437 : /// Referenge to the log stream
438 : Log & getLog();
439 : /// Return the number of the step
440 : long long int getStep()const {
441 7374168 : return step;
442 : }
443 : /// Stop the run
444 : void exit(int c=0);
445 : /// Load a shared library
446 : void load(const std::string&);
447 : /// Get the suffix string
448 : const std::string & getSuffix()const;
449 : /// Set the suffix string
450 : void setSuffix(const std::string&);
451 : /// get the value of the bias
452 : double getBias()const;
453 : /// get the value of the work
454 : double getWork()const;
455 : /// Opens a file.
456 : /// Similar to plain fopen, but, if it finds an error in opening the file, it also tries with
457 : /// path+suffix. This trick is useful for multiple replica simulations.
458 : FILE* fopen(const char *path, const char *mode);
459 : /// Closes a file opened with PlumedMain::fopen()
460 : int fclose(FILE*fp);
461 : /// Insert a file
462 : void insertFile(FileBase&);
463 : /// Erase a file
464 : void eraseFile(FileBase&);
465 : /// Get the files currently registered with insertFile()
466 : const std::set<FileBase*> & getFiles()const {
467 : return files;
468 : }
469 : /// Flush all files
470 : void fflush();
471 : /// Check if restarting
472 : bool getRestart()const;
473 : /// Set restart flag
474 : void setRestart(bool f) {
475 75 : if(!doParseOnly) {
476 75 : restart=f;
477 : }
478 : }
479 : /// Check if checkpointing
480 : bool getCPT()const;
481 : /// Set exchangeStep flag
482 : void setExchangeStep(bool f);
483 : /// Get exchangeStep flag
484 : bool getExchangeStep()const;
485 : /// Stop the calculation cleanly (both the MD code and plumed)
486 : void stop();
487 : /// Enforce active flag.
488 : /// This is a (bit dirty) hack to solve a bug. When there is no active ActionPilot,
489 : /// several shortcuts are used. However, these shortcuts can block GREX module.
490 : /// This function allows to enforce active plumed when doing exchanges,
491 : /// thus fixing the bug.
492 : void resetActive(bool active);
493 :
494 : /// Access to exchange patterns
495 : ExchangePatterns& getExchangePatterns() {
496 0 : return exchangePatterns;
497 : }
498 :
499 : /// Push a state to update flags
500 : void updateFlagsPush(bool);
501 : /// Pop a state from update flags
502 : void updateFlagsPop();
503 : /// Get top of update flags
504 : bool updateFlagsTop();
505 : /// Set end of input file
506 : void setEndPlumed();
507 : /// Get the value of the end plumed flag
508 : bool getEndPlumed() const ;
509 : /// Get the value of the gpuDeviceId
510 : int getGpuDeviceId() const ;
511 : /// Number of replicas in a multi-replica simulation (1 otherwise).
512 : /// Unlike multi_sim_comm.Get_size(), this is correct on every rank of a replica,
513 : /// not only on the rank that received the inter-replica communicator.
514 : int getNumberOfReplicas() const ;
515 : /// Index of this replica, in [0, getNumberOfReplicas()). Correct on every rank.
516 : int getReplicaIndex() const ;
517 : /// Recompute getNumberOfReplicas() and getReplicaIndex() from multi_sim_comm.
518 : /// Collective over intra, the intra-replica communicator. Called from init() and
519 : /// from GREX init, so the result does not depend on which the engine calls first.
520 : void updateReplicaIdentity(Communicator& intra);
521 : /// Call error handler.
522 : /// Should only be called from \ref plumed_plumedmain_cmd().
523 : /// If the error handler was not set, returns false.
524 : bool callErrorHandler(int code,const char* msg)const;
525 : private:
526 : std::atomic<unsigned> referenceCounter{};
527 : public:
528 : /// Atomically increase reference counter and return the new value
529 : unsigned increaseReferenceCounter() noexcept;
530 : /// Atomically decrease reference counter and return the new value
531 : unsigned decreaseReferenceCounter() noexcept;
532 : /// Report the reference counter
533 : unsigned useCountReferenceCounter() const noexcept;
534 : void enableNestedExceptions();
535 : bool getNestedExceptions()const {
536 323 : return nestedExceptions;
537 : }
538 : /// Check if there is active input in the action set
539 : bool inputsAreActive() const ;
540 : /// Transfer information from input MD code
541 : void writeBinary(std::ostream&)const;
542 : void readBinary(std::istream&);
543 : /// Used to set the name of the action that holds the energy
544 : void setEnergyValue( const std::string& name );
545 : /// Get the real preicision
546 : int getRealPrecision() const;
547 : /// Are we using natural units
548 : bool usingNaturalUnits() const ;
549 : /// Get the units that are being used
550 : const Units& getUnits();
551 : /// Take an energy that is calculated by PLUMED and pass it to a typesafe pointer
552 : /// that the MD code can access.
553 : void plumedQuantityToMD( const std::string& unit, const double& eng, const TypesafePtr & m) const ;
554 : /// Take a typesafe pointer from the MD code and convert it to a double
555 : double MDQuantityToPLUMED( const std::string& unit, const TypesafePtr & m) const ;
556 : /// Get the keywords for a particular action
557 : void getKeywordsForAction( const std::string& action, Keywords& keys ) const ;
558 : /// Check if the input has been initialized
559 : bool hasBeenInitialized() const ;
560 : /// Check if an action with the given name has been registered by default or LOADed
561 : bool checkAction(const std::string& action) const;
562 : };
563 :
564 : /////
565 : // FAST INLINE METHODS:
566 :
567 : inline
568 : const ActionSet & PlumedMain::getActionSet()const {
569 452691 : return actionSet;
570 : }
571 :
572 : inline
573 : const std::string & PlumedMain::getSuffix()const {
574 6920 : return suffix;
575 : }
576 :
577 : inline
578 : void PlumedMain::setSuffix(const std::string&s) {
579 1607 : suffix=s;
580 1607 : }
581 :
582 : inline
583 : bool PlumedMain::getRestart()const {
584 66108 : return restart;
585 : }
586 :
587 : inline
588 : bool PlumedMain::getCPT()const {
589 66033 : return doCheckPoint;
590 : }
591 :
592 : inline
593 : void PlumedMain::setExchangeStep(bool s) {
594 252 : exchangeStep=s;
595 : }
596 :
597 : inline
598 : bool PlumedMain::getExchangeStep()const {
599 56829 : return exchangeStep;
600 : }
601 :
602 : inline
603 : void PlumedMain::resetActive(bool setactive) {
604 126 : active=setactive;
605 : }
606 :
607 : inline
608 : void PlumedMain::updateFlagsPush(bool on) {
609 : updateFlags.push(on);
610 : }
611 :
612 : inline
613 : void PlumedMain::updateFlagsPop() {
614 : updateFlags.pop();
615 12 : }
616 :
617 : inline
618 : bool PlumedMain::updateFlagsTop() {
619 3525848 : return updateFlags.top();
620 : }
621 :
622 : inline
623 : void PlumedMain::setEndPlumed() {
624 372 : endPlumed=true;
625 : }
626 :
627 : inline
628 : bool PlumedMain::getEndPlumed() const {
629 24 : return endPlumed;
630 : }
631 :
632 : inline
633 : int PlumedMain::getGpuDeviceId() const {
634 : return gpuDeviceId;
635 : }
636 :
637 : inline
638 : int PlumedMain::getNumberOfReplicas() const {
639 1749 : return nReplicas;
640 : }
641 :
642 : inline
643 : int PlumedMain::getReplicaIndex() const {
644 1739 : return replicaIndex;
645 : }
646 :
647 : inline
648 : bool PlumedMain::callErrorHandler(int code,const char* msg)const {
649 : if(error_handler.handler) {
650 : error_handler.handler(error_handler.ptr,code,msg);
651 : return true;
652 : } else {
653 : return false;
654 : }
655 : }
656 :
657 : inline
658 : bool PlumedMain::hasBeenInitialized() const {
659 10880 : return initialized;
660 : }
661 :
662 :
663 : }
664 :
665 : #endif
666 :
|