2016-06-22 13:23:45 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <mpi.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <time.h>
|
2016-06-24 19:42:13 +00:00
|
|
|
#include <getopt.h>
|
2016-06-22 13:23:45 +00:00
|
|
|
#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;
|
|
|
|
}
|
|
|
|
|