diff --git a/hpc_mpi/src/bin_reduce.c b/hpc_mpi/src/bin_reduce.c index a88cf05..c79a5e5 100644 --- a/hpc_mpi/src/bin_reduce.c +++ b/hpc_mpi/src/bin_reduce.c @@ -7,7 +7,7 @@ #include #include -#include "mpi.h" +#include #include "bin_reduce.h" int int_log2(int x) { diff --git a/hpc_mpi/src/binom_reduce.c b/hpc_mpi/src/binom_reduce.c new file mode 100644 index 0000000..eff1858 --- /dev/null +++ b/hpc_mpi/src/binom_reduce.c @@ -0,0 +1,48 @@ +/* + * binom_reduce.c + * + * Created on: 18 Jun 2016 + * Author: johannes + */ + +#include +#include +#include "binom_reduce.h" + +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); + MPI_Free_mem(reduced); + } + + MPI_Free_mem(recv); + + return 0; +} diff --git a/hpc_mpi/src/binom_reduce.h b/hpc_mpi/src/binom_reduce.h new file mode 100644 index 0000000..5b36a10 --- /dev/null +++ b/hpc_mpi/src/binom_reduce.h @@ -0,0 +1,14 @@ +/* + * binom_reduce.h + * + * Created on: 18 Jun 2016 + * Author: johannes + */ + +#ifndef BINOM_REDUCE_H_ +#define BINOM_REDUCE_H_ + +int Binom_Reduce(const void *sendbuf, void *recvbuf, int count, + MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm); + +#endif /* BINOM_REDUCE_H_ */ diff --git a/hpc_mpi/src/fib_reduce.c b/hpc_mpi/src/fib_reduce.c new file mode 100644 index 0000000..01de8bb --- /dev/null +++ b/hpc_mpi/src/fib_reduce.c @@ -0,0 +1,87 @@ +/* + * fib_reduce.c + * + * Created on: 18 Jun 2016 + * Author: johannes + */ + +#include +#include +#include +#include "fib_reduce.h" + +int Fib_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_right; + + MPI_Comm_rank(comm, &r); + MPI_Comm_size(comm, &p); + MPI_Type_size(datatype, &size); + + int temp; + int fibm1 = 1; + int fib = 1; + + while (fib - 1 < p) { + temp = fib; + fib += fibm1; + fibm1 = temp; + } + + int right = fibm1; + int left = fib - fibm1; + int i = 0; + int parent = 0; + + while (i != r) { + parent = i; + if (r >= i + left) { + i += left; + temp = left; + left = right - left; + right = temp; + } else { + i++; + right -= left; + left -= right; + } + } + + if (r == root) { + recv_right = recvbuf; + } else { + MPI_Alloc_mem(size * count, MPI_INFO_NULL, &recv_right); + } + + if (right - 1 > 0 && r + 1 < p) { + void *recv_left; + MPI_Alloc_mem(count * size, MPI_INFO_NULL, &recv_left); + MPI_Recv(recv_left, count, datatype, r + 1, 0, comm, &status); + MPI_Reduce_local(sendbuf, recv_left, count, datatype, op); + + if (left - 1 > 0 && r + left < p) { + MPI_Recv(recv_right, count, datatype, r + left, 0, comm, &status); + MPI_Reduce_local(recv_left, recv_right, count, datatype, op); + } else { + memcpy(recv_right, recv_left, count * size); + } + + MPI_Free_mem(recv_left); + } else { + memcpy(recv_right, sendbuf, count * size); + } + + if (r != root) { + MPI_Send(recv_right, count, datatype, parent, 0, comm); + MPI_Free_mem(recv_right); + } + + return 0; +} diff --git a/hpc_mpi/src/fib_reduce.h b/hpc_mpi/src/fib_reduce.h new file mode 100644 index 0000000..fa20580 --- /dev/null +++ b/hpc_mpi/src/fib_reduce.h @@ -0,0 +1,14 @@ +/* + * fib_reduce.h + * + * Created on: 18 Jun 2016 + * Author: johannes + */ + +#ifndef FIB_REDUCE_H_ +#define FIB_REDUCE_H_ + +int Fib_Reduce(const void *sendbuf, void *recvbuf, int count, + MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm); + +#endif /* FIB_REDUCE_H_ */ diff --git a/hpc_mpi/src/hpc_mpi.c b/hpc_mpi/src/hpc_mpi.c index 9e83b84..3f90c5b 100644 --- a/hpc_mpi/src/hpc_mpi.c +++ b/hpc_mpi/src/hpc_mpi.c @@ -9,11 +9,10 @@ */ #include #include -#include "mpi.h" +#include #include "bin_reduce.h" - -int Binom_Reduce(const void *sendbuf, void *recvbuf, int count, - MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm); +#include "binom_reduce.h" +#include "fib_reduce.h" int main(int argc, char* argv[]) { int my_rank; /* rank of process */ @@ -32,7 +31,7 @@ int main(int argc, char* argv[]) { int a = my_rank; int recv; - Bin_Reduce(&a, &recv, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD); + Fib_Reduce(&a, &recv, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD); //Binom_Reduce(&a, &recv, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD); @@ -45,46 +44,3 @@ int main(int argc, char* argv[]) { 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); - MPI_Free_mem(reduced); - } - - MPI_Free_mem(recv); - - return 0; -} - -int Fib_Reduce(const void *sendbuf, void *recvbuf, int count, - MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm) { - return 0; -} -