QMCPACK
OperatorBase.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) 2022 QMCPACK developers.
6 //
7 // File developed by: Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
8 // Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
9 // Jaron T. Krogel, krogeljt@ornl.gov, Oak Ridge National Laboratory
10 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
11 // Peter W. Doak, doakpw@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 /**@file
18  *@brief Definition of OperatorBase
19  */
20 #include "Message/Communicate.h"
21 #include "OperatorBase.h"
23 
24 namespace qmcplusplus
25 {
26 // PUBLIC
27 
29  : value_(0.0),
30  my_index_(-1),
31  t_walker_(0),
32 #if !defined(REMOVE_TRACEMANAGER)
33  streaming_particles_(false),
34  have_required_traces_(false),
35  streaming_scalars_(false),
36 #endif
37  quantum_domain_(NO_QUANTUM_DOMAIN),
38  energy_domain_(NO_ENERGY_DOMAIN)
39 {
40  update_mode_.set(PRIMARY, 1);
41 }
42 
43 std::bitset<8>& OperatorBase::getUpdateMode() noexcept { return update_mode_; }
44 
46 
47 std::string OperatorBase::getName() const noexcept { return name_; }
48 
49 void OperatorBase::setName(const std::string name) noexcept { name_ = name; }
50 
51 #if !defined(REMOVE_TRACEMANAGER)
53 #endif
54 
55 //////// FUNCTIONS ////////////////
56 void OperatorBase::addObservables(PropertySetType& plist, BufferType& collectables) { addValue(plist); }
57 
58 void OperatorBase::registerObservables(std::vector<ObservableHelper>& h5desc, hdf_archive& file) const
59 {
60  const bool collect = update_mode_.test(COLLECTABLE);
61  //exclude collectables
62  if (!collect)
63  {
64  h5desc.emplace_back(hdf_path{name_});
65  auto& oh = h5desc.back();
66  std::vector<int> onedim(1, 1);
67  oh.set_dimensions(onedim, my_index_);
68  }
69 }
70 
71 void OperatorBase::registerCollectables(std::vector<ObservableHelper>& h5desc, hdf_archive& file) const {}
72 
74 
75 void OperatorBase::setParticlePropertyList(PropertySetType& plist, int offset) { plist[my_index_ + offset] = value_; }
76 
77 void OperatorBase::setHistories(Walker_t& ThisWalker) { t_walker_ = &(ThisWalker); }
78 
80 
83  const RefVectorWithLeader<ParticleSet>& p_list) const
84 {
85  assert(this == &o_list.getLeader());
86 /** Temporary raw omp pragma for simple thread parallelism
87  * ignoring the driver level concurrency
88  *
89  * TODO: replace this with a proper abstraction. It should adequately describe the behavior
90  * and strictly limit the activation of this level concurrency to when it is intended.
91  * It is unlikely to belong in this function.
92  *
93  * This implicitly depends on openmp work division logic. Essentially adhoc runtime
94  * crowds over which we have given up control of thread/global scope.
95  * How many walkers per thread? How to handle their data movement if any of these
96  * hamiltonians should be accelerated? We can neither reason about or describe it in C++
97  *
98  * As I understand it it should only be required for as long as the AMD openmp offload
99  * compliler is incapable of running multiple threads. They should/must fix their compiler
100  * before delivery of frontier and it should be removed at that point at latest
101  *
102  * If you want 16 threads of 1 walker that should be 16 crowds of 1
103  * not one crowd of 16 with openmp thrown in at hamiltonian level.
104  * If this must be different from the other crowd batching. Make this a reasoned about
105  * and controlled level of concurency blocking at the driver level.
106  *
107  * This is only thread safe only if each walker has a complete
108  * set of anything involved in an Operator.evaluate.
109  */
110 #pragma omp parallel for
111  for (int iw = 0; iw < o_list.size(); iw++)
112  o_list[iw].evaluate(p_list[iw]);
113 }
114 
117  const RefVectorWithLeader<ParticleSet>& p_list,
118  const std::vector<ListenerVector<RealType>>& listeners,
119  const std::vector<ListenerVector<RealType>>& listeners_ions) const
120 {
121  mw_evaluate(o_list, wf_list, p_list);
122 }
123 
124 
126  const RefVectorWithLeader<ParticleSet>& p_list,
127  const opt_variables_type& optvars,
128  const RecordArray<ValueType>& dlogpsi,
129  RecordArray<ValueType>& dhpsioverpsi) const
130 {
131  const int nparam = dlogpsi.getNumOfParams();
132  for (int iw = 0; iw < o_list.size(); iw++)
133  {
134  const Vector<ValueType> dlogpsi_record_view(const_cast<ValueType*>(dlogpsi[iw]), nparam);
135  Vector<ValueType> dhpsioverpsi_record_view(dhpsioverpsi[iw], nparam);
136 
137  o_list[iw].evaluateValueAndDerivatives(p_list[iw], optvars, dlogpsi_record_view, dhpsioverpsi_record_view);
138  }
139 }
140 
142 
144 
147  const RefVectorWithLeader<ParticleSet>& p_list) const
148 {
149  // Only in NLPP evaluateWithToperator doesn't decay to evaluate. All other derived classes don't
150  // provide evaluateWithToperator specialization but may provide mw_evaluate optimization.
151  // Thus decaying to mw_evaluate is better than decalying to a loop over evaluateWithToperator
152  mw_evaluate(o_list, wf_list, p_list);
153 }
154 
156  const RefVectorWithLeader<OperatorBase>& o_list,
158  const RefVectorWithLeader<ParticleSet>& p_list,
159  const std::vector<ListenerVector<RealType>>& listeners,
160  const std::vector<ListenerVector<RealType>>& listeners_ions) const
161 {
162  // This may or may not be what is expected.
163  // It the responsibility of the derived type to override this if the
164  // desired behavior is instead to call mw_evaluatePerParticle
165  mw_evaluateWithToperator(o_list, wf_list, p_list);
166 }
167 
169  const opt_variables_type& optvars,
170  const Vector<ValueType>& dlogpsi,
171  Vector<ValueType>& dhpsioverpsi)
172 {
173  if (dependsOnWaveFunction())
174  throw std::logic_error("Bug!! " + getClassName() +
175  "::evaluateValueAndDerivatives"
176  "must be overloaded when the OperatorBase depends on a wavefunction.");
177 
178  return evaluate(P);
179 }
180 
182  ParticleSet& ions,
183  TrialWaveFunction& psi,
184  ParticleSet::ParticlePos& hf_term,
185  ParticleSet::ParticlePos& pulay_term)
186 {
187  return evaluate(P);
188 }
189 
191  ParticleSet& ions,
192  TrialWaveFunction& psi,
193  ParticleSet::ParticlePos& hf_term,
194  ParticleSet::ParticlePos& pulay_term)
195 {
196  return evaluateWithIonDerivs(P, ions, psi, hf_term, pulay_term);
197 }
198 
200 
202 
204 
206  const RefVectorWithLeader<OperatorBase>& o_list) const
207 {}
208 
210  const RefVectorWithLeader<OperatorBase>& o_list) const
211 {}
212 
214 
216 {
217  std::unique_ptr<OperatorBase> myclone = makeClone(qp, psi);
218  if (myclone)
219  {
220  targetH.addOperator(std::move(myclone), name_, update_mode_[PHYSICAL]);
221  }
222 }
223 
224 #if !defined(REMOVE_TRACEMANAGER)
226 #endif
227 
228 // END FUNCTIONS //
229 
230 bool OperatorBase::isClassical() const noexcept { return quantum_domain_ == CLASSICAL; }
231 
232 bool OperatorBase::isQuantum() const noexcept { return quantum_domain_ == QUANTUM; }
233 
235 
237 
239 
240 bool OperatorBase::getMode(const int i) const noexcept { return update_mode_[i]; }
241 
242 bool OperatorBase::isNonLocal() const noexcept { return update_mode_[NONLOCAL]; }
243 
244 bool OperatorBase::hasListener() const noexcept { return has_listener_; }
245 
246 #if !defined(REMOVE_TRACEMANAGER)
247 
249 {
252 }
253 
255 {
258 }
259 
261 
263 {
266  streaming_scalars_ = false;
267  streaming_particles_ = false;
268  have_required_traces_ = false;
269  request_.reset();
270 }
271 #endif
272 
273 ////// PROTECTED FUNCTIONS
274 #if !defined(REMOVE_TRACEMANAGER)
276 
278 {
280  if (streaming_scalars_)
282 }
283 
285 {
286  if (streaming_scalars_)
287  (*value_sample_)(0) = value_;
288 }
289 
291 {
292  if (streaming_scalars_)
293  delete value_sample_;
294 }
295 
299 #endif
300 
301 void OperatorBase::setComputeForces(bool compute) {}
302 
304 {
305  if (energyDomainValid(edomain))
306  energy_domain_ = edomain;
307  else
308  APP_ABORT("QMCHamiltonainBase::setEnergyDomain\n input energy domain is invalid");
309 }
310 
312 {
313  if (quantumDomainValid(qdomain))
314  quantum_domain_ = qdomain;
315  else
316  APP_ABORT("QMCHamiltonainBase::setQuantumDomain\n input quantum domain is invalid");
317 }
318 
320 {
321  if (P.is_classical())
323  else if (P.is_quantum())
325  else
326  APP_ABORT("OperatorBase::oneBodyQuantumDomain\n quantum domain of input particles is invalid");
327 }
328 
330 {
331  if (P.is_classical())
333  else if (P.is_quantum())
335  else
336  APP_ABORT("OperatorBase::twoBodyQuantumDomain(P)\n quantum domain of input particles is invalid");
337 }
338 
340 {
341  const bool c1 = P1.is_classical();
342  const bool c2 = P2.is_classical();
343  const bool q1 = P1.is_quantum();
344  const bool q2 = P2.is_quantum();
345  if (c1 && c2)
347  else if ((q1 && c2) || (c1 && q2))
349  else if (q1 && q2)
351  else
352  APP_ABORT("OperatorBase::twoBodyQuantumDomain(P1,P2)\n quantum domain of input particles is invalid");
353 }
354 
356 {
358  my_index_ = plist.add(name_.c_str());
359 }
360 
361 ////// PRIVATE FUNCTIONS
362 bool OperatorBase::energyDomainValid(EnergyDomains edomain) const noexcept { return edomain != NO_ENERGY_DOMAIN; }
363 
364 bool OperatorBase::quantumDomainValid(QuantumDomains qdomain) const noexcept { return qdomain != NO_QUANTUM_DOMAIN; }
365 
366 } // namespace qmcplusplus
bool hasListener() const noexcept
virtual void mw_evaluate(const RefVectorWithLeader< OperatorBase > &o_list, const RefVectorWithLeader< TrialWaveFunction > &wf_list, const RefVectorWithLeader< ParticleSet > &p_list) const
Evaluate the contribution of this component of multiple walkers.
virtual std::unique_ptr< OperatorBase > makeClone(ParticleSet &qp, TrialWaveFunction &psi)=0
void twoBodyQuantumDomain(const ParticleSet &P)
set quantum domain for two-body operator
virtual void contributeScalarQuantities()
virtual void releaseResource(ResourceCollection &collection, const RefVectorWithLeader< OperatorBase > &o_list) const
Return a shared resource to a collection.
virtual void registerObservables(std::vector< ObservableHelper > &h5desc, hdf_archive &file) const
add to observable descriptor for hdf5 The default implementation is to register a scalar for this->va...
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
virtual void acquireResource(ResourceCollection &collection, const RefVectorWithLeader< OperatorBase > &o_list) const
Acquire a shared resource from a collection.
virtual void mw_evaluateWithParameterDerivatives(const RefVectorWithLeader< OperatorBase > &o_list, const RefVectorWithLeader< ParticleSet > &p_list, const opt_variables_type &optvars, const RecordArray< ValueType > &dlogpsi, RecordArray< ValueType > &dhpsioverpsi) const
TODO: add docs.
bool isQuantumClassical() const noexcept
void addOperator(std::unique_ptr< OperatorBase > &&h, const std::string &aname, bool physical=true)
add an operator
void collectScalarTraces()
Collect scalar trace data.
int my_index_
starting index of this object
Definition: OperatorBase.h:535
if(c->rank()==0)
virtual Return_t rejectedMove(ParticleSet &P)
TODO: add docs.
Declaration of OperatorBase.
virtual void add2Hamiltonian(ParticleSet &qp, TrialWaveFunction &psi, QMCHamiltonian &targetH)
TODO: add docs.
Collection of Local Energy Operators.
An object of this type is a listener expecting a callback to the report function with a vector of val...
Definition: Listener.hpp:38
bool energyDomainValid(EnergyDomains edomain) const noexcept
return whether the energy domain is valid
class to handle hdf file
Definition: hdf_archive.h:51
bool streaming_scalar(const std::string &name)
Definition: TraceManager.h:242
Vectorized record engine for scalar properties.
virtual void getRequiredTraces(TraceManager &tm)
TODO: add docs.
virtual void collectScalarQuantities()
bool is_classical() const
Definition: ParticleSet.h:171
Attaches a unit to a Vector for IO.
virtual void createResource(ResourceCollection &collection) const
Initialize a shared resource and hand it to a collection.
virtual Return_t evaluateValueAndDerivatives(ParticleSet &P, const opt_variables_type &optvars, const Vector< ValueType > &dlogpsi, Vector< ValueType > &dhpsioverpsi)
Evaluate value and derivatives wrt the optimizables.
TraceRequest request_
whether traces are being collected
Definition: OperatorBase.h:531
virtual void setRandomGenerator(RandomBase< FullPrecRealType > *rng)
Set the Random Generator object TODO: add docs.
OperatorBase()
Construct a new Operator Base object Default and unique empty constructor.
virtual void deleteParticleQuantities()
std::string name_
name of this object
Definition: OperatorBase.h:527
std::bitset< 8 > & getUpdateMode() noexcept
get update_mode_ reference
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
TraceRequest & getRequest() noexcept
Get request_ member.
Array< RealType, 1 > * value_sample_
array to store sample value
Definition: OperatorBase.h:606
virtual void addObservables(PropertySetType &plist, BufferType &collectables)
named values to the property list Default implementaton uses addValue(plist_)
virtual void mw_evaluatePerParticleWithToperator(const RefVectorWithLeader< OperatorBase > &o_list, const RefVectorWithLeader< TrialWaveFunction > &wf_list, const RefVectorWithLeader< ParticleSet > &p_list, const std::vector< ListenerVector< RealType >> &listeners, const std::vector< ListenerVector< RealType >> &listeners_ions) const
Evaluate the contribution of this component of multiple walkers per particle and report to registerd ...
bool isNonLocal() const noexcept
TODO: add docs.
EnergyDomains
enum to denote energy domain of operators
Definition: OperatorBase.h:87
int add(const std::string &aname)
virtual void contributeParticleQuantities()
virtual void mw_evaluatePerParticle(const RefVectorWithLeader< OperatorBase > &o_list, const RefVectorWithLeader< TrialWaveFunction > &wf_list, const RefVectorWithLeader< ParticleSet > &p_list, const std::vector< ListenerVector< RealType >> &listeners, const std::vector< ListenerVector< RealType >> &listeners_ions) const
Evaluate the contribution of this component of multiple walkers per particle and report to registerd ...
void contribute_scalar(const std::string &name, bool default_quantity=false)
Definition: TraceManager.h:189
bool has_listener_
Is there a per particle listener sadly this is necessary due to state machines.
Definition: OperatorBase.h:612
bool quantumDomainValid(QuantumDomains qdomain) const noexcept
return whether the quantum domain is valid
void oneBodyQuantumDomain(const ParticleSet &P)
set quantum domain for one-body operator
bool isQuantum() const noexcept
class to handle a set of variables that can be modified during optimizations
Definition: VariableSet.h:49
bool isClassicalClassical() const noexcept
virtual Return_t evaluateWithIonDerivsDeterministic(ParticleSet &P, ParticleSet &ions, TrialWaveFunction &psi, ParticleSet::ParticlePos &hf_term, ParticleSet::ParticlePos &pulay_term)
Evaluate contribution to local energy and derivatives w.r.t ionic coordinates from OperatorBase...
virtual Return_t evaluateWithIonDerivs(ParticleSet &P, ParticleSet &ions, TrialWaveFunction &psi, ParticleSet::ParticlePos &hf_term, ParticleSet::ParticlePos &pulay_term)
Evaluate contribution to local energy and derivatives w.r.t ionic coordinates from OperatorBase...
#define APP_ABORT(msg)
Widely used but deprecated fatal error macros from legacy code.
Definition: AppAbort.h:27
void setEnergyDomain(EnergyDomains edomain)
Set the Energy Domain.
void setName(const std::string name) noexcept
Set my_name member, uses small string optimization (pass by value)
bool getMode(const int i) const noexcept
Return the mode i.
Walker_t * t_walker_
reference to the current walker
Definition: OperatorBase.h:541
virtual void setHistories(Walker_t &ThisWalker)
void addValue(PropertySetType &plist)
named values to the property list
Return_t getValue() const noexcept
get a copy of value_
Array< TraceReal, D > * checkout_real(const std::string &name, int n1=1, int n2=0, int n3=0, int n4=0)
virtual Return_t getEnsembleAverage()
Return an average value by collective operation.
virtual void updateSource(ParticleSet &s)
Update data associated with a particleset.
FullPrecRealType Return_t
type of return value of evaluate
Definition: OperatorBase.h:64
void checkoutTraceQuantities(TraceManager &tm)
Checkout trace arrays Derived classes must guard individual checkouts using request info...
virtual void setParticlePropertyList(PropertySetType &plist, int offset)
Class to represent a many-body trial wave function.
bool isQuantumQuantum() const noexcept
void set_dimensions(const std::vector< int > &dims, int first)
set the shape of this observable
Return_t value_
current value
Definition: OperatorBase.h:524
virtual Return_t evaluateWithToperator(ParticleSet &P)
Evaluate the local energy contribution of this component with Toperators updated if requested...
std::string getName() const noexcept
getter a copy of my_name_, rvalue small string optimization
virtual void mw_evaluateWithToperator(const RefVectorWithLeader< OperatorBase > &o_list, const RefVectorWithLeader< TrialWaveFunction > &wf_list, const RefVectorWithLeader< ParticleSet > &p_list) const
Evaluate the contribution of this component of multiple walkers.
virtual Return_t evaluate(ParticleSet &P)=0
Evaluate the local energy contribution of this component.
virtual Return_t evaluateDeterministic(ParticleSet &P)
Evaluate the local energy contribution of this component, deterministically based on current state...
bool isClassical() const noexcept
virtual void setObservables(PropertySetType &plist)
Set the values evaluated by this object to plist Default implementation is to assign Value which is u...
void deleteTraceQuantities()
delete trace arrays
virtual bool dependsOnWaveFunction() const
return true if this operator depends on a wavefunction
Definition: OperatorBase.h:124
QuantumDomains quantum_domain_
quantum_domain_ of the (particle) operator, default = no_quantum_domain
Definition: OperatorBase.h:615
virtual void setComputeForces(bool compute)
virtual void checkoutParticleQuantities(TraceManager &tm)
virtual std::string getClassName() const =0
return class name
A container class to represent a walker.
Definition: Walker.h:49
virtual void deleteScalarQuantities()
EnergyDomains energy_domain_
energy domain of the operator (kinetic/potential), default = no_energy_domain
Definition: OperatorBase.h:617
void contributeTraceQuantities()
Make trace quantities available.
void setQuantumDomain(QuantumDomains qdomain)
set quantum domain
std::bitset< 8 > update_mode_
set the current update mode
Definition: OperatorBase.h:521
Declaration of QMCHamiltonian.
ObservableHelper oh
virtual void checkoutScalarQuantities(TraceManager &tm)
virtual void registerCollectables(std::vector< ObservableHelper > &h5desc, hdf_archive &file) const