int WalkerControlBase::copyWalkers(MCWalkerConfiguration& W) { //clear the WalkerList to populate them with the good walkers W.clear(); W.insert(W.begin(), good_w.begin(), good_w.end()); int cur_walker = good_w.size(); for(int i=0; i<good_w.size(); i++) { //,ie+=ncols) { for(int j=0; j<ncopy_w[i]; j++, cur_walker++) { Walker_t* awalker=new Walker_t(*(good_w[i])); awalker->ID=(++NumWalkersCreated)*NumContexts+MyContext; awalker->ParentID=good_w[i]->ParentID; W.push_back(awalker); } } //clear good_w and ncopy_w for the next branch good_w.clear(); ncopy_w.clear(); return W.getActiveWalkers(); }
/** swap Walkers with Recv/Send * * The algorithm ensures that the load per node can differ only by one walker. * The communication is one-dimensional. */ void GlobalWalkerControl::swapWalkersBlocked(MCWalkerConfiguration& W) { NumSwaps++; OffSet[0]=0; for(int i=0; i<NumContexts; i++) OffSet[i+1]=OffSet[i]+NumPerNode[i]; FairPartition(Cur_pop,NumContexts,FairOffSet); int toLeft=FairOffSet[MyContext]-OffSet[MyContext]; int toRight=FairOffSet[MyContext+1]-OffSet[MyContext+1]; Walker_t& wRef(*W[0]); vector<Walker_t*> newW; int num_deleted=0; int last=NumPerNode[MyContext]-1; //scehdule irecv if(toLeft<0) { // recv from node-1 int dn=-toLeft; OOMPI_Packed recvBuffer(dn*wRef.byteSize(),OOMPI_COMM_WORLD); OOMPI_COMM_WORLD[MyContext-1].Recv(recvBuffer); while(dn) { Walker_t *awalker= new Walker_t(wRef); awalker->getMessage(recvBuffer); newW.push_back(awalker); --dn; } } else if(toLeft>0) { //send to node-1 int dn=toLeft; num_deleted+=dn; OOMPI_Packed sendBuffer(dn*wRef.byteSize(),OOMPI_COMM_WORLD); while(dn) { W[last]->putMessage(sendBuffer); --dn; --last; } OOMPI_COMM_WORLD[MyContext-1].Send(sendBuffer); } if(toRight<0) { // send to node+1 int dn=-toRight; num_deleted+=dn; OOMPI_Packed sendBuffer(dn*wRef.byteSize(),OOMPI_COMM_WORLD); while(dn) { W[last]->putMessage(sendBuffer); --dn; --last; } OOMPI_COMM_WORLD[MyContext+1].Send(sendBuffer); } else if(toRight>0) { //recv from node+1 OOMPI_Packed recvBuffer(toRight*wRef.byteSize(),OOMPI_COMM_WORLD); OOMPI_COMM_WORLD[MyContext+1].Recv(recvBuffer); int dn=toRight; while(dn) { Walker_t *awalker= new Walker_t(wRef); awalker->getMessage(recvBuffer); newW.push_back(awalker); --dn; } } while(num_deleted>0) { W.pop_back(); --num_deleted; } if(newW.size()) W.insert(W.end(),newW.begin(),newW.end()); }
/** swap Walkers with Recv/Send * * The algorithm ensures that the load per node can differ only by one walker. * The communication is one-dimensional. */ void WalkerControlMPI::swapWalkersSimple(MCWalkerConfiguration& W) { NumSwaps++; FairDivideLow(Cur_pop,NumContexts,FairOffSet); vector<int> minus, plus; int deltaN; for(int ip=0; ip<NumContexts; ip++) { int dn=NumPerNode[ip]-(FairOffSet[ip+1]-FairOffSet[ip]); if(ip == MyContext) deltaN=dn; if(dn>0) { plus.insert(plus.end(),dn,ip); } else if(dn<0){ minus.insert(minus.end(),-dn,ip); } } Walker_t& wRef(*W[0]); vector<Walker_t*> newW; vector<Walker_t*> oldW; #ifdef MCWALKERSET_MPI_DEBUG char fname[128]; sprintf(fname,"test.%d",MyContext); ofstream fout(fname, ios::app); //fout << NumSwaps << " " << Cur_pop << " "; //for(int ic=0; ic<NumContexts; ic++) fout << NumPerNode[ic] << " "; //fout << " | "; //for(int ic=0; ic<NumContexts; ic++) fout << FairOffSet[ic+1]-FairOffSet[ic] << " "; //fout << " | "; for(int ic=0; ic<plus.size(); ic++) { fout << plus[ic] << " "; } fout << " | "; for(int ic=0; ic<minus.size(); ic++) { fout << minus[ic] << " "; } fout << endl; #endif int nswap=std::min(plus.size(), minus.size()); int last=W.getActiveWalkers()-1; int nsend=0; for(int ic=0; ic<nswap; ic++) { if(plus[ic]==MyContext) { //OOMPI_Packed sendBuffer(wRef.byteSize(),OOMPI_COMM_WORLD); OOMPI_Packed sendBuffer(wRef.byteSize(),myComm->getComm()); W[last]->putMessage(sendBuffer); //OOMPI_COMM_WORLD[minus[ic]].Send(sendBuffer); myComm->getComm()[minus[ic]].Send(sendBuffer); --last; ++nsend; } if(minus[ic]==MyContext) { //OOMPI_Packed recvBuffer(wRef.byteSize(),OOMPI_COMM_WORLD); OOMPI_Packed recvBuffer(wRef.byteSize(),myComm->getComm()); //OOMPI_COMM_WORLD[plus[ic]].Recv(recvBuffer); myComm->getComm()[plus[ic]].Recv(recvBuffer); Walker_t *awalker= new Walker_t(wRef); awalker->getMessage(recvBuffer); newW.push_back(awalker); } } if(nsend) { nsend=NumPerNode[MyContext]-nsend; W.destroyWalkers(W.begin()+nsend, W.end()); } //add walkers from other node if(newW.size()) W.insert(W.end(),newW.begin(),newW.end()); }