36 for (
int i = 0; i < vec.size(); i++)
38 std::cout << vec[i] <<
" ";
40 std::cout << std::endl;
44 TEST_CASE(
"Walker control assign walkers",
"[drivers][walker_control]")
48 std::vector<int> FairOffset(NumContexts + 1);
53 std::vector<int> NumPerRank = {4, 4, 0, 0};
54 std::vector<int> NewNum = NumPerRank;
55 for (
int me = 0;
me < NumContexts;
me++)
57 std::vector<int> minus;
58 std::vector<int> plus;
59 std::vector<int> num_per_rank = NumPerRank;
64 REQUIRE(minus.size() == plus.size());
69 for (
int i = 0; i < plus.size(); i++)
74 for (
int i = 0; i < minus.size(); i++)
82 for (
int i = 0; i < NewNum.size(); i++)
84 int num = FairOffset[i + 1] - FairOffset[i];
89 TEST_CASE(
"WalkerControl round trip index conversions",
"[drivers][walker_control]")
91 std::vector<int> walker_counts;
92 for (
int i = 0; i < 1000; ++i)
93 walker_counts.push_back(i);
94 for (
int i = 0; i < 1000000; i += 1000)
95 walker_counts.push_back(i);
96 for (
int i = 0; i < 100000000; i += 100000)
97 walker_counts.push_back(i);
99 std::vector<QMCTraits::FullPrecRealType> fp_counts(walker_counts.size());
100 std::vector<int> walker_count_results(walker_counts.size());
101 for (
int iw = 0; iw < walker_counts.size(); ++iw)
103 fp_counts[iw] = walker_counts[iw];
105 for (
int iw = 0; iw < fp_counts.size(); ++iw)
107 walker_count_results[iw] =
static_cast<int>(fp_counts[iw]);
109 bool all_pass =
true;
110 for (
int iw = 0; iw < walker_counts.size(); ++iw)
112 all_pass &= (walker_counts[iw] == walker_count_results[iw]);
118 TEST_CASE(
"Walker control assign walkers odd ranks",
"[drivers][walker_control]")
122 std::vector<int> NumPerRank = {5, 2, 2};
123 std::vector<int> FairOffset(NumContexts + 1);
125 std::vector<int> NewNum = NumPerRank;
126 for (
int me = 0;
me < NumContexts;
me++)
128 std::vector<int> minus;
129 std::vector<int> plus;
130 std::vector<int> num_per_rank = NumPerRank;
134 REQUIRE(minus.size() == plus.size());
139 for (
int i = 0; i < plus.size(); i++)
144 for (
int i = 0; i < minus.size(); i++)
152 for (
int i = 0; i < NewNum.size(); i++)
154 int num = FairOffset[i + 1] - FairOffset[i];
159 #ifdef PROPERTY_TESTING 168 TEST_CASE(
"Walker control assign walkers many",
"[drivers][walker_control][property]")
174 std::mt19937 mt(100);
175 std::uniform_int_distribution<int> NumNodes(1, 1000);
176 std::uniform_int_distribution<int> TotalPop(0, 1000);
178 for (
int nt = 0; nt < 1000; nt++)
180 int NumContexts = NumNodes(mt);
181 int Cur_pop = TotalPop(mt);
182 std::uniform_int_distribution<int> WalkerPop(0, 2 * Cur_pop / NumContexts);
183 std::vector<int> NumPerRank(NumContexts);
184 int current_pop = Cur_pop;
185 for (
int i = 0; i < NumContexts; i++)
187 int p = WalkerPop(mt);
191 if (i == NumContexts - 1 && current_pop > 0)
201 std::vector<int> NewNum = NumPerRank;
202 for (
int me = 0;
me < NumContexts;
me++)
204 std::vector<int> minus;
205 std::vector<int> plus;
207 determineNewWalkerPopulation(Cur_pop, NumContexts,
me, NumPerRank, minus, plus);
208 REQUIRE(minus.size() == plus.size());
210 for (
int i = 0; i < plus.size(); i++)
215 for (
int i = 0; i < minus.size(); i++)
222 std::vector<int> FairOffset;
224 for (
int i = 0; i < NewNum.size(); i++)
226 int num = FairOffset[i + 1] - FairOffset[i];
235 struct WalkerControlMPITest
239 void operator()(
bool use_nonblocking)
242 WalkerControlMPI wc(c);
244 wc.use_nonblocking = use_nonblocking;
246 const SimulationCell simulation_cell;
247 MCWalkerConfiguration W(simulation_cell);
254 wc.Cur_pop = c->
size();
255 for (
int i = 0; i < c->
size(); i++)
257 wc.NumPerRank[i] = 1;
260 wc.good_w.push_back(std::make_unique<Walker_t>());
261 wc.good_w[0]->setWalkerID(c->
rank());
262 wc.ncopy_w.push_back(0);
264 wc.swapWalkersSimple(W);
266 REQUIRE(wc.good_w.size() == 1);
276 wc.good_w.push_back(std::make_unique<Walker_t>());
277 wc.good_w.push_back(std::make_unique<Walker_t>());
280 wc.good_w[1]->setWalkerID(c->
size());
281 wc.good_w[2]->setWalkerID(c->
size() + 1);
283 wc.ncopy_w.push_back(0);
284 wc.ncopy_w.push_back(0);
286 wc.NumPerRank[0] = 3;
289 wc.swapWalkersSimple(W);
296 REQUIRE(wc.good_w.size() == 2);
299 bool okay1 = wc.good_w[1]->getWalkerID() == c->
size() || wc.good_w[1]->getWalkerID() == c->
size() + 1;
302 else if (c->
rank() == c->
size() - 1)
304 REQUIRE(wc.good_w.size() == 2);
305 bool okay2 = wc.good_w[1]->getWalkerID() == c->
size() || wc.good_w[1]->getWalkerID() == c->
size() + 1;
310 REQUIRE(wc.good_w.size() == 1);
313 wc.NumPerRank[0] = 1;
314 wc.NumPerRank[c->
size() - 1] = 2;
315 wc.NumPerRank[c->
size() - 2] = 2;
325 wc.good_w.push_back(std::make_unique<Walker_t>());
326 wc.good_w.push_back(std::make_unique<Walker_t>());
329 int nwalkers_rank = wc.good_w.size();
330 wc.good_w[nwalkers_rank - 1]->setWalkerID(c->
size() + 5);
331 wc.good_w[nwalkers_rank - 2]->setWalkerID(c->
size() + 4);
335 wc.ncopy_w.push_back(2);
336 wc.ncopy_w.push_back(1);
340 else if (c->
rank() == 1)
344 int nwalkers_rank = wc.good_w.size();
350 wc.NumPerRank[0] = 6;
353 reportWalkersPerRank(c, wc);
355 wc.swapWalkersSimple(W);
357 reportWalkersPerRank(c, wc);
363 CHECK(wc.good_w.size() == 3);
365 else if (c->
rank() == c->
size() - 1)
367 CHECK(wc.good_w.size() == 3);
371 CHECK(wc.good_w.size() == 2);
374 int walker_count = wc.copyWalkers(W);
376 reportWalkersPerRank(c, wc);
380 CHECK(walker_count == 3);
382 else if (c->
rank() == c->
size() - 1)
384 CHECK(walker_count == 4);
388 CHECK(walker_count == 3);
394 void reportWalkersPerRank(
Communicate* c, WalkerControlMPI& wc)
396 std::vector<int> rank_walker_count(c->
size(), 0);
397 rank_walker_count[c->
rank()] = wc.good_w.size();
401 std::cout <<
"Walkers Per Rank (Total: " << wc.Cur_pop <<
")\n";
402 for (
int i = 0; i < rank_walker_count.size(); ++i)
404 std::cout <<
" " << i <<
" " << rank_walker_count[i] <<
"\n";
410 void test_swap_walkers(
bool use_nonblocking)
412 WalkerControlMPITest test;
413 test(use_nonblocking);
416 TEST_CASE(
"Walker control swap walkers blocking",
"[drivers][walker_control]")
420 bool non_blocking =
false;
421 test_swap_walkers(non_blocking);
425 TEST_CASE(
"Walker control swap walkers nonblocking",
"[drivers][walker_control]")
427 SECTION(
"nonblocking")
429 bool non_blocking =
true;
430 test_swap_walkers(non_blocking);
434 TEST_CASE(
"Walker control reconfiguration",
"[drivers][walker_control]")
437 WalkerReconfigurationMPI wr(c);
439 wr.dN.resize(c->
size());
441 wr.dN[c->
rank()] = 0;
448 const SimulationCell simulation_cell;
449 MCWalkerConfiguration W(simulation_cell);
459 W[0]->setWalkerID(1);
462 std::vector<int> plus, minus;
473 wr.sendWalkers(W, plus);
474 REQUIRE(W.getActiveWalkers() == 1);
475 REQUIRE(W[0]->getWalkerID() == 100);
478 if (minus.size() > 0)
480 wr.recvWalkers(W, minus);
481 REQUIRE(W.getActiveWalkers() == 1);
484 REQUIRE(W[0]->getParentID() == 100);
helper functions for EinsplineSetBuilder
int rank() const
return the rank
TEST_CASE("complex_helper", "[type_traits]")
static void determineNewWalkerPopulation(int cur_pop, int num_contexts, int my_context, std::vector< int > &num_per_rank, std::vector< int > &fair_offset, std::vector< int > &minus, std::vector< int > &plus)
creates the distribution plan
Communicate * Controller
Global Communicator for a process.
int size() const
return the number of tasks
void FairDivideLow(int ntot, int npart, IV &adist)
partition ntot elements among npart
Wrapping information on parallelism.
REQUIRE(std::filesystem::exists(filename))
void output_vector(const std::string &name, std::vector< int > &vec)
WalkerConfigurations::Walker_t Walker_t
CHECK(log_values[0]==ComplexApprox(std::complex< double >{ 5.603777579195571, -6.1586603331188225 }))
void setWalkerID(long walker_id)
set function for walker walker_id_ only necessary because as an optimization we reuse walkers...
Declare a global Random Number Generator.
Declaration of a MCWalkerConfiguration.