Skip to content

Commit 045d0c5

Browse files
committed
Fix for Ireduce + MPI_IN_PLACE.
Fixes a wrong answer from MPI_Ireduce when the red_sched_chain() path was taken (which only happens for np<=4 and mesgsize>=64k). The way libnbc treats MPI_IN_PLACE is to set sbuf == rbuf, and whether an algorithm will work cleanly or not after that depends on the details. In this case the last steps of the algorithm amounted to (right neighbor is sending us reduction results from ranks 1..n-1) recv into rbuf from right neighbor add the contribution from our sbuf into rbuf this would be fine in general, but if sbuf==rbuf, that recv overwrites the sbuf. I changed it to recv into a tmpbuf if MPI_IN_PLACE was used. Signed-off-by: Geoffrey Paulsen <[email protected]>
1 parent 4e06b96 commit 045d0c5

File tree

1 file changed

+23
-2
lines changed

1 file changed

+23
-2
lines changed

ompi/mca/coll/libnbc/nbc_ireduce.c

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
* reserved.
1010
* Copyright (c) 2014-2017 Research Organization for Information Science
1111
* and Technology (RIST). All rights reserved.
12+
* Copyright (c) 2017 IBM Corporation. All rights reserved.
1213
*
1314
* Author(s): Torsten Hoefler <[email protected]>
1415
*
@@ -427,9 +428,29 @@ static inline int red_sched_chain (int rank, int p, int root, const void *sendbu
427428
/* last node does not recv */
428429
if (vrank != p-1) {
429430
if (vrank == 0) {
430-
res = NBC_Sched_recv ((char *)recvbuf+offset, false, thiscount, datatype, rpeer, schedule, true);
431+
if (sendbuf != recvbuf) {
432+
// for regular src, recv into recvbuf
433+
res = NBC_Sched_recv ((char *)recvbuf+offset, false, thiscount, datatype, rpeer, schedule, true);
434+
} else {
435+
// but for any-src, recv into tmpbuf
436+
// because for any-src if we recved into recvbuf here we'd be
437+
// overwriting our sendbuf, and we use it in the operation
438+
// that happens further down
439+
res = NBC_Sched_recv ((char *)offset, true, thiscount, datatype, rpeer, schedule, true);
440+
}
431441
} else {
432-
res = NBC_Sched_recv ((char *) offset, true, thiscount, datatype, rpeer, schedule, true);
442+
if (sendbuf != recvbuf) {
443+
// for regular src, add sendbuf into recvbuf
444+
// (here recvbuf holds the reduction from 1..n-1)
445+
res = NBC_Sched_op ((char *) sendbuf + offset, false, (char *) recvbuf + offset, false,
446+
thiscount, datatype, op, schedule, true);
447+
} else {
448+
// for any-src, add tmpbuf into recvbuf
449+
// (here tmpbuf holds the reduction from 1..n-1) and
450+
// recvbuf is our sendbuf
451+
res = NBC_Sched_op ((char *) offset, true, (char *) recvbuf + offset, false,
452+
thiscount, datatype, op, schedule, true);
453+
}
433454
}
434455
if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
435456
return res;

0 commit comments

Comments
 (0)