[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