Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2011-2019 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 "GREX.h"
23 : #include "PlumedMain.h"
24 : #include "Atoms.h"
25 : #include "tools/Tools.h"
26 : #include "tools/Communicator.h"
27 : #include <sstream>
28 : #include <unordered_map>
29 :
30 : #include "GREXEnum.inc"
31 :
32 : using namespace std;
33 : namespace PLMD {
34 :
35 1594 : const std::unordered_map<std::string, int> & GREXWordMap() {
36 1747 : static std::unordered_map<std::string, int> word_map;
37 : static bool init=false;
38 1594 : if(!init) {
39 : #include "GREXMap.inc"
40 : }
41 1594 : init=true;
42 1594 : return word_map;
43 : }
44 :
45 153 : GREX::GREX(PlumedMain&p):
46 : initialized(false),
47 153 : intracomm(*new Communicator),
48 153 : intercomm(*new Communicator),
49 : plumedMain(p),
50 : atoms(p.getAtoms()),
51 : partner(-1), // = unset
52 : localDeltaBias(0),
53 : foreignDeltaBias(0),
54 : localUNow(0),
55 : localUSwap(0),
56 765 : myreplica(-1) // = unset
57 : {
58 306 : p.setSuffix(".NA");
59 153 : }
60 :
61 459 : GREX::~GREX() {
62 153 : delete &intercomm;
63 153 : delete &intracomm;
64 306 : }
65 :
66 : #define CHECK_INIT(ini,word) plumed_massert(ini,"cmd(\"" + word +"\") should be only used after GREX initialization")
67 : #define CHECK_NOTINIT(ini,word) plumed_massert(!(ini),"cmd(\"" + word +"\") should be only used before GREX initialization")
68 : #define CHECK_NOTNULL(val,word) plumed_massert(val,"NULL pointer received in cmd(\"GREX " + word + "\")");
69 :
70 797 : void GREX::cmd(const string&key,void*val) {
71 1594 : std::vector<std::string> words=Tools::getWords(key);
72 797 : unsigned nw=words.size();
73 797 : if(nw==0) {
74 : // do nothing
75 : } else {
76 : int iword=-1;
77 797 : const auto it=GREXWordMap().find(words[0]);
78 797 : if(it!=GREXWordMap().end()) iword=it->second;
79 797 : switch(iword) {
80 0 : case cmd_initialized:
81 0 : CHECK_NOTNULL(val,key);
82 0 : *static_cast<int*>(val)=initialized;
83 0 : break;
84 153 : case cmd_setMPIIntracomm:
85 153 : CHECK_NOTINIT(initialized,key);
86 153 : intracomm.Set_comm(val);
87 : break;
88 113 : case cmd_setMPIIntercomm:
89 113 : CHECK_NOTINIT(initialized,key);
90 113 : intercomm.Set_comm(val);
91 113 : plumedMain.multi_sim_comm.Set_comm(val);
92 : break;
93 0 : case cmd_setMPIFIntracomm:
94 0 : CHECK_NOTINIT(initialized,key);
95 0 : intracomm.Set_fcomm(val);
96 : break;
97 0 : case cmd_setMPIFIntercomm:
98 0 : CHECK_NOTINIT(initialized,key);
99 0 : intercomm.Set_fcomm(val);
100 0 : plumedMain.multi_sim_comm.Set_fcomm(val);
101 : break;
102 153 : case cmd_init:
103 153 : CHECK_NOTINIT(initialized,key);
104 153 : initialized=true;
105 : // note that for PEs!=root this is automatically 0 (comm defaults to MPI_COMM_SELF)
106 153 : myreplica=intercomm.Get_rank();
107 153 : intracomm.Sum(myreplica);
108 : {
109 : std::string s;
110 153 : Tools::convert(myreplica,s);
111 306 : plumedMain.setSuffix("."+s);
112 : }
113 153 : break;
114 42 : case cmd_prepare:
115 42 : CHECK_INIT(initialized,key);
116 42 : if(intracomm.Get_rank()==0) return;
117 42 : intracomm.Bcast(partner,0);
118 42 : calculate();
119 : break;
120 42 : case cmd_setPartner:
121 42 : CHECK_INIT(initialized,key);
122 42 : partner=*static_cast<int*>(val);
123 42 : break;
124 84 : case cmd_savePositions:
125 84 : CHECK_INIT(initialized,key);
126 84 : savePositions();
127 : break;
128 42 : case cmd_calculate:
129 42 : CHECK_INIT(initialized,key);
130 42 : if(intracomm.Get_rank()!=0) return;
131 42 : intracomm.Bcast(partner,0);
132 42 : calculate();
133 : break;
134 0 : case cmd_getLocalDeltaBias:
135 0 : CHECK_INIT(initialized,key);
136 0 : CHECK_NOTNULL(val,key);
137 0 : atoms.double2MD(localDeltaBias/(atoms.getMDUnits().getEnergy()/atoms.getUnits().getEnergy()),val);
138 0 : break;
139 0 : case cmd_cacheLocalUNow:
140 0 : CHECK_INIT(initialized,key);
141 0 : CHECK_NOTNULL(val,key);
142 : {
143 : double x;
144 0 : atoms.MD2double(val,x);
145 0 : localUNow=x*(atoms.getMDUnits().getEnergy()/atoms.getUnits().getEnergy());
146 0 : intracomm.Sum(localUNow);
147 : }
148 0 : break;
149 0 : case cmd_cacheLocalUSwap:
150 0 : CHECK_INIT(initialized,key);
151 0 : CHECK_NOTNULL(val,key);
152 : {
153 : double x;
154 0 : atoms.MD2double(val,x);
155 0 : localUSwap=x*(atoms.getMDUnits().getEnergy()/atoms.getUnits().getEnergy());
156 0 : intracomm.Sum(localUSwap);
157 : }
158 0 : break;
159 0 : case cmd_getForeignDeltaBias:
160 0 : CHECK_INIT(initialized,key);
161 0 : CHECK_NOTNULL(val,key);
162 0 : atoms.double2MD(foreignDeltaBias/(atoms.getMDUnits().getEnergy()/atoms.getUnits().getEnergy()),val);
163 0 : break;
164 42 : case cmd_shareAllDeltaBias:
165 42 : CHECK_INIT(initialized,key);
166 42 : if(intracomm.Get_rank()!=0) return;
167 84 : allDeltaBias.assign(intercomm.Get_size(),0.0);
168 84 : allDeltaBias[intercomm.Get_rank()]=localDeltaBias;
169 42 : intercomm.Sum(allDeltaBias);
170 : break;
171 126 : case cmd_getDeltaBias:
172 126 : CHECK_INIT(initialized,key);
173 126 : CHECK_NOTNULL(val,key);
174 126 : plumed_assert(nw==2);
175 126 : plumed_massert(allDeltaBias.size()==static_cast<unsigned>(intercomm.Get_size()),
176 : "to retrieve bias with cmd(\"GREX getDeltaBias\"), first share it with cmd(\"GREX shareAllDeltaBias\")");
177 : {
178 : unsigned rep;
179 126 : Tools::convert(words[1],rep);
180 252 : plumed_massert(rep<allDeltaBias.size(),"replica index passed to cmd(\"GREX getDeltaBias\") is out of range");
181 126 : double d=allDeltaBias[rep]/(atoms.getMDUnits().getEnergy()/atoms.getUnits().getEnergy());
182 126 : atoms.double2MD(d,val);
183 : }
184 126 : break;
185 0 : default:
186 0 : plumed_merror("cannot interpret cmd(\" GREX" + key + "\"). check plumed developers manual to see the available commands.");
187 : break;
188 : }
189 : }
190 : }
191 :
192 84 : void GREX::savePositions() {
193 84 : plumedMain.prepareDependencies();
194 84 : plumedMain.resetActive(true);
195 84 : atoms.shareAll();
196 84 : plumedMain.waitData();
197 168 : ostringstream o;
198 84 : atoms.writeBinary(o);
199 168 : buffer=o.str();
200 84 : }
201 :
202 84 : void GREX::calculate() {
203 : //fprintf(stderr,"CALCULATE %d %d\n",intercomm.Get_rank(),partner);
204 : unsigned nn=buffer.size();
205 84 : vector<char> rbuf(nn);
206 84 : localDeltaBias=-plumedMain.getBias();
207 84 : if(intracomm.Get_rank()==0) {
208 42 : Communicator::Request req=intercomm.Isend(buffer,partner,1066);
209 42 : intercomm.Recv(rbuf,partner,1066);
210 42 : req.wait();
211 : }
212 84 : intracomm.Bcast(rbuf,0);
213 252 : istringstream i(string(&rbuf[0],rbuf.size()));
214 84 : atoms.readBinary(i);
215 84 : plumedMain.setExchangeStep(true);
216 84 : plumedMain.prepareDependencies();
217 84 : plumedMain.justCalculate();
218 84 : plumedMain.setExchangeStep(false);
219 84 : localDeltaBias+=plumedMain.getBias();
220 84 : localDeltaBias+=localUSwap-localUNow;
221 84 : if(intracomm.Get_rank()==0) {
222 42 : Communicator::Request req=intercomm.Isend(localDeltaBias,partner,1067);
223 42 : intercomm.Recv(foreignDeltaBias,partner,1067);
224 42 : req.wait();
225 : //fprintf(stderr,">>> %d %d %20.12f %20.12f %20.12f %20.12f\n",intercomm.Get_rank(),partner,localDeltaBias,foreignDeltaBias,localUSwap,localUNow);
226 : }
227 84 : intracomm.Bcast(foreignDeltaBias,0);
228 84 : }
229 :
230 4839 : }
|