I am trying to understand the MPI_Reduce_scatter
function but it seems that my deductions are always wrong :(
The documentation says (link):
MPI_Reduce_scatter first does an element-wise reduction on vector of count = S(i)recvcounts[i] elements in the send buffer defined by sendbuf, count, and datatype. Next, the resulting vector of results is split into n disjoint segments, where n is the number of processes in the group. Segment i contains recvcounts[i] elements. The ith segment is sent to process i and stored in the receive buffer defined by recvbuf, recvcounts[i], and datatype.
I have the following (very simple) C program and I expected to get the max of the first recvcounts[i] elements, but it seems that I am doing something wrong...
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
#define NUM_PE 5
#define NUM_ELEM 3
char *print(int arr[], int n);
int main(int argc, char *argv[]) {
int rank, size, i, n;
int sendbuf[5][3] = {
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 },
{ 10, 11, 12 },
{ 13, 14, 15 }
};
int recvbuf[15] = {0};
int recvcounts[5] = {
3, 3, 3, 3, 3
};
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
n = sizeof(sendbuf[rank]) / sizeof(int);
printf("sendbuf (thread %d): %s\n", rank, print(sendbuf[rank], n));
MPI_Reduce_scatter(sendbuf, recvbuf, recvcounts, MPI_INT, MPI_MAX, MPI_COMM_WORLD);
n = sizeof(recvbuf) / sizeof(int);
printf("recvbuf (thread %d): %s\n", rank, print(recvbuf, n)); // <--- I receive the same output as with sendbuf :(
MPI_Finalize();
return 0;
}
char *print(int arr[], int n) { } // it returns a string formatted as the following output
The output of my program is the same for recvbuf and sendbuf. I expected recvbuf to contain the max:
$ mpicc 03_reduce_scatter.c
$ mpirun -n 5 ./a.out
sendbuf (thread 4): [ 13, 14, 15 ]
sendbuf (thread 3): [ 10, 11, 12 ]
sendbuf (thread 2): [ 7, 8, 9 ]
sendbuf (thread 0): [ 1, 2, 3 ]
sendbuf (thread 1): [ 4, 5, 6 ]
recvbuf (thread 1): [ 4, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
recvbuf (thread 2): [ 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
recvbuf (thread 0): [ 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
recvbuf (thread 3): [ 10, 11, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
recvbuf (thread 4): [ 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]