QMCPACK
CSVMC.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: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
8 // Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
9 // Jaron T. Krogel, krogeljt@ornl.gov, Oak Ridge National Laboratory
10 // Raymond Clay III, j.k.rofling@gmail.com, Lawrence Livermore National Laboratory
11 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
12 //
13 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
14 //////////////////////////////////////////////////////////////////////////////////////
15 
16 
17 #include "CSVMC.h"
22 #include "RandomNumberControl.h"
23 #include "Concurrency/OpenMP.h"
24 #include "Message/CommOperators.h"
25 #include "Utilities/FairDivide.h"
26 #include "Utilities/qmc_common.h"
27 //#define ENABLE_VMC_OMP_MASTER
28 #if !defined(REMOVE_TRACEMANAGER)
30 #else
31 using TraceManager = int;
32 #endif
33 
34 namespace qmcplusplus
35 {
36 /// Constructor.
37 CSVMC::CSVMC(const ProjectData& project_data,
39  TrialWaveFunction& psi,
40  QMCHamiltonian& h,
42  : QMCDriver(project_data, w, psi, h, comm, "CSVMC"), UseDrift("yes"), multiEstimator(0), Mover(0)
43 {
44  RootName = "csvmc";
45  m_param.add(UseDrift, "useDrift");
46  m_param.add(UseDrift, "usedrift");
47  m_param.add(UseDrift, "use_drift");
48  equilBlocks = -1;
49  m_param.add(equilBlocks, "equilBlocks");
51 }
52 
53 /** allocate internal data here before run() is called
54  * @author SIMONE
55  *
56  * See QMCDriver::process
57  */
58 bool CSVMC::put(xmlNodePtr q)
59 {
60  int target_min = -1;
61  ParameterSet p;
62  p.add(target_min, "minimumtargetwalkers");
63  p.add(target_min, "minimumsamples");
64  p.put(q);
65 
66  app_log() << "\n<vmc function=\"put\">"
67  << "\n qmc_counter=" << qmc_common.qmc_counter << " my_counter=" << MyCounter << std::endl;
69  {
70  nSteps = prevSteps;
72  }
73  else
74  {
75  int nw = W.getActiveWalkers();
76  //compute samples and overwrite steps for the given samples
77  int Nthreads = omp_get_max_threads();
78  int Nprocs = myComm->size();
79  //target samples set by samples or samplesperthread/dmcwalkersperthread
80  nTargetPopulation = std::max(nTargetPopulation, nSamplesPerThread * Nprocs * Nthreads);
81  nTargetSamples = static_cast<int>(std::ceil(nTargetPopulation));
82 
83  if (nTargetSamples)
84  {
85  int nwtot = nw * Nprocs; //total number of walkers used by this qmcsection
86  nTargetSamples = std::max(nwtot, nTargetSamples);
87  if (target_min > 0)
88  {
89  nTargetSamples = std::max(nTargetSamples, target_min);
90  nTargetPopulation = std::max(nTargetPopulation, static_cast<RealType>(target_min));
91  }
92  nTargetSamples = ((nTargetSamples + nwtot - 1) / nwtot) *
93  nwtot; // nTargetSamples are always multiples of total number of walkers
94  nSamplesPerThread = nTargetSamples / Nprocs / Nthreads;
95  int ns_target = nTargetSamples * nStepsBetweenSamples; //total samples to generate
96  int ns_per_step = Nprocs * nw; //total samples per step
97  nSteps = std::max(nSteps, (ns_target / ns_per_step + nBlocks - 1) / nBlocks);
99  }
100  else
101  {
102  Period4WalkerDump = nStepsBetweenSamples = (nBlocks + 1) * nSteps; //some positive number, not used
103  nSamplesPerThread = 0;
104  }
105  }
106  prevSteps = nSteps;
108 
109  app_log() << " time step = " << Tau << std::endl;
110  app_log() << " blocks = " << nBlocks << std::endl;
111  app_log() << " steps = " << nSteps << std::endl;
112  app_log() << " substeps = " << nSubSteps << std::endl;
113  app_log() << " current = " << CurrentStep << std::endl;
114  app_log() << " target samples = " << nTargetPopulation << std::endl;
115  app_log() << " walkers/mpi = " << W.getActiveWalkers() << std::endl << std::endl;
116  app_log() << " stepsbetweensamples = " << nStepsBetweenSamples << std::endl;
117 
118  m_param.get(app_log());
119 
120  if (DumpConfig)
121  {
122  app_log() << " DumpConfig==true Configurations are dumped to config.h5 with a period of " << Period4CheckPoint
123  << " blocks" << std::endl;
124  }
125  else
126  {
127  app_log() << " DumpConfig==false Nothing (configurations, state) will be saved." << std::endl;
128  }
129 
130  if (Period4WalkerDump > 0)
131  app_log() << " Walker Samples are dumped every " << Period4WalkerDump << " steps." << std::endl;
132 
133  app_log() << "</vmc>" << std::endl;
134  app_log().flush();
135 
136  return true;
137 }
138 
139 /** Run the CSVMC algorithm.
140  *
141  * Similar to VMC::run
142  */
144 {
145  resetRun();
146  //start the main estimator
148  for (int ip = 0; ip < NumThreads; ++ip)
149  CSMovers[ip]->startRun(nBlocks, false);
150 
151 #if !defined(REMOVE_TRACEMANAGER)
152  Traces->startRun(nBlocks, traceClones);
153 #endif
154  const bool has_collectables = W.Collectables.size();
155  for (int block = 0; block < nBlocks; ++block)
156  {
157 #pragma omp parallel
158  {
159  int ip = omp_get_thread_num();
161  //assign the iterators and resuse them
162  MCWalkerConfiguration::iterator wit(W.begin() + wPerRank[ip]), wit_end(W.begin() + wPerRank[ip + 1]);
163  CSMovers[ip]->startBlock(nSteps);
164  int now_loc = CurrentStep;
165  RealType cnorm = 1.0 / static_cast<RealType>(wPerRank[ip + 1] - wPerRank[ip]);
166  for (int step = 0; step < nSteps; ++step)
167  {
168  CSMovers[ip]->set_step(now_loc);
169  //collectables are reset, it is accumulated while advancing walkers
170  wClones[ip]->resetCollectables();
171  CSMovers[ip]->advanceWalkers(wit, wit_end, false);
172  if (has_collectables)
173  wClones[ip]->Collectables *= cnorm;
174  CSMovers[ip]->accumulate(wit, wit_end);
175  ++now_loc;
176  if (Period4WalkerDump && now_loc % Period4WalkerDump == 0)
177  wClones[ip]->saveEnsemble(wit, wit_end);
178  }
179  CSMovers[ip]->stopBlock(false);
180 
181  } //end-of-parallel for
182  CurrentStep += nSteps;
184 #if !defined(REMOVE_TRACEMANAGER)
185  Traces->write_buffers(traceClones, block);
186 #endif
187  recordBlock(block);
188  } //block
190  for (int ip = 0; ip < NumThreads; ++ip)
191  CSMovers[ip]->stopRun2();
192 #if !defined(REMOVE_TRACEMANAGER)
193  Traces->stopRun();
194 #endif
195  //copy back the random states
196  for (int ip = 0; ip < NumThreads; ++ip)
197  RandomNumberControl::Children[ip] = Rng[ip]->makeClone();
198  ///write samples to a file
199  bool wrotesamples = DumpConfig;
200  if (DumpConfig)
201  {
203  if (wrotesamples)
204  app_log() << " samples are written to the config.h5" << std::endl;
205  }
206  //finalize a qmc section
207  return finalize(nBlocks, !wrotesamples);
208 }
209 
211 {
212  H1[0]->setPrimary(true);
213  IndexType nPsi = Psi1.size();
214  for (int ipsi = 1; ipsi < nPsi; ipsi++)
215  H1[ipsi]->setPrimary(false);
216 
217 
218  makeClones(W, Psi1, H1);
220 
221  if (NumThreads > 1)
222  APP_ABORT("OpenMP Parallelization for CSVMC not working at the moment");
223 
224  app_log() << " Initial partition of walkers ";
225  copy(wPerRank.begin(), wPerRank.end(), std::ostream_iterator<int>(app_log(), " "));
226  app_log() << std::endl;
227 
228 
229  if (Movers.empty())
230  {
231  CSMovers.resize(NumThreads);
232  estimatorClones.resize(NumThreads, nullptr);
233  traceClones.resize(NumThreads, nullptr);
234  Rng.resize(NumThreads);
235 
236  // hdf_archive::hdf_archive() is not thread-safe
237  for (int ip = 0; ip < NumThreads; ++ip)
239 
240 #pragma omp parallel for
241  for (int ip = 0; ip < NumThreads; ++ip)
242  {
243  std::ostringstream os;
244  estimatorClones[ip]->resetTargetParticleSet(*wClones[ip]);
245  estimatorClones[ip]->setCollectionMode(false);
246 #if !defined(REMOVE_TRACEMANAGER)
247  traceClones[ip] = Traces->makeClone();
248 #endif
249  Rng[ip] = RandomNumberControl::Children[ip]->makeClone();
251  {
252  if (UseDrift == "yes")
253  {
254  os << " Using particle-by-particle update with drift " << std::endl;
255  CSMovers[ip] = std::make_unique<CSVMCUpdatePbyPWithDriftFast>(*wClones[ip], PsiPoolClones[ip], HPoolClones[ip], *Rng[ip]);
256  }
257  else
258  {
259  os << " Using particle-by-particle update with no drift" << std::endl;
260  CSMovers[ip] = std::make_unique<CSVMCUpdatePbyP>(*wClones[ip], PsiPoolClones[ip], HPoolClones[ip], *Rng[ip]);
261  }
262  }
263  else
264  {
265  if (UseDrift == "yes")
266  {
267  os << " Using walker-by-walker update with Drift " << std::endl;
268  CSMovers[ip] = std::make_unique<CSVMCUpdateAllWithDrift>(*wClones[ip], PsiPoolClones[ip], HPoolClones[ip], *Rng[ip]);
269  }
270  else
271  {
272  os << " Using walker-by-walker update " << std::endl;
273  CSMovers[ip] = std::make_unique<CSVMCUpdateAll>(*wClones[ip], PsiPoolClones[ip], HPoolClones[ip], *Rng[ip]);
274  }
275  }
276  if (ip == 0)
277  app_log() << os.str() << std::endl;
278 
279  CSMovers[ip]->put(qmcNode);
280  CSMovers[ip]->resetRun(branchEngine.get(), estimatorClones[ip], traceClones[ip], DriftModifier);
281  }
282  }
283 #if !defined(REMOVE_TRACEMANAGER)
284  else
285  {
286 #pragma omp parallel for
287  for (int ip = 0; ip < NumThreads; ++ip)
288  {
289  traceClones[ip]->transfer_state_from(*Traces);
290  }
291  }
292 #endif
293 
294  app_log() << " Total Sample Size =" << nTargetSamples << std::endl;
295  app_log() << " Walker distribution on root = ";
296  copy(wPerRank.begin(), wPerRank.end(), std::ostream_iterator<int>(app_log(), " "));
297  app_log() << std::endl;
298  app_log().flush();
299 
300 #pragma omp parallel for
301  for (int ip = 0; ip < NumThreads; ++ip)
302  {
303  //int ip=omp_get_thread_num();
304  CSMovers[ip]->put(qmcNode);
305  CSMovers[ip]->resetRun(branchEngine.get(), estimatorClones[ip], traceClones[ip], DriftModifier);
307  CSMovers[ip]->initCSWalkersForPbyP(W.begin() + wPerRank[ip], W.begin() + wPerRank[ip + 1], nWarmupSteps > 0);
308  else
309  CSMovers[ip]->initCSWalkers(W.begin() + wPerRank[ip], W.begin() + wPerRank[ip + 1], nWarmupSteps > 0);
310 
311  for (int prestep = 0; prestep < nWarmupSteps; ++prestep)
312  {
313  CSMovers[ip]->advanceWalkers(W.begin() + wPerRank[ip], W.begin() + wPerRank[ip + 1], true);
314  if (prestep == nWarmupSteps - 1)
315  CSMovers[ip]->updateNorms();
316  }
317  }
318 
319  for (int ip = 0; ip < NumThreads; ++ip)
320  wClones[ip]->clearEnsemble();
321  if (nSamplesPerThread)
322  for (int ip = 0; ip < NumThreads; ++ip)
323  wClones[ip]->setNumSamples(nSamplesPerThread);
324  nWarmupSteps = 0;
325 }
326 
327 } // namespace qmcplusplus
bool run() override
Run the CSVMC algorithm.
Definition: CSVMC.cpp:143
size_type size() const
return the size of the data
Definition: PooledData.h:48
A set of walkers that are to be advanced by Metropolis Monte Carlo.
int equilBlocks
blocks over which normalization factors are accumulated
Definition: CSVMC.h:53
std::vector< int > wPerRank
Walkers per MPI rank.
Definition: CloneManager.h:91
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
QTBase::RealType RealType
Definition: Configuration.h:58
std::vector< TrialWaveFunction * > Psi1
a list of TrialWaveFunctions for multiple method
Definition: QMCDriver.h:335
size_t getActiveWalkers() const
return the number of active walkers
static std::vector< std::vector< TrialWaveFunction * > > PsiPoolClones
Definition: CloneManager.h:85
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
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: CSVMC.h:51
Collection of Local Energy Operators.
IndexType CurrentStep
current step
Definition: QMCDriver.h:263
UPtrVector< CSUpdateBase > CSMovers
Definition: CloneManager.h:88
std::vector< QMCUpdateBase * > Movers
update engines
Definition: CloneManager.h:73
Definition of CSVMCUpdateAll.
abstract base class for QMC engines
Definition: QMCDriver.h:71
int size() const
return the number of tasks
Definition: Communicate.h:118
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
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.
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
std::vector< EstimatorManagerBase * > estimatorClones
estimator managers
Definition: CloneManager.h:75
const IndexType NumThreads
number of threads
Definition: CloneManager.h:54
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)
int qmc_counter
init for <qmc> section
Definition: qmc_common.h:31
MCWalkerConfiguration & W
walker ensemble
Definition: QMCDriver.h:323
Definition of CSVMC.
static UPtrVector< RandomBase< FullPrecRealType > > Children
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
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>
Class to represent a many-body trial wave function.
std::vector< QMCHamiltonian * > H1
a list of QMCHamiltonians for multiple method
Definition: QMCDriver.h:338
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
CSVMC(const ProjectData &project_data, MCWalkerConfiguration &w, TrialWaveFunction &psi, QMCHamiltonian &h, Communicate *comm)
Constructor.
Definition: CSVMC.cpp:37
RealType Tau
timestep
Definition: QMCDriver.h:299
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
allocate internal data here before run() is called
Definition: CSVMC.cpp:58
static std::vector< std::vector< QMCHamiltonian * > > HPoolClones
Definition: CloneManager.h:87
std::vector< TraceManager * > traceClones
trace managers
Definition: CloneManager.h:77
int Period4WalkerDump
period of recording walker configurations
Definition: QMCDriver.h:255
int Period4CheckProperties
period of dumping walker positions and IDs for Forward Walking
Definition: QMCDriver.h:249
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
void start(int blocks, bool record=true)
start a run
int MyCounter
the number of times this QMCDriver is executed
Definition: QMCDriver.h:235
std::string UseDrift
Definition: CSVMC.h:49
iterator begin()
return the first iterator