/* ============================================================================ Name : hpc_mpi.c Author : Version : Copyright : Your copyright notice Description : Hello MPI World in C ============================================================================ */ #include #include #include #include #include #include #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; }