55 lines
1.1 KiB
C
55 lines
1.1 KiB
C
#include <mpi.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#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;
|
|
}
|