[mpich2-commits] r7804 - in mpich2/trunk: . src/include src/mpi/coll src/mpi/comm

goodell at mcs.anl.gov goodell at mcs.anl.gov
Fri Jan 21 12:37:25 CST 2011


Author: goodell
Date: 2011-01-21 12:37:25 -0600 (Fri, 21 Jan 2011)
New Revision: 7804

Modified:
   mpich2/trunk/CHANGES
   mpich2/trunk/src/include/mpiimpl.h
   mpich2/trunk/src/mpi/coll/iallreduce.c
   mpich2/trunk/src/mpi/comm/commutil.c
Log:
default implementation of MPIX_Iallreduce

This version uses a naive ireduce+ibcast algorithm for intracomms.  We should
definitely port the other algorithms from MPIR_Allreduce_intra to this
routine.

No reviewer.

Modified: mpich2/trunk/CHANGES
===================================================================
--- mpich2/trunk/CHANGES	2011-01-21 18:32:12 UTC (rev 7803)
+++ mpich2/trunk/CHANGES	2011-01-21 18:37:25 UTC (rev 7804)
@@ -6,7 +6,8 @@
    "MPIX_" functions (e.g. "MPIX_Ibcast").  All functions are provided and are
    available for device-level overrides, but only a subset of the functions have
    device-independent implementations at this time.  The current list of working
-   functions is: MPIX_Ibcast, MPIX_Ibarrier, MPIX_Ireduce, MPIX_Ialltoallv.
+   functions is: MPIX_Ibcast, MPIX_Ibarrier, MPIX_Ireduce, MPIX_Ialltoallv,
+   MPIX_Iallreduce.
 
 
 ===============================================================================

Modified: mpich2/trunk/src/include/mpiimpl.h
===================================================================
--- mpich2/trunk/src/include/mpiimpl.h	2011-01-21 18:32:12 UTC (rev 7803)
+++ mpich2/trunk/src/include/mpiimpl.h	2011-01-21 18:37:25 UTC (rev 7804)
@@ -3553,6 +3553,9 @@
 int MPIR_Ireduce_binomial(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPID_Comm *comm_ptr, MPID_Sched_t s);
 int MPIR_Ialltoallv_intra(void *sendbuf, int *sendcounts, int *sdispls, MPI_Datatype sendtype, void *recvbuf, int *recvcounts, int *rdispls, MPI_Datatype recvtype, MPID_Comm *comm_ptr, MPID_Sched_t s);
 int MPIR_Ialltoallv_inter(void *sendbuf, int *sendcounts, int *sdispls, MPI_Datatype sendtype, void *recvbuf, int *recvcounts, int *rdispls, MPI_Datatype recvtype, MPID_Comm *comm_ptr, MPID_Sched_t s);
+int MPIR_Iallreduce_intra(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPID_Comm *comm_ptr, MPID_Sched_t s);
+int MPIR_Iallreduce_inter(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPID_Comm *comm_ptr, MPID_Sched_t s);
+int MPIR_Iallreduce_naive(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPID_Comm *comm_ptr, MPID_Sched_t s);
 
 
 /* random initializers */

Modified: mpich2/trunk/src/mpi/coll/iallreduce.c
===================================================================
--- mpich2/trunk/src/mpi/coll/iallreduce.c	2011-01-21 18:32:12 UTC (rev 7803)
+++ mpich2/trunk/src/mpi/coll/iallreduce.c	2011-01-21 18:37:25 UTC (rev 7804)
@@ -24,7 +24,134 @@
 
 /* any non-MPI functions go here, especially non-static ones */
 
+/* implements the naive intracomm allreduce, that is, reduce followed by bcast */
 #undef FUNCNAME
+#define FUNCNAME MPIR_Iallreduce_naive
+#undef FCNAME
+#define FCNAME MPIU_QUOTE(FUNCNAME)
+int MPIR_Iallreduce_naive(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPID_Comm *comm_ptr, MPID_Sched_t s)
+{
+    int mpi_errno = MPI_SUCCESS;
+
+    mpi_errno = MPIR_Ireduce_intra(sendbuf, recvbuf, count, datatype, op, 0, comm_ptr, s);
+    if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+
+    mpi_errno = MPID_Sched_barrier(s);
+    if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+
+    mpi_errno = MPIR_Ibcast_intra(recvbuf, count, datatype, 0, comm_ptr, s);
+    if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+
+fn_exit:
+    return mpi_errno;
+fn_fail:
+    goto fn_exit;
+}
+
+#undef FUNCNAME
+#define FUNCNAME MPIR_Iallreduce_intra
+#undef FCNAME
+#define FCNAME MPIU_QUOTE(FUNCNAME)
+int MPIR_Iallreduce_intra(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPID_Comm *comm_ptr, MPID_Sched_t s)
+{
+    int mpi_errno = MPI_SUCCESS;
+    int is_homogeneous;
+
+    MPIU_Assert(comm_ptr->comm_kind == MPID_INTRACOMM);
+
+
+    is_homogeneous = TRUE;
+#ifdef MPID_HAS_HETERO
+    if (comm_ptr->is_hetero)
+        is_homogeneous = FALSE;
+#endif
+
+    MPIU_Assert(is_homogeneous); /* no hetero for the moment */
+
+    /* TODO port the better algorithms from MPIR_Allreduce_intra to augment the
+     * naive implementation */
+    mpi_errno = MPIR_Iallreduce_naive(sendbuf, recvbuf, count, datatype, op, comm_ptr, s);
+    if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+
+fn_exit:
+    return mpi_errno;
+fn_fail:
+    goto fn_exit;
+}
+
+#undef FUNCNAME
+#define FUNCNAME MPIR_Iallreduce_inter
+#undef FCNAME
+#define FCNAME MPIU_QUOTE(FUNCNAME)
+int MPIR_Iallreduce_inter(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPID_Comm *comm_ptr, MPID_Sched_t s)
+{
+/* Intercommunicator Allreduce.
+   We first do an intercommunicator reduce to rank 0 on left group,
+   then an intercommunicator reduce to rank 0 on right group, followed
+   by local intracommunicator broadcasts in each group.
+
+   We don't do local reduces first and then intercommunicator
+   broadcasts because it would require allocation of a temporary buffer.
+*/
+    int mpi_errno = MPI_SUCCESS;
+    int rank, root;
+    MPID_Comm *lcomm_ptr = NULL;
+
+    MPIU_Assert(comm_ptr->comm_kind == MPID_INTERCOMM);
+
+    rank = comm_ptr->rank;
+
+    /* first do a reduce from right group to rank 0 in left group,
+       then from left group to rank 0 in right group*/
+    if (comm_ptr->is_low_group) {
+        /* reduce from right group to rank 0*/
+        root = (rank == 0) ? MPI_ROOT : MPI_PROC_NULL;
+        mpi_errno = MPIR_Ireduce_inter(sendbuf, recvbuf, count, datatype, op, root, comm_ptr, s);
+        if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+
+        /* no barrier, these reductions can be concurrent */
+
+        /* reduce to rank 0 of right group */
+        root = 0;
+        mpi_errno = MPIR_Ireduce_inter(sendbuf, recvbuf, count, datatype, op, root, comm_ptr, s);
+        if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+    }
+    else {
+        /* reduce to rank 0 of left group */
+        root = 0;
+        mpi_errno = MPIR_Ireduce_inter(sendbuf, recvbuf, count, datatype, op, root, comm_ptr, s);
+        if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+
+        /* no barrier, these reductions can be concurrent */
+
+        /* reduce from right group to rank 0 */
+        root = (rank == 0) ? MPI_ROOT : MPI_PROC_NULL;
+        mpi_errno = MPIR_Ireduce_inter(sendbuf, recvbuf, count, datatype, op, root, comm_ptr, s);
+        if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+    }
+
+    /* don't bcast until the reductions have finished */
+    mpi_errno = MPID_Sched_barrier(s);
+    if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+
+    /* Get the local intracommunicator */
+    if (!comm_ptr->local_comm) {
+        MPIR_Setup_intercomm_localcomm( comm_ptr );
+        if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+    }
+    lcomm_ptr = comm_ptr->local_comm;
+
+    MPIU_Assert(lcomm_ptr->coll_fns && lcomm_ptr->coll_fns->Ibcast);
+    mpi_errno = lcomm_ptr->coll_fns->Ibcast(recvbuf, count, datatype, 0, lcomm_ptr, s);
+    if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+
+fn_exit:
+    return mpi_errno;
+fn_fail:
+    goto fn_exit;
+}
+
+#undef FUNCNAME
 #define FUNCNAME MPIR_Iallreduce_impl
 #undef FCNAME
 #define FCNAME MPIU_QUOTE(FUNCNAME)

Modified: mpich2/trunk/src/mpi/comm/commutil.c
===================================================================
--- mpich2/trunk/src/mpi/comm/commutil.c	2011-01-21 18:32:12 UTC (rev 7803)
+++ mpich2/trunk/src/mpi/comm/commutil.c	2011-01-21 18:37:25 UTC (rev 7804)
@@ -245,6 +245,7 @@
         ops->Ibarrier = &MPIR_Ibarrier_intra;
         ops->Ireduce = &MPIR_Ireduce_intra;
         ops->Ialltoallv = &MPIR_Ialltoallv_intra;
+        ops->Iallreduce = &MPIR_Iallreduce_intra;
         /* TODO add other fns here as they are added */
 
         /* override defaults, such as for SMP */
@@ -276,6 +277,7 @@
         ops->Ibarrier = &MPIR_Ibarrier_inter;
         ops->Ireduce = &MPIR_Ireduce_inter;
         ops->Ialltoallv = &MPIR_Ialltoallv_inter;
+        ops->Iallreduce = &MPIR_Iallreduce_inter;
 
         ic_default_collops = ops;
     }



More information about the mpich2-commits mailing list