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