コード例 #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 using (low,high) ordered pairs
 *
 * The communication occur only between the (low,high) pairs.
 * This does not guarantee a perfect balance swapWalkersBlocked and swapWalkersAsync
 * try to achieve. However, the number of messages and their sizes are less than
 * other methods.
 */
void GlobalWalkerControl::swapWalkersMap(MCWalkerConfiguration& W) {

  NumSwaps++;
  multimap<int,int> nw_map;
  for(int i=0; i<NumContexts; i++) {
    nw_map.insert(pair<int,int>(NumPerNode[i],i));
  }
  // multimap key is sorted with ascending order 
  multimap<int,int>::iterator it(nw_map.begin());
  multimap<int,int>::reverse_iterator it_b(nw_map.end());
  bool notpaired=true;
  int target_context=-1;
  int half=NumContexts/2;
  int item=0;
  bool minorcontext;
  while(notpaired &&item<half) {
    int i=(*it).second;
    int j=(*it_b).second;
    if(i == MyContext) {
      target_context=j;
      notpaired=false;
      minorcontext=true;
    } else if(j == MyContext) {
      target_context= i;
      notpaired=false;
      minorcontext=false;
    } 
    ++it; ++it_b; ++item;
  }

  int nw_tot=NumPerNode[MyContext]+NumPerNode[target_context];
  int nw_L=nw_tot/2;
  int nw_R=nw_tot-nw_L;
  int dnw(0);
  if(minorcontext) {
    dnw=nw_L-NumPerNode[MyContext];//how many to get
  } else {
    dnw=NumPerNode[MyContext]-nw_R;//how many to send
  }

  if(dnw) {//something to swap
    if(minorcontext) {//open recv buffer
      Walker_t& wRef(*W[0]);
      OOMPI_Packed recvBuffer(dnw*wRef.byteSize(),OOMPI_COMM_WORLD);
      OOMPI_COMM_WORLD[target_context].Recv(recvBuffer);
      //create walkers
      int last = W.getActiveWalkers();
      while(dnw) {
        Walker_t *awalker= new Walker_t(wRef);
        awalker->getMessage(recvBuffer);
        W.push_back(awalker);
        --dnw; ++last;
      }
    } else {
      Walker_t& wRef(*W[0]);
      OOMPI_Packed sendBuffer(dnw*wRef.byteSize(),OOMPI_COMM_WORLD);
      int last=W.getActiveWalkers()-1;
      while(dnw) {
        W[last]->putMessage(sendBuffer);
        --dnw; --last;
      }
      OOMPI_COMM_WORLD[target_context].Send(sendBuffer);
      //last=WalkerList.size()-1;
      //while(dnw_save) {
      //  delete WalkerList[last]; 
      //  WalkerList.pop_back();
      //  --dnw_save; --last;
      //}
      //destroyWalkers(WalkerList.begin()+nsub[MyContext], WalkerList.end());
      W.destroyWalkers(W.begin()+nw_R, W.end());
    }
  }

  /* not used yet
  struct lessNode {
    inline bool operator()(const pair<int,int>& a,
        const pair<int,int>& b) const {
      return a.second < b.second;
    }
  };
  //typedef pair<int,int> mytype;
  //vector<mytype> id2n(NumContexts);
  //for(int i=0; i<NumContexts; i++) {
  //  id2n=pair<int,int>(i,NumPerNode[i]);
  //}
  //
  //std::sort(id2n.begin(),id2n.end(),lessNode);
  */
}
コード例 #3
0
/** swap Walkers with Irecv/Send 
 *
 * The algorithm ensures that the load per node can differ only by one walker.
 * The communication is one-dimensional. 
 */
void GlobalWalkerControl::swapWalkersAsync(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]);

  int num_deleted=0;
  int last=NumPerNode[MyContext]-1;

  OOMPI_Packed* recvLeftBuffer=0;
  OOMPI_Packed* recvRightBuffer=0;
  OOMPI_Request recvLeftRequest;
  OOMPI_Request recvRightRequest;

  //initiate Irecv
  if(toLeft<0) { // recv from node-1 
    int dn=-toLeft;
    recvLeftBuffer = new OOMPI_Packed(dn*wRef.byteSize(),OOMPI_COMM_WORLD);
    recvLeftRequest = OOMPI_COMM_WORLD[MyContext-1].Irecv(*recvLeftBuffer,MPI_ANY_TAG);
  } 
  if(toRight>0) { //recv from node+1
    recvRightBuffer = new OOMPI_Packed(toRight*wRef.byteSize(),OOMPI_COMM_WORLD);
    recvRightRequest = OOMPI_COMM_WORLD[MyContext+1].Irecv(*recvRightBuffer,MPI_ANY_TAG);
  }
  
  //send the data
  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);
  } 

  while(num_deleted>0) {
    W.pop_back(); --num_deleted;
  }

  if(recvLeftBuffer) {
    recvLeftRequest.Wait();
    int dn=-toLeft;
    while(dn) {
      Walker_t *awalker= new Walker_t(wRef);
      awalker->getMessage(*recvLeftBuffer);
      W.push_back(awalker);
      --dn;
    }
    delete recvLeftBuffer;
    recvLeftBuffer=0;
  }

  if(recvRightBuffer) {
    recvRightRequest.Wait();
    int dn=toRight;
    while(dn) {
      Walker_t *awalker= new Walker_t(wRef);
      awalker->getMessage(*recvRightBuffer);
      W.push_back(awalker);
      --dn;
    }
    delete recvRightBuffer;
    recvRightBuffer=0;
  }
}