diff --git a/exercise4/wave_2d_parallel.c b/exercise4/wave_2d_parallel.c index bfe57b7..4b196ac 100644 --- a/exercise4/wave_2d_parallel.c +++ b/exercise4/wave_2d_parallel.c @@ -39,6 +39,13 @@ int world_size; int world_rank; #define ROOT 0 + +int local_M, local_N; + +MPI_Comm cartesian_comm; +int coordinates[2], dims[2] = { 0 }; +int cartesian_rank; + // END: T1b // Simulation parameters: size, step count, and how often to save the state @@ -256,16 +263,46 @@ int main(int argc, char **argv) { // TASK: T3 // Distribute the user arguments to all the processes // BEGIN: T3 - OPTIONS *options = parse_args(argc, argv); - if (!options) { - fprintf(stderr, "Argument parsing failed\n"); - exit(EXIT_FAILURE); + // create options type for easy broadcast + MPI_Datatype options_type; + MPI_Type_contiguous(4, MPI_INT64_T, &options_type); + MPI_Type_commit(&options_type); + + OPTIONS options; + if (world_rank == ROOT) { + OPTIONS *parsed = parse_args(argc, argv); + if (!parsed) { + fprintf(stderr, "Argument parsing failed\n"); + exit(EXIT_FAILURE); + } + options = *parsed; + free(parsed); } - M = options->M; - N = options->N; - max_iteration = options->max_iteration; - snapshot_freq = options->snapshot_frequency; + MPI_Bcast(&options, 1, options_type, ROOT, MPI_COMM_WORLD); + MPI_Type_free(&options_type); + + // read options + M = options.M; + N = options.N; + max_iteration = options.max_iteration; + snapshot_freq = options.snapshot_frequency; + + // grid dimensions + MPI_Dims_create(world_size, 2, dims); + + local_M = M / dims[0]; + local_N = N / dims[1]; + + // create cartesian communicator + int periodicity[2] = { 0, 0 }; + MPI_Cart_create(MPI_COMM_WORLD, 2, dims, periodicity, 1, &cartesian_comm); + + // fetch cartesian coords + MPI_Comm_rank(cartesian_comm, &cartesian_rank); + MPI_Cart_coords(cartesian_comm, cartesian_rank, 2, coordinates); + MPI_Cart_shift(cartesian_comm, 0, 1, &up, &down); + MPI_Cart_shift(cartesian_comm, 1, 1, &left, &right); // END: T3 // Set up the initial state of the domain @@ -296,6 +333,7 @@ int main(int argc, char **argv) { // TASK: T1d // Finalise MPI // BEGIN: T1d + MPI_Comm_free(&cartesian_comm); MPI_Finalize(); // END: T1d