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

goodell at mcs.anl.gov goodell at mcs.anl.gov
Thu Jan 20 16:09:12 CST 2011


Author: goodell
Date: 2011-01-20 16:09:12 -0600 (Thu, 20 Jan 2011)
New Revision: 7789

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

This is just a direct translation of the algorithm used in MPI_Barrier.

No reviewer.

Modified: mpich2/trunk/CHANGES
===================================================================
--- mpich2/trunk/CHANGES	2011-01-20 22:09:09 UTC (rev 7788)
+++ mpich2/trunk/CHANGES	2011-01-20 22:09:12 UTC (rev 7789)
@@ -6,7 +6,7 @@
    "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.
+   functions is: MPIX_Ibcast, MPIX_Ibarrier.
 
 
 ===============================================================================

Modified: mpich2/trunk/src/include/mpiimpl.h
===================================================================
--- mpich2/trunk/src/include/mpiimpl.h	2011-01-20 22:09:09 UTC (rev 7788)
+++ mpich2/trunk/src/include/mpiimpl.h	2011-01-20 22:09:12 UTC (rev 7789)
@@ -3523,6 +3523,8 @@
 int MPIR_Ibcast_intra(void *buffer, int count, MPI_Datatype datatype, int root, MPID_Comm *comm_ptr, MPID_Sched_t s);
 int MPIR_Ibcast_inter(void *buffer, int count, MPI_Datatype datatype, int root, MPID_Comm *comm_ptr, MPID_Sched_t s);
 int MPIR_Ibcast_SMP(void *buffer, int count, MPI_Datatype datatype, int root, MPID_Comm *comm_ptr, MPID_Sched_t s);
+int MPIR_Ibarrier_intra(MPID_Comm *comm_ptr, MPID_Sched_t s);
+int MPIR_Ibarrier_inter(MPID_Comm *comm_ptr, MPID_Sched_t s);
 
 
 /* random initializers */

Modified: mpich2/trunk/src/mpi/coll/ibarrier.c
===================================================================
--- mpich2/trunk/src/mpi/coll/ibarrier.c	2011-01-20 22:09:09 UTC (rev 7788)
+++ mpich2/trunk/src/mpi/coll/ibarrier.c	2011-01-20 22:09:12 UTC (rev 7789)
@@ -24,7 +24,142 @@
 
 /* any non-MPI functions go here, especially non-static ones */
 
+/* This is the default implementation of the barrier operation.  The
+   algorithm is:
+
+   Algorithm: MPI_Ibarrier
+
+   We use the dissemination algorithm described in:
+   Debra Hensgen, Raphael Finkel, and Udi Manber, "Two Algorithms for
+   Barrier Synchronization," International Journal of Parallel
+   Programming, 17(1):1-17, 1988.
+
+   It uses ceiling(lgp) steps. In step k, 0 <= k <= (ceiling(lgp)-1),
+   process i sends to process (i + 2^k) % p and receives from process
+   (i - 2^k + p) % p.
+
+   Possible improvements:
+
+   End Algorithm: MPI_Ibarrier
+
+   This is an intracommunicator barrier only!
+*/
+/* Provides a generic "flat" barrier that doesn't know anything about hierarchy.
+ * It will choose between several different algorithms based on the given
+ * parameters. */
 #undef FUNCNAME
+#define FUNCNAME MPIR_Ibarrier_intra
+#undef FCNAME
+#define FCNAME MPIU_QUOTE(FUNCNAME)
+int MPIR_Ibarrier_intra(MPID_Comm *comm_ptr, MPID_Sched_t s)
+{
+    int mpi_errno = MPI_SUCCESS;
+    int size, rank, src, dst, mask;
+
+    MPIU_Assert(comm_ptr->comm_kind == MPID_INTRACOMM);
+
+    size = comm_ptr->local_size;
+    rank = comm_ptr->rank;
+
+    /* Trivial barriers return immediately */
+    if (size == 1) goto fn_exit;
+
+    mask = 0x1;
+    while (mask < size) {
+        dst = (rank + mask) % size;
+        src = (rank - mask + size) % size;
+
+        mpi_errno = MPID_Sched_send(NULL, 0, MPI_BYTE, dst, comm_ptr, s);
+        if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+
+        mpi_errno = MPID_Sched_recv(NULL, 0, MPI_BYTE, src, 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);
+
+        mask <<= 1;
+    }
+
+fn_exit:
+    return mpi_errno;
+fn_fail:
+    goto fn_exit;
+}
+
+/* Provides a generic "flat" barrier that doesn't know anything about hierarchy.
+ * It will choose between several different algorithms based on the given
+ * parameters. */
+#undef FUNCNAME
+#define FUNCNAME MPIR_Ibarrier_inter
+#undef FCNAME
+#define FCNAME MPIU_QUOTE(FUNCNAME)
+int MPIR_Ibarrier_inter(MPID_Comm *comm_ptr, MPID_Sched_t s)
+{
+    int mpi_errno = MPI_SUCCESS;
+    int size, rank, root;
+    int buf = 0;
+
+    MPIU_Assert(comm_ptr->comm_kind == MPID_INTERCOMM);
+
+    size = comm_ptr->local_size;
+    rank = comm_ptr->rank;
+
+    /* Get the local intracommunicator */
+    if (!comm_ptr->local_comm) {
+        mpi_errno = MPIR_Setup_intercomm_localcomm(comm_ptr);
+        if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+    }
+
+    /* do a barrier on the local intracommunicator */
+    mpi_errno = MPIR_Ibarrier_intra(comm_ptr->local_comm, s);
+    if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+
+    mpi_errno = MPID_Sched_barrier(s);
+    if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+
+    /* rank 0 on each group does an intercommunicator broadcast to the
+       remote group to indicate that all processes in the local group
+       have reached the barrier. We do a 1-byte bcast because a 0-byte
+       bcast will just return without doing anything. */
+
+    /* first broadcast from left to right group, then from right to
+       left group */
+    if (comm_ptr->is_low_group) {
+        root = (rank == 0) ? MPI_ROOT : MPI_PROC_NULL;
+        mpi_errno = MPIR_Ibcast_inter(&buf, 1, MPI_BYTE, root, 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);
+
+        /* receive bcast from right */
+        root = 0;
+        mpi_errno = MPIR_Ibcast_inter(&buf, 1, MPI_BYTE, root, comm_ptr, s);
+        if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+    }
+    else {
+        /* receive bcast from left */
+        root = 0;
+        mpi_errno = MPIR_Ibcast_inter(&buf, 1, MPI_BYTE, root, 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);
+
+        /* bcast to left */
+        root = (rank == 0) ? MPI_ROOT : MPI_PROC_NULL;
+        mpi_errno = MPIR_Ibcast_inter(&buf, 1, MPI_BYTE, root, 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_Ibarrier_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-20 22:09:09 UTC (rev 7788)
+++ mpich2/trunk/src/mpi/comm/commutil.c	2011-01-20 22:09:12 UTC (rev 7789)
@@ -242,6 +242,7 @@
 
         /* intracomm default defaults... */
         ops->Ibcast = &MPIR_Ibcast_intra;
+        ops->Ibarrier = &MPIR_Ibarrier_intra;
         /* TODO add other fns here as they are added */
 
         /* override defaults, such as for SMP */
@@ -270,6 +271,7 @@
 
         /* intracomm defaults */
         ops->Ibcast = &MPIR_Ibcast_inter;
+        ops->Ibarrier = &MPIR_Ibarrier_inter;
 
         ic_default_collops = ops;
     }



More information about the mpich2-commits mailing list