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; }
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); }