From 7c00bf20bf046f012840d690865d56c82c20bf23 Mon Sep 17 00:00:00 2001 From: fredrikr79 Date: Mon, 22 Sep 2025 19:46:32 +0200 Subject: [PATCH 1/7] ex3: task 8 --- exercise3/wave_1d_parallel.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/exercise3/wave_1d_parallel.c b/exercise3/wave_1d_parallel.c index ef9847c..2aaa42d 100644 --- a/exercise3/wave_1d_parallel.c +++ b/exercise3/wave_1d_parallel.c @@ -50,6 +50,8 @@ real_t // Save the present time step in a numbered file under 'data/'. void domain_save(int_t step) { // BEGIN: T8 + if (comm_rank != ROOT) + return; char filename[256]; sprintf(filename, "data/%.5ld.dat", step); FILE *out = fopen(filename, "wb"); From 96de4ae5fe43a431edeae1609f2d0e477031bd73 Mon Sep 17 00:00:00 2001 From: fredrikr79 Date: Mon, 22 Sep 2025 19:46:21 +0200 Subject: [PATCH 2/7] ex3: task 7 --- exercise3/wave_1d_parallel.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/exercise3/wave_1d_parallel.c b/exercise3/wave_1d_parallel.c index ef9847c..14eb4d0 100644 --- a/exercise3/wave_1d_parallel.c +++ b/exercise3/wave_1d_parallel.c @@ -124,7 +124,16 @@ void border_exchange(void) { // to root and assemble it in the root buffer void send_data_to_root() { // BEGIN: T7 - ; + if (comm_rank != ROOT) { + MPI_Send(&U(0), n, MPI_DOUBLE, ROOT, 0, MPI_COMM_WORLD); + } else { + int offset = n; + for (int i = 1; i < comm_size; i++) { + int proc_n = N / comm_size + (i < N % comm_size); + MPI_Recv(&U(offset), proc_n, MPI_DOUBLE, i, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + offset += proc_n; + } + } // END: T7 } From 165c18a6fe12a0a93a6fd2ad547dbc287cd53c58 Mon Sep 17 00:00:00 2001 From: fredrikr79 Date: Mon, 22 Sep 2025 19:25:07 +0200 Subject: [PATCH 3/7] ex3: task 6 --- exercise3/wave_1d_parallel.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/exercise3/wave_1d_parallel.c b/exercise3/wave_1d_parallel.c index ef9847c..fc2ac7c 100644 --- a/exercise3/wave_1d_parallel.c +++ b/exercise3/wave_1d_parallel.c @@ -106,8 +106,12 @@ void time_step(void) { // Neumann (reflective) boundary condition. void boundary_condition(void) { // BEGIN: T6 - U(-1) = U(1); - U(N) = U(N - 2); + if (comm_rank == ROOT) { + U(-1) = U(1); + } + if (comm_rank == comm_size - 1) { + U(n) = U(n - 2); + } // END: T6 } From 9644fc5ddaf9ebceb652f64d3be81bb066d7b06c Mon Sep 17 00:00:00 2001 From: fredrikr79 Date: Mon, 22 Sep 2025 19:13:17 +0200 Subject: [PATCH 4/7] ex3: task 5 --- exercise3/wave_1d_parallel.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/exercise3/wave_1d_parallel.c b/exercise3/wave_1d_parallel.c index ef9847c..36c5b39 100644 --- a/exercise3/wave_1d_parallel.c +++ b/exercise3/wave_1d_parallel.c @@ -115,7 +115,16 @@ void boundary_condition(void) { // Communicate the border between processes. void border_exchange(void) { // BEGIN: T5 - ; + int left = (comm_size + comm_rank - 1) % comm_size; + int right = (comm_rank + 1) % comm_size; + + MPI_Sendrecv(&U(n - 1), 1, MPI_DOUBLE, right, 0, + &U(-1), 1, MPI_DOUBLE, left, 0, + MPI_COMM_WORLD, MPI_STATUS_IGNORE); + + MPI_Sendrecv(&U(0), 1, MPI_DOUBLE, left, 1, + &U(n), 1, MPI_DOUBLE, right, 1, + MPI_COMM_WORLD, MPI_STATUS_IGNORE); // END: T5 } From 7fa9edd59fe4b82c4ab9877ffdd4577e20b8ef9f Mon Sep 17 00:00:00 2001 From: fredrikr79 Date: Mon, 22 Sep 2025 18:38:38 +0200 Subject: [PATCH 5/7] ex3: task 4 --- exercise3/wave_1d_parallel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercise3/wave_1d_parallel.c b/exercise3/wave_1d_parallel.c index ef9847c..e9e4d86 100644 --- a/exercise3/wave_1d_parallel.c +++ b/exercise3/wave_1d_parallel.c @@ -96,7 +96,7 @@ void move_buffer_window(void) { // Derive step t+1 from steps t and t-1. void time_step(void) { // BEGIN: T4 - for (int_t i = 0; i < N; i++) { + for (int_t i = 0; i < n; i++) { U_nxt(i) = -U_prv(i) + 2.0 * U(i) + (dt * dt * c * c) / (dx * dx) * (U(i - 1) + U(i + 1) - 2.0 * U(i)); } // END: T4 From 34c7c09ca4fc01d4940ed284d2ce9ba18cb3badc Mon Sep 17 00:00:00 2001 From: fredrikr79 Date: Mon, 22 Sep 2025 17:20:04 +0200 Subject: [PATCH 6/7] ex3: task 3 --- exercise3/wave_1d_parallel.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/exercise3/wave_1d_parallel.c b/exercise3/wave_1d_parallel.c index ef9847c..5feac2f 100644 --- a/exercise3/wave_1d_parallel.c +++ b/exercise3/wave_1d_parallel.c @@ -19,7 +19,11 @@ typedef double real_t; // TASK: T1b // Declare variables each MPI process will need // BEGIN: T1b -; +int comm_size; +int comm_rank; +int_t n; + +#define I(i) ((i) + n * comm_rank) // END: T1b // Simulation parameters: size, step count, and how often to save the state. @@ -64,12 +68,13 @@ void domain_save(int_t step) { // and set the time step. void domain_initialize(void) { // BEGIN: T3 - buffers[0] = malloc((N + 2) * sizeof(real_t)); - buffers[1] = malloc((N + 2) * sizeof(real_t)); - buffers[2] = malloc((N + 2) * sizeof(real_t)); + const int_t bufsize = (comm_rank == ROOT ? N : n + 2); + buffers[0] = malloc(bufsize * sizeof(real_t)); + buffers[1] = malloc(bufsize * sizeof(real_t)); + buffers[2] = malloc(bufsize * sizeof(real_t)); - for (int_t i = 0; i < N; i++) { - U_prv(i) = U(i) = cos(2 * M_PI * i / (real_t)N); + for (int_t i = 0; i < n; i++) { + U_prv(i) = U(i) = cos(2 * M_PI * (i + offset) / (real_t)N); } // END: T3 From 90dbc4e17744f14a9c71256a9ce52f7df3349fb7 Mon Sep 17 00:00:00 2001 From: fredrikr79 Date: Mon, 22 Sep 2025 16:43:45 +0200 Subject: [PATCH 7/7] ex3: task 2 --- exercise3/wave_1d_parallel.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/exercise3/wave_1d_parallel.c b/exercise3/wave_1d_parallel.c index ef9847c..39dd771 100644 --- a/exercise3/wave_1d_parallel.c +++ b/exercise3/wave_1d_parallel.c @@ -160,7 +160,17 @@ int main(int argc, char **argv) { // TASK: T2 // Time your code // BEGIN: T2 + if (comm_rank == ROOT) + gettimeofday(&t_start, NULL); simulate(); + MPI_Barrier(MPI_COMM_WORLD); + + if (comm_rank == ROOT) { + gettimeofday(&t_end, NULL); + + printf("Total elapsed time: %lf seconds\n", + WALLTIME(t_end) - WALLTIME(t_start)); + } // END: T2 domain_finalize();