Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2012-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 : #include "core/ActionAnyorder.h" 23 : #include "core/ActionRegister.h" 24 : #include "core/PlumedMain.h" 25 : #include "tools/Exception.h" 26 : 27 : namespace PLMD { 28 : namespace setup { 29 : 30 : //+PLUMEDOC GENERIC LOAD 31 : /* 32 : Loads a library, possibly defining new actions. 33 : 34 : The LOAD action is only available on systems that allow dynamic loading. 35 : This action allows you load new funcionality into PLUMED at runtime. 36 : This new functionality can be in a .so file or a .cpp file. If the 37 : new functionality is in a cpp file then the code is compiled and the 38 : the resulting object is loaded. 39 : 40 : Using the LOAD action is useful for making quick tests while developing your own 41 : actions. Of course, once your implementation is ready you should 42 : add it to the PLUMED source tree and recompile PLUMED. 43 : 44 : One way to use the LOAD action is to directly load a cpp file as illustrated in the input below. 45 : 46 : ```plumed 47 : #SETTINGS INPUTFILES=regtest/basic/rt15/Distance2.cpp 48 : # load the new definition 49 : # this is a cpp file so it will be compiled 50 : LOAD FILE=regtest/basic/rt15/Distance2.cpp 51 : # compute standard distance 52 : d: DISTANCE ATOMS=1,10 53 : # compute modified distance 54 : d2: DISTANCE2 ATOMS=1,10 55 : # print them on a file 56 : PRINT ARG=d,d2 FILE=compare-them 57 : ``` 58 : 59 : When PLUMED reads the input above it first compiles the code in `Distance2.cpp`. The resulting object file 60 : is then loaded into PLUMED. If you look at the cpp file that is input in the command above you can see that 61 : a new action called `DISTANCE2` is defined within it. We can thus use this new action in the input above. 62 : 63 : Instead of compiling the code at runtime you can construct a shared object from the Distance2.cpp file and LOAD the shared library instead of 64 : the cpp file. To construct the shared object you would use the following command: 65 : 66 : ```` 67 : > plumed mklib Distance2.cpp 68 : ```` 69 : 70 : When you run this command a new file called `Distance2.so` (or `Distance2.dylib` on a mac) is created. 71 : You can then load this shared object in PLUMED by using the following LOAD command 72 : 73 : ```` 74 : LOAD FILE=Distance2.so 75 : ```` 76 : 77 : The new functionality within the Distance2.cpp file can then be used in the remainder of the input in the same way it was 78 : used in the previous example. 79 : (Notice that the only reason for not using the usual PLUMED syntax highlightling in the example above is that we have no 80 : file called Distance2.so.) 81 : 82 : From PLUMED 2.10 onwards the LOAD action can be placed at any point of the input 83 : file. The loaded functionality will then only affect commands that are placed after the LOAD action. 84 : These features are illustrated in the input below: 85 : 86 : ```plumed 87 : #SETTINGS INPUTFILES=regtest/basic/rt15/Distance3.cpp 88 : # compute standard distance 89 : d: DISTANCE ATOMS=1,10 90 : # load the new definition 91 : LOAD FILE=regtest/basic/rt15/Distance3.cpp 92 : # compute modified distance 93 : d2: DISTANCE ATOMS=1,10 94 : # print them on a file 95 : PRINT ARG=d,d2 FILE=compare-them 96 : ``` 97 : 98 : Notice that `Distance3.cpp` replaces DISTANCE2 in the command that was used in `Distance2.cpp`; namely: 99 : 100 : ```c++ 101 : PLUMED_REGISTER_ACTION(Distance,"DISTANCE2") 102 : ``` 103 : 104 : with DISTANCE. Consequently, when we load the `Distance3.cpp` file here we redefine the DISTANCE command. 105 : The functions that compute `d` and `d2` in the above input are thus different. 106 : 107 : A final point to note is that, starting with PLUMED 2.10, the LOAD action can be used in contexts where 108 : multiple Plumed objects exist. A possible example is multithreading: loading an action 109 : from a Plumed object used in one thread will not affect other threads. 110 : Another example is if multiple Plumed objects are created in the C/C++ or Python interface. 111 : If a LOAD command is used in one of these objects, the loaded action will not affect 112 : the other objects. 113 : 114 : 115 : ## Code written for older versions of PLUMED 116 : 117 : The C++ interface that is used by the files you LOAD changes between versions of PLUMED. 118 : If a file that you wrote for an older version does not compile, the following changes are usually enough: 119 : 120 : - `#include "core/Atoms.h"` and `plumed.getAtoms()`: the Atoms class was removed in PLUMED 2.10. 121 : The include is removed automatically by `plumed mklib` (with a warning). Use the methods of the action instead: 122 : `getKBoltzmann()` instead of `plumed.getAtoms().getKBoltzmann()`, `getkBT()` instead of `plumed.getAtoms().getKbT()` 123 : (`getkBT()` also reads the TEMP keyword), `getUnits()`, `usingNaturalUnits()` and `getTimeStep()`. 124 : - `error: invalid use of incomplete type 'class PLMD::Communicator'`: since PLUMED 2.10 the headers of the actions 125 : do not include the definition of the communicators any more. If your code uses `comm` or `multi_sim_comm`, add 126 : 127 : ```c++ 128 : #include "tools/Communicator.h" 129 : ``` 130 : 131 : - `componentsAreNotOptional(keys)` was removed. It only changed the text of the manual, so you can delete the line. 132 : - `keys.addOutputComponent(name,flag,description)` is deprecated: give the type of the component as third argument, 133 : e.g. `keys.addOutputComponent("x","COMPONENTS","scalar","the x component")`. 134 : - `keys.use("ARG")` after the `registerKeywords` of the base class is not needed any more (ARG is added by the base class), 135 : but it is still accepted. 136 : - A flag cannot be on by default: `keys.addFlag("COMPONENTS",true,...)` stops with "the second argument to addFlag must be false". 137 : Use `false` and, if needed, a flag with the opposite meaning. 138 : - Include paths such as `#include "colvar/ActionRegister.h"` are replaced by `#include "core/ActionRegister.h"` 139 : automatically by `plumed mklib` (with a warning). 140 : - The classes of the old multicolvar module (`multicolvar/MultiColvarBase.h`) were removed in PLUMED 2.10. 141 : A collective variable that is computed for many groups of atoms is now written for one group of atoms and then 142 : used with the `MultiColvarTemplate` class: see how `src/colvar/Distance.cpp` defines DISTANCE_SCALAR and DISTANCE_VECTOR. 143 : 144 : !!! note "" 145 : 146 : The example inputs on this page appear as not working because you cannot use the dynamic loading on GitHub Actions. On a machine where this functionality is available these inputs should work. 147 : 148 : */ 149 : //+ENDPLUMEDOC 150 : 151 : class Load : 152 : public virtual ActionAnyorder { 153 : public: 154 : static void registerKeywords( Keywords& keys ); 155 : explicit Load(const ActionOptions&ao); 156 : }; 157 : 158 : PLUMED_REGISTER_ACTION(Load,"LOAD") 159 : 160 54 : void Load::registerKeywords( Keywords& keys ) { 161 54 : ActionAnyorder::registerKeywords(keys); 162 54 : keys.add("compulsory","FILE","file to be loaded"); 163 54 : } 164 : 165 50 : Load::Load(const ActionOptions&ao): 166 : Action(ao), 167 50 : ActionAnyorder(ao) { 168 : std::string f; 169 51 : parse("FILE",f); 170 50 : checkRead(); 171 50 : plumed.load(f); 172 50 : } 173 : 174 : } 175 : } 176 :