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