QMCPACK
test_WalkerControl.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 Laboratory
8 //
9 // File created by: Peter Doak, doakpw@ornl.gov, Oak Ridge National Laboratory
10 //////////////////////////////////////////////////////////////////////////////////////
11 
12 
13 #include <functional>
14 #include "catch.hpp"
15 
16 #include "test_WalkerControl.h"
17 #include "Message/Communicate.h"
18 #include "ParticleSetPool.h"
19 #include "WaveFunctionPool.h"
20 #include "HamiltonianPool.h"
24 
25 
26 //#include "Concurrency/Info.hpp"
27 //#include "Concurrency/UtilityFunctions.hpp"
28 
29 namespace qmcplusplus
30 {
31 namespace testing
32 {
34 {
35  int num_ranks = dpools_.comm->size();
36  if (num_ranks != 3)
37  throw std::runtime_error("Bad Rank Count, WalkerControlMPI tests can only be run with 3 MPI ranks.");
38  pop_ =
39  std::make_unique<MCPopulation>(num_ranks, dpools_.comm->rank(), dpools_.particle_pool->getParticleSet("e"),
40  dpools_.wavefunction_pool->getPrimary(), dpools_.hamiltonian_pool->getPrimary());
41 
42  pop_->createWalkers(1, walker_confs);
43 }
44 
45 /** Getting the "fat" walker valid enough to be MPI swapable
46  *
47  * By no means is this "valid" from the perspective of running QMC
48  * See QMCDriverNew::initialLogEvaluation
49  * A fat walker does not seem to be "valid" until all that is done.
50  */
52 {
53  auto walker_elements = pop_->get_walker_elements();
54 
55  for (auto we : walker_elements)
56  {
57  we.pset.update();
58  if (we.walker.DataSet.size() <= 0)
59  {
60  we.walker.registerData();
61  we.twf.registerData(we.pset, we.walker.DataSet);
62  we.walker.DataSet.allocate();
63  }
64  we.twf.copyFromBuffer(we.pset, we.walker.DataSet);
65  we.twf.evaluateLog(we.pset);
66  we.twf.updateBuffer(we.pset, we.walker.DataSet);
67  }
68 }
69 
71 {
72 #if !defined(NDEBUG)
73  std::vector<int> rank_walker_count(c->size(), 0);
74  rank_walker_count[c->rank()] = pop.get_num_local_walkers();
75  c->allreduce(rank_walker_count);
76 
77  const int current_population = std::accumulate(rank_walker_count.begin(), rank_walker_count.end(), 0);
78 
79  if (c->rank() == 0)
80  {
81  std::cout << "Walkers Per Rank (Total: " << current_population << ")\n";
82  for (int i = 0; i < rank_walker_count.size(); ++i)
83  {
84  std::cout << " " << i << " " << rank_walker_count[i] << '\n';
85  }
86  }
87 #endif
88 }
89 
90 void UnifiedDriverWalkerControlMPITest::testNewDistribution(std::vector<int>& minus, std::vector<int>& plus)
91 {
92  std::vector<int> num_per_rank = {3, 1, 1};
93  std::vector<int> fair_offset;
94  WalkerControl::determineNewWalkerPopulation(num_per_rank, fair_offset, minus, plus);
95 }
96 
97 } // namespace testing
98 
99 TEST_CASE("WalkerControl::determineNewWalkerPopulation", "[drivers][walker_control]")
100 {
101  std::vector<int> minus;
102  std::vector<int> plus;
103 
105  CHECK(minus.size() == 2);
106  CHECK(plus.size() == 2);
107 }
108 
109 /** Here we manipulate just the Multiplicity of a set of 1 walkers per rank
110  */
111 // Fails in debug after PR #2855 run unit tests in debug!
112 // trips assert in ../src/Particle/Walker.h:514 !
113 
114 // TEST_CASE("MPI WalkerControl multiplicity swap walkers", "[drivers][walker_control]")
115 // {
116 // auto test_func = []() {
117 // outputManager.pause();
118 // testing::UnifiedDriverWalkerControlMPITest test;
119 // outputManager.resume();
120 // test.makeValidWalkers();
121 // SECTION("Simple")
122 // {
123 // std::vector<int> count_before{1, 1, 1};
124 // std::vector<int> count_after{1, 1, 1};
125 
126 // // One walker on every node, should be no swapping
127 // test.testMultiplicity(count_before, count_after);
128 // }
129 
130 // SECTION("LoadBalance")
131 // {
132 // std::vector<int> count_before{3, 1, 1};
133 // std::vector<int> count_after{1, 2, 2};
134 
135 // test.testMultiplicity(count_before, count_after);
136 // }
137 // };
138 // MPIExceptionWrapper mew;
139 // mew(test_func);
140 // }
141 
142 // Fails in debug after PR #2855 run unit tests in debug!
143 // trips assert at ../src/Particle/Walker.h:559 !
144 // TEST_CASE("MPI WalkerControl population swap walkers", "[drivers][walker_control]")
145 // {
146 // auto test_func = []() {
147 // outputManager.pause();
148 // testing::UnifiedDriverWalkerControlMPITest test;
149 // outputManager.resume();
150 
151 // SECTION("Simple")
152 // {
153 // std::vector<int> count_before{1, 1, 1};
154 // std::vector<int> count_after{1, 1, 1};
155 // // One walker on every node, should be no swapping
156 // test.testPopulationDiff(count_before, count_after);
157 // }
158 
159 // SECTION("LoadBalance")
160 // {
161 // std::vector<int> count_before{3, 1, 1};
162 // std::vector<int> count_after{1, 2, 2};
163 // test.testPopulationDiff(count_before, count_after);
164 // }
165 // };
166 // MPIExceptionWrapper mew;
167 // mew(test_func);
168 // }
169 
170 
171 } // namespace qmcplusplus
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
int rank() const
return the rank
Definition: Communicate.h:116
Declaration of OutputManager class.
void reportWalkersPerRank(Communicate *c, MCPopulation &pop)
UPtr< ParticleSetPool > particle_pool
Definition: SetupPools.h:33
TEST_CASE("complex_helper", "[type_traits]")
#define Random
UPtr< HamiltonianPool > hamiltonian_pool
Definition: SetupPools.h:35
int size() const
return the number of tasks
Definition: Communicate.h:118
void makeValidWalkers()
Getting the "fat" walker valid enough to be MPI swapable.
Wrapping information on parallelism.
Definition: Communicate.h:68
void allreduce(T &)
UPtr< WaveFunctionPool > wavefunction_pool
Definition: SetupPools.h:34
static void testNewDistribution(std::vector< int > &minus, std::vector< int > &plus)
Declaration of WaveFunctionPool.
Declaration of HamiltonianPool.
CHECK(log_values[0]==ComplexApprox(std::complex< double >{ 5.603777579195571, -6.1586603331188225 }))
IndexType get_num_local_walkers() const
Definition: MCPopulation.h:169
static void determineNewWalkerPopulation(const std::vector< int > &num_per_rank, std::vector< int > &fair_offset, std::vector< int > &minus, std::vector< int > &plus)
creates the distribution plan
Declaration of ParticleSetPool.