예제 #1
0
bool Communicator::Test_all(CommunicationTAG tag) {
  bool received = true;
  for (int i=0; i<Get_size(); i++) {
    if (i == Get_rank()) continue;
    MPI::Request* request = Get_request(i, tag);
    if (!request->Test()) {
      received = false;
      break;
    }
  }

  return received;
}
예제 #2
0
/*
* Receive a block.
*/
void PackedData::recv(MPI::Intracomm& comm, int source)
{
    MPI::Request request;
    int  myRank     = comm.Get_rank();
    int  comm_size  = comm.Get_size();

    // Preconditons
    if (source > comm_size - 1 || source < 0) {
        UTIL_THROW("Source rank out of bounds");
    }
    if (source == myRank) {
        UTIL_THROW("Source and desination identical");
    }

    request = comm.Irecv(begin_, capacity_, MPI::UNSIGNED_CHAR, source, 5);
    request.Wait();
    cursor_ = begin_;

}
예제 #3
0
/*
* Send a block.
*/
void PackedData::send(MPI::Intracomm& comm, int dest)
{
    MPI::Request request;
    int  sendBytes = 0;
    int  comm_size = comm.Get_size();
    int  myRank = comm.Get_rank();

    // Preconditions
    if (dest > comm_size - 1 || dest < 0) {
        UTIL_THROW("Destination rank out of bounds");
    }
    if (dest == myRank) {
        UTIL_THROW("Source and desination identical");
    }

    sendBytes = cursor_ - begin_;
    request = comm.Isend(begin_, sendBytes, MPI::UNSIGNED_CHAR, dest, 5);
    request.Wait();

}
예제 #4
0
   /*
   * Receive a buffer.
   */
   void Buffer::recv(MPI::Intracomm& comm, int source)
   {
      MPI::Request request;
      int  myRank     = comm.Get_rank();
      int  comm_size  = comm.Get_size();

      // Preconditons
      if (source > comm_size - 1 || source < 0) {
         UTIL_THROW("Source rank out of bounds");
      }
      if (source == myRank) {
         UTIL_THROW("Source and destination identical");
      }

      request = comm.Irecv(recvBufferBegin_, bufferCapacity_, 
                           MPI::CHAR, source, 5);
      request.Wait();
      recvType_ = NONE;
      recvPtr_ = recvBufferBegin_;
   }
예제 #5
0
   /*
   * Send a buffer.
   */
   void Buffer::send(MPI::Intracomm& comm, int dest)
   {
      MPI::Request request;
      int  sendBytes = 0;
      int  comm_size = comm.Get_size();
      int  myRank = comm.Get_rank();

      // Preconditions
      if (dest > comm_size - 1 || dest < 0) {
         UTIL_THROW("Destination rank out of bounds");
      }
      if (dest == myRank) {
         UTIL_THROW("Source and destination identical");
      }

      sendBytes = sendPtr_ - sendBufferBegin_;
      request = comm.Isend(sendBufferBegin_, sendBytes, MPI::CHAR, dest, 5);
      request.Wait();

      // Update statistics.
      if (sendBytes > maxSendLocal_) {
         maxSendLocal_ = sendBytes;
      }
   }
예제 #6
0
bool Communicator::Test(int source, CommunicationTAG tag) {
  MPI::Request* request = Get_request(source, tag);
  return request->Test();
}
예제 #7
0
int main(int argc, char *argv[]){
  if(argc < 1)exit(1);
  stringstream ss;
  size_t size;
  ss << argv[1]; ss >> size;

  MPI::Init();
  const int com_size = MPI::COMM_WORLD.Get_size(); // assume that com_size is a power of two
  const int com_rank = MPI::COMM_WORLD.Get_rank();
  const int com_last = com_size - 1;
  int *m, *tmp;
  m = new int[size];
  tmp = new int[size];
  size /= com_size;

  // initialize ary with random numbers
  srand((unsigned)time(NULL)+(unsigned)com_rank);
  for(size_t i=0; i<size; i++)m[i] = rand();

  // sort
  for(int division_unit = com_size; division_unit > 1;){
    int pivot;
    for(int i=0;i<(int)sqrt(size);i++)tmp[i] = m[(int)((rand()/((double)RAND_MAX+1.0)) * size)];
    sort(tmp, tmp + (int)sqrt(size));
    pivot = tmp[(int)sqrt(size)/2];
    
    if(com_rank%division_unit == 0){
      for(int j = com_rank+1; j<com_rank+division_unit; j++)
	MPI::COMM_WORLD.Send(&pivot, 1, MPI::INT, j, TAG_0);
    }else{
      MPI::COMM_WORLD.Recv(&pivot, 1, MPI::INT, (com_rank/division_unit)*division_unit, TAG_0);
    }

    division_unit /= 2;
    int receive_datasize;
    if((com_rank/division_unit)%2 == 0){
      int *senddata = (int *)partition(m, m+size, bind2nd(less<int>(), pivot));
      size_t rest_datasize = senddata - m;
      size_t send_datasize = size - rest_datasize;
      int send_to = com_rank+division_unit;

      MPI::COMM_WORLD.Isend(&send_datasize, 1, MPI::INT, send_to, TAG_0);
      MPI::Request req = MPI::COMM_WORLD.Isend(senddata, send_datasize, MPI::INT, send_to, TAG_1);

      MPI::COMM_WORLD.Recv(&receive_datasize, 1, MPI::INT, send_to, TAG_0);
      size = rest_datasize + receive_datasize;
      MPI::COMM_WORLD.Recv(tmp, receive_datasize, MPI::INT, send_to, TAG_2);
      req.Wait();
      memcpy(m+rest_datasize, tmp, receive_datasize*sizeof(int));
    }else{
      int *senddata = (int *)partition(m, m+size, bind2nd(greater_equal<int>(), pivot));
      size_t rest_datasize = senddata - m;
      size_t send_datasize = size - rest_datasize;
      int send_to = com_rank-division_unit;

      MPI::COMM_WORLD.Isend(&send_datasize, 1, MPI::INT, send_to, TAG_0);
      MPI::Request req = MPI::COMM_WORLD.Isend(senddata, send_datasize, MPI::INT, send_to, TAG_2);

      MPI::COMM_WORLD.Recv(&receive_datasize, 1, MPI::INT, send_to, TAG_0);
      size = rest_datasize + receive_datasize;
      MPI::COMM_WORLD.Recv(tmp, receive_datasize, MPI::INT, send_to, TAG_1);
      req.Wait();
      memcpy(m+rest_datasize, tmp, receive_datasize*sizeof(int));
    }
  }
  sort(m, m+size);

  // print
  int signal=0;
  if(com_rank == 0){
    for(size_t i=0; i<size; i++)cout << m[i] << endl;
    // for(size_t i=0; i<m.size(); i++)cout << "[0]" << m[i] << endl;
    if(com_rank != com_last)MPI::COMM_WORLD.Send(&signal, 1, MPI::INT, com_rank+1, TAG_0);
  }else{
    MPI::COMM_WORLD.Recv(&signal, 1, MPI::INT, com_rank-1, TAG_0);
    for(size_t i=0; i<size; i++)cout << m[i] << endl;
    // for(size_t i=0; i<m.size(); i++)cout << "[" << com_rank << "]" << m[i] << endl;
    if(com_rank != com_last)MPI::COMM_WORLD.Send(&signal, 1, MPI::INT, com_rank+1, TAG_0);
  }

  MPI::Finalize();

  delete [] m;
  delete [] tmp;
}