QMCPACK
EstimatorManagerNew.h
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) 2022 QMCPACK developers.
6 //
7 // File developed by: Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab
8 //
9 // File refactored from: EstimatorManagerBase.h
10 //////////////////////////////////////////////////////////////////////////////////////
11 
12 #ifndef QMCPLUSPLUS_ESTIMATORMANAGERNEW_H
13 #define QMCPLUSPLUS_ESTIMATORMANAGERNEW_H
14 
15 #include <memory>
16 
17 #include "Configuration.h"
18 #include "Utilities/Timer.h"
19 #include "Pools/PooledData.h"
20 #include "Message/Communicate.h"
22 #include "OperatorEstBase.h"
23 #include "Particle/Walker.h"
24 #include "OhmmsPETE/OhmmsVector.h"
26 #include "EstimatorManagerInput.h"
27 #include <bitset>
28 
29 namespace qmcplusplus
30 {
31 class QMCHamiltonian;
32 class hdf_archive;
33 
34 namespace testing
35 {
36 class EstimatorManagerNewTest;
37 class EstimatorManagerNewTestAccess;
38 } // namespace testing
39 
40 
41 /** Class to manage a set of ScalarEstimators
42  * As a manager, this class handles the aggregation of data from crowds, MPI ranks and I/O logics.
43  * The actually per-crowd data accumulation is done by EstimatorManagerCrowd.
44  */
46 {
47 public:
48  /// This is to deal with vague expression of precision in legacy code. Don't use in new code.
51 
52  using QMCT = QMCTraits;
53  using FPRBuffer = std::vector<FullPrecRealType>;
55 
56  ///default constructor
58  ///copy constructor, deleted
60  /** Batched version constructor.
61  *
62  * \param[in] emi EstimatorManagerInput consisting of merged global and local estimator definitions. Moved from!
63  * \param[in] H Fully Constructed Golden Hamiltonian.
64  * \param[in] pset The electron or equiv. pset
65  * \param[in] twf The fully constructed TrialWaveFunction.
66  */
69  const QMCHamiltonian& H,
70  const ParticleSet& pset,
71  const TrialWaveFunction& twf);
72  ///destructor
74 
75  /** add a "non" physical operator estimator
76  *
77  * this is a dratically reduced version of OperatorBase right now it just supports
78  * what the SpinDensityNew estimator needs
79  *
80  * What is actually important is that it has its own locality aware data and
81  * EstimatorManagerNew doesn't know about or manage that data.
82  */
83  int addEstOperator(OperatorEstBase& op_est);
84 
85  ///process xml tag associated with estimators
86  bool put(QMCHamiltonian& H, const ParticleSet& pset, const TrialWaveFunction& twf, xmlNodePtr cur);
87 
88  /** Start the manager at the beginning of a driver run().
89  * Open files. Setting zeros.
90  * @param blocks number of blocks
91  * @param record if true, will write to a file
92  *
93  * Replace reportHeader and reset functon.
94  */
95  void startDriverRun();
96 
97  /** Stop the manager at the end of a driver run().
98  * Flush/close files.
99  */
100  void stopDriverRun();
101 
102  /** start a block
103  * @param steps number of steps in a block
104  */
105  void startBlock(int steps);
106 
107  /** unified: stop a block
108  * @param accept acceptance rate of this block
109  * \param[in] accept
110  * \param[in] reject
111  * \param[in] block_weight
112  */
113  void stopBlock(unsigned long accept, unsigned long reject, RealType block_weight);
114 
115  /** At end of block collect the main scalar estimators for the entire rank
116  *
117  * One per crowd over multiple walkers
118  */
119  void collectMainEstimators(const RefVector<ScalarEstimatorBase>& scalar_estimators);
120 
121  /** Deals with possible free form scalar estimators
122  *
123  * \param[in] scalar_ests - vector of each crowds vector of references to their OperatorEstimators.
124  * Still looking for actual use case.
125  */
126  void collectScalarEstimators(const std::vector<RefVector<ScalarEstimatorBase>>& scalar_ests);
127 
128  /** Reduces OperatorEstimator data from Crowds to the manager's OperatorEstimator data
129  *
130  * \param[in] op_ests - vector of each crowds vector of references to their OperatorEstimators.
131  *
132  * A particular OperatorEstimators reduction via a call to collect may be straight forward
133  * if the crowd context OperatorEstimator holds a copy of the estimator data structure
134  * or more complex if it just collects for instance a list of writes to locations
135  * in the data structure.
136  */
137  void collectOperatorEstimators(const std::vector<RefVector<OperatorEstBase>>& op_ests);
138 
139  /** get the average of per-block energy and variance of all the blocks
140  * Note: this is not weighted average. It can be the same as weighted average only when block weights are identical.
141  */
143 
144  auto& get_AverageCache() { return AverageCache; }
145 
146  std::size_t getNumEstimators() { return operator_ests_.size(); }
147  std::size_t getNumScalarEstimators() { return scalar_ests_.size(); }
148 
149  /** Do any of the instantiated estimators in operator_ests_ listen to per particle hamiltonian values?
150  * Listeners are lambda functions captured from crowd scope estimators and passed to QMCHamiltonian leaders.
151  */
152  bool areThereListeners() const;
153 
154 private:
155  /** Construct estimator of type matching the underlying EstimatorInput type Consumer
156  * and push its its unique_ptr onto operator_ests_
157  */
158  template<typename EstInputType, typename... Args>
159  bool createEstimator(EstimatorInput& input, Args&&... args);
160 
161  /** Construct scalar estimator of type matching the underlying ScalarEstimatorInput type Consumer
162  * and push its its unique_ptr onto operator_ests_
163  */
164  template<typename EstInputType, typename... Args>
165  bool createScalarEstimator(ScalarEstimatorInput& input, Args&&... args);
166 
167  /** Return a string with information about which estimators estimator manager is holding.
168  */
169  void makeConfigReport(std::ostream& os) const;
170 
171  /** reset the estimator
172  */
173  void reset();
174 
175  /** add an Estimator
176  * @param[in] estimator New Estimator
177  * @return index of newestimator
178  */
179  int addScalarEstimator(std::unique_ptr<ScalarEstimatorBase>&& estimator);
180 
181  void addMainEstimator(std::unique_ptr<ScalarEstimatorBase>&& estimator);
182 
183  // ///return a pointer to the estimator aname
184  // ScalarEstimatorBase* getEstimator(const std::string& a);
185 
186  /// collect data and write
187  void makeBlockAverages(unsigned long accept, unsigned long reject);
188 
189  /// write scalars to scalar.dat and h5
190  void writeScalarH5();
191 
192  /** do the rank wise reduction of the OperatorEstimators
193  *
194  * Why do this here?
195  * 1. Operator estimators don't know about the concurrency model
196  * 2. EstimatorManager owns the resources:
197  * send & receive buffers
198  * 3. The operation is generic as long as OperatorEstimator satisfies
199  * the requirement that get_data_ref() returns a reference to
200  * std::vector<RealType>
201  *
202  * Implementation makes the assumption that sending each OperatorEstimator
203  * separately is the correct memory use vs. mpi message balance.
204  */
206  /** Write OperatorEstimator data to *.stat.h5
207  *
208  * Note that OperatorEstimator owns its own observable_helpers
209  */
211  /** OperatorEstimators need to be zeroed out after the block is finished.
212  */
213  void zeroOperatorEstimators();
214 
215  ///number of records in a block
217  ///index for the block weight PropertyCache(weightInd)
219  ///index for the block cpu PropertyCache(cpuInd)
220  int cpuInd;
221  ///index for the accept counter PropertyCache(acceptInd)
223  ///hdf5 handler
224  std::unique_ptr<hdf_archive> h_file;
225  ///file handler to write data
226  std::unique_ptr<std::ofstream> Archive;
227  ///file handler to write data for debugging
228  std::unique_ptr<std::ofstream> DebugArchive;
229  ///communicator to handle communication
231  /** accumulator for the energy
232  *
233  * @todo expand it for all the scalar observables to report the final results
234  */
236  /** accumulator for the variance **/
238  ///cached block averages of the values
239 
241  ///cached block averages of properties, e.g. BlockCPU
243  ///manager of scalar data
245  ///manager of property data
247  /// main estimator i.e. some version of a local energy estimator.
249  /** non main scalar estimators collecting simple scalars, are there any?
250  * with the removal of collectables these don't seem used or needed.
251  */
252  std::vector<UPtr<ScalarEstimatorBase>> scalar_ests_;
253  ///convenient descriptors for hdf5
254  std::vector<ObservableHelper> h5desc;
255  /** OperatorEst Observables
256  *
257  * since the operator estimators are also a close set at compile time
258  * they could be treated just like the inputs.
259  * However the idea of a shared interface is much more straight forward for
260  * them.
261  */
262  std::vector<std::unique_ptr<OperatorEstBase>> operator_ests_;
263 
264  ///block timer
266 
267  ///number of maximum data for a scalar.dat
269 
270  ///add header to an std::ostream
271  void addHeader(std::ostream& o);
272  size_t FieldWidth;
273 
274  static constexpr std::string_view error_tag_{"EstimatorManagerNew "};
275 
276  friend class EstimatorManagerCrowd;
279 };
280 } // namespace qmcplusplus
281 #endif
int addScalarEstimator(std::unique_ptr< ScalarEstimatorBase > &&estimator)
add an Estimator
std::unique_ptr< std::ofstream > Archive
file handler to write data
void zeroOperatorEstimators()
OperatorEstimators need to be zeroed out after the block is finished.
void makeBlockAverages(unsigned long accept, unsigned long reject)
collect data and write
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
declares the list supported estimator input types and declares the input type for EstimatorManagerNew...
void writeOperatorEstimators()
Write OperatorEstimator data to *.stat.h5.
std::vector< std::unique_ptr< OperatorEstBase > > operator_ests_
OperatorEst Observables.
int max4ascii
number of maximum data for a scalar.dat
Class to manage a set of ScalarEstimators As a manager, this class handles the aggregation of data fr...
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
Testing class breaking EstimatorManagerNew encapsultation.
Timer class.
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
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
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
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
void makeConfigReport(std::ostream &os) const
Return a string with information about which estimators estimator manager is holding.
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
int cpuInd
index for the block cpu PropertyCache(cpuInd)
Vector< RealType > PropertyCache
cached block averages of properties, e.g. BlockCPU
Thread local estimator container/accumulator.
void stopBlock(unsigned long accept, unsigned long reject, RealType block_weight)
unified: stop a block
ScalarEstimatorBase::accumulator_type varAccumulator
accumulator for the variance
An abstract class for gridded estimators.
std::variant< std::monostate, MomentumDistributionInput, SpinDensityInput, OneBodyDensityMatricesInput, SelfHealingOverlapInput, MagnetizationDensityInput, PerParticleHamiltonianLoggerInput > EstimatorInput
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.
std::unique_ptr< T > UPtr
bool createEstimator(EstimatorInput &input, Args &&... args)
Construct estimator of type matching the underlying EstimatorInput type Consumer and push its its uni...
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
std::vector< FullPrecRealType > FPRBuffer
Declaraton of Vector<T,Alloc> Manage memory through Alloc directly and allow referencing an existing ...
Class to represent a many-body trial wave function.
void reset()
reset the estimator
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().
std::unique_ptr< hdf_archive > h_file
hdf5 handler
std::variant< std::monostate, LocalEnergyInput, CSLocalEnergyInput, RMCLocalEnergyInput > ScalarEstimatorInput
Communicate * my_comm_
communicator to handle communication
QTFull::RealType FullPrecRealType
Definition: Configuration.h:66
QMCTraits::FullPrecRealType FullPrecRealType
int addEstOperator(OperatorEstBase &op_est)
add a "non" physical operator estimator
traits for QMC variables
Definition: Configuration.h:49
void addHeader(std::ostream &o)
add header to an std::ostream
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...
A container class to represent a walker.
Definition: Walker.h:49
QMCTraits::FullPrecRealType RealType
This is to deal with vague expression of precision in legacy code. Don&#39;t use in new code...
Define a serialized buffer to store anonymous data.
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