From 265bb2ac36771915e9d4c6eafb15889f67b53029 Mon Sep 17 00:00:00 2001 From: Johannes Winklehner Date: Wed, 11 May 2016 22:00:19 +0200 Subject: [PATCH] =?UTF-8?q?Binom=5FReduce=20funktioniert=20soweit=20denk?= =?UTF-8?q?=20ich,=20ob=20kommutativit=C3=A4t=20passt=20bin=20ich=20nicht?= =?UTF-8?q?=20sicher?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hpc_mpi/src/hpc_mpi.c | 78 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 hpc_mpi/src/hpc_mpi.c diff --git a/hpc_mpi/src/hpc_mpi.c b/hpc_mpi/src/hpc_mpi.c new file mode 100644 index 0000000..6c89719 --- /dev/null +++ b/hpc_mpi/src/hpc_mpi.c @@ -0,0 +1,78 @@ +/* + ============================================================================ + Name : hpc_mpi.c + Author : + Version : + Copyright : Your copyright notice + Description : Hello MPI World in C + ============================================================================ + */ +#include +#include +#include "mpi.h" + +int Binom_Reduce(const void *sendbuf, void *recvbuf, int count, + MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm); + +int main(int argc, char* argv[]) { + int my_rank; /* rank of process */ + int p; /* number of processes */ + + /* start up MPI */ + + MPI_Init(&argc, &argv); + + /* find out process rank */ + MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); + + /* find out number of processes */ + MPI_Comm_size(MPI_COMM_WORLD, &p); + + int a = my_rank; + int recv; + + Binom_Reduce(&a, &recv, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD); + + if (my_rank == 0) { + printf("%i\n", recv); + } + /* shut down MPI */ + MPI_Finalize(); + + return 0; +} + +int Binom_Reduce(const void *sendbuf, void *recvbuf, int count, + MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm) { + 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); + if (r != root) { + MPI_Alloc_mem(count * size, MPI_INFO_NULL, &reduced); + } else { + reduced = recvbuf; + } + 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(recv, reduced, count, datatype, op); + } + i <<= 1; + } + + if (r != root) { + MPI_Send(reduced, count, datatype, r - i, i, comm); + } + + return 0; +}