コード例 #1
0
  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();
  }
コード例 #2
0
/** 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());
}
コード例 #3
0
/** 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());
}