kleinigkeiten am reduce
This commit is contained in:
parent
73f6be7249
commit
db65a92e20
12 changed files with 504 additions and 34 deletions
|
@ -11,7 +11,7 @@
|
||||||
#include "bin_reduce.h"
|
#include "bin_reduce.h"
|
||||||
|
|
||||||
int int_log2(int x) {
|
int int_log2(int x) {
|
||||||
int r;
|
int r=0;
|
||||||
while (x >>= 1) {
|
while (x >>= 1) {
|
||||||
r++;
|
r++;
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,6 @@ int Bin_Reduce(const void *sendbuf, void *recvbuf, int count,
|
||||||
if (r == root) {
|
if (r == root) {
|
||||||
recv_right = recvbuf;
|
recv_right = recvbuf;
|
||||||
} else {
|
} else {
|
||||||
//printf("%i gets some memory\n", r);
|
|
||||||
MPI_Alloc_mem(count * size, MPI_INFO_NULL, &recv_right);
|
MPI_Alloc_mem(count * size, MPI_INFO_NULL, &recv_right);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,21 +59,14 @@ int Bin_Reduce(const void *sendbuf, void *recvbuf, int count,
|
||||||
max_nodes /= 2;
|
max_nodes /= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
//printf("%i: %i\n", r, parent);
|
|
||||||
|
|
||||||
if (depth != tree_depth && r + 1 < p) {
|
if (depth != tree_depth && r + 1 < p) {
|
||||||
MPI_Alloc_mem(count * size, MPI_INFO_NULL, &recv_left);
|
MPI_Alloc_mem(count * size, MPI_INFO_NULL, &recv_left);
|
||||||
MPI_Recv(recv_left, count, datatype, r + 1, 0, comm, &status);
|
MPI_Recv(recv_left, count, datatype, r + 1, 0, comm, &status);
|
||||||
//printf("%i received %i from %i\n", r, *((int*) recv_left), r + 1);
|
|
||||||
printf("%i: %i + %i\n", r, ((int *)sendbuf)[0], ((int *)recv_left)[0]);
|
|
||||||
MPI_Reduce_local(sendbuf, recv_left, count, datatype, op);
|
MPI_Reduce_local(sendbuf, recv_left, count, datatype, op);
|
||||||
//printf("right child of %i: %i\n", r, r + max_nodes + 1);
|
|
||||||
if (r + max_nodes + 1 < p) {
|
if (r + max_nodes + 1 < p) {
|
||||||
MPI_Recv(recv_right, count, datatype, r + max_nodes + 1, 0, comm,
|
MPI_Recv(recv_right, count, datatype, r + max_nodes + 1, 0, comm,
|
||||||
&status);
|
&status);
|
||||||
//printf("%i received %i from %i\n", r, *((int*) recv_right),
|
|
||||||
// r + max_nodes + 1);
|
|
||||||
printf("%i: %i + %i\n", r, ((int *)recv_left)[0], ((int *)recv_right)[0]);
|
|
||||||
MPI_Reduce_local(recv_left, recv_right, count, datatype, op);
|
MPI_Reduce_local(recv_left, recv_right, count, datatype, op);
|
||||||
} else {
|
} else {
|
||||||
memcpy(recv_right, recv_left, count * size);
|
memcpy(recv_right, recv_left, count * size);
|
||||||
|
@ -86,7 +78,6 @@ int Bin_Reduce(const void *sendbuf, void *recvbuf, int count,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r != root) {
|
if (r != root) {
|
||||||
//printf("%i sends %i to %i\n", r, *((int*) recv_right), parent);
|
|
||||||
MPI_Send(recv_right, count, datatype, parent, 0, comm);
|
MPI_Send(recv_right, count, datatype, parent, 0, comm);
|
||||||
MPI_Free_mem(recv_right);
|
MPI_Free_mem(recv_right);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,21 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "binom_reduce.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,
|
int Binom_Reduce(const void *sendbuf, void *recvbuf, int count,
|
||||||
MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm) {
|
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;
|
int r, p, size;
|
||||||
MPI_Status status;
|
MPI_Status status;
|
||||||
void *recv;
|
void *recv;
|
||||||
|
@ -22,29 +35,27 @@ int Binom_Reduce(const void *sendbuf, void *recvbuf, int count,
|
||||||
MPI_Type_size(datatype, &size);
|
MPI_Type_size(datatype, &size);
|
||||||
|
|
||||||
MPI_Alloc_mem(count * size, MPI_INFO_NULL, &recv);
|
MPI_Alloc_mem(count * size, MPI_INFO_NULL, &recv);
|
||||||
if (r != root) {
|
MPI_Alloc_mem(count * size, MPI_INFO_NULL, &reduced);
|
||||||
MPI_Alloc_mem(count * size, MPI_INFO_NULL, &reduced);
|
|
||||||
} else {
|
|
||||||
reduced = recvbuf;
|
|
||||||
}
|
|
||||||
memcpy(reduced, sendbuf, count * size);
|
memcpy(reduced, sendbuf, count * size);
|
||||||
|
|
||||||
int i = 1;
|
int i = 1;
|
||||||
while ((r + i) % (2 * i) != 0 && i < p) {
|
while ((r + i) % (2 * i) != 0 && i < p) {
|
||||||
if (r + i < p) {
|
if (r + i < p) {
|
||||||
MPI_Recv(recv, count, datatype, r + i, i, comm, &status);
|
MPI_Recv(recv, count, datatype, r + i, i, comm, &status);
|
||||||
printf("%i: %i + %i\n", r, ((int *)reduced)[0], ((int *)recv)[0]);
|
|
||||||
MPI_Reduce_local(reduced, recv, count, datatype, op);
|
MPI_Reduce_local(reduced, recv, count, datatype, op);
|
||||||
memcpy(reduced, recv, count*size);
|
swap(&reduced, &recv);
|
||||||
}
|
}
|
||||||
i <<= 1;
|
i <<= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r != root) {
|
if (r != root) {
|
||||||
MPI_Send(reduced, count, datatype, r - i, i, comm);
|
MPI_Send(reduced, count, datatype, r - i, i, comm);
|
||||||
MPI_Free_mem(reduced);
|
} else {
|
||||||
|
memcpy(recvbuf, reduced, count * size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MPI_Free_mem(reduced);
|
||||||
MPI_Free_mem(recv);
|
MPI_Free_mem(recv);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -26,17 +26,16 @@ int Fib_Reduce(const void *sendbuf, void *recvbuf, int count,
|
||||||
MPI_Type_size(datatype, &size);
|
MPI_Type_size(datatype, &size);
|
||||||
|
|
||||||
int temp;
|
int temp;
|
||||||
int fibm1 = 1;
|
int right = 1;
|
||||||
int fib = 1;
|
int fib = 1;
|
||||||
|
|
||||||
while (fib - 1 < p) {
|
while (fib - 1 < p) {
|
||||||
temp = fib;
|
temp = fib;
|
||||||
fib += fibm1;
|
fib += right;
|
||||||
fibm1 = temp;
|
right = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
int right = fibm1;
|
int left = fib - right;
|
||||||
int left = fib - fibm1;
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int parent = 0;
|
int parent = 0;
|
||||||
|
|
||||||
|
@ -64,12 +63,10 @@ int Fib_Reduce(const void *sendbuf, void *recvbuf, int count,
|
||||||
void *recv_left;
|
void *recv_left;
|
||||||
MPI_Alloc_mem(count * size, MPI_INFO_NULL, &recv_left);
|
MPI_Alloc_mem(count * size, MPI_INFO_NULL, &recv_left);
|
||||||
MPI_Recv(recv_left, count, datatype, r + 1, 0, comm, &status);
|
MPI_Recv(recv_left, count, datatype, r + 1, 0, comm, &status);
|
||||||
printf("%i: %i + %i\n", r, ((int *)sendbuf)[0], ((int *)recv_left)[0]);
|
|
||||||
MPI_Reduce_local(sendbuf, recv_left, count, datatype, op);
|
MPI_Reduce_local(sendbuf, recv_left, count, datatype, op);
|
||||||
|
|
||||||
if (left - 1 > 0 && r + left < p) {
|
if (left - 1 > 0 && r + left < p) {
|
||||||
MPI_Recv(recv_right, count, datatype, r + left, 0, comm, &status);
|
MPI_Recv(recv_right, count, datatype, r + left, 0, comm, &status);
|
||||||
printf("%i: %i + %i\n", r, ((int *)recv_left)[0], ((int *)recv_right)[0]);
|
|
||||||
MPI_Reduce_local(recv_left, recv_right, count, datatype, op);
|
MPI_Reduce_local(recv_left, recv_right, count, datatype, op);
|
||||||
} else {
|
} else {
|
||||||
memcpy(recv_right, recv_left, count * size);
|
memcpy(recv_right, recv_left, count * size);
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <mpi.h>
|
#include <mpi.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
#include "bin_reduce.h"
|
#include "bin_reduce.h"
|
||||||
#include "binom_reduce.h"
|
#include "binom_reduce.h"
|
||||||
#include "fib_reduce.h"
|
#include "fib_reduce.h"
|
||||||
|
@ -27,8 +28,9 @@ void usage(char *progname, int rank) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void fill(int *a, int count, int rank) {
|
void fill(int *a, int count, int rank) {
|
||||||
|
srand(time(NULL) + rank);
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
a[i] = rank + i;
|
a[i] = rand();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +94,7 @@ int main(int argc, char* argv[]) {
|
||||||
case '8':
|
case '8':
|
||||||
op = MPI_LXOR;
|
op = MPI_LXOR;
|
||||||
break;
|
break;
|
||||||
case '9':
|
default:
|
||||||
op = MPI_BXOR;
|
op = MPI_BXOR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -158,14 +160,8 @@ int main(int argc, char* argv[]) {
|
||||||
MPI_Alloc_mem(size * sizeof(int), MPI_INFO_NULL, &rbinom);
|
MPI_Alloc_mem(size * sizeof(int), MPI_INFO_NULL, &rbinom);
|
||||||
|
|
||||||
MPI_Reduce(a, red, size, MPI_INT, op, 0, MPI_COMM_WORLD);
|
MPI_Reduce(a, red, size, MPI_INT, op, 0, MPI_COMM_WORLD);
|
||||||
if(r==0)
|
|
||||||
printf("fib:\n");
|
|
||||||
Fib_Reduce(a, rfib, size, MPI_INT, op, 0, MPI_COMM_WORLD);
|
Fib_Reduce(a, rfib, size, MPI_INT, op, 0, MPI_COMM_WORLD);
|
||||||
if(r==0)
|
|
||||||
printf("bin:\n");
|
|
||||||
Bin_Reduce(a, rbin, size, MPI_INT, op, 0, MPI_COMM_WORLD);
|
Bin_Reduce(a, rbin, size, MPI_INT, op, 0, MPI_COMM_WORLD);
|
||||||
if(r==0)
|
|
||||||
printf("binom:\n");
|
|
||||||
Binom_Reduce(a, rbinom, size, MPI_INT, op, 0, MPI_COMM_WORLD);
|
Binom_Reduce(a, rbinom, size, MPI_INT, op, 0, MPI_COMM_WORLD);
|
||||||
|
|
||||||
if (r == 0) {
|
if (r == 0) {
|
||||||
|
|
7
reduce/Makefile
Normal file
7
reduce/Makefile
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
all: reduce
|
||||||
|
|
||||||
|
reduce: hpc_mpi.c binom_reduce.c fib_reduce.c bin_reduce.c
|
||||||
|
mpicc -Wall -Wextra -O3 -o reduce bin_reduce.c fib_reduce.c binom_reduce.c hpc_mpi.c
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm reduce
|
86
reduce/bin_reduce.c
Normal file
86
reduce/bin_reduce.c
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
/*
|
||||||
|
* bin_reduce.c
|
||||||
|
*
|
||||||
|
* Created on: 16 Jun 2016
|
||||||
|
* Author: johannes
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <mpi.h>
|
||||||
|
#include "bin_reduce.h"
|
||||||
|
|
||||||
|
int int_log2(int x) {
|
||||||
|
int r=0;
|
||||||
|
while (x >>= 1) {
|
||||||
|
r++;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Bin_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;
|
||||||
|
|
||||||
|
MPI_Comm_rank(comm, &r);
|
||||||
|
MPI_Comm_size(comm, &p);
|
||||||
|
MPI_Type_size(datatype, &size);
|
||||||
|
|
||||||
|
int tree_depth = int_log2(p) + 1;
|
||||||
|
int i = 0;
|
||||||
|
int depth;
|
||||||
|
int parent = 0;
|
||||||
|
|
||||||
|
// maximum possible number of nodes in a subtree with current depth
|
||||||
|
int max_nodes = ((1 << tree_depth) - 1) / 2;
|
||||||
|
|
||||||
|
void *recv_left;
|
||||||
|
void *recv_right;
|
||||||
|
|
||||||
|
if (r == root) {
|
||||||
|
recv_right = recvbuf;
|
||||||
|
} else {
|
||||||
|
MPI_Alloc_mem(count * size, MPI_INFO_NULL, &recv_right);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (depth = 1; i != r; depth++) {
|
||||||
|
parent = i;
|
||||||
|
if (r > i + max_nodes) {
|
||||||
|
i += max_nodes + 1;
|
||||||
|
} else {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
max_nodes /= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (depth != tree_depth && r + 1 < p) {
|
||||||
|
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 (r + max_nodes + 1 < p) {
|
||||||
|
MPI_Recv(recv_right, count, datatype, r + max_nodes + 1, 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;
|
||||||
|
}
|
14
reduce/bin_reduce.h
Normal file
14
reduce/bin_reduce.h
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
/*
|
||||||
|
* bin_reduce.h
|
||||||
|
*
|
||||||
|
* Created on: 16 Jun 2016
|
||||||
|
* Author: johannes
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BIN_REDUCE_H_
|
||||||
|
#define BIN_REDUCE_H_
|
||||||
|
|
||||||
|
int Bin_Reduce(const void *sendbuf, void *recvbuf, int count,
|
||||||
|
MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm);
|
||||||
|
|
||||||
|
#endif /* BIN_REDUCE_H_ */
|
62
reduce/binom_reduce.c
Normal file
62
reduce/binom_reduce.c
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
14
reduce/binom_reduce.h
Normal file
14
reduce/binom_reduce.h
Normal file
|
@ -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_ */
|
86
reduce/fib_reduce.c
Normal file
86
reduce/fib_reduce.c
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
/*
|
||||||
|
* fib_reduce.c
|
||||||
|
*
|
||||||
|
* Created on: 18 Jun 2016
|
||||||
|
* Author: johannes
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <mpi.h>
|
||||||
|
#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 right = 1;
|
||||||
|
int fib = 1;
|
||||||
|
|
||||||
|
while (fib - 1 < p) {
|
||||||
|
temp = fib;
|
||||||
|
fib += right;
|
||||||
|
right = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
int left = fib - right;
|
||||||
|
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;
|
||||||
|
}
|
14
reduce/fib_reduce.h
Normal file
14
reduce/fib_reduce.h
Normal file
|
@ -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_ */
|
192
reduce/hpc_mpi.c
Normal file
192
reduce/hpc_mpi.c
Normal file
|
@ -0,0 +1,192 @@
|
||||||
|
/*
|
||||||
|
============================================================================
|
||||||
|
Name : hpc_mpi.c
|
||||||
|
Author :
|
||||||
|
Version :
|
||||||
|
Copyright : Your copyright notice
|
||||||
|
Description : Hello MPI World in C
|
||||||
|
============================================================================
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <mpi.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include "bin_reduce.h"
|
||||||
|
#include "binom_reduce.h"
|
||||||
|
#include "fib_reduce.h"
|
||||||
|
|
||||||
|
void usage(char *progname, int rank) {
|
||||||
|
if (rank == 0) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"USAGE: %s [-b] [-o operation] size\n supported operations:\n 0 MAX\n 1 MIN\n 2 SUM\n 3 PROD\n 4 LAND\n 5 BAND\n 6 LOR\n 7 BOR\n 8 LXOR\n 9 BXOR\n",
|
||||||
|
progname);
|
||||||
|
}
|
||||||
|
MPI_Finalize();
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fill(int *a, int count, int rank) {
|
||||||
|
srand(time(NULL) + rank);
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
a[i] = rand();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
int r;
|
||||||
|
int p;
|
||||||
|
|
||||||
|
MPI_Init(&argc, &argv);
|
||||||
|
MPI_Comm_rank(MPI_COMM_WORLD, &r);
|
||||||
|
MPI_Comm_size(MPI_COMM_WORLD, &p);
|
||||||
|
|
||||||
|
int opt;
|
||||||
|
int benchmark = 0;
|
||||||
|
char oparg = '0';
|
||||||
|
|
||||||
|
while ((opt = getopt(argc, argv, "bo:")) != -1) {
|
||||||
|
switch (opt) {
|
||||||
|
case 'b':
|
||||||
|
benchmark = 1;
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
oparg = optarg[0];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
usage(argv[0], r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (optind >= argc) {
|
||||||
|
usage(argv[0], r);
|
||||||
|
}
|
||||||
|
|
||||||
|
int size = atoi(argv[optind]);
|
||||||
|
MPI_Op op;
|
||||||
|
|
||||||
|
switch (oparg) {
|
||||||
|
case '0':
|
||||||
|
op = MPI_MAX;
|
||||||
|
break;
|
||||||
|
case '1':
|
||||||
|
op = MPI_MIN;
|
||||||
|
break;
|
||||||
|
case '2':
|
||||||
|
op = MPI_SUM;
|
||||||
|
break;
|
||||||
|
case '3':
|
||||||
|
op = MPI_PROD;
|
||||||
|
break;
|
||||||
|
case '4':
|
||||||
|
op = MPI_LAND;
|
||||||
|
break;
|
||||||
|
case '5':
|
||||||
|
op = MPI_BAND;
|
||||||
|
break;
|
||||||
|
case '6':
|
||||||
|
op = MPI_LOR;
|
||||||
|
break;
|
||||||
|
case '7':
|
||||||
|
op = MPI_BOR;
|
||||||
|
break;
|
||||||
|
case '8':
|
||||||
|
op = MPI_LXOR;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
op = MPI_BXOR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int *a;
|
||||||
|
MPI_Alloc_mem(size * sizeof(int), MPI_INFO_NULL, &a);
|
||||||
|
fill(a, size, r);
|
||||||
|
|
||||||
|
if (benchmark) {
|
||||||
|
int *red;
|
||||||
|
MPI_Alloc_mem(size * sizeof(int), MPI_INFO_NULL, &red);
|
||||||
|
double start, end, global_end;
|
||||||
|
|
||||||
|
MPI_Barrier(MPI_COMM_WORLD);
|
||||||
|
start = MPI_Wtime();
|
||||||
|
MPI_Reduce(a, red, size, MPI_INT, op, 0, MPI_COMM_WORLD);
|
||||||
|
end = MPI_Wtime();
|
||||||
|
MPI_Reduce(&end, &global_end, 1, MPI_DOUBLE, MPI_MAX, 0,
|
||||||
|
MPI_COMM_WORLD);
|
||||||
|
if (r == 0) {
|
||||||
|
printf("%f, ", global_end - start);
|
||||||
|
}
|
||||||
|
|
||||||
|
MPI_Barrier(MPI_COMM_WORLD);
|
||||||
|
start = MPI_Wtime();
|
||||||
|
Fib_Reduce(a, red, size, MPI_INT, op, 0, MPI_COMM_WORLD);
|
||||||
|
end = MPI_Wtime();
|
||||||
|
MPI_Reduce(&end, &global_end, 1, MPI_DOUBLE, MPI_MAX, 0,
|
||||||
|
MPI_COMM_WORLD);
|
||||||
|
if (r == 0) {
|
||||||
|
printf("%f, ", global_end - start);
|
||||||
|
}
|
||||||
|
|
||||||
|
MPI_Barrier(MPI_COMM_WORLD);
|
||||||
|
start = MPI_Wtime();
|
||||||
|
Bin_Reduce(a, red, size, MPI_INT, op, 0, MPI_COMM_WORLD);
|
||||||
|
end = MPI_Wtime();
|
||||||
|
MPI_Reduce(&end, &global_end, 1, MPI_DOUBLE, MPI_MAX, 0,
|
||||||
|
MPI_COMM_WORLD);
|
||||||
|
if (r == 0) {
|
||||||
|
printf("%f, ", global_end - start);
|
||||||
|
}
|
||||||
|
|
||||||
|
MPI_Barrier(MPI_COMM_WORLD);
|
||||||
|
start = MPI_Wtime();
|
||||||
|
Binom_Reduce(a, red, size, MPI_INT, op, 0, MPI_COMM_WORLD);
|
||||||
|
end = MPI_Wtime();
|
||||||
|
MPI_Reduce(&end, &global_end, 1, MPI_DOUBLE, MPI_MAX, 0,
|
||||||
|
MPI_COMM_WORLD);
|
||||||
|
if (r == 0) {
|
||||||
|
printf("%f\n", global_end - start);
|
||||||
|
}
|
||||||
|
|
||||||
|
MPI_Free_mem(red);
|
||||||
|
} else {
|
||||||
|
int *red;
|
||||||
|
int *rfib;
|
||||||
|
int *rbin;
|
||||||
|
int *rbinom;
|
||||||
|
MPI_Alloc_mem(size * sizeof(int), MPI_INFO_NULL, &red);
|
||||||
|
MPI_Alloc_mem(size * sizeof(int), MPI_INFO_NULL, &rfib);
|
||||||
|
MPI_Alloc_mem(size * sizeof(int), MPI_INFO_NULL, &rbin);
|
||||||
|
MPI_Alloc_mem(size * sizeof(int), MPI_INFO_NULL, &rbinom);
|
||||||
|
|
||||||
|
MPI_Reduce(a, red, size, MPI_INT, op, 0, MPI_COMM_WORLD);
|
||||||
|
Fib_Reduce(a, rfib, size, MPI_INT, op, 0, MPI_COMM_WORLD);
|
||||||
|
Bin_Reduce(a, rbin, size, MPI_INT, op, 0, MPI_COMM_WORLD);
|
||||||
|
Binom_Reduce(a, rbinom, size, MPI_INT, op, 0, MPI_COMM_WORLD);
|
||||||
|
|
||||||
|
if (r == 0) {
|
||||||
|
if (memcmp(red, rfib, size * sizeof(int))) {
|
||||||
|
printf("Fib_Reduce does not match\n");
|
||||||
|
}
|
||||||
|
if (memcmp(red, rbin, size * sizeof(int))) {
|
||||||
|
printf("Bin_Reduce does not match\n");
|
||||||
|
}
|
||||||
|
if (memcmp(red, rbinom, size * sizeof(int))) {
|
||||||
|
printf("Binom_Reduce does not match\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("All checks done\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
MPI_Free_mem(red);
|
||||||
|
MPI_Free_mem(rfib);
|
||||||
|
MPI_Free_mem(rbin);
|
||||||
|
MPI_Free_mem(rbinom);
|
||||||
|
}
|
||||||
|
|
||||||
|
MPI_Free_mem(a);
|
||||||
|
|
||||||
|
MPI_Finalize();
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue