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