QMCPACK
DMC.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: Ken Esler, kpesler@gmail.com, University of Illinois at Urbana-Champaign
8 // Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
9 // Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
10 // Cynthia Gu, zg1@ornl.gov, Oak Ridge National Laboratory
11 // Paul R. C. Kent, kentpr@ornl.gov, Oak Ridge National Laboratory
12 // Jaron T. Krogel, krogeljt@ornl.gov, Oak Ridge National Laboratory
13 // Ye Luo, yeluo@anl.gov, Argonne National Laboratory
14 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
15 //
16 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
17 //////////////////////////////////////////////////////////////////////////////////////
18 
19 
20 #include "DMC.h"
26 #include "Message/Communicate.h"
27 #include "Message/CommOperators.h"
28 #include "Concurrency/OpenMP.h"
29 #include "Utilities/Timer.h"
32 #include "Utilities/qmc_common.h"
33 #include "Utilities/FairDivide.h"
34 #if !defined(REMOVE_TRACEMANAGER)
36 #else
37 using TraceManager = int;
38 #endif
39 #include "WalkerLogManager.h"
40 
41 namespace qmcplusplus
42 {
43 /// Constructor.
44 DMC::DMC(const ProjectData& project_data,
46  TrialWaveFunction& psi,
47  QMCHamiltonian& h,
50  bool enable_profiling)
51  : QMCDriver(project_data, w, psi, h, comm, "DMC", enable_profiling),
52  rngs_(rngs),
53  KillNodeCrossing(0),
54  BranchInterval(-1),
55  L2("no"),
56  Reconfiguration("no"),
57  mover_MaxAge(-1)
58 {
59  RootName = "dmc";
61  m_param.add(KillWalker, "killnode");
62  m_param.add(Reconfiguration, "reconfiguration");
63  //m_param.add(BranchInterval,"branchInterval");
64  m_param.add(NonLocalMove, "nonlocalmove");
65  m_param.add(NonLocalMove, "nonlocalmoves");
66  m_param.add(mover_MaxAge, "MaxAge");
67  m_param.add(L2, "L2_diffusion");
68 }
69 
71 {
72  ReportEngine PRE("DMC", "resetUpdateEngines");
73  bool fixW = (Reconfiguration == "runwhileincorrect");
74  if (Reconfiguration != "no" && Reconfiguration != "runwhileincorrect")
75  throw std::runtime_error("Reconfiguration is currently broken and gives incorrect results. Use dynamic "
76  "population control by setting reconfiguration=\"no\" or removing the reconfiguration "
77  "option from the DMC input section. If accessing the broken reconfiguration code path "
78  "is still desired, set reconfiguration to \"runwhileincorrect\" instead of \"yes\".");
79  makeClones(W, Psi, H);
80  Timer init_timer;
81  bool spinor = false;
82  if (Movers.empty())
83  {
86  int nw_multi = branchEngine->initWalkerController(W, fixW, false);
87  if (nw_multi > 1)
88  {
89  W.createWalkers((nw_multi - 1) * W.getActiveWalkers());
91  }
92  //if(qmc_driver_mode[QMC_UPDATE_MODE]) W.clearAuxDataSet();
93  Movers.resize(NumThreads, nullptr);
94  Rng.resize(NumThreads);
95  estimatorClones.resize(NumThreads, nullptr);
96  traceClones.resize(NumThreads, nullptr);
99 
100  {
101  //log file
102  std::ostringstream o;
103  o << " Initial partition of walkers on a node: ";
104  copy(wPerRank.begin(), wPerRank.end(), std::ostream_iterator<int>(o, " "));
105  o << "\n";
107  {
108  o << " Updates by particle-by-particle moves";
109  if (L2 == "yes")
110  app_log() << "Using DMCUpdatePbyPL2" << std::endl;
111  else
112  app_log() << "Using DMCUpdatePbyPWithRejectionFast" << std::endl;
113  }
114  else
115  o << " Updates by walker moves";
116  // Appears to be set in constructor reported here and used nowhere
117  if (KillNodeCrossing)
118  o << "\n Walkers are killed when a node crossing is detected";
119  else
120  o << "\n DMC moves are rejected when a node crossing is detected";
121  app_log() << o.str() << std::endl;
122  }
123 
124  // hdf_archive::hdf_archive() is not thread-safe
125  for (int ip = 0; ip < NumThreads; ++ip)
127 
128 #pragma omp parallel for
129  for (int ip = 0; ip < NumThreads; ++ip)
130  {
131  estimatorClones[ip]->setCollectionMode(false);
132 #if !defined(REMOVE_TRACEMANAGER)
133  traceClones[ip] = Traces->makeClone();
134 #endif
135  wlog_collectors[ip] = wlog_manager_->makeCollector();
136  Rng[ip] = rngs_[ip]->makeClone();
137  hClones[ip]->setRandomGenerator(Rng[ip].get());
138  if (W.isSpinor())
139  {
140  spinor = true;
142  {
143  Movers[ip] = new SODMCUpdatePbyPWithRejectionFast(*wClones[ip], *psiClones[ip], *hClones[ip], *Rng[ip]);
144  Movers[ip]->setSpinMass(SpinMass);
145  Movers[ip]->put(qmcNode);
146  //Movers[ip]->resetRun(branchEngine.get(), estimatorClones[ip], traceClones[ip], DriftModifier);
147  Movers[ip]->resetRun2(branchEngine.get(), estimatorClones[ip], traceClones[ip], wlog_collectors[ip].get(), DriftModifier);
148  Movers[ip]->initWalkersForPbyP(W.begin() + wPerRank[ip], W.begin() + wPerRank[ip + 1]);
149  }
150  else
151  {
152  APP_ABORT("SODMC Driver Mode must be PbyP\n");
153  }
154  }
155  else
156  {
158  {
159  if (L2 == "yes")
160  Movers[ip] = new DMCUpdatePbyPL2(*wClones[ip], *psiClones[ip], *hClones[ip], *Rng[ip]);
161  else
162  Movers[ip] = new DMCUpdatePbyPWithRejectionFast(*wClones[ip], *psiClones[ip], *hClones[ip], *Rng[ip]);
163 
164  Movers[ip]->put(qmcNode);
165  //Movers[ip]->resetRun(branchEngine.get(), estimatorClones[ip], traceClones[ip], DriftModifier);
166  Movers[ip]->resetRun2(branchEngine.get(), estimatorClones[ip], traceClones[ip], wlog_collectors[ip].get(), DriftModifier);
167  Movers[ip]->initWalkersForPbyP(W.begin() + wPerRank[ip], W.begin() + wPerRank[ip + 1]);
168  }
169  else
170  {
171  if (KillNodeCrossing)
172  Movers[ip] = new DMCUpdateAllWithKill(*wClones[ip], *psiClones[ip], *hClones[ip], *Rng[ip]);
173  else
174  Movers[ip] = new DMCUpdateAllWithRejection(*wClones[ip], *psiClones[ip], *hClones[ip], *Rng[ip]);
175  Movers[ip]->put(qmcNode);
176  //Movers[ip]->resetRun(branchEngine.get(), estimatorClones[ip], traceClones[ip], DriftModifier);
177  Movers[ip]->resetRun2(branchEngine.get(), estimatorClones[ip], traceClones[ip], wlog_collectors[ip].get(), DriftModifier);
178  Movers[ip]->initWalkers(W.begin() + wPerRank[ip], W.begin() + wPerRank[ip + 1]);
179  }
180  }
181  }
182  }
183 #if !defined(REMOVE_TRACEMANAGER)
184  else
185  {
186 #pragma omp parallel for
187  for (int ip = 0; ip < NumThreads; ++ip)
188  traceClones[ip]->transfer_state_from(*Traces);
189  }
190 #endif
191  if (spinor)
192  app_log() << " Spins treated as dynamic variable with SpinMass: " << SpinMass << std::endl;
193 
194  branchEngine->checkParameters(W);
195  int mxage = mover_MaxAge;
196  if (fixW)
197  {
198  if (BranchInterval < 0)
199  BranchInterval = 1;
200  mxage = (mover_MaxAge < 0) ? 0 : mover_MaxAge;
201  for (int ip = 0; ip < Movers.size(); ++ip)
202  Movers[ip]->MaxAge = mxage;
203  }
204  else
205  {
206  if (BranchInterval < 0)
207  BranchInterval = 1;
208  int miage = (qmc_driver_mode[QMC_UPDATE_MODE]) ? 1 : 5;
209  mxage = (mover_MaxAge < 0) ? miage : mover_MaxAge;
210  for (int i = 0; i < NumThreads; ++i)
211  Movers[i]->MaxAge = mxage;
212  }
213  {
214  std::ostringstream o;
215  if (fixW)
216  o << " Fixed population using reconfiguration method\n";
217  else
218  o << " Fluctuating population\n";
219  o << " Persistent walkers are killed after " << mxage << " MC sweeps\n";
220  o << " BranchInterval = " << BranchInterval << "\n";
221  o << " Steps per block = " << nSteps << "\n";
222  o << " Number of blocks = " << nBlocks << "\n";
223  app_log() << o.str() << std::endl;
224  }
225  app_log() << " DMC Engine Initialization = " << init_timer.elapsed() << " secs" << std::endl;
226 }
227 
228 bool DMC::run()
229 {
230  LoopTimer<> dmc_loop;
231 
232  bool variablePop = (Reconfiguration == "no");
234  //estimator does not need to collect data
237  for (int ip = 0; ip < NumThreads; ip++)
238  Movers[ip]->startRun(nBlocks, false);
239 #if !defined(REMOVE_TRACEMANAGER)
240  Traces->startRun(nBlocks, traceClones);
241 #endif
243  IndexType block = 0;
245  int sample = 0;
246 
247  RunTimeControl<> runtimeControl(run_time_manager, MaxCPUSecs, myComm->getName(), myComm->rank() == 0);
248 
249  do // block
250  {
251  dmc_loop.start();
253  for (int ip = 0; ip < NumThreads; ip++)
254  Movers[ip]->startBlock(nSteps);
255 
256  for (IndexType step = 0; step < nSteps; ++step, CurrentStep += BranchInterval)
257  {
258  // if(storeConfigs && (CurrentStep%storeConfigs == 0)) {
259  // ForwardWalkingHistory.storeConfigsForForwardWalking(W);
260  // W.resetWalkerParents();
261  // }
262 
263 #pragma omp parallel
264  {
265  int ip = omp_get_thread_num();
266  Movers[ip]->set_step(sample);
267  bool recompute = (step + 1 == nSteps && nBlocksBetweenRecompute && (1 + block) % nBlocksBetweenRecompute == 0 &&
269  wClones[ip]->resetCollectables();
270  const size_t nw = W.getActiveWalkers();
271 #pragma omp for nowait
272  for (size_t iw = 0; iw < nw; ++iw)
273  {
274  Walker_t& thisWalker(*W[iw]);
275  Movers[ip]->advanceWalker(thisWalker, recompute);
276  }
277  }
278 
279  //Collectables are weighted but not yet normalized
280  if (W.Collectables.size())
281  {
282  // only when collectable is not empty, need to generalize for W != wClones[0]
283  for (int ip = 1; ip < NumThreads; ++ip)
284  W.Collectables += wClones[ip]->Collectables;
285  }
286  branchEngine->branch(CurrentStep, W);
287  // if(storeConfigs && (CurrentStep%storeConfigs == 0)) {
288  // ForwardWalkingHistory.storeConfigsForForwardWalking(W);
289  // W.resetWalkerParents();
290  // }
291  if (variablePop)
293  sample++;
294  }
295  // branchEngine->debugFWconfig();
297 #if !defined(REMOVE_TRACEMANAGER)
298  Traces->write_buffers(traceClones, block);
299 #endif
300  wlog_manager_->writeBuffers();
301  block++;
302  if (DumpConfig && block % Period4CheckPoint == 0)
303  {
304  for (int ip = 0; ip < NumThreads; ip++)
305  rngs_[ip] = Rng[ip]->makeClone();
306  }
307  recordBlock(block);
308  dmc_loop.stop();
309 
310  bool stop_requested = false;
311  // Rank 0 decides whether the time limit was reached
312  if (!myComm->rank())
313  stop_requested = runtimeControl.checkStop(dmc_loop);
314  myComm->bcast(stop_requested);
315 
316  if (stop_requested)
317  {
318  if (!myComm->rank())
319  app_log() << runtimeControl.generateStopMessage("DMC", block - 1);
320  run_time_manager.markStop();
321  break;
322  }
323 
324  } while (block < nBlocks);
325 
326  for (int ip = 0; ip < NumThreads; ip++)
327  rngs_[ip] = Rng[ip]->makeClone();
328  Estimators->stop();
329  for (int ip = 0; ip < NumThreads; ++ip)
330  Movers[ip]->stopRun2();
331 #if !defined(REMOVE_TRACEMANAGER)
332  Traces->stopRun();
333 #endif
334  wlog_manager_->stopRun();
335  return finalize(nBlocks);
336 }
337 
338 
339 bool DMC::put(xmlNodePtr q)
340 {
341  BranchInterval = -1;
342  ParameterSet p;
343  p.add(BranchInterval, "branchInterval");
344  p.add(BranchInterval, "branchinterval");
345  p.add(BranchInterval, "substeps");
346  p.add(BranchInterval, "subSteps");
347  p.add(BranchInterval, "sub_steps");
348  p.put(q);
349 
350  //app_log() << "\n DMC::put qmc_counter=" << qmc_common.qmc_counter << " my_counter=" << MyCounter<< std::endl;
351  //app_log() << " timestep = " << Tau << std::endl;
352  //app_log() << " blocks = " << nBlocks << std::endl;
353  //app_log() << " steps = " << nSteps << std::endl;
354  //app_log() << " current = " << CurrentStep << std::endl;
355  //app_log() << " walkers/mpi = " << W.getActiveWalkers() << std::endl << std::endl;
356  //app_log().flush();
357  return true;
358 }
359 } // namespace qmcplusplus
bool run() override
Definition: DMC.cpp:228
double elapsed() const
Definition: Timer.h:30
size_type size() const
return the size of the data
Definition: PooledData.h:48
UPtrVector< WalkerLogCollector > wlog_collectors
trace collectors
Definition: CloneManager.h:79
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
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
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
bool DumpConfig
flag to turn off dumping configurations
Definition: QMCDriver.h:226
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
void resetUpdateEngines()
Definition: DMC.cpp:70
RunTimeManager< ChronoClock > run_time_manager
Collection of Local Energy Operators.
IndexType CurrentStep
current step
Definition: QMCDriver.h:263
Timer class.
std::vector< std::unique_ptr< T > > UPtrVector
std::vector< QMCUpdateBase * > Movers
update engines
Definition: CloneManager.h:73
abstract base class for QMC engines
Definition: QMCDriver.h:71
IndexType mover_MaxAge
input to control maximum age allowed for walkers.
Definition: DMC.h:68
RealType SpinMass
spin mass for spinor calcs
Definition: QMCDriver.h:353
UPtrVector< RandomBase< QMCTraits::FullPrecRealType > > & rngs_
Definition: DMC.h:49
void loadEnsemble()
load SampleStack data to the current list of walker configurations
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
DMC(const ProjectData &project_data, MCWalkerConfiguration &w, TrialWaveFunction &psi, QMCHamiltonian &h, UPtrVector< RandomBase< QMCTraits::FullPrecRealType >> &rngs, Communicate *comm, bool enable_profiling)
Constructor.
Definition: DMC.cpp:44
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
void copy(const Array< T1, 3 > &src, Array< T2, 3 > &dest)
Definition: Blitz.h:639
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
void startBlock(int steps)
start a block
bool finalize(int block, bool dumpwalkers=true)
finalize a qmc section
Definition: QMCDriver.cpp:318
const std::string & getName() const
Definition: Communicate.h:131
A collection of functions for dividing fairly.
class to handle a set of parameters
Definition: ParameterSet.h:27
void setCollectionMode(bool collect)
set CollectSum
std::bitset< QMC_MODE_MAX > qmc_driver_mode
bits to classify QMCDriver
Definition: QMCDriver.h:93
Final class and should not be derived.
Communicate * myComm
pointer to Communicate
Definition: MPIObjectBase.h:62
std::unique_ptr< BranchEngineType > branchEngine
branch engine
Definition: QMCDriver.h:218
declaration of ProgressReportEngine
std::vector< EstimatorManagerBase * > estimatorClones
estimator managers
Definition: CloneManager.h:75
std::string Reconfiguration
input std::string to determine to use reconfiguration
Definition: DMC.h:64
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)
MCWalkerConfiguration & W
walker ensemble
Definition: QMCDriver.h:323
OHMMS_INDEXTYPE IndexType
define other types
Definition: Configuration.h:65
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>
Declaration of HamiltonianPool.
Class for determining elapsed run time enabling simulations to adjust to time limits.
Class to represent a many-body trial wave function.
EstimatorManagerBase * Estimators
Observables manager.
Definition: QMCDriver.h:192
int Period4CheckPoint
period of dumping walker configurations and everything else for restart
Definition: QMCDriver.h:242
void stopBlock(RealType accept, bool collectall=true)
stop a block
TrialWaveFunction & Psi
trial function
Definition: QMCDriver.h:326
RealType acceptRatio() const
void bcast(T &)
IndexType nBlocks
maximum number of blocks
Definition: QMCDriver.h:266
bool put(xmlNodePtr cur) override
Definition: DMC.cpp:339
void createWalkers(int numWalkers)
create numWalkers Walkers
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
RefVector< WalkerLogCollector > getWalkerLogCollectorRefs()
void setWalkerOffsets()
set global offsets of the walkers
Definition: QMCDriver.cpp:370
IndexType BranchInterval
Interval between branching.
Definition: DMC.h:54
UPtrVector< RandomBase< FullPrecRealType > > Rng
Random number generators.
Definition: QMCDriver.h:341
std::unique_ptr< WalkerLogManager > wlog_manager_
Traces manager.
Definition: QMCDriver.h:198
IndexType nBlocksBetweenRecompute
the number of blocks between recomptePsi
Definition: QMCDriver.h:284
void start(int blocks, bool record=true)
start a run
std::string KillWalker
input std::string to determine kill walkers or not
Definition: DMC.h:58
A container class to represent a walker.
Definition: Walker.h:49
std::string L2
input to control diffusion with L2 operator
Definition: DMC.h:62
Define OpenMP-able DMC Driver.
IndexType KillNodeCrossing
Index to determine what to do when node crossing is detected.
Definition: DMC.h:52
std::string NonLocalMove
input std::string to determine to use nonlocal move
Definition: DMC.h:66
iterator begin()
return the first iterator