|
Packit Service |
c5cf8c |
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* (C) 2001 by Argonne National Laboratory.
|
|
Packit Service |
c5cf8c |
* See COPYRIGHT in top-level directory.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#include "mpiimpl.h"
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Algorithm: Inplace Alltoallw
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* We use pair-wise sendrecv_replace in order to conserve memory usage, which
|
|
Packit Service |
c5cf8c |
* is keeping with the spirit of the MPI-2.2 Standard. But because of this
|
|
Packit Service |
c5cf8c |
* approach all processes must agree on the global schedule of sendrecv_replace
|
|
Packit Service |
c5cf8c |
* operations to avoid deadlock.
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* Note that this is not an especially efficient algorithm in terms of time and
|
|
Packit Service |
c5cf8c |
* there will be multiple repeated malloc/free's rather than maintaining a
|
|
Packit Service |
c5cf8c |
* single buffer across the whole loop. Something like MADRE is probably the
|
|
Packit Service |
c5cf8c |
* best solution for the MPI_IN_PLACE scenario.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
#undef FUNCNAME
|
|
Packit Service |
c5cf8c |
#define FUNCNAME MPIR_Alltoallw_intra_pairwise_sendrecv_replace
|
|
Packit Service |
c5cf8c |
#undef FCNAME
|
|
Packit Service |
c5cf8c |
#define FCNAME MPL_QUOTE(FUNCNAME)
|
|
Packit Service |
c5cf8c |
int MPIR_Alltoallw_intra_pairwise_sendrecv_replace(const void *sendbuf, const int sendcounts[],
|
|
Packit Service |
c5cf8c |
const int sdispls[],
|
|
Packit Service |
c5cf8c |
const MPI_Datatype sendtypes[], void *recvbuf,
|
|
Packit Service |
c5cf8c |
const int recvcounts[], const int rdispls[],
|
|
Packit Service |
c5cf8c |
const MPI_Datatype recvtypes[],
|
|
Packit Service |
c5cf8c |
MPIR_Comm * comm_ptr, MPIR_Errflag_t * errflag)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int comm_size, i, j;
|
|
Packit Service |
c5cf8c |
int mpi_errno = MPI_SUCCESS;
|
|
Packit Service |
c5cf8c |
int mpi_errno_ret = MPI_SUCCESS;
|
|
Packit Service |
c5cf8c |
MPI_Status status;
|
|
Packit Service |
c5cf8c |
int rank;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
comm_size = comm_ptr->local_size;
|
|
Packit Service |
c5cf8c |
rank = comm_ptr->rank;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#ifdef HAVE_ERROR_CHECKING
|
|
Packit Service |
c5cf8c |
MPIR_Assert(sendbuf == MPI_IN_PLACE);
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* We use pair-wise sendrecv_replace in order to conserve memory usage,
|
|
Packit Service |
c5cf8c |
* which is keeping with the spirit of the MPI-2.2 Standard. But
|
|
Packit Service |
c5cf8c |
* because of this approach all processes must agree on the global
|
|
Packit Service |
c5cf8c |
* schedule of sendrecv_replace operations to avoid deadlock.
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* Note that this is not an especially efficient algorithm in terms of
|
|
Packit Service |
c5cf8c |
* time and there will be multiple repeated malloc/free's rather than
|
|
Packit Service |
c5cf8c |
* maintaining a single buffer across the whole loop. Something like
|
|
Packit Service |
c5cf8c |
* MADRE is probably the best solution for the MPI_IN_PLACE scenario. */
|
|
Packit Service |
c5cf8c |
for (i = 0; i < comm_size; ++i) {
|
|
Packit Service |
c5cf8c |
/* start inner loop at i to avoid re-exchanging data */
|
|
Packit Service |
c5cf8c |
for (j = i; j < comm_size; ++j) {
|
|
Packit Service |
c5cf8c |
if (rank == i) {
|
|
Packit Service |
c5cf8c |
/* also covers the (rank == i && rank == j) case */
|
|
Packit Service |
c5cf8c |
mpi_errno = MPIC_Sendrecv_replace(((char *) recvbuf + rdispls[j]),
|
|
Packit Service |
c5cf8c |
recvcounts[j], recvtypes[j],
|
|
Packit Service |
c5cf8c |
j, MPIR_ALLTOALLW_TAG,
|
|
Packit Service |
c5cf8c |
j, MPIR_ALLTOALLW_TAG,
|
|
Packit Service |
c5cf8c |
comm_ptr, &status, errflag);
|
|
Packit Service |
c5cf8c |
if (mpi_errno) {
|
|
Packit Service |
c5cf8c |
/* for communication errors, just record the error but continue */
|
|
Packit Service |
c5cf8c |
*errflag =
|
|
Packit Service |
c5cf8c |
MPIX_ERR_PROC_FAILED ==
|
|
Packit Service |
c5cf8c |
MPIR_ERR_GET_CLASS(mpi_errno) ? MPIR_ERR_PROC_FAILED : MPIR_ERR_OTHER;
|
|
Packit Service |
c5cf8c |
MPIR_ERR_SET(mpi_errno, *errflag, "**fail");
|
|
Packit Service |
c5cf8c |
MPIR_ERR_ADD(mpi_errno_ret, mpi_errno);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
} else if (rank == j) {
|
|
Packit Service |
c5cf8c |
/* same as above with i/j args reversed */
|
|
Packit Service |
c5cf8c |
mpi_errno = MPIC_Sendrecv_replace(((char *) recvbuf + rdispls[i]),
|
|
Packit Service |
c5cf8c |
recvcounts[i], recvtypes[i],
|
|
Packit Service |
c5cf8c |
i, MPIR_ALLTOALLW_TAG,
|
|
Packit Service |
c5cf8c |
i, MPIR_ALLTOALLW_TAG,
|
|
Packit Service |
c5cf8c |
comm_ptr, &status, errflag);
|
|
Packit Service |
c5cf8c |
if (mpi_errno) {
|
|
Packit Service |
c5cf8c |
/* for communication errors, just record the error but continue */
|
|
Packit Service |
c5cf8c |
*errflag =
|
|
Packit Service |
c5cf8c |
MPIX_ERR_PROC_FAILED ==
|
|
Packit Service |
c5cf8c |
MPIR_ERR_GET_CLASS(mpi_errno) ? MPIR_ERR_PROC_FAILED : MPIR_ERR_OTHER;
|
|
Packit Service |
c5cf8c |
MPIR_ERR_SET(mpi_errno, *errflag, "**fail");
|
|
Packit Service |
c5cf8c |
MPIR_ERR_ADD(mpi_errno_ret, mpi_errno);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (mpi_errno_ret)
|
|
Packit Service |
c5cf8c |
mpi_errno = mpi_errno_ret;
|
|
Packit Service |
c5cf8c |
else if (*errflag != MPIR_ERR_NONE)
|
|
Packit Service |
c5cf8c |
MPIR_ERR_SET(mpi_errno, *errflag, "**coll_fail");
|
|
Packit Service |
c5cf8c |
return mpi_errno;
|
|
Packit Service |
c5cf8c |
}
|