QMCPACK
QMCMain.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 // Raymond Clay III, j.k.rofling@gmail.com, Lawrence Livermore National Laboratory
11 // Cynthia Gu, zg1@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 /**@file QMCMain.cpp
21  * @brief Implments QMCMain operators.
22  */
23 #include "QMCMain.h"
24 #include "DeviceManager.h"
31 #include "Utilities/Timer.h"
32 #include "Utilities/TimerManager.h"
34 #include "Particle/HDFWalkerIO.h"
37 #include "QMCDrivers/QMCDriver.h"
39 #include "Message/Communicate.h"
41 #include "Concurrency/OpenMP.h"
43 #include <queue>
44 #include <cstring>
45 #include "hdf/HDFVersion.h"
46 #include "OhmmsData/AttributeSet.h"
47 #include "Utilities/qmc_common.h"
48 #include "MemoryUsage.h"
49 #ifdef BUILD_AFQMC
50 #include "AFQMC/AFQMCFactory.h"
51 #endif
52 
53 #define STR_VAL(arg) #arg
54 #define GET_MACRO_VAL(arg) STR_VAL(arg)
55 
56 namespace qmcplusplus
57 {
59  : MPIObjectBase(c),
60  QMCAppBase(),
61  particle_set_pool_(std::make_unique<ParticleSetPool>(myComm)),
62  psi_pool_(std::make_unique<WaveFunctionPool>(my_project_.getRuntimeOptions(), *particle_set_pool_, myComm)),
63  ham_pool_(std::make_unique<HamiltonianPool>(*particle_set_pool_, *psi_pool_, myComm)),
64  qmc_system_(nullptr),
65  first_qmc_(true),
66  walker_logs_xml_(NULL)
67 #if !defined(REMOVE_TRACEMANAGER)
68  ,
69  traces_xml_(NULL)
70 #endif
71 {
73  // assign accelerators within a node
74  DeviceManager::initializeGlobalDeviceManager(node_comm.rank(), node_comm.size());
75 
76  app_summary() << "================================================================\n"
77  << " QMCPACK " << QMCPACK_VERSION_MAJOR << "." << QMCPACK_VERSION_MINOR << "."
78  << QMCPACK_VERSION_PATCH << "\n"
79  << "\n"
80  << " (c) Copyright 2003-2023 QMCPACK developers\n"
81  << "\n"
82  << " Please cite:\n"
83  << " J. Kim et al. J. Phys. Cond. Mat. 30 195901 (2018)\n"
84  << " https://doi.org/10.1088/1361-648X/aab9c3\n"
85  << " and\n"
86  << " P. Kent et al. J. Chem. Phys. 152 174105 (2020)\n"
87  << " https://doi.org/10.1063/5.0004860\n";
89  app_summary() << "================================================================\n";
91  // clang-format off
92  app_summary()
93 #if !defined(HAVE_MPI)
94  << "\n Built without MPI. Running in serial or with OMP threads." << std::endl
95 #endif
96  << "\n Total number of MPI ranks = " << OHMMS::Controller->size()
97  << "\n Number of MPI groups = " << myComm->getNumGroups()
98  << "\n MPI group ID = " << myComm->getGroupID()
99  << "\n Number of ranks in group = " << myComm->size()
100  << "\n MPI ranks per node = " << node_comm.size()
101 #if defined(ENABLE_OFFLOAD) || defined(ENABLE_CUDA) || defined(ENABLE_HIP) || defined(ENABLE_SYCL)
102  << "\n Accelerators per node = " << DeviceManager::getGlobal().getNumDevices()
103 #endif
104  << std::endl;
105  // clang-format on
106 
107 #pragma omp parallel
108  {
109  const int L1_tid = omp_get_thread_num();
110  if (L1_tid == 0)
111  app_summary() << " OMP 1st level threads = " << omp_get_num_threads() << std::endl;
112 #pragma omp parallel
113  {
114  const int L2_tid = omp_get_thread_num();
115  const int L2_num_threads = omp_get_num_threads();
116  if (L1_tid == 0 && L2_tid == 0)
117  {
118  if (L2_num_threads == 1)
119  app_summary() << " OMP nested threading disabled or only 1 thread on the 2nd level" << std::endl;
120  else
121  app_summary() << " OMP 2nd level threads = " << L2_num_threads << std::endl;
122  }
123  }
124  }
125  app_summary() << "\n Precision used in this calculation, see definitions in the manual:"
126  << "\n Base precision = " << GET_MACRO_VAL(OHMMS_PRECISION)
127  << "\n Full precision = " << GET_MACRO_VAL(OHMMS_PRECISION_FULL) << std::endl;
128 
129  // Record features configured in cmake or selected via command-line arguments to the printout
130  app_summary() << std::endl;
131 #if !defined(ENABLE_OFFLOAD) && !defined(ENABLE_CUDA) && !defined(ENABLE_HIP) && !defined(ENABLE_SYCL)
132  app_summary() << " CPU only build" << std::endl;
133 #else // GPU case
134 #if defined(ENABLE_OFFLOAD)
135  app_summary() << " OpenMP target offload to accelerators build option is enabled" << std::endl;
136 #endif
137 #if defined(ENABLE_HIP)
138  app_summary() << " HIP acceleration with direct HIP source code build option is enabled" << std::endl;
139 #endif
140 
141 #if defined(QMC_CUDA2HIP) && defined(ENABLE_CUDA)
142  app_summary() << " HIP acceleration with CUDA source code build option is enabled" << std::endl;
143 #elif defined(ENABLE_CUDA)
144  app_summary() << " CUDA acceleration build option is enabled" << std::endl;
145 #elif defined(ENABLE_SYCL)
146  app_summary() << " SYCL acceleration build option is enabled" << std::endl;
147 #endif
148 #endif // GPU case end
149 
150  if (my_project_.isComplex())
151  app_summary() << " Complex build. QMC_COMPLEX=ON" << std::endl;
152  else
153  app_summary() << " Real build. QMC_COMPLEX=OFF" << std::endl;
154 
155 #ifdef ENABLE_TIMERS
156  app_summary() << " Timer build option is enabled. Current timer level is "
157  << getGlobalTimerManager().get_timer_threshold_string() << std::endl;
158 #endif
159  app_summary() << std::endl;
160 
161  print_mem("when QMCPACK starts", app_summary());
162  app_summary() << std::endl;
163 }
164 
166 {
167  // free last_driver before clearing P,Psi,H clones
168  last_driver_.reset();
170 }
171 
173 {
174  Timer t0;
175  if (xml_doc_stack_.empty())
176  {
177  ERRORMSG("No valid input file exists! Aborting QMCMain::execute")
178  return false;
179  }
180 
181  std::string simulationType = "realspaceQMC";
182  { // mmorales: is this necessary??? Don't want to leave xmlNodes lying around unused
183  xmlNodePtr cur = xml_doc_stack_.top()->getRoot();
184  OhmmsAttributeSet simType;
185  simType.add(simulationType, "type");
186  simType.add(simulationType, "name");
187  simType.add(simulationType, "method");
188  simType.put(cur);
189  }
190 
191 #ifdef BUILD_AFQMC
192  if (simulationType == "afqmc")
193  {
195  app_log() << std::endl
196  << "/*************************************************\n"
197  << " ******** This is an AFQMC calculation ********\n"
198  << " *************************************************" << std::endl;
199  xmlNodePtr cur = xml_doc_stack_.top()->getRoot();
200 
201  xmlXPathContextPtr m_context = xml_doc_stack_.top()->getXPathContext();
202  //initialize the random number generator
203  xmlNodePtr rptr = my_random_control_.initialize(m_context);
204 
205  auto world = boost::mpi3::environment::get_world_instance();
206  afqmc::AFQMCFactory afqmc_fac(world);
207  if (!afqmc_fac.parse(cur))
208  {
209  app_log() << " Error in AFQMCFactory::parse() ." << std::endl;
210  return false;
211  }
212  cur = xml_doc_stack_.top()->getRoot();
213  return afqmc_fac.execute(cur);
214  }
215 #else
216  if (simulationType == "afqmc")
217  {
218  app_error() << " Executable not compiled with AFQMC. Recompile with BUILD_AFQMC set to 1." << std::endl;
219  return false;
220  }
221 #endif
222 
224  t2.start();
225 
227  t3.start();
228 
229  //validate the input file
230  bool success = validateXML();
231  if (!success)
232  myComm->barrier_and_abort("QMCMain::execute. Input document does not contain valid objects");
233 
234  //initialize all the instances of distance tables and evaluate them
235  particle_set_pool_->reset();
236  infoSummary.flush();
237  infoLog.flush();
238  app_log() << " Initialization Execution time = " << std::setprecision(4) << t0.elapsed() << " secs" << std::endl;
239  //write stuff
240  app_log() << "=========================================================\n";
241  app_log() << " Summary of QMC systems \n";
242  app_log() << "=========================================================\n";
243  particle_set_pool_->get(app_log());
244  ham_pool_->get(app_log());
246  t3.stop();
247  if (qmc_common.dryrun)
248  {
249  app_log() << " dryrun == 1 : Skipping all QMC and loop elements " << std::endl;
250  return true;
251  }
252  Timer t1;
254  for (int qa = 0; qa < qmc_action_.size(); qa++)
255  {
256  if (run_time_manager.isStopNeeded())
257  break;
258  xmlNodePtr cur = qmc_action_[qa].first;
259  std::string cname((const char*)cur->name);
260  if (cname == "qmc" || cname == "optimize")
261  {
262  executeQMCSection(cur);
263  qmc_common.qmc_counter++; // increase the counter
264  }
265  else if (cname == "loop")
266  {
268  executeLoop(cur);
270  }
271  else if (cname == "cmc")
272  {
273  executeCMCSection(cur);
274  }
275  else if (cname == "debug")
276  {
277  executeDebugSection(cur);
278  app_log() << " Debug is done. Skip the rest of the input " << std::endl;
279  break;
280  }
281  }
282  // free if m_qmcation owns the memory of xmlNodePtr before clearing
283  for (auto& qmcactionPair : qmc_action_)
284  if (!qmcactionPair.second)
285  xmlFreeNode(qmcactionPair.first);
286 
287  qmc_action_.clear();
288  t2.stop();
289  app_log() << " Total Execution time = " << std::setprecision(4) << t1.elapsed() << " secs" << std::endl;
290  if (is_manager())
291  {
292  //generate multiple files
293  xmlNodePtr mcptr = NULL;
294  if (walker_set_.size())
295  mcptr = walker_set_[0];
296  //remove input mcwalkerset but one
297  for (int i = 1; i < walker_set_.size(); i++)
298  {
299  xmlUnlinkNode(walker_set_[i]);
300  xmlFreeNode(walker_set_[i]);
301  }
302  walker_set_.clear(); //empty the container
303  std::ostringstream np_str, v_str;
304  np_str << myComm->size();
305  HDFVersion cur_version;
306  v_str << cur_version[0] << " " << cur_version[1];
307  xmlNodePtr newmcptr = xmlNewNode(NULL, (const xmlChar*)"mcwalkerset");
308  xmlNewProp(newmcptr, (const xmlChar*)"fileroot", (const xmlChar*)my_project_.currentMainRoot().c_str());
309  xmlNewProp(newmcptr, (const xmlChar*)"node", (const xmlChar*)"-1");
310  xmlNewProp(newmcptr, (const xmlChar*)"nprocs", (const xmlChar*)np_str.str().c_str());
311  xmlNewProp(newmcptr, (const xmlChar*)"version", (const xmlChar*)v_str.str().c_str());
312  xmlNewProp(newmcptr, (const xmlChar*)"collected", (const xmlChar*)"yes");
313  if (mcptr == NULL)
314  {
315  xmlAddNextSibling(last_input_node_, newmcptr);
316  }
317  else
318  {
319  xmlReplaceNode(mcptr, newmcptr);
320  xmlFreeNode(mcptr);
321  }
322  saveXml();
323  }
324  return true;
325 }
326 
327 void QMCMain::executeLoop(xmlNodePtr cur)
328 {
329  int niter = 1;
331  a.add(niter, "max");
332  a.put(cur);
333  //reset qmc_counter
335  app_log() << "Loop execution max-interations = " << niter << std::endl;
336  for (int iter = 0; iter < niter; iter++)
337  {
338  if (run_time_manager.isStopNeeded())
339  break;
340  xmlNodePtr tcur = cur->children;
341  while (tcur != NULL)
342  {
343  std::string cname((const char*)tcur->name);
344  if (cname == "qmc")
345  {
346  //prevent completed is set
347  bool success = executeQMCSection(tcur, true);
348  if (!success)
349  {
350  app_warning() << " Terminated loop execution. A sub section returns false." << std::endl;
351  return;
352  }
353  qmc_common.qmc_counter++; // increase the counter
354  }
355  tcur = tcur->next;
356  }
357  }
358  // Destroy the last driver at the end of a loop with no further reuse of a driver needed.
359  last_driver_.reset(nullptr);
360 }
361 
362 /** validate the main document and (read the walker sets !)
363  * @return false, if any of the basic objects is not properly created.
364  *
365  * Current xml schema is changing. Instead validating the input file,
366  * we use xpath to create necessary objects. The order follows
367  * - project: determine the simulation title and sequence
368  * - random: initialize random number generator
369  * - particleset: create all the particleset
370  * - wavefunction: create wavefunctions
371  * - hamiltonian: create hamiltonians
372  * Finally, if /simulation/mcwalkerset exists, read the configurations
373  * from the external files.
374  * TODO: Move this out of what should be a stateless call
375  */
377 {
378  xmlXPathContextPtr m_context = xml_doc_stack_.top()->getXPathContext();
379  OhmmsXPathObject result("//project", m_context);
381  if (result.empty())
382  {
383  app_warning() << "Project is not defined" << std::endl;
384  my_project_.reset();
385  }
386  else
387  {
388  try
389  {
390  my_project_.put(result[0]);
391  }
392  catch (const UniformCommunicateError& ue)
393  {
394  myComm->barrier_and_abort(ue.what());
395  }
396  }
397  app_summary() << std::endl;
399  app_summary() << std::endl;
400  OhmmsXPathObject ham("//hamiltonian", m_context);
401  if (ham.empty())
402  {
403  qmc_common.use_density = true;
404  }
405  else
406  {
407  for (int i = 0; i < ham.size(); ++i)
408  {
409  xmlNodePtr cur = ham[i]->children;
410  while (cur != NULL)
411  {
412  std::string aname = "0";
414  a.add(aname, "type");
415  a.put(cur);
416  if (aname == "mpc" || aname == "MPC")
417  {
418  qmc_common.use_density = true;
419  }
420  cur = cur->next;
421  }
422  }
423  }
425  {
426  app_log() << " hamiltonian has MPC. Will read density if it is found." << std::endl << std::endl;
427  }
428 
429  //initialize the random number generator
430  xmlNodePtr rptr = my_random_control_.initialize(m_context);
431  //preserve the input order
432  xmlNodePtr cur = xml_doc_stack_.top()->getRoot()->children;
433  last_input_node_ = NULL;
434  while (cur != NULL)
435  {
436  std::string cname((const char*)cur->name);
437  bool inputnode = true;
438  if (cname == "particleset")
439  {
440  particle_set_pool_->put(cur);
441  }
442  else if (cname == "wavefunction")
443  {
444  psi_pool_->put(cur);
445  }
446  else if (cname == "hamiltonian")
447  {
448  ham_pool_->put(cur);
449  }
450  else if (cname == "include")
451  {
452  //file is provided
453  const std::string include_name(getXMLAttributeValue(cur, "href"));
454  if (!include_name.empty())
455  {
456  bool success = pushDocument(include_name);
457  if (success)
458  {
459  inputnode = processPWH(xml_doc_stack_.top()->getRoot());
460  popDocument();
461  }
462  else
463  myComm->barrier_and_abort("Invalid XML document");
464  }
465  else
466  myComm->barrier_and_abort(R"(tag "include" must include an "href" attribute.)");
467  }
468  else if (cname == "qmcsystem")
469  {
470  inputnode = processPWH(cur);
471  }
472  else if (cname == "init")
473  {
475  moinit.put(cur);
476  }
477 #if !defined(REMOVE_TRACEMANAGER)
478  else if (cname == "traces")
479  {
480  traces_xml_ = cur;
481  }
482 #endif
483  else if (cname == "walkerlogs")
484  {
485  walker_logs_xml_ = cur;
486  }
487  else
488  {
489  //everything else goes to m_qmcaction
490  qmc_action_.push_back(std::pair<xmlNodePtr, bool>(cur, true));
491  inputnode = false;
492  }
493  if (inputnode)
494  last_input_node_ = cur;
495  cur = cur->next;
496  }
497 
498  if (particle_set_pool_->empty())
499  myComm->barrier_and_abort("QMCMain::validateXML. Illegal input. Missing particleset.");
500 
501  if (psi_pool_->empty())
502  myComm->barrier_and_abort("QMCMain::validateXML. Illegal input. Missing wavefunction.");
503 
504  if (ham_pool_->empty())
505  myComm->barrier_and_abort("QMCMain::validateXML. Illegal input. Missing Hamiltonian.");
506 
507  //randomize any particleset with random="yes" && random_source="ion0"
508  particle_set_pool_->randomize();
509 
510  setMCWalkers(m_context);
511 
512  return true;
513 }
514 
515 
516 /** grep basic objects and add to Pools
517  * @param cur current node
518  *
519  * Recursive search all the xml elements with particleset, wavefunction and hamiltonian
520  * tags
521  */
522 bool QMCMain::processPWH(xmlNodePtr cur)
523 {
524  //return true and will be ignored
525  if (cur == NULL)
526  return true;
527  bool inputnode = false;
528  //save the root to grep @tilematrix
529  xmlNodePtr cur_root = cur;
530  cur = cur->children;
531  while (cur != NULL)
532  {
533  std::string cname((const char*)cur->name);
534  if (cname == "simulationcell")
535  {
536  inputnode = true;
537  particle_set_pool_->readSimulationCellXML(cur);
538  }
539  else if (cname == "particleset")
540  {
541  inputnode = true;
542  particle_set_pool_->put(cur);
543  }
544  else if (cname == "wavefunction")
545  {
546  inputnode = true;
547  psi_pool_->put(cur);
548  }
549  else if (cname == "hamiltonian")
550  {
551  inputnode = true;
552  ham_pool_->put(cur);
553  }
554  else if (cname == "estimators")
555  {
556  inputnode = true;
557  try
558  {
561  "QMCMain::validateXML. Illegal Input, only one global <estimators> node is permitted");
562  estimator_manager_input_ = std::optional<EstimatorManagerInput>(std::in_place, cur);
563  }
564  catch (const UniformCommunicateError& ue)
565  {
566  myComm->barrier_and_abort(ue.what());
567  }
568  }
569  else
570  //add to m_qmcaction
571  {
572  qmc_action_.push_back(std::pair<xmlNodePtr, bool>(xmlCopyNode(cur, 1), false));
573  }
574  cur = cur->next;
575  }
576  //flush
577  app_log().flush();
578  return inputnode;
579 }
580 
581 /** prepare for a QMC run
582  * @param cur qmc element
583  * @param reuse if true, the current call is from a loop
584  * @return true, if a valid QMCDriver is set.
585  */
586 bool QMCMain::runQMC(xmlNodePtr cur, bool reuse)
587 {
588  std::unique_ptr<QMCDriverInterface> qmc_driver;
589  bool append_run = false;
590 
591  if (reuse && last_driver_)
592  qmc_driver = std::move(last_driver_);
593  else
594  {
595  QMCDriverFactory driver_factory(my_project_);
596  try
597  {
598  QMCDriverFactory::DriverAssemblyState das = driver_factory.readSection(cur);
599  qmc_driver = driver_factory.createQMCDriver(cur, das, estimator_manager_input_, *qmc_system_, *particle_set_pool_,
601  append_run = das.append_run;
602  }
603  catch (const UniformCommunicateError& ue)
604  {
605  myComm->barrier_and_abort(ue.what());
606  }
607  }
608 
609  if (qmc_driver)
610  {
612  {
613  last_branch_engine_legacy_driver_->resetRun(cur);
614  qmc_driver->setBranchEngine(std::move(last_branch_engine_legacy_driver_));
615  }
616 
617  //advance the project id
618  //if it is NOT the first qmc node and qmc/@append!='yes'
619  if (!first_qmc_ && !append_run)
621 
622  qmc_driver->setStatus(my_project_.currentMainRoot(), "", append_run);
623  // PD:
624  // Q: How does walker_set_in end up being non empty?
625  // A: Anytime that we aren't doing a restart.
626  // So put walkers is an exceptional call. This code does not tell a useful
627  // story of a QMCDriver's life.
628  qmc_driver->putWalkers(walker_set_in_);
629 #if !defined(REMOVE_TRACEMANAGER)
630  qmc_driver->putTraces(traces_xml_);
631 #endif
632  qmc_driver->putWalkerLogs(walker_logs_xml_);
633  {
634  ScopedTimer qmc_run_timer(createGlobalTimer(qmc_driver->getEngineName(), timer_level_coarse));
635  Timer process_and_run;
636  qmc_driver->process(cur);
637  infoSummary.flush();
638  infoLog.flush();
639 
640  qmc_driver->run();
641  app_log() << " " << qmc_driver->getEngineName() << " Execution time = " << std::setprecision(4)
642  << process_and_run.elapsed() << " secs" << std::endl;
643  }
644  // transfer the states of a driver before its destruction
645  last_branch_engine_legacy_driver_ = qmc_driver->getBranchEngine();
646  // save the driver in a driver loop
647  if (reuse)
648  last_driver_ = std::move(qmc_driver);
649  return true;
650  }
651  else
652  {
653  // Ye: in which case, the code hits this?
654  return false;
655  }
656 }
657 
658 
659 /** Reads walkers sets from the restart file during XML validation
660  *
661  * TODO: Move this, it is not a concern of QMCMain
662  */
663 bool QMCMain::setMCWalkers(xmlXPathContextPtr context_)
664 {
665  OhmmsXPathObject result("/simulation/mcwalkerset", context_);
666  for (int iconf = 0; iconf < result.size(); iconf++)
667  {
668  xmlNodePtr mc_ptr = result[iconf];
669  walker_set_.push_back(mc_ptr);
670  walker_set_in_.push_back(mc_ptr);
671  }
672  //use the last mcwalkerset to initialize random numbers if possible
673  if (result.size())
674  {
675  std::string fname;
677  a.add(fname, "fileroot");
678  a.add(fname, "href");
679  a.add(fname, "src");
680  a.put(result[result.size() - 1]);
681  if (fname.size())
683  }
684  return true;
685 }
686 
687 bool QMCMain::executeDebugSection(xmlNodePtr cur)
688 {
689  app_log() << "QMCMain::executeDebugSection " << std::endl;
690  app_log() << " Use this to debug new features with <debug/> in the input file " << std::endl;
691 
692  return true;
693 }
694 
695 bool QMCMain::executeQMCSection(xmlNodePtr cur, bool reuse)
696 {
697  std::string target("e");
698  std::string random_test("no");
700  a.add(target, "target");
701  a.add(random_test, "testrng");
702  a.put(cur);
703  if (random_test == "yes")
705  if (qmc_system_ == nullptr)
706  qmc_system_ = particle_set_pool_->getWalkerSet(target);
707  bool success = runQMC(cur, reuse);
708  first_qmc_ = false;
709  return success;
710 }
711 
712 bool QMCMain::executeCMCSection(xmlNodePtr cur)
713 {
714  bool success = true;
715  std::string target("ion0");
717  a.add(target, "target");
718  a.put(cur);
719 
720  MCWalkerConfiguration* ions = particle_set_pool_->getWalkerSet(target);
721  TrialWaveFunction* primaryPsi = psi_pool_->getPrimary();
722  QMCHamiltonian* primaryH = ham_pool_->getPrimary();
723 
724  app_log() << "QMCMain::executeCMCSection moving " << target << " by dummy move." << std::endl;
725 
726  int nat = ions->getTotalNum();
727  ParticleSet::ParticlePos deltaR(nat);
728 
729  makeGaussRandomWithEngine(deltaR, Random); //generate random displacement
730  qmc_system_->update();
731 
732  double logpsi1 = primaryPsi->evaluateLog(*qmc_system_);
733  std::cout << "logpsi1 " << logpsi1 << std::endl;
734 
735  double eloc1 = primaryH->evaluate(*qmc_system_);
736  std::cout << "Local Energy " << eloc1 << std::endl;
737 
738  for (int i = 0; i < primaryH->sizeOfObservables(); i++)
739  app_log() << " HamTest " << primaryH->getObservableName(i) << " " << primaryH->getObservable(i) << std::endl;
740 
741  for (int iat = 0; iat < nat; ++iat)
742  {
743  ions->R[iat] += deltaR[iat];
744 
745  ions->update(); //update position and distance table of itself
746  primaryH->updateSource(*ions);
747 
748  qmc_system_->update();
749  double logpsi2 = primaryPsi->evaluateLog(*qmc_system_);
750  double eloc2 = primaryH->evaluate(*qmc_system_);
751 
752  std::cout << "\nION " << iat << " " << ions->R[iat] << std::endl;
753  std::cout << "logpsi " << logpsi2 << std::endl;
754  std::cout << "Local Energy " << eloc2 << std::endl;
755  for (int i = 0; i < primaryH->sizeOfObservables(); i++)
756  app_log() << " HamTest " << primaryH->getObservableName(i) << " " << primaryH->getObservable(i) << std::endl;
757 
758  ions->R[iat] -= deltaR[iat];
759  ions->update(); //update position and distance table of itself
760  primaryH->updateSource(*ions);
761 
762  qmc_system_->update();
763  double logpsi3 = primaryPsi->evaluateLog(*qmc_system_);
764  double eloc3 = primaryH->evaluate(*qmc_system_);
765 
766  if (std::abs(eloc1 - eloc3) > 1e-12)
767  {
768  std::cout << "ERROR Energies are different " << std::endl;
769  }
770  }
771  return success;
772 }
773 
774 
775 } // namespace qmcplusplus
RealType evaluateLog(ParticleSet &P)
evalaute the log (internally gradients and laplacian) of the trial wavefunction.
bool runQMC(xmlNodePtr cur, bool reuse)
execute <qmc> element
Definition: QMCMain.cpp:586
void print_git_info_if_present(std::ostream &os)
Print git info (commit hash, etc) if project was build from git repository.
Definition: qmc_common.cpp:99
static void read(const std::string &fname, Communicate *comm)
read in parallel or serial
#define ERRORMSG(msg)
Definition: OutputManager.h:86
double elapsed() const
Definition: Timer.h:30
std::string getObservableName(int i) const
return the name of the i-th observable
void barrier() const
A set of walkers that are to be advanced by Metropolis Monte Carlo.
std::ostream & app_warning()
Definition: OutputManager.h:69
Base class for any object which needs to know about a MPI communicator.
Definition: MPIObjectBase.h:26
std::vector< xmlNodePtr > walker_set_
xml mcwalkerset elements for output
Definition: QMCMain.h:73
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
timer_manager class.
~QMCMain() override
Definition: QMCMain.cpp:165
bool executeQMCSection(xmlNodePtr cur, bool reuse=false)
execute qmc
Definition: QMCMain.cpp:695
Declaration of OutputManager class.
DriverAssemblyState readSection(xmlNodePtr cur) const
default constructor
void setCommunicator(Communicate *c)
Definition: ProjectData.cpp:50
InfoStream infoSummary
MakeReturn< UnaryNode< FnFabs, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t abs(const Vector< T1, C1 > &l)
size_t getTotalNum() const
Definition: ParticleSet.h:493
std::optional< EstimatorManagerInput > estimator_manager_input_
Global estimators defined outside of <qmc> nodes.
Definition: QMCMain.h:61
#define OHMMS_PRECISION
Definition: config.h:70
std::ostream & app_log()
Definition: OutputManager.h:65
if(c->rank()==0)
std::ostream & app_summary()
Definition: OutputManager.h:63
bool put(xmlNodePtr cur)
assign attributes to the set
Definition: AttributeSet.h:55
bool isComplex() const noexcept
std::ostream & app_error()
Definition: OutputManager.h:67
std::unique_ptr< ParticleSetPool > particle_set_pool_
ParticleSet Pool.
Definition: QMCMain.h:49
RunTimeManager< ChronoClock > run_time_manager
void advance()
increment a series number and reset project_root_
Definition: ProjectData.cpp:81
RealType getObservable(int i) const
return the value of the i-th observable
Collection of Local Energy Operators.
xmlNodePtr traces_xml_
traces xml
Definition: QMCMain.h:82
std::unique_ptr< SimpleFixedNodeBranch > last_branch_engine_legacy_driver_
last branch engine used by legacy drivers
Definition: QMCMain.h:70
Timer class.
Timer accumulates time and call counts.
Definition: NewTimer.h:135
#define Random
xmlNodePtr last_input_node_
pointer to the last node of the main inputfile
Definition: QMCMain.h:88
void update(bool skipSK=false)
update the internal data
Attaches a unit to a Vector for IO.
Communicate * Controller
Global Communicator for a process.
Definition: Communicate.cpp:35
void executeLoop(xmlNodePtr cur)
execute loop
Definition: QMCMain.cpp:327
void print_mem(const std::string &title, std::ostream &log)
Definition: MemoryUsage.cpp:30
void saveXml()
save the xml document
Definition: QMCAppBase.cpp:70
int size() const
return the number of tasks
Definition: Communicate.h:118
std::unique_ptr< WaveFunctionPool > psi_pool_
TrialWaveFunction Pool.
Definition: QMCMain.h:52
QMCMain(Communicate *c)
Definition: QMCMain.cpp:58
InfoStream infoLog
class to handle xmlXPathObject
Definition: Libxml2Doc.h:26
xmlNodePtr initialize(xmlXPathContextPtr)
Wrapping information on parallelism.
Definition: Communicate.h:68
static const DeviceManager & getGlobal()
global instance accessor
omp_int_t omp_get_thread_num()
Definition: OpenMP.h:25
int getGroupID() const
return the group id
Definition: Communicate.h:121
Declaration of QMCDriver.
bool dryrun
true, if it is a dryrun
Definition: qmc_common.h:37
bool put(std::istream &is)
Definition: ProjectData.cpp:60
Declaration of InitMolecularSystem.
Compilation units that construct QMCDriverInput need visibility to the actual input classes types in ...
std::unique_ptr< QMCDriverInterface > createQMCDriver(xmlNodePtr cur, DriverAssemblyState &das, const std::optional< EstimatorManagerInput > &emi, MCWalkerConfiguration &qmc_system, ParticleSetPool &particle_pool, WaveFunctionPool &wave_function_pool, HamiltonianPool &hamiltonian_pool, Communicate *comm) const
create a new QMCDriver
std::vector< std::pair< xmlNodePtr, bool > > qmc_action_
qmc sections
Definition: QMCMain.h:85
bool processPWH(xmlNodePtr cur)
add unique ParticleSet, TrialWaveFunction and QMCHamiltonian elements to Pool objects ...
Definition: QMCMain.cpp:522
Communicate * myComm
pointer to Communicate
Definition: MPIObjectBase.h:62
Declaration of WaveFunctionPool.
int size() const
return the number of Hamiltonians
class to handle a set of attributes of an xmlNode
Definition: AttributeSet.h:24
bool first_qmc_
flag to indicate that a qmc is the first QMC
Definition: QMCMain.h:64
std::unique_ptr< HamiltonianPool > ham_pool_
QMCHamiltonian Pool.
Definition: QMCMain.h:55
ProjectData my_project_
project description
Definition: QMCAppBase.h:67
This a subclass for runtime errors that will occur on all ranks.
bool execute() override
execute the main function
Definition: QMCMain.cpp:172
Manage a collection of ParticleSet objects.
NewTimer & createGlobalTimer(const std::string &myname, timer_levels mylevel)
Declaration of QMCMain class.
bool pushDocument(const std::string &infile)
open a new document
Definition: QMCAppBase.cpp:30
int sizeOfObservables() const
return the size of observables
ParticlePos R
Position.
Definition: ParticleSet.h:79
int qmc_counter
init for <qmc> section
Definition: qmc_common.h:31
omp_int_t omp_get_num_threads()
Definition: OpenMP.h:27
std::string getXMLAttributeValue(const xmlNodePtr cur, const std::string_view name)
get the value string for attribute name if name is unfound in cur you get an empty string back this i...
RandomNumberControl my_random_control_
random number controller
Definition: QMCAppBase.h:70
#define GET_MACRO_VAL(arg)
Definition: QMCMain.cpp:54
Communicate NodeComm() const
provide a node/shared-memory communicator from current (parent) communicator
int getNumGroups() const
return the number of intra_comms which belong to the same group
Definition: Communicate.h:123
Declaration of a TrialWaveFunction.
const std::string & currentMainRoot() const noexcept
returns the projectmain of the project, the series id is incremented at every QMC section <project id...
std::vector< xmlNodePtr > walker_set_in_
xml mcwalkerset read-in elements
Definition: QMCMain.h:76
bool validateXML() override
validate the main document and (read the walker sets !)
Definition: QMCMain.cpp:376
void print_options(std::ostream &os)
print command-line options
Definition: qmc_common.cpp:86
std::unique_ptr< QMCDriverInterface > last_driver_
the last driver object. Should be in a loop only.
Definition: QMCMain.h:67
Declaration of HamiltonianPool.
Class for determining elapsed run time enabling simulations to adjust to time limits.
void flush()
flush stream buffer
Definition: InfoStream.cpp:39
Class to represent a many-body trial wave function.
bool setMCWalkers(xmlXPathContextPtr cur)
add <mcwalkerset> elements to continue a run
Definition: QMCMain.cpp:663
FullPrecRealType evaluate(ParticleSet &P)
evaluate Local Energy
Manager class to handle multiple threads.
void updateSource(ParticleSet &s)
remove a named Hamiltonian from the list
bool is_manager() const
return true if the rank == 0
Definition: MPIObjectBase.h:51
bool get(std::ostream &os) const
Definition: ProjectData.cpp:52
MCWalkerConfiguration * qmc_system_
current MCWalkerConfiguration
Definition: QMCMain.h:58
TimerManager< NewTimer > & getGlobalTimerManager()
bool executeCMCSection(xmlNodePtr cur)
execute <cmc> element
Definition: QMCMain.cpp:712
void popDocument()
close the current document
Definition: QMCAppBase.cpp:46
QMCState qmc_common
a unique QMCState during a run
Definition: qmc_common.cpp:111
void barrier_and_abort(const std::string &msg) const
xmlNodePtr walker_logs_xml_
walkerlogs xml
Definition: QMCMain.h:79
Base class for QMC applications and utilities.
Definition: QMCAppBase.h:34
void add(PDT &aparam, const std::string &aname, std::vector< PDT > candidate_values={}, TagStatus status=TagStatus::OPTIONAL)
add a new attribute
Definition: AttributeSet.h:42
static void initializeGlobalDeviceManager(int local_rank, int local_size)
initialize the global instance of DeviceManager arguments are the same as the constructor ...
std::stack< Libxml2Document * > xml_doc_stack_
stack of xml document
Definition: QMCAppBase.h:64
bool put(std::istream &is) override
read from std::istream
bool executeDebugSection(xmlNodePtr cur)
execute <debug> element
Definition: QMCMain.cpp:687
Manage a collection of TrialWaveFunction objects.
Declaration of ParticleSetPool.
Declaration of QMCHamiltonian.
void reset()
Construct the root name with title_ and m_series.
Definition: ProjectData.cpp:97
Manage a collection of QMCHamiltonian objects.
bool use_density
true, if density is used, e.g. MPC
Definition: qmc_common.h:35
void makeGaussRandomWithEngine(ParticleAttrib< TinyVector< T, D >> &a, RG &rng)