QMCPACK
RMC.cpp
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////////////////
2 // This file is distributed under the University of Illinois/NCSA Open Source License.
3 // See LICENSE file in top directory for details.
4 //
5 // Copyright (c) 2016 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by: Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
8 // Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
9 // Raymond Clay III, j.k.rofling@gmail.com, Lawrence Livermore National Laboratory
10 // Jaron T. Krogel, krogeljt@ornl.gov, Oak Ridge National Laboratory
11 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
12 //
13 // File created by: Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
14 //////////////////////////////////////////////////////////////////////////////////////
15 
16 
17 #include "RMC.h"
22 #include "RandomNumberControl.h"
23 #include "Concurrency/OpenMP.h"
24 #include "Message/CommOperators.h"
25 #include "Particle/Reptile.h"
26 #include "Utilities/FairDivide.h"
28 #if !defined(REMOVE_TRACEMANAGER)
30 #else
31 using TraceManager = int;
32 #endif
33 
34 
35 namespace qmcplusplus
36 {
37 /// Constructor.
38 RMC::RMC(const ProjectData& project_data,
40  TrialWaveFunction& psi,
41  QMCHamiltonian& h,
43  : QMCDriver(project_data, w, psi, h, comm, "RMC"),
44  prestepsVMC(-1),
45  rescaleDrift("no"),
46  beta(-1),
47  beads(-1),
48  fromScratch(true)
49 {
50  RootName = "rmc";
53  m_param.add(rescaleDrift, "drift");
54  m_param.add(beta, "beta");
55  m_param.add(beads, "beads");
56  m_param.add(resizeReptile, "resize");
57  m_param.add(prestepsVMC, "vmcpresteps");
58 
59  Action.resize(3);
60  Action[0] = w.addProperty("ActionBackward");
61  Action[1] = w.addProperty("ActionForward");
62  Action[2] = w.addProperty("ActionLocal");
63  TransProb.resize(2);
64  TransProb[0] = w.addProperty("TransProbBackward");
65  TransProb[1] = w.addProperty("TransProbForward");
66 }
67 
68 bool RMC::run()
69 {
70  resetRun();
71  //start the main estimator
73  for (int ip = 0; ip < NumThreads; ++ip)
74  Movers[ip]->startRun(nBlocks, false);
75 #if !defined(REMOVE_TRACEMANAGER)
76  Traces->startRun(nBlocks, traceClones);
77 #endif
78  const bool has_collectables = W.Collectables.size();
79 
80  LoopTimer<> rmc_loop;
82  for (int block = 0; block < nBlocks; ++block)
83  {
84  rmc_loop.start();
85 #pragma omp parallel
86  {
87  int ip = omp_get_thread_num();
89  //assign the iterators and resuse them
90  MCWalkerConfiguration::iterator wit(W.begin() + wPerRank[ip]), wit_end(W.begin() + wPerRank[ip + 1]);
91  Movers[ip]->startBlock(nSteps);
92  int now_loc = CurrentStep;
93 
94  RealType cnorm = 1.0; //This is because there is only one reptile per walkerset.
95 
96  for (int step = 0; step < nSteps; ++step)
97  {
98  //collectables are reset, it is accumulated while advancing walkers
99  wClones[ip]->resetCollectables();
100  Movers[ip]->advanceWalkers(wit, wit_end, false);
101  if (has_collectables)
102  wClones[ip]->Collectables *= cnorm;
103  Movers[ip]->accumulate(wit, wit_end);
104 
105  ++now_loc;
106  if (Period4WalkerDump && now_loc % myPeriod4WalkerDump == 0)
107  wClones[ip]->saveEnsemble(wit, wit_end);
108 
109  branchEngine->collect(
110  CurrentStep,
111  W); //Ray Clay: For now, collects and syncs based on first reptile. Need a better way to do this.
112  }
113  Movers[ip]->stopBlock(false);
114  } //end-of-parallel for
115  CurrentStep += nSteps;
117  recordBlock(block);
118  rmc_loop.stop();
119 
120  bool stop_requested = false;
121  // Rank 0 decides whether the time limit was reached
122  if (!myComm->rank())
123  stop_requested = runtimeControl.checkStop(rmc_loop);
124  myComm->bcast(stop_requested);
125 
126  if (stop_requested)
127  {
128  if (!myComm->rank())
129  app_log() << runtimeControl.generateStopMessage("RMC", block);
130  run_time_manager.markStop();
131  break;
132  }
133  } //block
135  //copy back the random states
136  for (int ip = 0; ip < NumThreads; ++ip)
137  RandomNumberControl::Children[ip] = Rng[ip]->makeClone();
138  //return nbeads and stuff to its original unset state;
139  resetVars();
140  return finalize(nBlocks);
141 }
142 
144 {
146  //For now, assume that nReptiles=NumThreads;
148 
149  if (beads < 1)
150  beads = beta / Tau;
151  else
152  beta = beads * Tau;
153 
154  app_log() << "Projection time: " << beta << " Ha^-1" << std::endl;
155  //Calculate the number of VMC presteps if not given:
156  if (prestepsVMC == -1 && fromScratch == true)
157  prestepsVMC = beads + 2;
158  //Check to see if the MCWalkerConfiguration is in a state suitable for reptation
159  if (!W.ReptileList.empty())
160  {
161  fromScratch = false;
162 
163  app_log() << "Previous RMC reptiles detected...\n";
164  if (Tau == W.ReptileList[0]->getTau() && beads == W.ReptileList[0]->size())
165  app_log() << " Using current reptiles\n"; //do nothing
166  else //we need to extrapolate off of the current reptile set.
167  {
168  //pull the reptile configurations out
169  app_log() << " Previous Tau/Beta: " << W.ReptileList[0]->getTau() << "/"
170  << W.ReptileList[0]->getTau() * W.ReptileList[0]->size() << std::endl;
171  app_log() << " New Tau/Beta: " << Tau << "/" << beta << std::endl;
172  app_log() << " Linear interpolation to get new reptile.\n";
173  std::vector<ReptileConfig_t> repSamps(0);
174  for (IndexType sampid = 0; sampid < W.ReptileList.size() && sampid < nReptiles; sampid++)
175  repSamps.push_back(W.ReptileList[sampid]->getReptileSlicePositions(Tau, beta));
176 
177  //In the event of a disparity in the number of requested reptiles and the ones received.... just copy
178  //Copies cyclically. First iteration copies the first entry, second the second, and so on. So we don't replicate just one config.
179  for (IndexType copyid = 0; repSamps.size() < nReptiles; copyid++)
180  repSamps.push_back(repSamps[copyid]);
181 
182 
183  resetReptiles(repSamps, Tau);
184  }
185  }
186 
187  //Previous run was nothing, VMC, or DMC. No reptiles--so we initialize based on whatever is there.
188  else
189  {
190  //Initialize on whatever walkers are in MCWalkerConfiguration.
191  app_log() << "Using walkers from previous non-RMC run.\n";
192  std::vector<ParticlePos> wSamps(0);
193  MCWalkerConfiguration::iterator wit(W.begin()), wend(W.end());
194  for (IndexType sampid = 0; wit != wend && sampid < nReptiles; wit++)
195  wSamps.push_back((**wit).R);
196 
197  for (IndexType copyid = 0; wSamps.size() < nReptiles; copyid++)
198  wSamps.push_back(wSamps[copyid]);
199  resetReptiles(wSamps, beads, Tau);
200  }
201 
202  //Now that we know if we're starting from scratch... decide whether to force VMC warmup.
203  if (prestepsVMC == -1 && fromScratch == true)
204  prestepsVMC = beads + 2;
205  makeClones(W, Psi, H);
207 
208  if (Movers.empty())
209  {
210  Movers.resize(NumThreads, nullptr);
211  estimatorClones.resize(NumThreads, nullptr);
212  traceClones.resize(NumThreads, nullptr);
213  Rng.resize(NumThreads);
214  branchEngine->initReptile(W);
215 
216  // hdf_archive::hdf_archive() is not thread-safe
217  for (int ip = 0; ip < NumThreads; ++ip)
219 
220 #pragma omp parallel for
221  for (int ip = 0; ip < NumThreads; ++ip)
222  {
223  std::ostringstream os;
224  estimatorClones[ip]->resetTargetParticleSet(*wClones[ip]);
225  estimatorClones[ip]->setCollectionMode(false);
226  Rng[ip] = RandomNumberControl::Children[ip]->makeClone();
227 #if !defined(REMOVE_TRACEMANAGER)
228  traceClones[ip] = Traces->makeClone();
229 #endif
230  hClones[ip]->setRandomGenerator(Rng[ip].get());
232  {
233  os << " PbyP moves with drift, using RMCUpdatePbyPWithDriftFast" << std::endl;
234  Movers[ip] =
235  new RMCUpdatePbyPWithDrift(*wClones[ip], *psiClones[ip], *hClones[ip], *Rng[ip], Action, TransProb);
236  }
237  else
238  {
239  os << " walker moves with drift, using RMCUpdateAllWithDriftFast" << std::endl;
240  Movers[ip] = new RMCUpdateAllWithDrift(*wClones[ip], *psiClones[ip], *hClones[ip], *Rng[ip], Action, TransProb);
241  }
242  Movers[ip]->nSubSteps = nSubSteps;
243  if (ip == 0)
244  app_log() << os.str() << std::endl;
245  }
246  }
247 #if !defined(REMOVE_TRACEMANAGER)
248  else
249  {
250 #pragma omp parallel for
251  for (int ip = 0; ip < NumThreads; ++ip)
252  {
253  traceClones[ip]->transfer_state_from(*Traces);
254  }
255  }
256 #endif
257  app_log().flush();
258 #pragma omp parallel for
259  for (int ip = 0; ip < NumThreads; ++ip)
260  {
261  Movers[ip]->put(qmcNode);
262  Movers[ip]->resetRun(branchEngine.get(), estimatorClones[ip], traceClones[ip], DriftModifier);
263 
264  wClones[ip]->reptile = W.ReptileList[ip].get();
265  wClones[ip]->activeBead = 0;
266  wClones[ip]->direction = +1;
267 
269  {
270  // app_log () << ip << " initWalkers for pbyp...\n";
271  Movers[ip]->initWalkersForPbyP(W.ReptileList[ip]->repstart, W.ReptileList[ip]->repend);
272  }
273  else
274  {
275  Movers[ip]->initWalkers(W.begin() + wPerRank[ip], W.begin() + wPerRank[ip + 1]);
276  }
277 
278  //this will "unroll" the reptile according to forced VMC steps (no bounce). See beginning of function for logic of setting prestepVMC.
279  for (IndexType prestep = 0; prestep < prestepsVMC; prestep++)
280  {
281  Movers[ip]->advanceWalkers(W.begin(), W.begin(), true);
282  }
283 
284  //set up initial action and transprob.
285  MCWalkerConfiguration::iterator wit(W.begin() + wPerRank[ip]), wit_end(W.begin() + wPerRank[ip + 1]);
286  }
287 
288 
289  app_log() << "Finished " << prestepsVMC << " VMC presteps\n";
290  branchEngine->checkParameters(W);
291 
292 #pragma omp parallel for
293  for (int ip = 0; ip < NumThreads; ++ip)
294  {
295  for (int prestep = 0; prestep < nWarmupSteps; ++prestep)
296  {
297  Movers[ip]->advanceWalkers(W.begin() + wPerRank[ip], W.begin() + wPerRank[ip + 1], false);
298  branchEngine->collect(CurrentStep, W);
299  }
300  }
301 
302  fromScratch = false;
303 }
304 
305 bool RMC::put(xmlNodePtr q)
306 {
307  m_param.put(q);
308  return true;
309 }
310 
311 //This will resize the MCWalkerConfiguration and initialize the ReptileList. Does not care for previous runs.
312 void RMC::resetReptiles(int nReptiles_in, int nbeads_in, RealType tau)
313 {
314  W.ReptileList.clear();
315  // Maybe we should be more vigorous in cleaning the MCWC WalkerList?
316  std::vector<int> repWalkerSlice;
317  int nwtot = nbeads_in * nReptiles_in;
318  FairDivideLow(nwtot, nReptiles_in, repWalkerSlice);
319  if (W.getActiveWalkers() - nwtot != 0)
320  addWalkers(nwtot - W.getActiveWalkers());
321 
322  for (int i = 0; i < nReptiles_in; i++)
323  {
324  W.ReptileList.push_back(
325  std::make_unique<Reptile>(W, W.begin() + repWalkerSlice[i], W.begin() + repWalkerSlice[i + 1]));
326  W.ReptileList[i]->setTau(tau);
327  }
328 }
329 //This will resize the MCWalkerConfiguration and initialize Reptile list. It will then reinitialize the MCWC with a list of Reptile coordinates
330 void RMC::resetReptiles(std::vector<ReptileConfig_t>& reptile_samps, RealType tau)
331 {
332  if (reptile_samps.empty())
333  {
334  APP_ABORT("RMC::resetReptiles(std::vector< ReptileConfig_t > reptile_samps): No samples!\n");
335  }
336  else
337  {
338  IndexType nReptiles_in = reptile_samps.size();
339  IndexType nBeads_in = reptile_samps[0].size();
340  resetReptiles(nReptiles_in, nBeads_in, tau);
341 
342  for (IndexType i = 0; i < W.ReptileList.size(); i++)
343  {
344  W.ReptileList[i]->setReptileSlicePositions(reptile_samps[i]);
345  }
346  }
347 }
348 //For # of walker samples, create that many reptiles with nbeads each. Initialize each reptile to have the value of the walker "seed".
349 void RMC::resetReptiles(std::vector<ParticlePos>& walker_samps, int nBeads_in, RealType tau)
350 {
351  if (walker_samps.empty())
352  {
353  APP_ABORT("RMC::resetReptiles(std::vector< ParticlePos > walker_samps): No samples!\n");
354  }
355  else
356  {
357  IndexType nReptiles_in = walker_samps.size();
358  resetReptiles(nReptiles_in, nBeads_in, tau);
359 
360  for (IndexType i = 0; i < W.ReptileList.size(); i++)
361  {
362  W.ReptileList[i]->setReptileSlicePositions(walker_samps[i]);
363  }
364  }
365 }
366 
367 }; // namespace qmcplusplus
bool run() override
Definition: RMC.cpp:68
int prestepsVMC
Definition: RMC.h:42
size_type size() const
return the size of the data
Definition: PooledData.h:48
int MaxCPUSecs
maximum cpu in secs
Definition: QMCDriver.h:302
A set of walkers that are to be advanced by Metropolis Monte Carlo.
static std::vector< TrialWaveFunction * > psiClones
Definition: CloneManager.h:65
ReptileList_t ReptileList
a collection of reptiles contained in MCWalkerConfiguration.
std::vector< int > wPerRank
Walkers per MPI rank.
Definition: CloneManager.h:91
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
int rank() const
return the rank
Definition: Communicate.h:116
QTBase::RealType RealType
Definition: Configuration.h:58
size_t getActiveWalkers() const
return the number of active walkers
void recordBlock(int block) override
record the state of the block
Definition: QMCDriver.cpp:307
std::string RootName
root of all the output files
Definition: QMCDriver.h:317
static std::vector< MCWalkerConfiguration * > wClones
Definition: CloneManager.h:61
std::ostream & app_log()
Definition: OutputManager.h:65
xmlNodePtr qmcNode
pointer to qmc node in xml file
Definition: QMCDriver.h:310
class ProjectData
Definition: ProjectData.h:36
int addProperty(const std::string &pname)
Definition: ParticleSet.h:411
RunTimeManager< ChronoClock > run_time_manager
Collection of Local Energy Operators.
bool fromScratch
Definition: RMC.h:57
IndexType CurrentStep
current step
Definition: QMCDriver.h:263
std::vector< QMCUpdateBase * > Movers
update engines
Definition: CloneManager.h:73
abstract base class for QMC engines
Definition: QMCDriver.h:71
std::unique_ptr< TraceManager > Traces
Traces manager.
Definition: QMCDriver.h:195
bool put(std::istream &is) override
read from std::istream
Definition: ParameterSet.h:42
void FairDivideLow(int ntot, int npart, IV &adist)
partition ntot elements among npart
Definition: FairDivide.h:114
ParameterSet m_param
store any parameter that has to be read from a file
Definition: QMCDriver.h:320
IndexType nSubSteps
number of steps between a step: VMCs do not evaluate energies
Definition: QMCDriver.h:272
int nReptiles
Definition: RMC.h:52
Wrapping information on parallelism.
Definition: Communicate.h:68
omp_int_t omp_get_thread_num()
Definition: OpenMP.h:25
IndexType nSteps
maximum number of steps
Definition: QMCDriver.h:269
bool finalize(int block, bool dumpwalkers=true)
finalize a qmc section
Definition: QMCDriver.cpp:318
const std::string & getName() const
Definition: Communicate.h:131
WalkerList_t::iterator iterator
FIX: a type alias of iterator for an object should not be for just one of many objects it holds...
A collection of functions for dividing fairly.
std::bitset< QMC_MODE_MAX > qmc_driver_mode
bits to classify QMCDriver
Definition: QMCDriver.h:93
Communicate * myComm
pointer to Communicate
Definition: MPIObjectBase.h:62
int myPeriod4WalkerDump
period for walker dump
Definition: RMC.h:48
std::unique_ptr< BranchEngineType > branchEngine
branch engine
Definition: QMCDriver.h:218
std::vector< EstimatorManagerBase * > estimatorClones
estimator managers
Definition: CloneManager.h:75
const IndexType NumThreads
number of threads
Definition: CloneManager.h:54
QMCHamiltonian & H
Hamiltonian.
Definition: QMCDriver.h:329
DriftModifierBase * DriftModifier
drift modifer
Definition: QMCDriver.h:220
#define APP_ABORT(msg)
Widely used but deprecated fatal error macros from legacy code.
Definition: AppAbort.h:27
void makeClones(MCWalkerConfiguration &w, TrialWaveFunction &psi, QMCHamiltonian &ham)
void resetReptiles(int nReptiles, int nbeads, RealType tau)
Definition: RMC.cpp:312
MCWalkerConfiguration & W
walker ensemble
Definition: QMCDriver.h:323
static UPtrVector< RandomBase< FullPrecRealType > > Children
Implements the RMC algorithm using all electron moves
Definition: RMCUpdateAll.h:23
OHMMS_INDEXTYPE IndexType
define other types
Definition: Configuration.h:65
Implements the RMC algorithm using all electron moves
Definition: RMCUpdatePbyP.h:24
Buffer_t Collectables
observables in addition to those registered in Properties/PropertyList
Definition: ParticleSet.h:126
Class to manage a set of ScalarEstimators.
static std::vector< QMCHamiltonian * > hClones
Definition: CloneManager.h:71
void add(PDT &aparam, const std::string &aname_in, std::vector< PDT > candidate_values={}, TagStatus status=TagStatus::OPTIONAL)
add a new parameter corresponding to an xmlNode <parameter>
void resetRun()
Definition: RMC.cpp:143
Class for determining elapsed run time enabling simulations to adjust to time limits.
Class to represent a many-body trial wave function.
int resizeReptile
rescale for time step studies. some int>2 and new beads are inserted in between the old ones...
Definition: RMC.h:54
RMC(const ProjectData &project_data, MCWalkerConfiguration &w, TrialWaveFunction &psi, QMCHamiltonian &h, Communicate *comm)
Constructor.
Definition: RMC.cpp:38
Declaraton of ParticleAttrib<T>
EstimatorManagerBase * Estimators
Observables manager.
Definition: QMCDriver.h:192
void stopBlock(RealType accept, bool collectall=true)
stop a block
TrialWaveFunction & Psi
trial function
Definition: QMCDriver.h:326
RealType Tau
timestep
Definition: QMCDriver.h:299
void bcast(T &)
IndexType nBlocks
maximum number of blocks
Definition: QMCDriver.h:266
std::vector< int > Action
Definition: RMC.h:59
bool put(xmlNodePtr cur) override
Definition: RMC.cpp:305
int Period4WalkerDump
period of recording walker configurations
Definition: QMCDriver.h:255
std::vector< TraceManager * > traceClones
trace managers
Definition: CloneManager.h:77
int Period4CheckProperties
period of dumping walker positions and IDs for Forward Walking
Definition: QMCDriver.h:249
void addWalkers(int nwalkers)
Add walkers to the end of the ensemble of walkers.
Definition: QMCDriver.cpp:338
RealType beta
projection time of reptile
Definition: RMC.h:46
IndexType nWarmupSteps
number of warmup steps
Definition: QMCDriver.h:275
UPtrVector< RandomBase< FullPrecRealType > > Rng
Random number generators.
Definition: QMCDriver.h:341
void start(int blocks, bool record=true)
start a run
iterator end()
return the last iterator, [begin(), end())
void resetVars()
check the run-time environments
Definition: RMC.h:63
std::vector< int > TransProb
Definition: RMC.h:60
int beads
number of beads on the reptile, beta/tau
Definition: RMC.h:50
std::string rescaleDrift
option to enable/disable drift equation for RMC
Definition: RMC.h:44
iterator begin()
return the first iterator