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 Log;
59 : class Atoms;
60 : class ActionSet;
61 : class DLLoader;
62 : class Communicator;
63 : class Stopwatch;
64 : class Citations;
65 : class ExchangePatterns;
66 : class FileBase;
67 : class DataFetchingObject;
68 : class TypesafePtr;
69 : class IFile;
70 :
71 : /**
72 : Main plumed object.
73 : In MD engines this object is not manipulated directly but it is wrapped in
74 : plumed or PLMD::Plumed objects. Its main method is cmd(),
75 : which defines completely the external plumed interface.
76 : It does not contain any static data.
77 : */
78 : class PlumedMain:
79 : public WithCmd {
80 : /// Pointers to files opened in actions associated to this object.
81 : /// Notice that with the current implementation this should be at the top of this
82 : /// structure. Indeed, this should be destroyed *after* all the actions allocated
83 : /// in this PlumedMain object have been destroyed.
84 : std::set<FileBase*> files;
85 : /// Forward declaration.
86 : ForwardDecl<Communicator> comm_fwd;
87 : public:
88 : /// Communicator for plumed.
89 : /// Includes all the processors used by plumed.
90 : Communicator&comm=*comm_fwd;
91 :
92 : private:
93 : /// Forward declaration.
94 : ForwardDecl<Communicator> multi_sim_comm_fwd;
95 : public:
96 : Communicator&multi_sim_comm=*multi_sim_comm_fwd;
97 :
98 : private:
99 : /// Error handler.
100 : /// Pointer to a function that is called an exception thrown within
101 : /// the library is about to leave the library.
102 : /// Can be used to remap exceptions in case the plumed wrapper was compiled
103 : /// with a different version of the C++ standard library.
104 : /// Should only be called from \ref plumed_plumedmain_cmd().
105 : typedef struct {
106 : void* ptr;
107 : void(*handler)(void* ptr,int code,const char*);
108 : } plumed_error_handler;
109 :
110 : plumed_error_handler error_handler= {NULL,NULL};
111 :
112 : bool nestedExceptions=false;
113 :
114 : /// Forward declaration.
115 : ForwardDecl<DLLoader> dlloader_fwd;
116 : DLLoader& dlloader=*dlloader_fwd;
117 :
118 : std::unique_ptr<WithCmd> cltool;
119 :
120 : std::unique_ptr<WithCmd> grex;
121 : /// Flag to avoid double initialization
122 : bool initialized;
123 : /// Name of MD engine
124 : std::string MDEngine;
125 :
126 : /// Forward declaration.
127 : ForwardDecl<Log> log_fwd;
128 : /// Log stream
129 : Log& log=*log_fwd;
130 :
131 : /// Forward declaration.
132 : /// Should be placed after log since its constructor takes a log reference as an argument.
133 : ForwardDecl<Stopwatch> stopwatch_fwd;
134 : Stopwatch& stopwatch=*stopwatch_fwd;
135 :
136 : /// Forward declaration.
137 : ForwardDecl<Citations> citations_fwd;
138 : /// tools/Citations.holder
139 : Citations& citations=*citations_fwd;
140 :
141 : /// Present step number.
142 : long long int step;
143 :
144 : /// Condition for plumed to be active.
145 : /// At every step, PlumedMain is checking if there are Action's requiring some work.
146 : /// If at least one Action requires some work, this variable is set to true.
147 : bool active;
148 :
149 : /// Name of the input file
150 : std::string plumedDat;
151 :
152 : /// Object containing data we would like to grab and pass back
153 : std::unique_ptr<DataFetchingObject> mydatafetcher;
154 :
155 : /// End of input file.
156 : /// Set to true to terminate reading
157 : bool endPlumed;
158 :
159 : /// Forward declaration.
160 : ForwardDecl<Atoms> atoms_fwd;
161 : /// Object containing information about atoms (such as positions,...).
162 : Atoms& atoms=*atoms_fwd; // atomic coordinates
163 :
164 : /// Forward declaration.
165 : ForwardDecl<ActionSet> actionSet_fwd;
166 : /// Set of actions found in plumed.dat file
167 : ActionSet& actionSet=*actionSet_fwd;
168 :
169 : /// Set of Pilot actions.
170 : /// These are the action the, if they are Pilot::onStep(), can trigger execution
171 : std::vector<ActionPilot*> pilots;
172 :
173 : /// Suffix string for file opening, useful for multiple simulations in the same directory
174 : std::string suffix;
175 :
176 : /// The total bias (=total energy of the restraints)
177 : double bias;
178 :
179 : /// The total work.
180 : /// This computed by accumulating the change in external potentials.
181 : double work;
182 :
183 : /// Forward declaration.
184 : ForwardDecl<ExchangePatterns> exchangePatterns_fwd;
185 : /// Class of possible exchange patterns, used for BIASEXCHANGE but also for future parallel tempering
186 : ExchangePatterns& exchangePatterns=*exchangePatterns_fwd;
187 :
188 : /// Set to true if on an exchange step
189 : bool exchangeStep;
190 :
191 : /// Flag for restart
192 : bool restart;
193 :
194 : /// Flag for checkpointig
195 : bool doCheckPoint;
196 :
197 : /// Flag for parse only mode -- basically just forces restart to turn off
198 : bool doParseOnly;
199 :
200 : private:
201 : /// Forward declaration.
202 : ForwardDecl<TypesafePtr> stopFlag_fwd;
203 : public:
204 : /// Stuff to make plumed stop the MD code cleanly
205 : TypesafePtr& stopFlag=*stopFlag_fwd;
206 : bool stopNow;
207 :
208 : /// Stack for update flags.
209 : /// Store information used in class \ref generic::UpdateIf
210 : std::stack<bool> updateFlags;
211 :
212 : public:
213 : /// Flag to switch off virial calculation (for debug and MD codes with no barostat)
214 : bool novirial;
215 :
216 : /// Flag to switch on detailed timers
217 : bool detailedTimers;
218 :
219 : /// GpuDevice Identifier
220 : int gpuDeviceId;
221 :
222 : /// Generic map string -> double
223 : /// intended to pass information across Actions
224 : std::map<std::string,double> passMap;
225 :
226 : /// Add a citation, returning a string containing the reference number, something like "[10]"
227 : std::string cite(const std::string&);
228 :
229 : /// Get number of threads that can be used by openmp
230 : unsigned getNumThreads()const;
231 :
232 : /// Get a reasonable number of threads so as to access to an array of size s located at x
233 : template<typename T>
234 : unsigned getGoodNumThreads(const T*x,unsigned s)const;
235 :
236 : /// Get a reasonable number of threads so as to access to vector v;
237 : template<typename T>
238 : unsigned getGoodNumThreads(const std::vector<T> & v)const;
239 :
240 : public:
241 : PlumedMain();
242 : // this is to access to WithCmd versions of cmd (allowing overloading of a virtual method)
243 : using WithCmd::cmd;
244 : /**
245 : cmd method, accessible with standard Plumed.h interface.
246 : \param key The name of the command to be executed.
247 : \param val The argument of the command to be executed.
248 : It is called as plumed_cmd() or as PLMD::Plumed::cmd()
249 : It is the interpreter for plumed commands. It basically contains the definition of the plumed interface.
250 : If you want to add a new functionality to the interface between plumed
251 : and an MD engine, this is the right place
252 : Notice that this interface should always keep retro-compatibility
253 : */
254 : void cmd(const std::string&key,const TypesafePtr & val=nullptr) override;
255 : ~PlumedMain();
256 : /**
257 : Turn on parse only mode to deactivate restart in all actions.
258 : This is only used by plumed driver --parse-only
259 : */
260 : void activateParseOnlyMode();
261 : /**
262 : This checks if parse only mode is active and turns off any restart.
263 : */
264 : bool parseOnlyMode() const ;
265 : /**
266 : Read an input file.
267 : \param str name of the file
268 : */
269 : void readInputFile(const std::string & str);
270 : /**
271 : Read an input file.
272 : \param ifile
273 : */
274 : void readInputFile(IFile & ifile);
275 : /**
276 : Read an input string.
277 : \param str name of the string
278 : */
279 : void readInputWords(const std::vector<std::string> & str);
280 :
281 : /**
282 : Read an input string.
283 : \param str name of the string
284 : At variance with readInputWords(), this is splitting the string into words
285 : */
286 : void readInputLine(const std::string & str);
287 :
288 : /**
289 : Read an input buffer.
290 : \param str name of the string
291 : Same as readInputFile, but first write str on a temporary file and then read
292 : that files. At variance with readInputLine, it can take care of comments and
293 : continuation lines.
294 : */
295 : void readInputLines(const std::string & str);
296 :
297 : /**
298 : Initialize the object.
299 : Should be called once.
300 : */
301 : void init();
302 : /**
303 : Prepare the calculation.
304 : Here it is checked which are the active Actions and communication of the relevant atoms is initiated.
305 : Shortcut for prepareDependencies() + shareData()
306 : */
307 : void prepareCalc();
308 : /**
309 : Prepare the list of active Actions and needed atoms.
310 : Scan the Actions to see which are active and which are not, so as to prepare a list of
311 : the atoms needed at this step.
312 : */
313 : void prepareDependencies();
314 : /**
315 : Share the needed atoms.
316 : In asynchronous implementations, this method sends the required atoms to all the plumed processes,
317 : without waiting for the communication to complete.
318 : */
319 : void shareData();
320 : /**
321 : Perform the calculation.
322 : Shortcut for waitData() + justCalculate() + justApply().
323 : Equivalently: waitData() + justCalculate() + backwardPropagate() + update().
324 : */
325 : void performCalc();
326 : /**
327 : Perform the calculation without update()
328 : Shortcut for: waitData() + justCalculate() + backwardPropagate()
329 : */
330 : void performCalcNoUpdate();
331 : /**
332 : Perform the calculation without backpropagation nor update()
333 : Shortcut for: waitData() + justCalculate()
334 : */
335 : void performCalcNoForces();
336 : /**
337 : Complete PLUMED calculation.
338 : Shortcut for prepareCalc() + performCalc()
339 : */
340 : void calc();
341 : /**
342 : Scatters the needed atoms.
343 : In asynchronous implementations, this method waits for the communications started in shareData()
344 : to be completed. Otherwise, just send around needed atoms.
345 : */
346 : void waitData();
347 : /**
348 : Perform the forward loop on active actions.
349 : */
350 : void justCalculate();
351 : /**
352 : Backward propagate and update.
353 : Shortcut for backwardPropagate() + update()
354 : I leave it here for backward compatibility
355 : */
356 : void justApply();
357 : /**
358 : Perform the backward loop on active actions.
359 : Needed to apply the forces back.
360 : */
361 : void backwardPropagate();
362 : /**
363 : Call the update() method.
364 : */
365 : void update();
366 : /**
367 : If there are calculations that need to be done at the very end of the calculations this
368 : makes sures they are done
369 : */
370 : void runJobsAtEndOfCalculation();
371 : /// Reference to atoms object
372 : Atoms& getAtoms();
373 : /// Reference to the list of Action's
374 : const ActionSet & getActionSet()const;
375 : /// Referenge to the log stream
376 : Log & getLog();
377 : /// Return the number of the step
378 : long long int getStep()const {
379 4615913 : return step;
380 : }
381 : /// Stop the run
382 : void exit(int c=0);
383 : /// Load a shared library
384 : void load(const std::string&);
385 : /// Get the suffix string
386 : const std::string & getSuffix()const;
387 : /// Set the suffix string
388 : void setSuffix(const std::string&);
389 : /// get the value of the bias
390 : double getBias()const;
391 : /// get the value of the work
392 : double getWork()const;
393 : /// Opens a file.
394 : /// Similar to plain fopen, but, if it finds an error in opening the file, it also tries with
395 : /// path+suffix. This trick is useful for multiple replica simulations.
396 : FILE* fopen(const char *path, const char *mode);
397 : /// Closes a file opened with PlumedMain::fopen()
398 : int fclose(FILE*fp);
399 : /// Insert a file
400 : void insertFile(FileBase&);
401 : /// Erase a file
402 : void eraseFile(FileBase&);
403 : /// Flush all files
404 : void fflush();
405 : /// Check if restarting
406 : bool getRestart()const;
407 : /// Set restart flag
408 : void setRestart(bool f) {
409 56 : if(!doParseOnly) {
410 56 : restart=f;
411 : }
412 : }
413 : /// Check if checkpointing
414 : bool getCPT()const;
415 : /// Set exchangeStep flag
416 : void setExchangeStep(bool f);
417 : /// Get exchangeStep flag
418 : bool getExchangeStep()const;
419 : /// Stop the calculation cleanly (both the MD code and plumed)
420 : void stop();
421 : /// Enforce active flag.
422 : /// This is a (bit dirty) hack to solve a bug. When there is no active ActionPilot,
423 : /// several shortcuts are used. However, these shortcuts can block GREX module.
424 : /// This function allows to enforce active plumed when doing exchanges,
425 : /// thus fixing the bug.
426 : void resetActive(bool active);
427 :
428 : /// Access to exchange patterns
429 : ExchangePatterns& getExchangePatterns() {
430 0 : return exchangePatterns;
431 : }
432 :
433 : /// Push a state to update flags
434 : void updateFlagsPush(bool);
435 : /// Pop a state from update flags
436 : void updateFlagsPop();
437 : /// Get top of update flags
438 : bool updateFlagsTop();
439 : /// Set end of input file
440 : void setEndPlumed();
441 : /// Get the value of the end plumed flag
442 : bool getEndPlumed() const ;
443 : /// Get the value of the gpuDeviceId
444 : int getGpuDeviceId() const ;
445 : /// Call error handler.
446 : /// Should only be called from \ref plumed_plumedmain_cmd().
447 : /// If the error handler was not set, returns false.
448 : bool callErrorHandler(int code,const char* msg)const;
449 : private:
450 : std::atomic<unsigned> referenceCounter{};
451 : public:
452 : /// Atomically increase reference counter and return the new value
453 : unsigned increaseReferenceCounter() noexcept;
454 : /// Atomically decrease reference counter and return the new value
455 : unsigned decreaseReferenceCounter() noexcept;
456 : /// Report the reference counter
457 : unsigned useCountReferenceCounter() const noexcept;
458 : void enableNestedExceptions();
459 : bool getNestedExceptions()const {
460 99 : return nestedExceptions;
461 : }
462 : };
463 :
464 : /////
465 : // FAST INLINE METHODS:
466 :
467 : inline
468 : const ActionSet & PlumedMain::getActionSet()const {
469 1110288 : return actionSet;
470 : }
471 :
472 : inline
473 : Atoms& PlumedMain::getAtoms() {
474 3283267 : return atoms;
475 : }
476 :
477 : inline
478 : const std::string & PlumedMain::getSuffix()const {
479 5006 : return suffix;
480 : }
481 :
482 : inline
483 : void PlumedMain::setSuffix(const std::string&s) {
484 419 : suffix=s;
485 419 : }
486 :
487 : inline
488 : bool PlumedMain::getRestart()const {
489 14606 : return restart;
490 : }
491 :
492 : inline
493 : bool PlumedMain::getCPT()const {
494 14550 : return doCheckPoint;
495 : }
496 :
497 : inline
498 : void PlumedMain::setExchangeStep(bool s) {
499 228 : exchangeStep=s;
500 : }
501 :
502 : inline
503 : bool PlumedMain::getExchangeStep()const {
504 30198 : return exchangeStep;
505 : }
506 :
507 : inline
508 : void PlumedMain::resetActive(bool active) {
509 114 : this->active=active;
510 : }
511 :
512 : inline
513 : void PlumedMain::updateFlagsPush(bool on) {
514 : updateFlags.push(on);
515 : }
516 :
517 : inline
518 : void PlumedMain::updateFlagsPop() {
519 : updateFlags.pop();
520 12 : }
521 :
522 : inline
523 : bool PlumedMain::updateFlagsTop() {
524 1656841 : return updateFlags.top();
525 : }
526 :
527 : inline
528 : void PlumedMain::setEndPlumed() {
529 276 : endPlumed=true;
530 : }
531 :
532 : inline
533 : bool PlumedMain::getEndPlumed() const {
534 0 : return endPlumed;
535 : }
536 :
537 : inline
538 : int PlumedMain::getGpuDeviceId() const {
539 : return gpuDeviceId;
540 : }
541 :
542 : inline
543 : bool PlumedMain::callErrorHandler(int code,const char* msg)const {
544 : if(error_handler.handler) {
545 : error_handler.handler(error_handler.ptr,code,msg);
546 : return true;
547 : } else {
548 : return false;
549 : }
550 : }
551 :
552 :
553 : }
554 :
555 : #endif
556 :
|