QMCPACK
test_MCPopulation.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) 2020 QMCPACK developers.
6 //
7 // File developed by: Peter Doak, doakpw@ornl.gov, Oak Ridge National Laboratory
8 //
9 // File created by: Peter Doak, doakpw@ornl.gov, Oak Ridge National Laboratory
10 //////////////////////////////////////////////////////////////////////////////////////
11 
12 
13 #include "catch.hpp"
14 #include <vector>
15 #include <algorithm>
16 
17 #include "Configuration.h"
18 #include "OhmmsPETE/TinyVector.h"
25 
26 namespace qmcplusplus
27 {
28 TEST_CASE("MCPopulation::createWalkers", "[particle][population]")
29 {
30  using namespace testing;
31 
32  RuntimeOptions runtime_options;
34 
38  TrialWaveFunction twf(runtime_options);
39  WalkerConfigurations walker_confs;
40 
41  // Test is intended to be run on one rank
42  MCPopulation population(1, comm->rank(), particle_pool.getParticleSet("e"), &twf, hamiltonian_pool.getPrimary());
43 
44  population.createWalkers(8, walker_confs, 2.0);
45  CHECK(population.get_walkers().size() == 8);
46  CHECK(population.get_dead_walkers().size() == 8);
47  CHECK(population.get_num_local_walkers() == 8);
48  population.saveWalkerConfigurations(walker_confs);
49  CHECK(walker_confs.getActiveWalkers() == 8);
50 
51  MCPopulation population2(1, comm->rank(), particle_pool.getParticleSet("e"), &twf, hamiltonian_pool.getPrimary());
52  // keep 3 only configurations.
53  walker_confs.resize(3, 0);
54  CHECK(walker_confs.getActiveWalkers() == 3);
55  auto old_R00 = walker_confs[0]->R[0][0];
56  // first and second configurations are both copied from the gold particle set.
57  // must be identical.
58  CHECK(walker_confs[1]->R[0][0] == old_R00);
59  // modify the first configuration
60  auto new_R00 = walker_confs[1]->R[0][0] = 0.3;
61  population2.createWalkers(8, walker_confs, 1.0);
62  CHECK(population2.get_walkers()[0]->R[0][0] == old_R00);
63  CHECK(population2.get_walkers()[1]->R[0][0] == new_R00);
64  CHECK(population2.get_walkers()[2]->R[0][0] == old_R00);
65  CHECK(population2.get_walkers()[3]->R[0][0] == old_R00);
66  CHECK(population2.get_walkers()[4]->R[0][0] == new_R00);
67  CHECK(population2.get_walkers()[5]->R[0][0] == old_R00);
68  CHECK(population2.get_walkers()[6]->R[0][0] == old_R00);
69  CHECK(population2.get_walkers()[7]->R[0][0] == new_R00);
70 }
71 
72 
73 TEST_CASE("MCPopulation::createWalkers_walker_ids", "[particle][population]")
74 {
75  using namespace testing;
76 
77  RuntimeOptions runtime_options;
79 
83  TrialWaveFunction twf(runtime_options);
84  WalkerConfigurations walker_confs;
85 
86  std::vector<MCPopulation> pops;
87 
88  int num_ranks = 3;
89  for (int i = 0; i < num_ranks; ++i)
90  pops.emplace_back(num_ranks, i, particle_pool.getParticleSet("e"), &twf, hamiltonian_pool.getPrimary());
91 
92  std::vector<long> walker_ids;
93  for (int i = 0; i < num_ranks; ++i)
94  {
95  pops[i].createWalkers(8, walker_confs, 2.0);
96  CHECK(pops[i].get_walkers().size() == 8);
97  CHECK(pops[i].get_dead_walkers().size() == 8);
98  CHECK(pops[i].get_num_local_walkers() == 8);
99  auto walker_elems = pops[i].get_walker_elements();
100  for (WalkerElementsRef& wer : walker_elems)
101  {
102  walker_ids.push_back(wer.walker.getWalkerID());
103  }
104  }
105  std::sort(walker_ids.begin(), walker_ids.end());
106  // Walker IDs cannot collide
107  for (int i = 1; i < walker_ids.size(); ++i)
108  CHECK(walker_ids[i - 1] != walker_ids[i]);
109 
110  int new_walkers = 3;
111 
112  for (int i = 0; i < num_ranks; ++i)
113  for (int iw = 0; iw < new_walkers; ++iw)
114  {
115  auto wer = pops[i].spawnWalker();
116  walker_ids.push_back(wer.walker.getWalkerID());
117  }
118 
119  std::sort(walker_ids.begin(), walker_ids.end());
120  // Walker IDs cannot collide
121  for (int i = 1; i < walker_ids.size(); ++i)
122  CHECK(walker_ids[i - 1] != walker_ids[i]);
123 }
124 
125 
126 // TEST_CASE("MCPopulation::createWalkers first touch", "[particle][population]")
127 // {
128 // MCPopulation population(1, 2);
129 // ParticleAttrib<TinyVector<QMCTraits::RealType, 3>> some_pos(2);
130 // some_pos[0] = TinyVector<double, 3>(1.0, 0.0, 0.0);
131 // some_pos[1] = TinyVector<double, 3>(0.0, 1.0, 0.0);
132 
133 // population.createWalkers(8, 2, 16, some_pos);
134 // REQUIRE(population.get_walkers().size() == 16);
135 // // Someday here we should use hwloc or similar to query that the memory is close to
136 // // each thread.
137 // }
138 
139 TEST_CASE("MCPopulation::redistributeWalkers", "[particle][population]")
140 {
141  using namespace testing;
142 
143  RuntimeOptions runtime_options;
145 
149  WalkerConfigurations walker_confs;
150  MCPopulation population(1, comm->rank(), particle_pool.getParticleSet("e"), wavefunction_pool.getPrimary(),
151  hamiltonian_pool.getPrimary());
152 
153  population.createWalkers(8, walker_confs);
154  REQUIRE(population.get_walkers().size() == 8);
155 
156  std::vector<std::unique_ptr<WalkerConsumer>> walker_consumers(2);
157  std::for_each(walker_consumers.begin(), walker_consumers.end(),
158  [](std::unique_ptr<WalkerConsumer>& wc) { wc.reset(new WalkerConsumer()); });
159  population.redistributeWalkers(walker_consumers);
160 
161  REQUIRE((*walker_consumers[0]).walkers.size() == 4);
162 
163  std::vector<std::unique_ptr<WalkerConsumer>> walker_consumers_incommensurate(3);
164  std::for_each(walker_consumers_incommensurate.begin(), walker_consumers_incommensurate.end(),
165  [](std::unique_ptr<WalkerConsumer>& wc) { wc.reset(new WalkerConsumer()); });
166 
167  population.redistributeWalkers(walker_consumers_incommensurate);
168  REQUIRE((*walker_consumers_incommensurate[0]).walkers.size() == 3);
169  REQUIRE((*walker_consumers_incommensurate[2]).walkers.size() == 2);
170 }
171 
172 } // namespace qmcplusplus
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
int rank() const
return the rank
Definition: Communicate.h:116
size_t getActiveWalkers() const
return the number of active walkers
type for returning the walker and its elements from MCPopulation
static ParticleSetPool make_diamondC_1x1x1(Communicate *c)
A set of light weight walkers that are carried between driver sections and restart.
TEST_CASE("complex_helper", "[type_traits]")
static WaveFunctionPool make_diamondC_1x1x1(const RuntimeOptions &runtime_options, Communicate *comm, ParticleSetPool &particle_pool)
const char walkers[]
Definition: HDFVersion.h:36
Communicate * Controller
Global Communicator for a process.
Definition: Communicate.cpp:35
mock class to avoid testing dependency between Crowd and MCPopulation
Wrapping information on parallelism.
Definition: Communicate.h:68
REQUIRE(std::filesystem::exists(filename))
void createWalkers(int numWalkers, size_t numPtcls)
create numWalkers Walkers
void createWalkers(IndexType num_walkers, const WalkerConfigurations &walker_configs, RealType reserve=1.0)
}@
static HamiltonianPool make_hamWithEE(Communicate *comm, ParticleSetPool &particle_pool, WaveFunctionPool &wavefunction_pool)
void resize(int numWalkers, size_t numPtcls)
clean up the walker list and make a new list
Class to represent a many-body trial wave function.
CHECK(log_values[0]==ComplexApprox(std::complex< double >{ 5.603777579195571, -6.1586603331188225 }))