hpc/reduce/binom_reduce.c
2016-06-22 15:23:45 +02:00

62 lines
1.2 KiB
C

/*
* binom_reduce.c
*
* Created on: 18 Jun 2016
* Author: johannes
*/
#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;
}