#include #include #include #include "binom_reduce.h" void swap(void **a, void **b) { void *temp; temp = *a; *a = *b; *b = temp; } int Binom_Reduce(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm) { if (root != 0) { fprintf(stderr, "Sorry, root!=0 not allowed"); return -1; } int r, p, size; MPI_Status status; void *recv; void *reduced; MPI_Comm_rank(comm, &r); MPI_Comm_size(comm, &p); MPI_Type_size(datatype, &size); MPI_Alloc_mem(count * size, MPI_INFO_NULL, &recv); MPI_Alloc_mem(count * size, MPI_INFO_NULL, &reduced); memcpy(reduced, sendbuf, count * size); int i = 1; while ((r + i) % (2 * i) != 0 && i < p) { if (r + i < p) { MPI_Recv(recv, count, datatype, r + i, i, comm, &status); MPI_Reduce_local(reduced, recv, count, datatype, op); swap(&reduced, &recv); } i <<= 1; } if (r != root) { MPI_Send(reduced, count, datatype, r - i, i, comm); } else { memcpy(recvbuf, reduced, count * size); } MPI_Free_mem(reduced); MPI_Free_mem(recv); return 0; }