diff --git a/NEWS b/NEWS index a7f795f9a5..16e7f66784 100644 --- a/NEWS +++ b/NEWS @@ -68,8 +68,9 @@ version 1.0. - Fix for large-sized Fortran LOGICAL datatypes. - Fix various error checking in MPI_INFO_GET_NTHKEY and - MPI_GROUP_TRANSLATE_RANKS. Thanks to Lisandro Dalcin for reporting - the problem. + MPI_GROUP_TRANSLATE_RANKS, and some collective operations + (particularly with regards to MPI_IN_PLACE). Thanks to Lisandro + Dalcin for reporting the problems. - Fix receiving messages to buffers allocated by MPI_ALLOC_MEM. - Fix the "tuned" collective componenete where some cases where MPI_BCAST could hang. diff --git a/ompi/mpi/c/allgather.c b/ompi/mpi/c/allgather.c index 4550ba2f22..5a31f4dd01 100644 --- a/ompi/mpi/c/allgather.c +++ b/ompi/mpi/c/allgather.c @@ -60,12 +60,14 @@ int MPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype, OMPI_ERRHANDLER_CHECK(err, comm, err, FUNC_NAME); } - /* Can we optimize? Everyone had to give the same send signature, - which means that everyone must have given a sendcount > 0 if - there's anything to send. */ + /* Do we need to do anything? Everyone had to give the same send + signature, which means that everyone must have given a + sendcount > 0 if there's anything to send. If we're doing + IN_PLACE, however, check recvcount, not sendcount. */ - if (sendcount == 0) { - return MPI_SUCCESS; + if ((MPI_IN_PLACE != sendbuf && 0 == sendcount) || + (0 == recvcount)) { + return MPI_SUCCESS; } /* Invoke the coll component to perform the back-end operation */ diff --git a/ompi/mpi/c/alltoall.c b/ompi/mpi/c/alltoall.c index f85f26bbcf..c156cba57b 100644 --- a/ompi/mpi/c/alltoall.c +++ b/ompi/mpi/c/alltoall.c @@ -61,10 +61,9 @@ int MPI_Alltoall(void *sendbuf, int sendcount, MPI_Datatype sendtype, OMPI_ERRHANDLER_CHECK(err, comm, err, FUNC_NAME); } - /* If the sendcount is 0, since everyone gave the same value, then - we don't need to do anything */ + /* Do we need to do anything? */ - if (0 == sendcount) { + if (0 == sendcount && 0 == recvcount) { return MPI_SUCCESS; } diff --git a/ompi/mpi/c/bcast.c b/ompi/mpi/c/bcast.c index aff4616e11..da6c113a7a 100644 --- a/ompi/mpi/c/bcast.c +++ b/ompi/mpi/c/bcast.c @@ -71,17 +71,12 @@ int MPI_Bcast(void *buffer, int count, MPI_Datatype datatype, } } - /* If there's only one node, we're done */ + /* If there's only one node, or if the count is 0, we're done */ - if (OMPI_COMM_IS_INTRA(comm) && ompi_comm_size(comm) <= 1) { - return MPI_SUCCESS; - } - - /* Can we optimize? */ - - if (count == 0) { - return MPI_SUCCESS; - } + if ((OMPI_COMM_IS_INTRA(comm) && ompi_comm_size(comm) <= 1) || + 0 == count) { + return MPI_SUCCESS; + } /* Invoke the coll component to perform the back-end operation */ diff --git a/ompi/mpi/c/exscan.c b/ompi/mpi/c/exscan.c index bde5bba714..92e298158e 100644 --- a/ompi/mpi/c/exscan.c +++ b/ompi/mpi/c/exscan.c @@ -62,6 +62,14 @@ int MPI_Exscan(void *sendbuf, void *recvbuf, int count, OMPI_ERRHANDLER_CHECK(err, comm, err, FUNC_NAME); } + /* Do we need to do anything? (MPI says that reductions have to + have a count of at least 1, but at least IMB calls reduce with + a count of 0 -- blah!) */ + + if (0 == count) { + return MPI_SUCCESS; + } + /* Invoke the coll component to perform the back-end operation */ OBJ_RETAIN(op); diff --git a/ompi/mpi/c/gather.c b/ompi/mpi/c/gather.c index eecd43b400..898579f62e 100644 --- a/ompi/mpi/c/gather.c +++ b/ompi/mpi/c/gather.c @@ -112,12 +112,14 @@ int MPI_Gather(void *sendbuf, int sendcount, MPI_Datatype sendtype, } } - /* Can we optimize? Everyone had to give the same send signature, - which means that everyone must have given a sendcount > 0 if - there's anything to send. */ + /* Do we need to do anything? */ - if (sendcount == 0) { - return MPI_SUCCESS; + if ((0 == sendcount && + (ompi_comm_rank(comm) != root || + (ompi_comm_rank(comm) == root && MPI_IN_PLACE != sendbuf))) || + (ompi_comm_rank(comm) == root && MPI_IN_PLACE == sendbuf && + 0 == recvbuf)) { + return MPI_SUCCESS; } /* Invoke the coll component to perform the back-end operation */ diff --git a/ompi/mpi/c/gatherv.c b/ompi/mpi/c/gatherv.c index 3e4b2a9723..66befe91fa 100644 --- a/ompi/mpi/c/gatherv.c +++ b/ompi/mpi/c/gatherv.c @@ -128,12 +128,6 @@ int MPI_Gatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype, } } - /* If we have nothing to do, just return */ - - if (0 == sendcount && ompi_comm_rank(comm) != root) { - return MPI_SUCCESS; - } - /* Invoke the coll component to perform the back-end operation */ err = comm->c_coll.coll_gatherv(sendbuf, sendcount, sendtype, recvbuf, diff --git a/ompi/mpi/c/reduce.c b/ompi/mpi/c/reduce.c index c1307ddc6d..c3e24ac72b 100644 --- a/ompi/mpi/c/reduce.c +++ b/ompi/mpi/c/reduce.c @@ -81,10 +81,10 @@ int MPI_Reduce(void *sendbuf, void *recvbuf, int count, } } - /* MPI-1, p114, says that each process must supply at least - one element. But at least the Pallas benchmarks call - MPI_REDUCE with a count of 0. So be sure to handle it. */ - + /* Do we need to do anything? (MPI says that reductions have to + have a count of at least 1, but at least IMB calls reduce with + a count of 0 -- blah!) */ + if (0 == count) { return MPI_SUCCESS; } diff --git a/ompi/mpi/c/reduce_scatter.c b/ompi/mpi/c/reduce_scatter.c index ecb3eaf2ae..228c6411d9 100644 --- a/ompi/mpi/c/reduce_scatter.c +++ b/ompi/mpi/c/reduce_scatter.c @@ -88,7 +88,7 @@ int MPI_Reduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts, if (size == count) { return MPI_SUCCESS; } - + /* Invoke the coll component to perform the back-end operation */ OBJ_RETAIN(op); diff --git a/ompi/mpi/c/scan.c b/ompi/mpi/c/scan.c index 369b4aaf6d..e96f7cdb24 100644 --- a/ompi/mpi/c/scan.c +++ b/ompi/mpi/c/scan.c @@ -70,7 +70,9 @@ int MPI_Scan(void *sendbuf, void *recvbuf, int count, OMPI_ERRHANDLER_CHECK(err, comm, err, FUNC_NAME); } - /* If everyone supplied count == 0, we can just return */ + /* Do we need to do anything? (MPI says that reductions have to + have a count of at least 1, but at least IMB calls reduce with + a count of 0 -- blah!) */ if (0 == count) { return MPI_SUCCESS; diff --git a/ompi/mpi/c/scatter.c b/ompi/mpi/c/scatter.c index 61ca44bbca..d3881a19c9 100644 --- a/ompi/mpi/c/scatter.c +++ b/ompi/mpi/c/scatter.c @@ -107,10 +107,13 @@ int MPI_Scatter(void *sendbuf, int sendcount, MPI_Datatype sendtype, } } - /* If we have nothing to receive, return success (everyone must - have given the same recvcount) */ + /* Do we need to do anything? */ - if (0 == recvcount) { + if ((0 == recvcount && + (ompi_comm_rank(comm) != root || + (ompi_comm_rank(comm) == root && MPI_IN_PLACE != recvbuf))) || + (ompi_comm_rank(comm) == root && MPI_IN_PLACE == recvbuf && + 0 == sendcount)) { return MPI_SUCCESS; } diff --git a/ompi/mpi/c/scatterv.c b/ompi/mpi/c/scatterv.c index 244d258a4d..608c613e81 100644 --- a/ompi/mpi/c/scatterv.c +++ b/ompi/mpi/c/scatterv.c @@ -136,12 +136,6 @@ int MPI_Scatterv(void *sendbuf, int *sendcounts, int *displs, } } - /* If we have nothing to do, just return */ - - if (0 == recvcount && ompi_comm_rank(comm) != root) { - return MPI_SUCCESS; - } - /* Invoke the coll component to perform the back-end operation */ err = comm->c_coll.coll_scatterv(sendbuf, sendcounts, displs, sendtype,