|
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 |
/* Remote Gather Local Bcast
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* This is done differently from the intercommunicator allgather
|
|
Packit Service |
c5cf8c |
* because we don't have all the information to do a local
|
|
Packit Service |
c5cf8c |
* intracommunictor gather (sendcount can be different on each
|
|
Packit Service |
c5cf8c |
* process). Therefore, we do the following: Each group first does an
|
|
Packit Service |
c5cf8c |
* intercommunicator gather to rank 0 and then does an
|
|
Packit Service |
c5cf8c |
* intracommunicator broadcast.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#undef FUNCNAME
|
|
Packit Service |
c5cf8c |
#define FUNCNAME MPIR_Allgatherv_inter_remote_gather_local_bcast
|
|
Packit Service |
c5cf8c |
#undef FCNAME
|
|
Packit Service |
c5cf8c |
#define FCNAME MPL_QUOTE(FUNCNAME)
|
|
Packit Service |
c5cf8c |
int MPIR_Allgatherv_inter_remote_gather_local_bcast(const void *sendbuf, int sendcount,
|
|
Packit Service |
c5cf8c |
MPI_Datatype sendtype, void *recvbuf,
|
|
Packit Service |
c5cf8c |
const int *recvcounts, const int
|
|
Packit Service |
c5cf8c |
*displs, MPI_Datatype recvtype,
|
|
Packit Service |
c5cf8c |
MPIR_Comm * comm_ptr, MPIR_Errflag_t * errflag)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int remote_size, mpi_errno, root, rank;
|
|
Packit Service |
c5cf8c |
int mpi_errno_ret = MPI_SUCCESS;
|
|
Packit Service |
c5cf8c |
MPIR_Comm *newcomm_ptr = NULL;
|
|
Packit Service |
c5cf8c |
MPI_Datatype newtype = MPI_DATATYPE_NULL;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
remote_size = comm_ptr->remote_size;
|
|
Packit Service |
c5cf8c |
rank = comm_ptr->rank;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* first do an intercommunicator gatherv from left to right group,
|
|
Packit Service |
c5cf8c |
* then from right to left group */
|
|
Packit Service |
c5cf8c |
if (comm_ptr->is_low_group) {
|
|
Packit Service |
c5cf8c |
/* gatherv from right group */
|
|
Packit Service |
c5cf8c |
root = (rank == 0) ? MPI_ROOT : MPI_PROC_NULL;
|
|
Packit Service |
c5cf8c |
mpi_errno = MPIR_Gatherv(sendbuf, sendcount, sendtype, recvbuf,
|
|
Packit Service |
c5cf8c |
recvcounts, displs, recvtype, root, comm_ptr, 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 |
/* gatherv to right group */
|
|
Packit Service |
c5cf8c |
root = 0;
|
|
Packit Service |
c5cf8c |
mpi_errno = MPIR_Gatherv(sendbuf, sendcount, sendtype, recvbuf,
|
|
Packit Service |
c5cf8c |
recvcounts, displs, recvtype, root, comm_ptr, 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 {
|
|
Packit Service |
c5cf8c |
/* gatherv to left group */
|
|
Packit Service |
c5cf8c |
root = 0;
|
|
Packit Service |
c5cf8c |
mpi_errno = MPIR_Gatherv(sendbuf, sendcount, sendtype, recvbuf,
|
|
Packit Service |
c5cf8c |
recvcounts, displs, recvtype, root, comm_ptr, 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 |
/* gatherv from left group */
|
|
Packit Service |
c5cf8c |
root = (rank == 0) ? MPI_ROOT : MPI_PROC_NULL;
|
|
Packit Service |
c5cf8c |
mpi_errno = MPIR_Gatherv(sendbuf, sendcount, sendtype, recvbuf,
|
|
Packit Service |
c5cf8c |
recvcounts, displs, recvtype, root, comm_ptr, 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 |
/* now do an intracommunicator broadcast within each group. we use
|
|
Packit Service |
c5cf8c |
* a derived datatype to handle the displacements */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Get the local intracommunicator */
|
|
Packit Service |
c5cf8c |
if (!comm_ptr->local_comm) {
|
|
Packit Service |
c5cf8c |
mpi_errno = MPII_Setup_intercomm_localcomm(comm_ptr);
|
|
Packit Service |
c5cf8c |
if (mpi_errno)
|
|
Packit Service |
c5cf8c |
MPIR_ERR_POP(mpi_errno);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
newcomm_ptr = comm_ptr->local_comm;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
mpi_errno = MPIR_Type_indexed_impl(remote_size, recvcounts, displs, recvtype, &newtype);
|
|
Packit Service |
c5cf8c |
if (mpi_errno)
|
|
Packit Service |
c5cf8c |
MPIR_ERR_POP(mpi_errno);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
mpi_errno = MPIR_Type_commit_impl(&newtype);
|
|
Packit Service |
c5cf8c |
if (mpi_errno)
|
|
Packit Service |
c5cf8c |
MPIR_ERR_POP(mpi_errno);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
mpi_errno = MPIR_Bcast_intra_auto(recvbuf, 1, newtype, 0, newcomm_ptr, 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 |
MPIR_Type_free_impl(&newtype);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
fn_exit:
|
|
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, MPI_ERR_OTHER, "**coll_fail");
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return mpi_errno;
|
|
Packit Service |
c5cf8c |
fn_fail:
|
|
Packit Service |
c5cf8c |
/* --BEGIN ERROR HANDLING-- */
|
|
Packit Service |
c5cf8c |
if (newtype != MPI_DATATYPE_NULL)
|
|
Packit Service |
c5cf8c |
MPIR_Type_free_impl(&newtype);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
goto fn_exit;
|
|
Packit Service |
c5cf8c |
/* --END ERROR HANDLING-- */
|
|
Packit Service |
c5cf8c |
}
|