QMCPACK
VMC.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: Bryan Clark, bclark@Princeton.edu, Princeton University
8 // Ken Esler, kpesler@gmail.com, University of Illinois at Urbana-Champaign
9 // Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
10 // Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
11 // Cynthia Gu, zg1@ornl.gov, Oak Ridge National Laboratory
12 // Jaron T. Krogel, krogeljt@ornl.gov, Oak Ridge National Laboratory
13 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
14 //
15 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
16 //////////////////////////////////////////////////////////////////////////////////////
17 
18 
19 #include "VMC.h"
24 #include "Concurrency/OpenMP.h"
25 #include "Message/CommOperators.h"
27 #include "Utilities/qmc_common.h"
28 //#define ENABLE_VMC_OMP_MASTER
29 #include "Utilities/FairDivide.h"
30 #if !defined(REMOVE_TRACEMANAGER)
32 #else
33 using TraceManager = int;
34 #endif
35 #include "WalkerLogManager.h"
36 
37 namespace qmcplusplus
38 {
39 /// Constructor.
40 VMC::VMC(const ProjectData& project_data,
42  TrialWaveFunction& psi,
43  QMCHamiltonian& h,
46  bool enable_profiling)
47  : QMCDriver(project_data, w, psi, h, comm, "VMC", enable_profiling), UseDrift("yes"), rngs_(rngs)
48 {
49  RootName = "vmc";
52  m_param.add(UseDrift, "useDrift");
53  m_param.add(UseDrift, "usedrift");
54  m_param.add(UseDrift, "use_drift");
55 
56  prevSteps = nSteps;
58 }
59 
60 bool VMC::run()
61 {
62  resetRun();
63  //start the main estimator
65  for (int ip = 0; ip < NumThreads; ++ip)
66  Movers[ip]->startRun(nBlocks, false);
67 #if !defined(REMOVE_TRACEMANAGER)
68  Traces->startRun(nBlocks, traceClones);
69 #endif
71 
72  LoopTimer<> vmc_loop;
74 
75  const bool has_collectables = W.Collectables.size();
76  for (int block = 0; block < nBlocks; ++block)
77  {
78  vmc_loop.start();
79 #pragma omp parallel
80  {
81  int ip = omp_get_thread_num();
82  //IndexType updatePeriod=(qmc_driver_mode[QMC_UPDATE_MODE])?Period4CheckProperties:(nBlocks+1)*nSteps;
84  //assign the iterators and resuse them
85  MCWalkerConfiguration::iterator wit(W.begin() + wPerRank[ip]), wit_end(W.begin() + wPerRank[ip + 1]);
86  Movers[ip]->startBlock(nSteps);
87  int now_loc = CurrentStep;
88  RealType cnorm = 1.0 / static_cast<RealType>(wPerRank[ip + 1] - wPerRank[ip]);
89  for (int step = 0; step < nSteps; ++step)
90  {
91  Movers[ip]->set_step(now_loc);
92  //collectables are reset, it is accumulated while advancing walkers
93  wClones[ip]->resetCollectables();
94  bool recompute = (nBlocksBetweenRecompute && (step + 1) == nSteps &&
96  Movers[ip]->advanceWalkers(wit, wit_end, recompute);
97  if (has_collectables)
98  wClones[ip]->Collectables *= cnorm;
99  Movers[ip]->accumulate(wit, wit_end);
100  ++now_loc;
101  if (Period4WalkerDump && now_loc % Period4WalkerDump == 0)
102  wClones[ip]->saveEnsemble(wit, wit_end);
103  // if(storeConfigs && (now_loc%storeConfigs == 0))
104  // ForwardWalkingHistory.storeConfigsForForwardWalking(*wClones[ip]);
105  }
106  Movers[ip]->stopBlock(false);
107  } //end-of-parallel for
108  //Estimators->accumulateCollectables(wClones,nSteps);
109  CurrentStep += nSteps;
111 #if !defined(REMOVE_TRACEMANAGER)
112  Traces->write_buffers(traceClones, block);
113 #endif
114  wlog_manager_->writeBuffers();
115  recordBlock(block);
116  vmc_loop.stop();
117 
118  bool stop_requested = false;
119  // Rank 0 decides whether the time limit was reached
120  if (!myComm->rank())
121  stop_requested = runtimeControl.checkStop(vmc_loop);
122  myComm->bcast(stop_requested);
123  if (stop_requested)
124  {
125  if (!myComm->rank())
126  app_log() << runtimeControl.generateStopMessage("VMC", block);
127  run_time_manager.markStop();
128  break;
129  }
130  } //block
132  for (int ip = 0; ip < NumThreads; ++ip)
133  Movers[ip]->stopRun2();
134 #if !defined(REMOVE_TRACEMANAGER)
135  Traces->stopRun();
136 #endif
137  wlog_manager_->stopRun();
138  //copy back the random states
139  for (int ip = 0; ip < NumThreads; ++ip)
140  rngs_[ip] = Rng[ip]->makeClone();
141  ///write samples to a file
142  bool wrotesamples = DumpConfig;
143  if (DumpConfig)
144  {
146  if (wrotesamples)
147  app_log() << " samples are written to the config.h5" << std::endl;
148  }
149  //finalize a qmc section
150  return finalize(nBlocks, !wrotesamples);
151 }
152 
154 {
155  ////only VMC can overwrite this
156  if (nTargetPopulation > 0)
158  makeClones(W, Psi, H);
160  app_log() << " Initial partition of walkers ";
161  copy(wPerRank.begin(), wPerRank.end(), std::ostream_iterator<int>(app_log(), " "));
162  app_log() << std::endl;
163 
164  bool movers_created = false;
165  bool spinors = false;
166  if (Movers.empty())
167  {
168  movers_created = true;
169  Movers.resize(NumThreads, nullptr);
170  estimatorClones.resize(NumThreads, nullptr);
171  traceClones.resize(NumThreads, nullptr);
172  wlog_collectors.resize(NumThreads);
173  Rng.resize(NumThreads);
174 
175  // hdf_archive::hdf_archive() is not thread-safe
176  for (int ip = 0; ip < NumThreads; ++ip)
178 
179 #pragma omp parallel for
180  for (int ip = 0; ip < NumThreads; ++ip)
181  {
182  std::ostringstream os;
183  estimatorClones[ip]->resetTargetParticleSet(*wClones[ip]);
184  estimatorClones[ip]->setCollectionMode(false);
185 #if !defined(REMOVE_TRACEMANAGER)
186  traceClones[ip] = Traces->makeClone();
187 #endif
188  wlog_collectors[ip] = wlog_manager_->makeCollector();
189  Rng[ip] = rngs_[ip]->makeClone();
190  hClones[ip]->setRandomGenerator(Rng[ip].get());
191  if (W.isSpinor())
192  {
193  spinors = true;
195  {
196  Movers[ip] = new SOVMCUpdatePbyP(*wClones[ip], *psiClones[ip], *hClones[ip], *Rng[ip]);
197  }
198  else
199  {
200  Movers[ip] = new SOVMCUpdateAll(*wClones[ip], *psiClones[ip], *hClones[ip], *Rng[ip]);
201  }
202  }
203  else
204  {
206  {
207  Movers[ip] = new VMCUpdatePbyP(*wClones[ip], *psiClones[ip], *hClones[ip], *Rng[ip]);
208  }
209  else
210  {
211  Movers[ip] = new VMCUpdateAll(*wClones[ip], *psiClones[ip], *hClones[ip], *Rng[ip]);
212  }
213  }
214  Movers[ip]->nSubSteps = nSubSteps;
215  if (ip == 0)
216  app_log() << os.str() << std::endl;
217  }
218  }
219 #if !defined(REMOVE_TRACEMANAGER)
220  else
221  {
222 #pragma omp parallel for
223  for (int ip = 0; ip < NumThreads; ++ip)
224  traceClones[ip]->transfer_state_from(*Traces);
225  }
226 #endif
228  {
229  app_log() << " Using Particle by Particle moves" << std::endl;
230  }
231  else
232  {
233  app_log() << " Using All Particle moves" << std::endl;
234  }
235 
236  if (UseDrift == "yes")
237  {
238  app_log() << " Walker moves with drift" << std::endl;
239  for (int i = 0; i < Movers.size(); i++)
240  Movers[i]->UseDrift = true;
241  }
242  else
243  {
244  app_log() << " Walker moves without drift" << std::endl;
245  for (int i = 0; i < Movers.size(); i++)
246  Movers[i]->UseDrift = false;
247  }
248 
249  if (spinors)
250  {
251  app_log() << " Spins treated as dynamic variable with SpinMass: " << SpinMass << std::endl;
252  for (int i = 0; i < Movers.size(); i++)
253  Movers[i]->setSpinMass(SpinMass);
254  }
255 
256  app_log() << " Total Sample Size =" << nTargetSamples << std::endl;
257  app_log() << " Walker distribution on root = ";
258  copy(wPerRank.begin(), wPerRank.end(), std::ostream_iterator<int>(app_log(), " "));
259  app_log() << std::endl;
260  //app_log() << " Sample Size per node=" << samples_this_node << std::endl;
261  //for (int ip=0; ip<NumThreads; ++ip)
262  // app_log() << " Sample size for thread " <<ip<<" = " << samples_th[ip] << std::endl;
263  app_log().flush();
264 #pragma omp parallel for
265  for (int ip = 0; ip < NumThreads; ++ip)
266  {
267  //int ip=omp_get_thread_num();
268  Movers[ip]->put(qmcNode);
269  //Movers[ip]->resetRun(branchEngine.get(), estimatorClones[ip], traceClones[ip], DriftModifier);
270  Movers[ip]->resetRun2(branchEngine.get(), estimatorClones[ip], traceClones[ip], wlog_collectors[ip].get(), DriftModifier);
272  Movers[ip]->initWalkersForPbyP(W.begin() + wPerRank[ip], W.begin() + wPerRank[ip + 1]);
273  else
274  Movers[ip]->initWalkers(W.begin() + wPerRank[ip], W.begin() + wPerRank[ip + 1]);
275  // if (UseDrift != "rn")
276  // {
277  for (int prestep = 0; prestep < nWarmupSteps; ++prestep)
278  Movers[ip]->advanceWalkers(W.begin() + wPerRank[ip], W.begin() + wPerRank[ip + 1], false);
279  // }
280  }
281 
282  if (movers_created)
283  {
284  size_t before = qmc_common.memory_allocated;
285  app_log() << " Anonymous Buffer size per walker : " << W[0]->DataSet.byteSize() << " Bytes." << std::endl;
286  qmc_common.memory_allocated += W.getActiveWalkers() * W[0]->DataSet.byteSize();
287  qmc_common.print_memory_change("VMC::resetRun", before);
288  }
289 
290  for (int ip = 0; ip < NumThreads; ++ip)
291  wClones[ip]->clearEnsemble();
292  if (nSamplesPerThread)
293  for (int ip = 0; ip < NumThreads; ++ip)
294  wClones[ip]->setNumSamples(nSamplesPerThread);
295  nWarmupSteps = 0;
296 }
297 
298 bool VMC::put(xmlNodePtr q)
299 {
300  //grep minimumTargetWalker
301  int target_min = -1;
302  ParameterSet p;
303  p.add(target_min, "minimumtargetwalkers"); //p.add(target_min,"minimumTargetWalkers");
304  p.add(target_min, "minimumsamples"); //p.add(target_min,"minimumSamples");
305  p.put(q);
306 
307  app_log() << "\n<vmc function=\"put\">"
308  << "\n qmc_counter=" << qmc_common.qmc_counter << " my_counter=" << MyCounter << std::endl;
309 
310 
312  {
313  nSteps = prevSteps;
315  }
316  else
317  {
318  int nw = W.getActiveWalkers();
319  //compute samples and overwrite steps for the given samples
320  int Nthreads = omp_get_max_threads();
321  int Nprocs = myComm->size();
322 
323 
324  //target samples set by samples or samplesperthread/dmcwalkersperthread
325  nTargetPopulation = std::max(nTargetPopulation, nSamplesPerThread * Nprocs * Nthreads);
326  nTargetSamples = static_cast<int>(std::ceil(nTargetPopulation));
327 
328  if (nTargetSamples)
329  {
330  int nwtot = nw * Nprocs; //total number of walkers used by this qmcsection
331  nTargetSamples = std::max(nwtot, nTargetSamples);
332  if (target_min > 0)
333  {
334  nTargetSamples = std::max(nTargetSamples, target_min);
335  nTargetPopulation = std::max(nTargetPopulation, static_cast<RealType>(target_min));
336  }
337  nTargetSamples = ((nTargetSamples + nwtot - 1) / nwtot) *
338  nwtot; // nTargetSamples are always multiples of total number of walkers
339  nSamplesPerThread = nTargetSamples / Nprocs / Nthreads;
340  int ns_target = nTargetSamples * nStepsBetweenSamples; //total samples to generate
341  int ns_per_step = Nprocs * nw; //total samples per step
342  nSteps = std::max(nSteps, (ns_target / ns_per_step + nBlocks - 1) / nBlocks);
344  }
345  else
346  {
347  Period4WalkerDump = nStepsBetweenSamples = (nBlocks + 1) * nSteps; //some positive number, not used
348  nSamplesPerThread = 0;
349  }
350  }
351  prevSteps = nSteps;
353 
354  app_log() << " time step = " << Tau << std::endl;
355  app_log() << " blocks = " << nBlocks << std::endl;
356  app_log() << " steps = " << nSteps << std::endl;
357  app_log() << " substeps = " << nSubSteps << std::endl;
358  app_log() << " current = " << CurrentStep << std::endl;
359  app_log() << " target samples = " << nTargetPopulation << std::endl;
360  app_log() << " walkers/mpi = " << W.getActiveWalkers() << std::endl << std::endl;
361  app_log() << " stepsbetweensamples = " << nStepsBetweenSamples << std::endl;
362 
363  m_param.get(app_log());
364 
365  if (DumpConfig)
366  {
367  app_log() << " DumpConfig==true Configurations are dumped to config.h5 with a period of " << Period4CheckPoint
368  << " blocks" << std::endl;
369  }
370  else
371  {
372  app_log() << " DumpConfig==false Nothing (configurations, state) will be saved." << std::endl;
373  }
374 
375  if (Period4WalkerDump > 0)
376  app_log() << " Walker Samples are dumped every " << Period4WalkerDump << " steps." << std::endl;
377 
378  app_log() << "</vmc>" << std::endl;
379  app_log().flush();
380 
381  return true;
382 }
383 } // namespace qmcplusplus
bool run() override
Definition: VMC.cpp:60
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
QTBase::RealType RealType
Definition: Configuration.h:58
size_t getActiveWalkers() const
return the number of active walkers
int prevSteps
Definition: VMC.h:40
void recordBlock(int block) override
record the state of the block
Definition: QMCDriver.cpp:307
Implements the Spin VMC algorithm using particle-by-particle move.
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
RealType nSamplesPerThread
samples per thread
Definition: QMCDriver.h:293
xmlNodePtr qmcNode
pointer to qmc node in xml file
Definition: QMCDriver.h:310
class ProjectData
Definition: ProjectData.h:36
int prevStepsBetweenSamples
Definition: VMC.h:41
RunTimeManager< ChronoClock > run_time_manager
Collection of Local Energy Operators.
IndexType CurrentStep
current step
Definition: QMCDriver.h:263
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
RealType SpinMass
spin mass for spinor calcs
Definition: QMCDriver.h:353
int size() const
return the number of tasks
Definition: Communicate.h:118
UPtrVector< RandomBase< QMCTraits::FullPrecRealType > > & rngs_
Definition: VMC.h:46
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
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
std::unique_ptr< HDFWalkerOutput > wOut
record engine for walkers
Definition: QMCDriver.h:332
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...
VMC(const ProjectData &project_data_, MCWalkerConfiguration &w, TrialWaveFunction &psi, QMCHamiltonian &h, UPtrVector< RandomBase< QMCTraits::FullPrecRealType >> &rngs, Communicate *comm, bool enable_profiling)
Constructor.
Definition: VMC.cpp:40
A collection of functions for dividing fairly.
class to handle a set of parameters
Definition: ParameterSet.h:27
MakeReturn< UnaryNode< FnCeil, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t ceil(const Vector< T1, C1 > &l)
omp_int_t omp_get_max_threads()
Definition: OpenMP.h:26
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
bool get(std::ostream &os) const override
write to a std::ostream
Definition: ParameterSet.h:35
std::unique_ptr< BranchEngineType > branchEngine
branch engine
Definition: QMCDriver.h:218
Implements the VMC algorithm using particle-by-particle move.
Definition: VMCUpdateAll.h:24
std::vector< EstimatorManagerBase * > estimatorClones
estimator managers
Definition: CloneManager.h:75
Implements the VMC algorithm using particle-by-particle move.
Definition: VMCUpdatePbyP.h:25
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
void makeClones(MCWalkerConfiguration &w, TrialWaveFunction &psi, QMCHamiltonian &ham)
int qmc_counter
init for <qmc> section
Definition: qmc_common.h:31
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 bool dumpEnsemble(std::vector< MCWalkerConfiguration *> &others, HDFWalkerOutput &out, int np, int nBlock)
dump Samples to a file
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()
check the run-time environments
Definition: VMC.cpp:153
Implements the VMC algorithm using particle-by-particle move, including spin-moves ...
Class for determining elapsed run time enabling simulations to adjust to time limits.
Class to represent a many-body trial wave function.
IndexType nTargetSamples
the number of saved samples
Definition: QMCDriver.h:289
EstimatorManagerBase * Estimators
Observables manager.
Definition: QMCDriver.h:192
int Period4CheckPoint
period of dumping walker configurations and everything else for restart
Definition: QMCDriver.h:242
RealType nTargetPopulation
target population
Definition: QMCDriver.h:295
void stopBlock(RealType accept, bool collectall=true)
stop a block
TrialWaveFunction & Psi
trial function
Definition: QMCDriver.h:326
size_t memory_allocated
size of memory allocated in byte per MPI
Definition: qmc_common.h:29
RealType Tau
timestep
Definition: QMCDriver.h:299
void print_memory_change(const std::string &who, size_t before)
print memory increase
Definition: qmc_common.cpp:93
void bcast(T &)
IndexType nStepsBetweenSamples
alternate method of setting QMC run parameters
Definition: QMCDriver.h:291
IndexType nBlocks
maximum number of blocks
Definition: QMCDriver.h:266
bool put(xmlNodePtr cur) override
Definition: VMC.cpp:298
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
RefVector< WalkerLogCollector > getWalkerLogCollectorRefs()
QMCState qmc_common
a unique QMCState during a run
Definition: qmc_common.cpp:111
IndexType nWarmupSteps
number of warmup steps
Definition: QMCDriver.h:275
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
int MyCounter
the number of times this QMCDriver is executed
Definition: QMCDriver.h:235
target total number of walkers per mpi group
std::string UseDrift
option to enable/disable drift equation or RN for VMC
Definition: VMC.h:44
iterator begin()
return the first iterator