QMCPACK
test_PerParticleHamiltonianLogger.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: Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab
8 //
9 // File created by: Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab
10 //////////////////////////////////////////////////////////////////////////////////////
11 
12 #include "catch.hpp"
13 
15 
16 #include <filesystem>
17 
18 #include "Utilities/StdRandom.h"
19 
20 namespace qmcplusplus
21 {
22 
23 using QMCT = QMCTraits;
24 using Real = QMCT::RealType;
25 
27 {
28 private:
29  std::vector<ListenerVector<Real>> listener_vectors_;
30  const std::string name_{"Talker"};
31  int walkers_;
32 
33 public:
34  MultiWalkerTalker(const std::string& name, int walkers) : name_(name), walkers_(walkers){};
35  void registerVector(ListenerVector<Real>& listener_vector) { listener_vectors_.push_back(listener_vector); }
36  void reportVector()
37  {
38  Vector<Real> vec_part(4);
39 
40  for (auto& listener : listener_vectors_)
41  for (int iw = 0; iw < walkers_; ++iw)
42  {
43  std::iota(vec_part.begin(), vec_part.end(), iw * walkers_);
44 
45  listener.report(iw, name_, vec_part);
46  }
47  }
48 };
49 
50 
51 TEST_CASE("PerParticleHamiltonianLogger_sum", "[estimators]")
52 {
53  std::string_view xml{R"XML(
54 <PerParticleHamiltonianLogger to_stdout="false"/>
55 )XML"};
56 
58  bool okay = doc.parseFromString(xml);
59  REQUIRE(okay);
60  xmlNodePtr node = doc.getRoot();
62 
63  CHECK(!pphli.get_to_stdout());
64 
65  if (std::filesystem::exists("rank_0_per_particle_log.dat"))
66  std::filesystem::remove("rank_0_per_particle_log.dat");
67 
68  {
69  int rank = 0;
70  PerParticleHamiltonianLogger rank_logger(std::move(pphli), rank);
71 
72  int ncrowds = 3;
73 
74  UPtrVector<OperatorEstBase> crowd_loggers;
75  for (int ic = 0; ic < ncrowds; ++ic)
76  {
77  crowd_loggers.emplace_back(rank_logger.spawnCrowdClone());
78  }
79 
80  int nwalkers = 3;
81 
82  const SimulationCell simulation_cell;
83  std::vector<OperatorEstBase::MCPWalker> walkers;
84  for (int iw = 0; iw < nwalkers; ++iw)
85  walkers.emplace_back(iw, iw, 2);
86 
87  std::vector<ParticleSet> psets;
88  for (int iw = 0; iw < nwalkers; ++iw)
89  {
90  psets.emplace_back(simulation_cell);
91  ParticleSet& pset = psets.back();
92  pset.create({2});
93  pset.R[0] = ParticleSet::PosType(0.00000000, 0.00000000, 0.00000000);
94  pset.R[1] = ParticleSet::PosType(0.68658058, 0.68658058, 0.68658058);
95  }
96 
97  std::vector<TrialWaveFunction> wfns;
98  std::vector<QMCHamiltonian> hams;
99 
100  auto ref_walkers = makeRefVector<OperatorEstBase::MCPWalker>(walkers);
101  auto ref_psets = makeRefVector<ParticleSet>(psets);
102  auto ref_wfns = makeRefVector<TrialWaveFunction>(wfns);
103  auto ref_hams = makeRefVector<QMCHamiltonian>(hams);
104 
105  std::vector<MultiWalkerTalker> multi_walker_talkers{{"Talker1", nwalkers},
106  {"Talker2", nwalkers},
107  {"Talker3", nwalkers}};
108  for (auto& crowd_oeb : crowd_loggers)
109  for (auto& mwt : multi_walker_talkers)
110  {
111  auto& crowd_logger = dynamic_cast<PerParticleHamiltonianLogger&>(*crowd_oeb);
112  ListenerVector<Real> listener("whatever", crowd_logger.getLogger());
113  mwt.registerVector(listener);
114  }
115 
116  rank_logger.startBlock(100);
117  CHECK(rank_logger.get_block() == 1);
118 
119  for (auto& mwt : multi_walker_talkers)
120  mwt.reportVector();
121 
123 
124  int crowd_id = 0;
125  long walker_id = 0;
126  for (auto& crowd_oeb : crowd_loggers)
127  {
128  // Mocking walker ids
129  using Walker = typename decltype(ref_walkers)::value_type::type;
130  for(Walker& walker : ref_walkers)
131  walker.setWalkerID(walker_id++);
132  crowd_oeb->accumulate(ref_walkers, ref_psets, ref_wfns, ref_hams, rng);
133  }
134 
135  RefVector<OperatorEstBase> crowd_loggers_refs = convertUPtrToRefVector(crowd_loggers);
136  rank_logger.collect(crowd_loggers_refs);
137  }
138  // Now that the rank_logger has be destroyed its file must be present
139  CHECK(std::filesystem::exists("rank_0_per_particle_log.dat"));
140 }
141 
142 } // namespace qmcplusplus
class that handles xmlDoc
Definition: Libxml2Doc.h:76
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
QTBase::RealType RealType
Definition: Configuration.h:58
if(!okay) throw std xmlNodePtr node
UPtr< OperatorEstBase > spawnCrowdClone() const override
TEST_CASE("complex_helper", "[type_traits]")
xmlNodePtr getRoot()
Definition: Libxml2Doc.h:88
An object of this type is a listener expecting a callback to the report function with a vector of val...
Definition: Listener.hpp:38
std::vector< std::unique_ptr< T > > UPtrVector
const char walkers[]
Definition: HDFVersion.h:36
static RefVector< T > convertUPtrToRefVector(const UPtrVector< T > &ptr_list)
convert a vector of std::unique_ptrs<T> to a refvector<T>
void registerVector(ListenerVector< Real > &listener_vector)
ForceBase::Real Real
Definition: ForceBase.cpp:26
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
REQUIRE(std::filesystem::exists(filename))
A minimally functional wrapper for the since c++11 <random>
QTBase::PosType PosType
Definition: Configuration.h:61
std::vector< ListenerVector< Real > > listener_vectors_
std::vector< std::reference_wrapper< T > > RefVector
bool parseFromString(const std::string_view data)
Definition: Libxml2Doc.cpp:204
CHECK(log_values[0]==ComplexApprox(std::complex< double >{ 5.603777579195571, -6.1586603331188225 }))
void collect(const RefVector< OperatorEstBase > &type_erased_operator_estimators) override
Reduce estimator result data from crowds to rank.
MultiWalkerTalker(const std::string &name, int walkers)
A container class to represent a walker.
Definition: Walker.h:49