QMCPACK
EstimatorManagerNew.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) 2024 QMCPACK developers.
6 //
7 // File developed by: Peter Doak, doakpw@ornl.gov, Oak Ridge National Laboratory
8 //
9 // File refactored from: EstimatorManagerBase.cpp
10 //////////////////////////////////////////////////////////////////////////////////////
11 
12 #include <array>
13 #include <functional>
14 #include <numeric>
15 #include <algorithm>
16 #include <variant>
17 #include <cstdint>
18 
19 #include "EstimatorManagerNew.h"
21 #include "SpinDensityNew.h"
22 #include "MomentumDistribution.h"
23 #include "OneBodyDensityMatrices.h"
24 #include "SelfHealingOverlap.h"
25 #include "MagnetizationDensity.h"
28 #include "Message/Communicate.h"
29 #include "Message/CommOperators.h"
30 #include "Message/CommUtilities.h"
37 #include "hdf/hdf_archive.h"
38 #include "OhmmsData/AttributeSet.h"
41 
42 //leave it for serialization debug
43 //#define DEBUG_ESTIMATOR_ARCHIVE
44 
45 namespace qmcplusplus
46 {
47 
49 
51  : RecordCount(0), my_comm_(c), max4ascii(8), FieldWidth(20)
52 {
53  app_log() << " Legacy constructor adding a default LocalEnergyEstimator for the MainEstimator " << std::endl;
55  addMainEstimator(std::make_unique<LocalEnergyEstimator>(ham, true));
56 }
57 
59 {
60  return std::any_of(operator_ests_.begin(), operator_ests_.end(),
61  [](auto& oper_est) { return oper_est->isListenerRequired(); });
62 }
63 
64 template<class EstInputType, typename... Args>
66 {
67  if (has<EstInputType>(input))
68  {
69  operator_ests_.push_back(std::make_unique<typename EstInputType::Consumer>(std::move(std::get<EstInputType>(input)),
70  std::forward<Args>(args)...));
71  return true;
72  }
73  else
74  return false;
75 }
76 
77 template<class EstInputType, typename... Args>
79 {
80  if (has<EstInputType>(input))
81  {
82  auto estimator = std::make_unique<typename EstInputType::Consumer>(std::move(std::get<EstInputType>(input)),
83  std::forward<Args>(args)...);
84  if (estimator->isMainEstimator())
85  addMainEstimator(std::move(estimator));
86  else
87  scalar_ests_.push_back(std::move(estimator));
88  return true;
89  }
90  else
91  return false;
92 }
93 
94 //initialize the name of the primary estimator
97  const QMCHamiltonian& H,
98  const ParticleSet& pset,
99  const TrialWaveFunction& twf)
100  : RecordCount(0), my_comm_(c), max4ascii(8), FieldWidth(20)
101 {
102  for (auto& est_input : emi.get_estimator_inputs())
103  if (!(createEstimator<SpinDensityInput>(est_input, pset.getLattice(), pset.getSpeciesSet()) ||
104  createEstimator<MomentumDistributionInput>(est_input, pset.getTotalNum(), pset.getTwist(),
105  pset.getLattice()) ||
106  createEstimator<SelfHealingOverlapInput>(est_input,twf) ||
107  createEstimator<OneBodyDensityMatricesInput>(est_input, pset.getLattice(), pset.getSpeciesSet(),
108  twf.getSPOMap(), pset) ||
109  createEstimator<MagnetizationDensityInput>(est_input, pset.getLattice()) ||
110  createEstimator<PerParticleHamiltonianLoggerInput>(est_input, my_comm_->rank())))
111  throw UniformCommunicateError(std::string(error_tag_) +
112  "cannot construct an estimator from estimator input object.");
113 
115  if (!(createScalarEstimator<LocalEnergyInput>(scalar_input, H) ||
116  createScalarEstimator<CSLocalEnergyInput>(scalar_input, H) ||
117  createScalarEstimator<RMCLocalEnergyInput>(scalar_input, H)))
118  throw UniformCommunicateError(std::string(error_tag_) +
119  "cannot construct a scalar estimator from scalar estimator input object.");
120 
121  if (main_estimator_ == nullptr)
122  {
123  app_log() << " Adding a default LocalEnergyEstimator for the MainEstimator " << std::endl;
124  max4ascii = H.sizeOfObservables() + 3;
125  addMainEstimator(std::make_unique<LocalEnergyEstimator>(H, true));
126  }
127 
129 }
130 
132 
133 /** reset names of the properties
134  *
135  * \todo this should be in in constructor object shouldn't be reused
136  * Warning this is different from some "resets" in the code, it does not clear the object
137  *
138  * The number of estimators and their order can vary from the previous state.
139  * reinitialized properties before setting up a new BlockAverage data list.
140  *
141  * The object is still not completely valid.
142  *
143  */
145 {
146  //It's essential that this one is first, other code assumes weightInd always == 0
147  weightInd = BlockProperties.add("BlockWeight");
148  assert(weightInd == 0);
149  cpuInd = BlockProperties.add("BlockCPU");
150  acceptRatioInd = BlockProperties.add("AcceptRatio");
151  BlockAverages.clear(); //cleaup the records
152  // Side effect of this is that BlockAverages becomes size to number of scalar values tracked by all the
153  // scalar estimators
154  main_estimator_->add2Record(BlockAverages);
155  for (int i = 0; i < scalar_ests_.size(); i++)
156  scalar_ests_[i]->add2Record(BlockAverages);
157  // possibly redundant variable
159 }
160 
161 void EstimatorManagerNew::makeConfigReport(std::ostream& os) const
162 {
163  os << "EstimatorManager setup for this section:\n"
164  << " Main Estimator: " << main_estimator_->getSubTypeStr() << '\n';
165  if (scalar_ests_.size() > 0)
166  {
167  os << " ScalarEstimators:\n";
168  for (auto& scalar_est : scalar_ests_)
169  os << " " << scalar_est->getSubTypeStr() << '\n';
170  }
171  if (operator_ests_.size() > 0)
172  {
173  os << " General Estimators:\n";
174  for (auto& est : operator_ests_)
175  os << " " << est->get_my_name() << '\n';
176  }
177 }
178 
179 void EstimatorManagerNew::addHeader(std::ostream& o)
180 {
181  o.setf(std::ios::scientific, std::ios::floatfield);
182  o.setf(std::ios::left, std::ios::adjustfield);
183  o.precision(10);
184  for (int i = 0; i < BlockAverages.size(); i++)
185  FieldWidth = std::max(FieldWidth, BlockAverages.Names[i].size() + 2);
186  for (int i = 0; i < BlockProperties.size(); i++)
187  FieldWidth = std::max(FieldWidth, BlockProperties.Names[i].size() + 2);
188  int maxobjs = std::min(BlockAverages.size(), max4ascii);
189  o << "# index ";
190  for (int i = 0; i < maxobjs; i++)
191  o << std::setw(FieldWidth) << BlockAverages.Names[i];
192  for (int i = 0; i < BlockProperties.size(); i++)
193  o << std::setw(FieldWidth) << BlockProperties.Names[i];
194  o << std::endl;
195  o.setf(std::ios::right, std::ios::adjustfield);
196 }
197 
198 /// \todo clean up this method its a mess
200 {
201  reset();
202  RecordCount = 0;
208  // Now Estimatormanager New is actually valid i.e. in the state you would expect after the constructor.
209  // Until the put is dropped this isn't feasible to fix.
210 #if defined(DEBUG_ESTIMATOR_ARCHIVE)
211  if (!DebugArchive)
212  {
213  std::array<char, 128> fname;
214  if (std::snprintf(fname.data(), fname.size(), "%s.p%03d.scalar.dat", my_comm_->getName().c_str(),
215  my_comm_->rank()) < 0)
216  throw std::runtime_error("Error generating filename");
217  DebugArchive = std::make_unique<std::ofstream>(fname.data());
219  }
220 #endif
221  if (my_comm_->rank() == 0)
222  {
223  std::filesystem::path fname(my_comm_->getName());
224  fname.concat(".scalar.dat");
225  Archive = std::make_unique<std::ofstream>(fname);
226  addHeader(*Archive);
227  if (h5desc.size())
228  {
229  h5desc.clear();
230  }
231  fname = my_comm_->getName() + ".stat.h5";
232  h_file = std::make_unique<hdf_archive>();
233  h_file->create(fname);
234  main_estimator_->registerObservables(h5desc, *h_file);
235  for (int i = 0; i < scalar_ests_.size(); i++)
236  scalar_ests_[i]->registerObservables(h5desc, *h_file);
237  for (auto& uope : operator_ests_)
238  uope->registerOperatorEstimator(*h_file);
239  }
240 }
241 
243 
245 
246 void EstimatorManagerNew::stopBlock(unsigned long accept, unsigned long reject, RealType block_weight)
247 {
248  /* Need a redesign of how accept, reject and block_weight are handled from driver to this manager.
249  * DMC needs to add non-local move counters.
250  * also need to add num_samples which differs from block_weight
251  */
252  //take block averages and update properties per block
253  PropertyCache[weightInd] = block_weight;
254  makeBlockAverages(accept, reject);
258  // intentionally put after all the estimator I/O
260  writeScalarH5();
261  RecordCount++;
262 }
263 
265 {
266  AverageCache = 0.0;
267  for (ScalarEstimatorBase& est : main_estimators)
268  est.addAccumulated(AverageCache.begin());
269 }
270 
272 {
273  assert(crowd_scalar_ests[0].size() == scalar_ests_.size());
274  for (int iop = 0; iop < scalar_ests_.size(); ++iop)
275  {
276  RefVector<ScalarEstimatorBase> this_scalar_est_for_all_crowds;
277  for (int icrowd = 0; icrowd < crowd_scalar_ests.size(); ++icrowd)
278  this_scalar_est_for_all_crowds.emplace_back(crowd_scalar_ests[icrowd][iop]);
279  // There is actually state in each Scalar estimator that tells it what it's "first" index in the AverageCache
280  // is, It's quite unclear to me if that would really work so I'm doing this in anticipation of having to rework that
281  // if we don't drop multiple scalar estimators per crowd all together.
282  for (ScalarEstimatorBase& est : this_scalar_est_for_all_crowds)
283  est.addAccumulated(AverageCache.begin());
284  }
285 }
286 
288 {
289  for (int iop = 0; iop < operator_ests_.size(); ++iop)
290  {
291  RefVector<OperatorEstBase> this_op_est_for_all_crowds;
292  for (int icrowd = 0; icrowd < crowd_op_ests.size(); ++icrowd)
293  this_op_est_for_all_crowds.emplace_back(crowd_op_ests[icrowd][iop]);
294  operator_ests_[iop]->collect(this_op_est_for_all_crowds);
295  }
296 }
297 
298 void EstimatorManagerNew::makeBlockAverages(unsigned long accepts, unsigned long rejects)
299 {
300  // accumulate unsigned long counters over ranks.
301  // Blocks ends are infrequent, two MPI transfers to preserve type
302  // these could be replaced with a singple call MPI_struct_type some packing scheme or even
303  // a pack into and out of an fp type that can be assured to hold the integral type exactly
304  // IMHO they should not be primarily stored in a vector with magic indexes
305  std::vector<unsigned long> accepts_and_rejects(my_comm_->size() * 2, 0);
306  accepts_and_rejects[my_comm_->rank()] = accepts;
307  accepts_and_rejects[my_comm_->size() + my_comm_->rank()] = rejects;
308  my_comm_->allreduce(accepts_and_rejects);
309  int64_t total_block_accept =
310  std::accumulate(accepts_and_rejects.begin(), accepts_and_rejects.begin() + my_comm_->size(), int64_t(0));
311  int64_t total_block_reject = std::accumulate(accepts_and_rejects.begin() + my_comm_->size(),
312  accepts_and_rejects.begin() + my_comm_->size() * 2, int64_t(0));
313 
314  //Transfer FullPrecisionRead data
315  const size_t n1 = AverageCache.size();
316  const size_t n2 = n1 + PropertyCache.size();
317 
318  // This is a hack but it needs to be the correct size
319 
320  std::vector<double> reduce_buffer(n2, 0.0);
321  {
322  auto cur = reduce_buffer.begin();
324  copy(PropertyCache.begin(), PropertyCache.end(), cur + n1);
325  }
326 
327  // This is necessary to use mpi3's C++ style reduce
328 #ifdef HAVE_MPI
329  my_comm_->comm.reduce_in_place_n(reduce_buffer.begin(), reduce_buffer.size(), std::plus<>{});
330 #endif
331  if (my_comm_->rank() == 0)
332  {
333  auto cur = reduce_buffer.begin();
334  copy(cur, cur + n1, AverageCache.begin());
335  copy(cur + n1, cur + n2, PropertyCache.begin());
336  const RealType invTotWgt = 1.0 / PropertyCache[weightInd];
337  AverageCache *= invTotWgt;
338  //do not weight weightInd i.e. its index 0!
339  for (int i = 1; i < PropertyCache.size(); i++)
340  PropertyCache[i] *= invTotWgt;
341  }
342 
343  // now we put the correct accept ratio in
344  PropertyCache[acceptRatioInd] = static_cast<FullPrecRealType>(total_block_accept) /
345  static_cast<FullPrecRealType>(total_block_accept + total_block_reject);
346 
347  //add the block average to summarize
350 }
351 
353 {
354  //Do not assume h_file is valid
355  if (h_file)
356  {
357  for (int o = 0; o < h5desc.size(); ++o)
358  // cheating here, remove SquaredAverageCache from API
359  h5desc[o].write(AverageCache.data(), *h_file);
360  h_file->flush();
361  }
362 
363  if (Archive)
364  {
365  *Archive << std::setw(10) << RecordCount;
366  int maxobjs = std::min(BlockAverages.size(), max4ascii);
367  for (int j = 0; j < maxobjs; j++)
368  *Archive << std::setw(FieldWidth) << AverageCache[j];
369  for (int j = 0; j < PropertyCache.size(); j++)
370  *Archive << std::setw(FieldWidth) << PropertyCache[j];
371  *Archive << std::endl;
372  }
373 }
374 
376 {
377  if (operator_ests_.size() > 0)
378  {
379  std::vector<size_t> operator_data_sizes(operator_ests_.size());
381  for (int iop = 0; iop < operator_data_sizes.size(); ++iop)
382  {
383  operator_data_sizes[iop] = operator_ests_[iop]->get_data().size();
384  }
385  // 1 larger because we put the weight in to avoid dependence of the Scalar estimators being reduced firt.
386  size_t nops = *(std::max_element(operator_data_sizes.begin(), operator_data_sizes.end())) + 1;
387  std::vector<RealType> operator_send_buffer;
388  std::vector<RealType> operator_recv_buffer;
389  operator_send_buffer.reserve(nops);
390  operator_recv_buffer.reserve(nops);
391  for (int iop = 0; iop < operator_ests_.size(); ++iop)
392  {
393  auto& estimator = *operator_ests_[iop];
394  auto& data = estimator.get_data();
395  size_t adjusted_size = data.size() + 1;
396  operator_send_buffer.resize(adjusted_size, 0.0);
397  operator_recv_buffer.resize(adjusted_size, 0.0);
398  std::copy_n(data.begin(), data.size(), operator_send_buffer.begin());
399  operator_send_buffer[data.size()] = estimator.get_walkers_weight();
400  // This is necessary to use mpi3's C++ style reduce
401 #ifdef HAVE_MPI
402  my_comm_->comm.reduce_n(operator_send_buffer.begin(), adjusted_size, operator_recv_buffer.begin(), std::plus<>{},
403  0);
404 #else
405  operator_recv_buffer = operator_send_buffer;
406 #endif
407  if (my_comm_->rank() == 0)
408  {
409  std::copy_n(operator_recv_buffer.begin(), data.size(), data.begin());
410  size_t reduced_walker_weights = operator_recv_buffer[data.size()];
411  RealType invTotWgt = 1.0 / static_cast<QMCT::RealType>(reduced_walker_weights);
412  operator_ests_[iop]->normalize(invTotWgt);
413  }
414  }
415  }
416 }
417 
419 {
420  if (my_comm_->rank() == 0)
421  {
422  if (h_file)
423  {
424  for (auto& op_est : operator_ests_)
425  op_est->write(*h_file);
426  h_file->flush();
427  }
428  }
429 }
430 
432 {
433  for (auto& op_est : operator_ests_)
434  op_est->zero();
435 }
436 
438 {
439  RealType tmp[3];
440  tmp[0] = energyAccumulator.count();
441  tmp[1] = energyAccumulator.result();
442  tmp[2] = varAccumulator.result();
443  my_comm_->bcast(tmp, 3);
444  e = tmp[1] / tmp[0];
445  var = tmp[2] / tmp[0] - e * e;
446 }
447 
449 {
450  std::vector<std::string> extra_types;
451  std::vector<std::string> extra_names;
452  cur = cur->children;
453  std::string MainEstimatorName("LocalEnergy");
454  while (cur != NULL)
455  {
456  std::string cname((const char*)(cur->name));
457  if (cname == "estimator")
458  {
459  std::string est_type("none");
460  std::string est_name(MainEstimatorName);
461  std::string use_hdf5("yes");
462  OhmmsAttributeSet hAttrib;
463  hAttrib.add(est_type, "type");
464  hAttrib.add(est_name, "name");
465  hAttrib.add(use_hdf5, "hdf5");
466  hAttrib.put(cur);
467  if ((est_name == MainEstimatorName) || (est_name == "elocal"))
468  {
469  max4ascii = H.sizeOfObservables() + 3;
470  addMainEstimator(std::make_unique<LocalEnergyEstimator>(H, use_hdf5 == "yes"));
471  }
472  else if (est_name == "RMC")
473  {
474  int nobs(20);
475  OhmmsAttributeSet hAttrib;
476  hAttrib.add(nobs, "nobs");
477  hAttrib.put(cur);
478  max4ascii = nobs * H.sizeOfObservables() + 3;
479  addMainEstimator(std::make_unique<RMCLocalEnergyEstimator>(H, nobs));
480  }
481  else if (est_name == "CSLocalEnergy")
482  {
483  OhmmsAttributeSet hAttrib;
484  int nPsi = 1;
485  hAttrib.add(nPsi, "nPsi");
486  hAttrib.put(cur);
487  addMainEstimator(std::make_unique<CSEnergyEstimator>(H, nPsi));
488  app_log() << " Adding a CSLocalEnergy estimator for the MainEstimator " << std::endl;
489  }
490  else if (est_name == "SpinDensityNew")
491  {
492  SpinDensityInput spdi(cur);
494  if (spdi.get_save_memory())
495  dl = DataLocality::rank;
496  if (spdi.get_cell().explicitly_defined)
497  operator_ests_.emplace_back(std::make_unique<SpinDensityNew>(std::move(spdi), pset.getSpeciesSet(), dl));
498  else
499  operator_ests_.emplace_back(
500  std::make_unique<SpinDensityNew>(std::move(spdi), pset.getLattice(), pset.getSpeciesSet(), dl));
501  }
502  else if (est_type == "MomentumDistribution")
503  {
504  MomentumDistributionInput mdi(cur);
506  operator_ests_.emplace_back(std::make_unique<MomentumDistribution>(std::move(mdi), pset.getTotalNum(),
507  pset.getTwist(), pset.getLattice(), dl));
508  }
509  else if (est_type == "OneBodyDensityMatrices")
510  {
512  // happens once insures golden particle set is not abused.
514  operator_ests_.emplace_back(std::make_unique<OneBodyDensityMatrices>(std::move(obdmi), pset.getLattice(),
515  pset.getSpeciesSet(), twf.getSPOMap(),
516  pset_target));
517  }
518  else if (est_type == "MagnetizationDensity")
519  {
520  MagnetizationDensityInput magdensinput(cur);
522  operator_ests_.emplace_back(std::make_unique<MagnetizationDensity>(std::move(magdensinput), pset.getLattice()));
523  }
524  else
525  {
526  extra_types.push_back(est_type);
527  extra_names.push_back(est_name);
528  }
529  }
530  cur = cur->next;
531  }
532  if (main_estimator_ == nullptr)
533  {
534  app_log() << " ::put Adding a default LocalEnergyEstimator for the MainEstimator " << std::endl;
535  max4ascii = H.sizeOfObservables() + 3;
536  addMainEstimator(std::make_unique<LocalEnergyEstimator>(H, true));
537  }
538  if (!extra_types.empty())
539  {
540  app_log() << "\nUnrecognized estimators in input:" << std::endl;
541  for (int i = 0; i < extra_types.size(); i++)
542  {
543  app_log() << " type: " << extra_types[i] << " name: " << extra_names[i] << std::endl;
544  }
545  app_log() << std::endl;
546  throw UniformCommunicateError("Unrecognized estimators encountered in input. See log message for more details.");
547  }
548  return true;
549 }
550 
551 void EstimatorManagerNew::addMainEstimator(std::unique_ptr<ScalarEstimatorBase>&& estimator)
552 {
553  if (main_estimator_ != nullptr)
554  app_log() << " EstimatorManagerNew replaced its main estimator with " << estimator->getSubTypeStr()
555  << " estimator." << std::endl;
556  main_estimator_ = std::move(estimator);
557 }
558 
559 int EstimatorManagerNew::addScalarEstimator(std::unique_ptr<ScalarEstimatorBase>&& estimator)
560 {
561  scalar_ests_.push_back(std::move(estimator));
562  return scalar_ests_.size() - 1;
563 }
564 
565 } // namespace qmcplusplus
void resize(size_type n, Type_t val=Type_t())
Resize the container.
Definition: OhmmsVector.h:166
int addScalarEstimator(std::unique_ptr< ScalarEstimatorBase > &&estimator)
add an Estimator
double elapsed() const
Definition: Timer.h:30
std::unique_ptr< std::ofstream > Archive
file handler to write data
void zeroOperatorEstimators()
OperatorEstimators need to be zeroed out after the block is finished.
ScalarEstimatorInputs & get_scalar_estimator_inputs()
void restart()
Definition: Timer.h:29
void makeBlockAverages(unsigned long accept, unsigned long reject)
collect data and write
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
int rank() const
return the rank
Definition: Communicate.h:116
void writeOperatorEstimators()
Write OperatorEstimator data to *.stat.h5.
QTBase::RealType RealType
Definition: Configuration.h:58
std::vector< std::unique_ptr< OperatorEstBase > > operator_ests_
OperatorEst Observables.
int max4ascii
number of maximum data for a scalar.dat
std::ostream & app_log()
Definition: OutputManager.h:65
bool put(xmlNodePtr cur)
assign attributes to the set
Definition: AttributeSet.h:55
Vector< RealType > AverageCache
cached block averages of the values
void addMainEstimator(std::unique_ptr< ScalarEstimatorBase > &&estimator)
std::vector< ObservableHelper > h5desc
convenient descriptors for hdf5
Collection of Local Energy Operators.
void stopDriverRun()
Stop the manager at the end of a driver run().
int weightInd
index for the block weight PropertyCache(weightInd)
static constexpr std::string_view error_tag_
std::unique_ptr< std::ofstream > DebugArchive
file handler to write data for debugging
int RecordCount
number of records in a block
EstimatorManagerInput emi(estimators_doc.getRoot())
void writeScalarH5()
write scalars to scalar.dat and h5
EstimatorManagerNew(const QMCHamiltonian &ham, Communicate *comm)
default constructor
int size() const
return the number of tasks
Definition: Communicate.h:118
static RefVector< T > convertUPtrToRefVector(const UPtrVector< T > &ptr_list)
convert a vector of std::unique_ptrs<T> to a refvector<T>
T min(T a, T b)
void collectScalarEstimators(const std::vector< RefVector< ScalarEstimatorBase >> &scalar_ests)
Deals with possible free form scalar estimators.
void reduceOperatorEstimators()
do the rank wise reduction of the OperatorEstimators
void copy(const Array< T1, 3 > &src, Array< T2, 3 > &dest)
Definition: Blitz.h:639
bool createScalarEstimator(ScalarEstimatorInput &input, Args &&... args)
Construct scalar estimator of type matching the underlying ScalarEstimatorInput type Consumer and pus...
Wrapping information on parallelism.
Definition: Communicate.h:68
std::vector< std::string > Names
void allreduce(T &)
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
const std::string & getName() const
Definition: Communicate.h:131
Native representation for DensityMatrices1B Estimator&#39;s inputs.
void makeConfigReport(std::ostream &os) const
Return a string with information about which estimators estimator manager is holding.
size_type size() const
return the current size
Definition: OhmmsVector.h:162
int acceptRatioInd
index for the accept counter PropertyCache(acceptInd)
void getApproximateEnergyVariance(RealType &e, RealType &var)
get the average of per-block energy and variance of all the blocks Note: this is not weighted average...
ScalarEstimatorBase::accumulator_type energyAccumulator
accumulator for the energy
Compilation units that construct QMCDriverInput need visibility to the actual input classes types in ...
int add(const std::string &aname)
class to handle a set of attributes of an xmlNode
Definition: AttributeSet.h:24
This a subclass for runtime errors that will occur on all ranks.
int cpuInd
index for the block cpu PropertyCache(cpuInd)
Vector< RealType > PropertyCache
cached block averages of properties, e.g. BlockCPU
define convenience functions for mpi operations.
void stopBlock(unsigned long accept, unsigned long reject, RealType block_weight)
unified: stop a block
ScalarEstimatorBase::accumulator_type varAccumulator
accumulator for the variance
std::variant< std::monostate, MomentumDistributionInput, SpinDensityInput, OneBodyDensityMatricesInput, SelfHealingOverlapInput, MagnetizationDensityInput, PerParticleHamiltonianLoggerInput > EstimatorInput
int sizeOfObservables() const
return the size of observables
OneBodyDensityMatricesInput obdmi(node)
void collectOperatorEstimators(const std::vector< RefVector< OperatorEstBase >> &op_ests)
Reduces OperatorEstimator data from Crowds to the manager&#39;s OperatorEstimator data.
void collectMainEstimators(const RefVector< ScalarEstimatorBase > &scalar_estimators)
At end of block collect the main scalar estimators for the entire rank.
bool createEstimator(EstimatorInput &input, Args &&... args)
Construct estimator of type matching the underlying EstimatorInput type Consumer and push its its uni...
Native representation for Spin Density Estimators inputs.
UPtr< ScalarEstimatorBase > main_estimator_
main estimator i.e. some version of a local energy estimator.
RecordNamedProperty< RealType > BlockAverages
manager of scalar data
std::vector< std::reference_wrapper< T > > RefVector
SPOSet::SPOMap SPOMap
sycl::event copy_n(sycl::queue &aq, const T1 *restrict VA, size_t array_size, T2 *restrict VC, const std::vector< sycl::event > &events)
Definition: syclBLAS.cpp:548
return_type result() const
return the sum
Definition: accumulators.h:108
Class to represent a many-body trial wave function.
void reset()
reset the estimator
std::map< std::string, const std::unique_ptr< const SPOSet > > SPOMap
Definition: SPOSet.h:57
Input type for EstimatorManagerNew Parses Estimators level of input and and delegates child estimator...
void startDriverRun()
Start the manager at the beginning of a driver run().
DataLocality
data locality with respect to walker buffer
Definition: DataLocality.h:19
std::unique_ptr< hdf_archive > h_file
hdf5 handler
std::variant< std::monostate, LocalEnergyInput, CSLocalEnergyInput, RMCLocalEnergyInput > ScalarEstimatorInput
Communicate * my_comm_
communicator to handle communication
return_type count() const
return the count
Definition: accumulators.h:116
declare a handler of DMC branching
void bcast(T &)
bool explicitly_defined
true, the lattice is defined by the input instead of an artificial default
QMCTraits::FullPrecRealType FullPrecRealType
Abstract class for an estimator of a scalar operator.
void addHeader(std::ostream &o)
add header to an std::ostream
A collection of functions to help with the use of variants.
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
bool put(QMCHamiltonian &H, const ParticleSet &pset, const TrialWaveFunction &twf, xmlNodePtr cur)
process xml tag associated with estimators
RecordNamedProperty< RealType > BlockProperties
manager of property data
bool areThereListeners() const
Do any of the instantiated estimators in operator_ests_ listen to per particle hamiltonian values...
QMCTraits::FullPrecRealType RealType
This is to deal with vague expression of precision in legacy code. Don&#39;t use in new code...
Native representation for Momentum Distribution Estimators inputs.
std::vector< UPtr< ScalarEstimatorBase > > scalar_ests_
non main scalar estimators collecting simple scalars, are there any? with the removal of collectables...
void startBlock(int steps)
start a block
Declaration of QMCHamiltonian.