[mpich2-commits] r7974 - in mpich2/trunk/src: include mpi/coll mpi/comm
goodell at mcs.anl.gov
goodell at mcs.anl.gov
Tue Feb 15 15:59:02 CST 2011
Author: goodell
Date: 2011-02-15 15:59:01 -0600 (Tue, 15 Feb 2011)
New Revision: 7974
Modified:
mpich2/trunk/src/include/mpiimpl.h
mpich2/trunk/src/mpi/coll/igather.c
mpich2/trunk/src/mpi/comm/commutil.c
Log:
default implementation of MPIX_Igather
This is a straightforward port of the algorithms in MPI_Gather, but does
not support the heterogeneous case yet.
Reviewed by buntinas at .
Modified: mpich2/trunk/src/include/mpiimpl.h
===================================================================
--- mpich2/trunk/src/include/mpiimpl.h 2011-02-15 21:58:59 UTC (rev 7973)
+++ mpich2/trunk/src/include/mpiimpl.h 2011-02-15 21:59:01 UTC (rev 7974)
@@ -3611,6 +3611,9 @@
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);
+int MPIR_Igather_binomial(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPID_Comm *comm_ptr, MPID_Sched_t s);
+int MPIR_Igather_intra(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPID_Comm *comm_ptr, MPID_Sched_t s);
+int MPIR_Igather_inter(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPID_Comm *comm_ptr, MPID_Sched_t s);
/* random initializers */
Modified: mpich2/trunk/src/mpi/coll/igather.c
===================================================================
--- mpich2/trunk/src/mpi/coll/igather.c 2011-02-15 21:58:59 UTC (rev 7973)
+++ mpich2/trunk/src/mpi/coll/igather.c 2011-02-15 21:59:01 UTC (rev 7974)
@@ -24,7 +24,498 @@
/* any non-MPI functions go here, especially non-static ones */
+/* This is the default implementation of igather. The algorithm is:
+
+ Algorithm: MPIX_Igather
+
+ We use a binomial tree algorithm for both short and long
+ messages. At nodes other than leaf nodes we need to allocate a
+ temporary buffer to store the incoming message. If the root is not
+ rank 0, for very small messages, we pack it into a temporary
+ contiguous buffer and reorder it to be placed in the right
+ order. For small (but not very small) messages, we use a derived
+ datatype to unpack the incoming data into non-contiguous buffers in
+ the right order. In the heterogeneous case we first pack the
+ buffers by using MPI_Pack and then do the gather.
+
+ Cost = lgp.alpha + n.((p-1)/p).beta
+ where n is the total size of the data gathered at the root.
+
+ Possible improvements:
+
+ End Algorithm: MPI_Gather
+*/
#undef FUNCNAME
+#define FUNCNAME MPIR_Igather_binomial
+#undef FCNAME
+#define FCNAME MPIU_QUOTE(FUNCNAME)
+int MPIR_Igather_binomial(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPID_Comm *comm_ptr, MPID_Sched_t s)
+{
+ int mpi_errno = MPI_SUCCESS;
+ int comm_size, rank;
+ int curr_cnt=0, relative_rank, nbytes, is_homogeneous;
+ int mask, sendtype_size, recvtype_size, src, dst, relative_src;
+ int recvblks;
+ int tmp_buf_size, missing;
+ void *tmp_buf = NULL;
+ int blocks[2];
+ int displs[2];
+ MPI_Aint struct_displs[2];
+ MPI_Aint extent=0;
+ int copy_offset = 0, copy_blks = 0;
+ MPI_Datatype types[2], tmp_type;
+ MPIU_CHKPMEM_DECL(1);
+
+ comm_size = comm_ptr->local_size;
+ rank = comm_ptr->rank;
+
+ if (((rank == root) && (recvcount == 0)) || ((rank != root) && (sendcount == 0)))
+ goto fn_exit;
+
+ is_homogeneous = TRUE;
+#ifdef MPID_HAS_HETERO
+ is_homogeneous = !comm_ptr->is_hetero;
+#endif
+
+ MPIU_Assert(comm_ptr->comm_kind == MPID_INTRACOMM);
+
+ /* Use binomial tree algorithm. */
+
+ relative_rank = (rank >= root) ? rank - root : rank - root + comm_size;
+
+ if (rank == root)
+ {
+ MPID_Datatype_get_extent_macro(recvtype, extent);
+ MPID_Ensure_Aint_fits_in_pointer(MPI_VOID_PTR_CAST_TO_MPI_AINT recvbuf+
+ (extent*recvcount*comm_size));
+ }
+
+ if (is_homogeneous)
+ {
+ /* communicator is homogeneous. no need to pack buffer. */
+ if (rank == root)
+ {
+ MPID_Datatype_get_size_macro(recvtype, recvtype_size);
+ nbytes = recvtype_size * recvcount;
+ }
+ else
+ {
+ MPID_Datatype_get_size_macro(sendtype, sendtype_size);
+ nbytes = sendtype_size * sendcount;
+ }
+
+ /* Find the number of missing nodes in my sub-tree compared to
+ * a balanced tree */
+ for (mask = 1; mask < comm_size; mask <<= 1);
+ --mask;
+ while (relative_rank & mask) mask >>= 1;
+ missing = (relative_rank | mask) - comm_size + 1;
+ if (missing < 0) missing = 0;
+ tmp_buf_size = (mask - missing);
+
+ /* If the message is smaller than the threshold, we will copy
+ * our message in there too */
+ if (nbytes < MPIR_PARAM_GATHER_VSMALL_MSG_SIZE) tmp_buf_size++;
+
+ tmp_buf_size *= nbytes;
+
+ /* For zero-ranked root, we don't need any temporary buffer */
+ if ((rank == root) && (!root || (nbytes >= MPIR_PARAM_GATHER_VSMALL_MSG_SIZE)))
+ tmp_buf_size = 0;
+
+ if (tmp_buf_size) {
+ MPIU_CHKPMEM_MALLOC(tmp_buf, void *, tmp_buf_size, mpi_errno, "tmp_buf");
+ }
+
+ if (rank == root) {
+ if (sendbuf != MPI_IN_PLACE) {
+ mpi_errno = MPIR_Localcopy(sendbuf, sendcount, sendtype,
+ ((char *) recvbuf + extent*recvcount*rank), recvcount, recvtype);
+ if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+ }
+ }
+ else if (tmp_buf_size && (nbytes < MPIR_PARAM_GATHER_VSMALL_MSG_SIZE)) {
+ /* copy from sendbuf into tmp_buf */
+ mpi_errno = MPIR_Localcopy(sendbuf, sendcount, sendtype,
+ tmp_buf, nbytes, MPI_BYTE);
+ if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+ }
+ curr_cnt = nbytes;
+
+ mask = 0x1;
+ while (mask < comm_size) {
+ if ((mask & relative_rank) == 0) {
+ src = relative_rank | mask;
+ if (src < comm_size) {
+ src = (src + root) % comm_size;
+
+ if (rank == root) {
+ recvblks = mask;
+ if ((2 * recvblks) > comm_size)
+ recvblks = comm_size - recvblks;
+
+ if ((rank + mask + recvblks == comm_size) ||
+ (((rank + mask) % comm_size) < ((rank + mask + recvblks) % comm_size)))
+ {
+ /* If the data contiguously fits into the
+ * receive buffer, place it directly. This
+ * should cover the case where the root is
+ * rank 0. */
+ char *rp = (char *)recvbuf + (((rank + mask) % comm_size)*recvcount*extent);
+ mpi_errno = MPID_Sched_recv(rp, (recvblks * recvcount), recvtype, 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);
+ }
+ else if (nbytes < MPIR_PARAM_GATHER_VSMALL_MSG_SIZE) {
+ mpi_errno = MPID_Sched_recv(tmp_buf, (recvblks * nbytes), 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);
+ copy_offset = rank + mask;
+ copy_blks = recvblks;
+ }
+ else {
+ blocks[0] = recvcount * (comm_size - root - mask);
+ displs[0] = recvcount * (root + mask);
+ blocks[1] = (recvcount * recvblks) - blocks[0];
+ displs[1] = 0;
+
+ mpi_errno = MPIR_Type_indexed_impl(2, blocks, displs, recvtype, &tmp_type);
+ if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+ mpi_errno = MPIR_Type_commit_impl(&tmp_type);
+ if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+
+ mpi_errno = MPID_Sched_recv(recvbuf, 1, tmp_type, 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);
+
+ /* this "premature" free is safe b/c the sched holds an actual ref to keep it alive */
+ MPIR_Type_free_impl(&tmp_type);
+ }
+ }
+ else { /* Intermediate nodes store in temporary buffer */
+ int offset;
+
+ /* Estimate the amount of data that is going to come in */
+ recvblks = mask;
+ relative_src = ((src - root) < 0) ? (src - root + comm_size) : (src - root);
+ if (relative_src + mask > comm_size)
+ recvblks -= (relative_src + mask - comm_size);
+
+ if (nbytes < MPIR_PARAM_GATHER_VSMALL_MSG_SIZE)
+ offset = mask * nbytes;
+ else
+ offset = (mask - 1) * nbytes;
+ mpi_errno = MPID_Sched_recv(((char *)tmp_buf + offset), (recvblks * nbytes),
+ 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);
+ curr_cnt += (recvblks * nbytes);
+ }
+ }
+ }
+ else {
+ dst = relative_rank ^ mask;
+ dst = (dst + root) % comm_size;
+
+ if (!tmp_buf_size) {
+ /* leaf nodes send directly from sendbuf */
+ mpi_errno = MPID_Sched_send(sendbuf, sendcount, sendtype, dst, 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);
+ }
+ else if (nbytes < MPIR_PARAM_GATHER_VSMALL_MSG_SIZE) {
+ mpi_errno = MPID_Sched_send(tmp_buf, curr_cnt, MPI_BYTE, dst, 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);
+ }
+ else {
+ blocks[0] = sendcount;
+ struct_displs[0] = MPI_VOID_PTR_CAST_TO_MPI_AINT sendbuf;
+ types[0] = sendtype;
+ blocks[1] = curr_cnt - nbytes;
+ struct_displs[1] = MPI_VOID_PTR_CAST_TO_MPI_AINT tmp_buf;
+ types[1] = MPI_BYTE;
+
+ mpi_errno = MPIR_Type_create_struct_impl(2, blocks, struct_displs, types, &tmp_type);
+ if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+ mpi_errno = MPIR_Type_commit_impl(&tmp_type);
+ if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+
+ mpi_errno = MPID_Sched_send(MPI_BOTTOM, 1, tmp_type, dst, comm_ptr, s);
+ mpi_errno = MPID_Sched_barrier(s);
+ if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+
+ /* this "premature" free is safe b/c the sched holds an actual ref to keep it alive */
+ MPIR_Type_free_impl(&tmp_type);
+ }
+
+ break;
+ }
+ mask <<= 1;
+ }
+
+ if ((rank == root) && root && (nbytes < MPIR_PARAM_GATHER_VSMALL_MSG_SIZE) && copy_blks) {
+ /* reorder and copy from tmp_buf into recvbuf */
+ /* FIXME why are there two copies here? */
+ mpi_errno = MPID_Sched_copy(tmp_buf, nbytes * (comm_size - copy_offset), MPI_BYTE,
+ ((char *)recvbuf + extent * recvcount * copy_offset),
+ recvcount * (comm_size - copy_offset), recvtype, s);
+ if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+ mpi_errno = MPID_Sched_copy((char *)tmp_buf + nbytes * (comm_size - copy_offset),
+ nbytes * (copy_blks - comm_size + copy_offset), MPI_BYTE,
+ recvbuf, recvcount * (copy_blks - comm_size + copy_offset),
+ recvtype, s);
+ if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+ }
+ }
+#ifdef MPID_HAS_HETERO
+ else {
+ /* communicator is heterogeneous. pack data into tmp_buf. */
+
+ /* currently unimplemented & untested */
+ MPIU_Assertp(FALSE);
+
+#if 0
+ if (rank == root)
+ MPIR_Pack_size_impl(recvcount*comm_size, recvtype, &tmp_buf_size);
+ else
+ MPIR_Pack_size_impl(sendcount*(comm_size/2), sendtype, &tmp_buf_size);
+
+ MPIU_CHKPMEM_MALLOC(tmp_buf, void *, tmp_buf_size, mpi_errno, "tmp_buf");
+
+ position = 0;
+ if (sendbuf != MPI_IN_PLACE) {
+ mpi_errno = MPIR_Pack_impl(sendbuf, sendcount, sendtype, tmp_buf,
+ tmp_buf_size, &position);
+ if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+ nbytes = position;
+ }
+ else {
+ /* do a dummy pack just to calculate nbytes */
+ mpi_errno = MPIR_Pack_impl(recvbuf, 1, recvtype, tmp_buf,
+ tmp_buf_size, &position);
+ if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+ nbytes = position*recvcount;
+ }
+
+ curr_cnt = nbytes;
+
+ mask = 0x1;
+ while (mask < comm_size) {
+ if ((mask & relative_rank) == 0) {
+ src = relative_rank | mask;
+ if (src < comm_size) {
+ src = (src + root) % comm_size;
+ mpi_errno = MPIC_Recv_ft(((char *)tmp_buf + curr_cnt),
+ tmp_buf_size-curr_cnt, MPI_BYTE, src,
+ MPIR_GATHER_TAG, comm,
+ &status, errflag);
+ /* the recv size is larger than what may be sent in
+ some cases. query amount of data actually received */
+ recv_size = 0;
+ MPIR_Get_count_impl(&status, MPI_BYTE, &recv_size);
+ curr_cnt += recv_size;
+ }
+ }
+ else
+ {
+ dst = relative_rank ^ mask;
+ dst = (dst + root) % comm_size;
+ mpi_errno = MPIC_Send_ft(tmp_buf, curr_cnt, MPI_BYTE, dst,
+ MPIR_GATHER_TAG, comm, errflag);
+ if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+ break;
+ }
+ mask <<= 1;
+ }
+
+ if (rank == root)
+ {
+ /* reorder and copy from tmp_buf into recvbuf */
+ if (sendbuf != MPI_IN_PLACE) {
+ position = 0;
+ mpi_errno = MPIR_Unpack_impl(tmp_buf, tmp_buf_size, &position,
+ ((char *) recvbuf + extent*recvcount*rank),
+ recvcount*(comm_size-rank), recvtype);
+ if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+ }
+ else {
+ position = nbytes;
+ mpi_errno = MPIR_Unpack_impl(tmp_buf, tmp_buf_size, &position,
+ ((char *) recvbuf + extent*recvcount*(rank+1)),
+ recvcount*(comm_size-rank-1), recvtype);
+ if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+ }
+ if (root != 0) {
+ mpi_errno = MPIR_Unpack_impl(tmp_buf, tmp_buf_size, &position, recvbuf,
+ recvcount*rank, recvtype);
+ if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+ }
+ }
+
+ }
+#endif
+#endif /* MPID_HAS_HETERO */
+
+ if (tmp_buf) {
+ mpi_errno = MPID_Sched_cb(&MPIR_Sched_cb_free_buf, tmp_buf, s);
+ if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+ }
+
+ MPIU_CHKPMEM_COMMIT();
+fn_exit:
+ return mpi_errno;
+fn_fail:
+ MPIU_CHKPMEM_REAP();
+ goto fn_exit;
+}
+
+#undef FUNCNAME
+#define FUNCNAME MPIR_Igather_intra
+#undef FCNAME
+#define FCNAME MPIU_QUOTE(FUNCNAME)
+int MPIR_Igather_intra(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPID_Comm *comm_ptr, MPID_Sched_t s)
+{
+ int mpi_errno = MPI_SUCCESS;
+
+ mpi_errno = MPIR_Igather_binomial(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, 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_Igather_inter
+#undef FCNAME
+#define FCNAME MPIU_QUOTE(FUNCNAME)
+int MPIR_Igather_inter(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPID_Comm *comm_ptr, MPID_Sched_t s)
+{
+ int mpi_errno = MPI_SUCCESS;
+ int rank, local_size, remote_size;
+ int i, nbytes, sendtype_size, recvtype_size;
+ MPI_Aint extent, true_extent, true_lb = 0;
+ void *tmp_buf = NULL;
+ MPID_Comm *newcomm_ptr = NULL;
+ MPIU_CHKPMEM_DECL(1);
+
+/* Intercommunicator gather.
+ For short messages, remote group does a local intracommunicator
+ gather to rank 0. Rank 0 then sends data to root.
+
+ Cost: (lgp+1).alpha + n.((p-1)/p).beta + n.beta
+
+ For long messages, we use linear gather to avoid the extra n.beta.
+
+ Cost: p.alpha + n.beta
+*/
+
+ MPIU_Assertp(FALSE);
+
+ if (root == MPI_PROC_NULL) {
+ /* local processes other than root do nothing */
+ goto fn_exit;
+ }
+
+ remote_size = comm_ptr->remote_size;
+ local_size = comm_ptr->local_size;
+
+ if (root == MPI_ROOT) {
+ MPID_Datatype_get_size_macro(recvtype, recvtype_size);
+ nbytes = recvtype_size * recvcount * remote_size;
+ }
+ else {
+ /* remote side */
+ MPID_Datatype_get_size_macro(sendtype, sendtype_size);
+ nbytes = sendtype_size * sendcount * local_size;
+ }
+
+ if (nbytes < MPIR_PARAM_GATHER_INTER_SHORT_MSG_SIZE) {
+ if (root == MPI_ROOT) {
+ /* root receives data from rank 0 on remote group */
+ mpi_errno = MPID_Sched_recv(recvbuf, recvcount*remote_size, recvtype, 0, comm_ptr, s);
+ if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+ }
+ else {
+ /* remote group. Rank 0 allocates temporary buffer, does
+ local intracommunicator gather, and then sends the data
+ to root. */
+
+ rank = comm_ptr->rank;
+
+ if (rank == 0) {
+ MPIR_Type_get_true_extent_impl(sendtype, &true_lb, &true_extent);
+ MPID_Datatype_get_extent_macro(sendtype, extent);
+
+ MPID_Ensure_Aint_fits_in_pointer(sendcount*local_size*(MPIR_MAX(extent, true_extent)));
+ MPIU_CHKPMEM_MALLOC(tmp_buf, void *, sendcount*local_size*(MPIR_MAX(extent,true_extent)),
+ mpi_errno, "tmp_buf");
+ /* adjust for potential negative lower bound in datatype */
+ tmp_buf = (void *)((char*)tmp_buf - true_lb);
+ }
+
+ /* all processes in remote group form new intracommunicator */
+ if (!comm_ptr->local_comm) {
+ mpi_errno = MPIR_Setup_intercomm_localcomm( comm_ptr );
+ if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+ }
+
+ newcomm_ptr = comm_ptr->local_comm;
+
+ /* now do the a local gather on this intracommunicator */
+ MPIU_Assert(newcomm_ptr->coll_fns && newcomm_ptr->coll_fns->Igather);
+ mpi_errno = newcomm_ptr->coll_fns->Igather(sendbuf, sendcount, sendtype,
+ tmp_buf, sendcount, sendtype, 0,
+ newcomm_ptr, s);
+ if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+
+ if (rank == 0) {
+ mpi_errno = MPID_Sched_send(tmp_buf, sendcount*local_size, sendtype, root, comm_ptr, s);
+ if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+ }
+ }
+ }
+ else {
+ /* long message. use linear algorithm. */
+ if (root == MPI_ROOT) {
+ MPID_Datatype_get_extent_macro(recvtype, extent);
+ MPID_Ensure_Aint_fits_in_pointer(MPI_VOID_PTR_CAST_TO_MPI_AINT recvbuf +
+ (recvcount*remote_size*extent));
+
+ for (i=0; i<remote_size; i++) {
+ mpi_errno = MPID_Sched_recv(((char *)recvbuf+recvcount*i*extent),
+ recvcount, recvtype, i, comm_ptr, s);
+ if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+ }
+ }
+ else {
+ mpi_errno = MPID_Sched_send(sendbuf, sendcount, sendtype, root, comm_ptr, s);
+ if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+ }
+ }
+
+ if (tmp_buf) {
+ mpi_errno = MPID_Sched_cb(&MPIR_Sched_cb_free_buf, tmp_buf, s);
+ if (mpi_errno) MPIU_ERR_POP(mpi_errno);
+ }
+
+ MPIU_CHKPMEM_COMMIT();
+fn_exit:
+ return mpi_errno;
+fn_fail:
+ MPIU_CHKPMEM_REAP();
+ goto fn_exit;
+}
+
+#undef FUNCNAME
#define FUNCNAME MPIR_Igather_impl
#undef FCNAME
#define FCNAME MPIU_QUOTE(FUNCNAME)
Modified: mpich2/trunk/src/mpi/comm/commutil.c
===================================================================
--- mpich2/trunk/src/mpi/comm/commutil.c 2011-02-15 21:58:59 UTC (rev 7973)
+++ mpich2/trunk/src/mpi/comm/commutil.c 2011-02-15 21:59:01 UTC (rev 7974)
@@ -249,6 +249,7 @@
ops->Ireduce = &MPIR_Ireduce_intra;
ops->Ialltoallv = &MPIR_Ialltoallv_intra;
ops->Iallreduce = &MPIR_Iallreduce_intra;
+ ops->Igather = &MPIR_Igather_intra;
/* TODO add other fns here as they are added */
/* override defaults, such as for SMP */
@@ -281,6 +282,7 @@
ops->Ireduce = &MPIR_Ireduce_inter;
ops->Ialltoallv = &MPIR_Ialltoallv_inter;
ops->Iallreduce = &MPIR_Iallreduce_inter;
+ ops->Igather = &MPIR_Igather_inter;
ic_default_collops = ops;
}
More information about the mpich2-commits
mailing list