I am trying to implement my own version of MPI_Allreduce in C. The logic is that odd ranks send their data to even ranks to their rank-1, ie rank 1 sends to rank 0. Rank 0 then receives the data from rank 1 and operates on it depending on the MPI_Op operator passed as an argument. I am unsure if my way of operating on the data is correct, for example if MPI_SUM is passed then for each count passed my code does recvbuf[count] += sendbuf[count]. Once the even rank has received data from the odd rank+1, it then does rank /= 2 and the contents of the while loop repeat, with rank 0, being unchanged, rank 2 becoming rank 1 and now containing the original ranks 2+3 data, and so on. Num is also halfed each interation of the while loop until it becomes 1, which is when only rank 0 should remain.
My code thus far is below:
int tree_reduction(const int rank_in, const int np, const int *sendbuf, int *recvbuf,
int count, MPI_Op op, MPI_Comm comm){
// Create variables for rank and size
int rank = rank_in;
int num = np;
int tag = 0;
int depth = 1; // Depth of the tree
// While size is greater than 1 there is 2 or more ranks to operate on
while(num > 1){
if(rank < num){
if( (rank % 2) != 0 ){ // If rank is odd
MPI_Ssend(sendbuf, count, MPI_INT, (rank-1)*depth, tag, comm);
rank *= num; // any ranks above 0 will be filtered out
break;
}
else{ // If rank is even
MPI_Recv(recvbuf, count, MPI_INT, (rank+1)*depth, tag, comm,
MPI_STATUS_IGNORE);
/* START OF OPERATORS */
if(op == MPI_SUM){
for(int c=0; c<count; c++){
recvbuf[c] += sendbuf[c];
}
}
if(op == MPI_PROD){
for(int c=0; c<count; c++){
recvbuf[count] *= sendbuf[count];
}
}
if(op == MPI_MIN){
for(int c=0; c<count; c++){
if(sendbuf[count] < recvbuf[count]){
recvbuf[count] = sendbuf[count];
}
}
}
if(op == MPI_MAX){
for(int c=0; c<count; c++){
if(sendbuf[count] > recvbuf[count]){
recvbuf[count] = sendbuf[count];
}
}
}
/* END OF OPERATORS */
}
depth *= 2;
}
num = num/2;
}
// NEED TO BROADCAST BACK TO ALL RANKS
MPI_Bcast(recvbuf, count, MPI_INT, 0, comm);
return 0;
When I run this with more than 2 processes, it hangs indefinitely without printing anything to the terminal, why is this?