int main(int argc, char **argv) { int rank, procs; long long int my_sum = 0; long long int total_sum = 0; int vector[VECTOR_SIZE]; int chunk_size; MPI_Status status; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &procs); chunk_size = calc_chunk_for_proc(rank, VECTOR_SIZE, procs); if (rank == 0) { init_vector(vector); distribute_vector(vector, procs); } else { receive_vector(vector, chunk_size); } my_sum = sum_vector(vector, chunk_size); MPI_Reduce(&my_sum, &total_sum, 1, MPI_LONG_LONG_INT, MPI_SUM, 0, MPI_COMM_WORLD); /* if (rank == 0) { long long int serial_sum = 0; for (int i = 0; i < VECTOR_SIZE; ++i) serial_sum += vector[i]; if (serial_sum == total_sum) { printf("DEBUG: Serial == parallel\n"); } else { printf("DEBUG: Serial != parallel, %d\n", abs(serial_sum - my_sum)); } } */ MPI_Finalize(); return(0); }
int main(int argc, char** argv) { int rank, size; int N; char opt; int nt = -1; int max_threads = 16; // on jupiter bool id = false; algo_t algo = reduce_scatter; FILE *f = NULL; static const char optstring[] = "n:a:f:i:p:"; static const struct option long_options[] = { {"n", 1, NULL, 'n'}, {"file", 1, NULL, 'f'}, {"i", 1, NULL, 'i'}, {NULL, 0, NULL, 0} }; MPI_Init(&argc,&argv); // get rank and size from communicator MPI_Comm_size(MPI_COMM_WORLD,&size); MPI_Comm_rank(MPI_COMM_WORLD,&rank); while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != EOF) { switch(opt) { case 'i': if (strcmp("procs", optarg) == 0) { id = true; } break; case 'p': nt = atoi(optarg); if (nt > max_threads) { printf("Using too much procs %d, use max %d", nt, max_threads); return EXIT_FAILURE; } else { printf("Using %d procs.", nt); } case 'n': N = atoi(optarg); break; case 'f': f = fopen(optarg,"a"); if (f == NULL) { mpi_printf(root, "Could not open log file '%s': %s\n", optarg, strerror(errno)); MPI_Finalize(); return EXIT_FAILURE; } break; case 'a': if (strcmp("ref", optarg) == 0) { mpi_printf(root, "Using reference implementation \n"); algo = ref; } else if ((strcmp("reduce_scatter", optarg) == 0)) { mpi_printf(root, "Using MPI_Allgather implementation \n"); algo = reduce_scatter; } break; default: MPI_Finalize(); return EXIT_FAILURE; } } if(N == 0) { if ( rank == root ){ printf("Usage: mpirun -nn nodecount p3-reduce_scatter.exe -n N\n"); printf("N is the the matrix size. \n\n"); } return 1; } /* ======================================================== */ /* Initialisation matrix & vector */ ATYPE *matrix = NULL; ATYPE *vector = NULL; if (rank == root) { debug("Setting up root data structures"); matrix = init_matrix(N,1); vector = init_vector(N,1); } int colcnt = N - (N/size ) * (size - 1 ); int partition = N/size; ATYPE *local_matrix = NULL; local_matrix = (ATYPE*) malloc (sizeof(ATYPE) * N * colcnt); ATYPE *local_vector = NULL; local_vector = (ATYPE*) malloc (sizeof(ATYPE) * partition) ; ATYPE *reference = NULL; reference = init_vector(N,1); ATYPE *result = NULL; result = init_vector(N,1); double inittime,totaltime; if( algo == ref) { if (rank == root) { inittime = MPI_Wtime(); matrix_vector_mult_ref(matrix, vector, N, reference); totaltime = MPI_Wtime() - inittime; } } else if (algo == reduce_scatter) { if(rank == root){ debug("Comptuting reference"); matrix_vector_mult_ref(matrix, vector, N, reference); } MPI_Barrier(MPI_COMM_WORLD); /* ======================================================== */ /* distributing matrix and vector */ distribute_vector(vector, local_vector, rank, size, partition, N); distribute_matrix(matrix, local_matrix, rank, size, partition, N); debug("begin MPI_Reduce_scatter"); MPI_Barrier(MPI_COMM_WORLD); inittime = MPI_Wtime(); compute_reduce_scatter(local_matrix, local_vector, result, rank, size, N, partition); MPI_Barrier(MPI_COMM_WORLD); totaltime = MPI_Wtime() - inittime; double localtime = totaltime; MPI_Reduce(&localtime, &totaltime, 1, MPI_DOUBLE, MPI_MAX, root, MPI_COMM_WORLD); debug("after MPI_Reduce_scatter"); /* TODO: fix test so it uses vector idea */ /* debug("Testing result"); */ /* if (test_vector_part(result, local_vector, (rank * partition) , partition)) { */ /* debug("testresult: OK"); */ /* } else { */ /* debug("testresult: FAILURE"); */ /* debug("Result:"); */ /* printArray(recvbuff, N); */ /* debug("Reference:"); */ /* printArray(reference,N); */ /* } */ MPI_Barrier(MPI_COMM_WORLD); } if (rank == 0) { if (f != NULL) { if (id) { fprintf(f,"%d,%lf\n",nt, totaltime); } else { fprintf(f,"%d,%lf\n",N, totaltime); } } if (id) { printf("%d,%lf\n",nt , totaltime); } else { printf("%d,%lf\n",N , totaltime); } } debug("cleaning up"); free(vector); free(matrix); MPI_Finalize(); if ( f != NULL) { fclose(f); } return 0; }