예제 #1
0
int MPICH_AlltoAll_medium( 
						  void *sendbuf, 
						  int sendcount, 
						  MPI_Datatype sendtype, 
						  void *recvbuf, 
						  int recvcount, 
						  MPI_Datatype recvtype, 
						  MPI_Comm comm )
{

  int          comm_size, i, pof2;
  MPI_Aint     sendtype_extent, recvtype_extent;
 
  int mpi_errno=MPI_SUCCESS, src, dst, rank, nbytes;
  MPI_Status status;
  int sendtype_size;

  MPI_Request *reqarray;
  MPI_Status *starray;

  if (sendcount == 0) return MPI_SUCCESS;
  
  MPI_Comm_rank (MPI_COMM_WORLD, &rank);
  MPI_Comm_size (MPI_COMM_WORLD, &comm_size);
    
  /* Get extent of send and recv types */
  MPID_Datatype_get_extent_macro(recvtype, recvtype_extent);
  MPID_Datatype_get_extent_macro(sendtype, sendtype_extent);

  MPID_Datatype_get_size_macro(sendtype, sendtype_size);
  nbytes = sendtype_size * sendcount;
    
  /* Medium-size message. Use isend/irecv with scattered destinations */

  reqarray = (MPI_Request *) malloc(2*comm_size*sizeof(MPI_Request));
        
  if (!reqarray) 
	return MPI_ERR_OTHER;
        
  starray = (MPI_Status *) malloc(2*comm_size*sizeof(MPI_Status));
  if (!starray) 
	return MPI_ERR_OTHER;
        
  /* do the communication -- post all sends and receives: */
  for ( i=0; i<comm_size; i++ ) { 
	dst = (rank+i) % comm_size;
	mpi_errno = AMPI_Irecv((char *)recvbuf +
						   dst*recvcount*recvtype_extent, 
						   recvcount, recvtype, dst,
						   MPI_ATA_TAG, comm,
						   &reqarray[i]);
	
	if (mpi_errno)
	  return MPI_ERR_OTHER;
  }

  for ( i=0; i<comm_size; i++ ) { 
	dst = (rank+i) % comm_size;
	mpi_errno = AMPI_Isend((char *)sendbuf +
						   dst*sendcount*sendtype_extent, 
						   sendcount, sendtype, dst,
						   MPI_ATA_TAG, comm,
						   &reqarray[i+comm_size]);
	if (mpi_errno)
	  return mpi_errno;
  }
  
  /* ... then wait for *all* of them to finish: */
  mpi_errno = AMPI_Waitall(2*comm_size,reqarray,starray);

  /* --BEGIN ERROR HANDLING-- */
//   if (mpi_errno == MPI_ERR_IN_STATUS) {
// 	for (int j=0; j<2*comm_size; j++) {
// 	  if (starray[j] != MPI_SUCCESS) 
// 		mpi_errno = starray[j];
// 	}
//   }
  /* --END ERROR HANDLING-- */

  free(starray);
  free(reqarray);
  
  return mpi_errno;
}
예제 #2
0
void mpi_irecv(void *buf, int *count, int *datatype, int *src,
   int *tag, int *comm, int *request, int *ierr)
{
  *ierr = AMPI_Irecv(buf, *count, *datatype, *src, *tag, *comm, (MPI_Request *)request);
}