[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