123 walker->Multiplicity = 1.0;
135 std::vector<int>& num_per_rank,
136 std::vector<int>& fair_offset,
137 std::vector<int>& minus,
138 std::vector<int>& plus)
141 for (
int ip = 0; ip < num_contexts; ip++)
144 int dn = num_per_rank[ip] - (fair_offset[ip + 1] - fair_offset[ip]);
145 num_per_rank[ip] -= dn;
148 plus.insert(plus.end(), dn, ip);
152 minus.insert(minus.end(), -dn, ip);
156 if (plus.size() != minus.size())
158 app_error() <<
"Walker send/recv pattern doesn't match. " 159 <<
"The send size " << plus.size() <<
" is not equal to the recv size " << minus.size() <<
" ." 161 throw std::runtime_error(
"Trying to swap in WalkerControlMPI::swapWalkersSimple with mismatched queues");
179 std::vector<int> minus, plus;
186 app_error() <<
"It should never happen that no walkers, " 187 <<
"neither good nor bad, exist on a rank. " 188 <<
"Please report to developers. " << std::endl;
189 APP_ABORT(
"WalkerControlMPI::swapWalkersSimple no existing walker");
193 std::vector<std::unique_ptr<Walker_t>> newW;
194 std::vector<int> ncopy_newW;
195 #ifdef MCWALKERSET_MPI_DEBUG 196 std::array<char, 128> fname;
197 if (std::snprintf(fname.data(), fname.size()
"test.%d",
MyContext) < 0)
198 throw std::runtime_error(
"Error generating filename");
199 std::ofstream fout(fname.data(), std::ios::app);
205 for (
int ic = 0; ic < plus.size(); ic++)
207 fout << plus[ic] <<
" ";
210 for (
int ic = 0; ic < minus.size(); ic++)
212 fout << minus[ic] <<
" ";
216 int nswap = plus.size();
219 std::vector<std::pair<int, int>> ncopy_pairs;
220 for (
int iw = 0; iw <
ncopy_w.size(); iw++)
221 ncopy_pairs.push_back(std::make_pair(
ncopy_w[iw], iw));
222 std::sort(ncopy_pairs.begin(), ncopy_pairs.end());
229 job(
int wid,
int target_in) : walkerID(wid), target(target_in){};
231 std::vector<job> job_list;
232 for (
int ic = 0; ic < nswap; ic++)
237 auto& awalker =
good_w[ncopy_pairs.back().second];
241 for (
int id = ic + 1;
id < nswap;
id++)
242 if (plus[ic] == plus[
id] && minus[ic] == minus[
id] && ncopy_pairs.back().first > 0)
244 ncopy_pairs.back().first--;
253 myComm->comm.send_value(nsentcopy, minus[ic]);
254 job_list.push_back(job(ncopy_pairs.back().second, minus[ic]));
255 #ifdef MCWALKERSET_MPI_DEBUG 256 fout <<
"rank " << plus[ic] <<
" sends a walker with " << nsentcopy <<
" copies to rank " << minus[ic]
265 if (ncopy_pairs.back().first > 0)
267 ncopy_pairs.back().first--;
268 std::sort(ncopy_pairs.begin(), ncopy_pairs.end());
272 ncopy_pairs.pop_back();
273 bad_w.push_back(std::make_unique<Walker_t>(*awalker));
278 std::unique_ptr<Walker_t> awalker;
281 awalker = std::move(
bad_w.back());
287 myComm->comm.receive_n(&nsentcopy, 1, plus[ic]);
288 job_list.push_back(job(newW.size(), plus[ic]));
289 if (plus[ic] != plus[ic + nsentcopy] || minus[ic] != minus[ic + nsentcopy])
290 APP_ABORT(
"WalkerControlMPI::swapWalkersSimple send/recv pair checking failed!");
291 #ifdef MCWALKERSET_MPI_DEBUG 292 fout <<
"rank " << minus[ic] <<
" recvs a walker with " << nsentcopy <<
" copies from rank " << plus[ic]
299 newW.push_back(std::make_unique<Walker_t>(*awalker));
303 newW.push_back(
nullptr);
305 ncopy_newW.push_back(nsentcopy);
313 std::vector<mpi3::request> requests;
315 for (
auto jobit = job_list.begin(); jobit != job_list.end(); jobit++)
316 good_w[jobit->walkerID]->SendInProgress =
false;
317 for (
auto jobit = job_list.begin(); jobit != job_list.end(); jobit++)
320 auto& awalker =
good_w[jobit->walkerID];
321 size_t byteSize = awalker->byteSize();
322 if (!awalker->SendInProgress)
324 awalker->updateBuffer();
325 awalker->SendInProgress =
true;
328 requests.push_back(
myComm->comm.isend_n(awalker->DataSet.data(), byteSize, jobit->target));
332 myComm->comm.send_n(awalker->DataSet.data(), byteSize, jobit->target);
338 for (
int im = 0; im < requests.size(); im++)
348 std::vector<mpi3::request> requests;
349 for (
auto jobit = job_list.begin(); jobit != job_list.end(); jobit++)
352 auto& awalker = newW[jobit->walkerID];
354 awalker = std::make_unique<Walker_t>(wRef);
355 size_t byteSize = awalker->byteSize();
357 requests.push_back(
myComm->comm.ireceive_n(awalker->DataSet.data(), byteSize, jobit->target));
361 myComm->comm.receive_n(awalker->DataSet.data(), byteSize, jobit->target);
362 awalker->copyFromBuffer();
367 std::vector<bool> not_completed(requests.size(),
true);
368 bool completed =
false;
372 for (
int im = 0; im < requests.size(); im++)
373 if (not_completed[im])
375 if (requests[im].completed())
377 newW[job_list[im].walkerID]->copyFromBuffer();
378 not_completed[im] =
false;
390 std::vector<std::unique_ptr<Walker_t>> good_w_temp(std::move(
good_w));
391 good_w.resize(ncopy_pairs.size());
392 ncopy_w.resize(ncopy_pairs.size());
393 for (
int iw = 0; iw < ncopy_pairs.size(); iw++)
395 good_w[iw] = std::move(good_w_temp[ncopy_pairs[iw].
second]);
396 ncopy_w[iw] = ncopy_pairs[iw].first;
401 good_w.insert(
good_w.end(), std::make_move_iterator(newW.begin()), std::make_move_iterator(newW.end()));
402 ncopy_w.insert(
ncopy_w.end(), ncopy_newW.begin(), ncopy_newW.end());
std::vector< std::unique_ptr< Walker_t > > bad_w
IndexType NumWalkers
current number of walkers per processor
int copyWalkers(MCWalkerConfiguration &W)
legacy: copy good walkers to W
A set of walkers that are to be advanced by Metropolis Monte Carlo.
std::vector< int > NumPerRank
number of particle per rank
int branch(int iter, MCWalkerConfiguration &W, FullPrecRealType trigger) override
legacy: perform branch and swap walkers as required
helper functions for EinsplineSetBuilder
std::vector< TimerIDName_t< T > > TimerNameList_t
std::ostream & app_error()
std::vector< int > ncopy_w
temporary storage for copy counters
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
IndexType MyContext
context id
void FairDivideLow(int ntot, int npart, IV &adist)
partition ntot elements among npart
for(int i=0;i< size_test;++i) CHECK(Approx(gauss_random_vals[offset_for_rs+i])
WalkerControlMPI(Communicate *comm)
default constructor
bool use_nonblocking
Use non-blocking isend/irecv.
TimerNameList_t< DMC_MPI_Timers > DMCMPITimerNames
Wrapping information on parallelism.
std::vector< int > FairOffSet
offset of the particle index for a fair distribution
A collection of functions for dividing fairly.
Communicate * myComm
pointer to Communicate
void measureProperties(int iter)
take averages and writes to a file
std::vector< FullPrecRealType > curData
any temporary data includes many ridiculous conversions of integral types to and from fp ...
#define APP_ABORT(msg)
Widely used but deprecated fatal error macros from legacy code.
IndexType num_contexts_
number of contexts
Declaration of a TrialWaveFunction.
std::vector< std::unique_ptr< Walker_t > > good_w
temporary storage for good and bad walkers
void swapWalkersSimple(MCWalkerConfiguration &W)
legacy: swap implementation
Base class to control the walkers for DMC simulations.
QMCTraits::FullPrecRealType FullPrecRealType
typedef of FullPrecRealType
TimerManager< NewTimer > & getGlobalTimerManager()
int sortWalkers(MCWalkerConfiguration &W)
legacy: sort Walkers between good and bad and prepare branching
MCDataType< FullPrecRealType > EnsembleProperty
MCDataType< FullPrecRealType > ensemble_property_
ensemble properties
IndexType SwapMode
0 is default
A container class to represent a walker.
int applyNmaxNmin(int current_population)
legacy: apply per rank limit Nmax and Nmin