From 4e23c62a9acd4ada329071ebd9e55a102c389e68 Mon Sep 17 00:00:00 2001 From: Extra5enS Date: Sat, 3 Oct 2020 12:05:44 +0300 Subject: [PATCH 1/6] Add impl with all done tests --- OpenMP2/src/main.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/OpenMP2/src/main.cpp b/OpenMP2/src/main.cpp index 8dab215..4a69b5b 100644 --- a/OpenMP2/src/main.cpp +++ b/OpenMP2/src/main.cpp @@ -3,9 +3,21 @@ #include #include -double calc(uint32_t x_last, uint32_t num_threads) -{ - return 0; +double calc(uint32_t x_last, uint32_t num_threads) { + double res = 0; + double* res_buf = (double*)calloc(x_last, sizeof(double)); + #pragma omp parallel num_threads(num_threads) + { + #pragma omp for + for(int i = x_last; i > 0; --i) { + double buf = 1.0 / i; + res_buf[i - 1] = buf; + } + } + for(int i = x_last; i > 0; --i) { + res += res_buf[i - 1]; + } + return res; } int main(int argc, char** argv) From 1ceffe20b5cf33899c0ad6253f28a6bc1fcaf65f Mon Sep 17 00:00:00 2001 From: Extra5enS Date: Thu, 12 Nov 2020 22:59:55 +0300 Subject: [PATCH 2/6] b --- OpenMP2/src/main.cpp | 5 ++--- OpenMP3/src/main.cpp | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/OpenMP2/src/main.cpp b/OpenMP2/src/main.cpp index 4a69b5b..cfe430c 100644 --- a/OpenMP2/src/main.cpp +++ b/OpenMP2/src/main.cpp @@ -4,14 +4,13 @@ #include double calc(uint32_t x_last, uint32_t num_threads) { - double res = 0; + double res = 0; double* res_buf = (double*)calloc(x_last, sizeof(double)); #pragma omp parallel num_threads(num_threads) { #pragma omp for for(int i = x_last; i > 0; --i) { - double buf = 1.0 / i; - res_buf[i - 1] = buf; + res_buf[i - 1] = 1.0 / i; } } for(int i = x_last; i > 0; --i) { diff --git a/OpenMP3/src/main.cpp b/OpenMP3/src/main.cpp index 416ee06..1395d53 100644 --- a/OpenMP3/src/main.cpp +++ b/OpenMP3/src/main.cpp @@ -4,6 +4,7 @@ #include #include +<<<<<<< HEAD double func(double x) { return sin(x); @@ -12,6 +13,25 @@ double func(double x) double calc(double x0, double x1, double dx, uint32_t num_threads) { return 0; +======= +double calc() { + size_t n_thread = 0; + double x1, x2, dx, res = 0.0; + printf("Enter first and last x, and dx\n"); + scanf("%lf %lf %lf", &x1, &x2, &dx); + printf("Enter num of thread\n"); + scanf("%ld", &n_thread); + int n = ceil((x2 - x1) / dx); // #pragma omp for don't work with double type + + #pragma omp parallel num_threads(n_thread) + { + #pragma omp for reduction(+:res) + for(int _x = 0; _x < n; ++_x) { + res += (f(x1 + _x * dx) + f(x1 + (_x + 1)*dx)) / 2 * dx; + } + } + return res; +>>>>>>> for rebase } int main(int argc, char** argv) From a7fb4b329a58e5b4f4193d001036b6f1852b36f8 Mon Sep 17 00:00:00 2001 From: Extra5enS Date: Fri, 13 Nov 2020 15:25:31 +0300 Subject: [PATCH 3/6] 2 task main part --- CompMath2/src/main.cpp | 151 ++++++++++++++++++++++++++--------------- 1 file changed, 98 insertions(+), 53 deletions(-) diff --git a/CompMath2/src/main.cpp b/CompMath2/src/main.cpp index 5c4527a..e8693d2 100644 --- a/CompMath2/src/main.cpp +++ b/CompMath2/src/main.cpp @@ -5,64 +5,109 @@ #include #include -void calc(double* frame, uint32_t ySize, uint32_t xSize, double delta, int rank, int size) -{ - if (rank == 0 && size > 0) - { - double diff = 0; - double* tmpFrame = new double[ySize * xSize]; - // Prepare tmpFrame - for (uint32_t y = 0; y < ySize; y++) - { - tmpFrame[y*xSize] = frame[y*xSize]; - tmpFrame[y*xSize + xSize - 1] = frame[y*xSize + xSize - 1]; - } - for (uint32_t x = 1; x < xSize - 1; x++) - { - tmpFrame[x] = frame[x]; - tmpFrame[(ySize - 1)*xSize + x] = frame[(ySize - 1)*xSize + x]; - } - // Calculate first iteration - for (uint32_t y = 1; y < ySize - 1; y++) - { - for (uint32_t x = 1; x < xSize - 1; x++) - { - tmpFrame[y*xSize + x] = (frame[(y + 1)*xSize + x] + frame[(y - 1)*xSize + x] +\ - frame[y*xSize + x + 1] + frame[y*xSize + x - 1])/4.0; - diff += std::abs(tmpFrame[y*xSize + x] - frame[y*xSize + x]); - } - } +#define ROOT 0 - double* currFrame = tmpFrame; - double* nextFrame = frame; - uint32_t iteration = 1; - // Calculate frames - while (diff > delta) - { - diff = 0; - for (uint32_t y = 1; y < ySize - 1; y++) - { - for (uint32_t x = 1; x < xSize - 1; x++) - { - nextFrame[y*xSize + x] = (currFrame[(y + 1)*xSize + x] + currFrame[(y - 1)*xSize + x] +\ - currFrame[y*xSize + x + 1] + currFrame[y*xSize + x - 1])/4.0; - diff += std::abs(nextFrame[y*xSize + x] - currFrame[y*xSize + x]); +void calc(double* frame, uint32_t ySize, uint32_t xSize, double delta, int rank, int size) { + int* send_dist = NULL; + int* send_range = NULL; + + int* recv_dist = NULL; + int* recv_range = NULL; + + double* new_frame = NULL; + + MPI_Bcast(&ySize, 1, MPI_UNSIGNED, ROOT, MPI_COMM_WORLD); + MPI_Bcast(&xSize, 1, MPI_UNSIGNED, ROOT, MPI_COMM_WORLD); + int real_rank_size = 0; + + if(rank == ROOT) { + size_t my_calc_size = ceil((ySize - 2) * 1.0 / size); + // if proc_rank > ceil(ySize / my_calc_size) it will do nothing + real_rank_size = ceil((ySize - 2) * 1.0 / my_calc_size); + size_t now_size = 1; + + new_frame = (double*)calloc(xSize*ySize, sizeof(double)); + + recv_dist = (int*)calloc(size, sizeof(int)); + recv_range = (int*)calloc(size, sizeof(int)); + + send_dist = (int*)calloc(size, sizeof(int)); + send_range = (int*)calloc(size, sizeof(int)); + + for(int i = 0; i < real_rank_size; ++i) { + recv_dist[i] = i * xSize * my_calc_size + xSize; + recv_range[i] = xSize * std::min(my_calc_size, ySize - 1 - now_size); + now_size += std::min(my_calc_size, ySize - 1 - now_size); } - } - std::swap(currFrame, nextFrame); - iteration++; + + for(int i = 0; i < real_rank_size; ++i) { + send_range[i] = recv_range[i] + 2*xSize; + send_dist[i] = recv_dist[i] - xSize; + } + delta++; + /* + printf("xSize = %u, ySize = %u\n", xSize, ySize); + for(int i = 0; i < real_rank_size; ++i) { + printf("send_range = %d, send_dist = %d, recv_range = %d, recv_dist = %d\n", + send_range[i], send_dist[i], recv_range[i], recv_dist[i]); + }*/ } - // Copy result from tmp - if (iteration % 2 == 1) - { - for (uint32_t i = 0; i < xSize*ySize; i++) - { - frame[i] = tmpFrame[i]; - } + int send_step = 0; + int recv_step = 0; + + + // Bug with MPI <- i hate it! really! + MPI_Scatter( + send_range, 1, MPI_INT, + &send_step, size, MPI_INT, + ROOT, MPI_COMM_WORLD); + MPI_Scatter( + recv_range, 1, MPI_INT, + &recv_step, size, MPI_INT, + ROOT, MPI_COMM_WORLD); + + double* my_calc = (double*)calloc(send_step, sizeof(double)); + double* recv_calc = (double*)calloc(send_step, sizeof(double)); + + double diff = 0; + do { + MPI_Scatterv( + frame, send_range, send_dist, MPI_DOUBLE, + my_calc, send_step, MPI_DOUBLE, + ROOT, MPI_COMM_WORLD); + + for(size_t y = 1; y < send_step * 1.0 / xSize - 1; ++y) { + for(size_t x = 1; x < xSize - 1; ++x) { + recv_calc[y * xSize + x] = (my_calc[(y + 1) * xSize + x] +\ + my_calc[(y - 1) * xSize + x] +\ + my_calc[y * xSize + x + 1] +\ + my_calc[y * xSize + x - 1]) / 4.0; + } + } + + MPI_Gatherv( + my_calc, recv_step, MPI_DOUBLE, + new_frame, recv_range, recv_dist, MPI_DOUBLE, + ROOT, MPI_COMM_WORLD); + if(rank == ROOT) { + for(size_t i = 0; i < xSize * ySize; ++i) { + diff += std::abs(new_frame[i] - frame[i]); + } + memcpy(frame, new_frame, sizeof(double) * xSize * ySize); + } + MPI_Bcast(&diff, 1, MPI_DOUBLE, ROOT, MPI_COMM_WORLD); + //printf("[%d] diff = %lf\n", rank, diff); + } while(diff > delta); + printf("here\n"); + free(my_calc); + free(recv_calc); + if(rank == ROOT) { + free(recv_dist); + free(recv_range); + free(send_dist); + free(send_range); } - delete tmpFrame; - } } int main(int argc, char** argv) From 6f7c506258804085d761aee4a25264cd6c6358aa Mon Sep 17 00:00:00 2001 From: Extra5enS Date: Sat, 14 Nov 2020 16:15:39 +0300 Subject: [PATCH 4/6] start addition --- CompMath2/src/main.cpp | 146 ++++++++++++++++++++++------------------- 1 file changed, 80 insertions(+), 66 deletions(-) diff --git a/CompMath2/src/main.cpp b/CompMath2/src/main.cpp index e8693d2..a0daf06 100644 --- a/CompMath2/src/main.cpp +++ b/CompMath2/src/main.cpp @@ -21,10 +21,10 @@ void calc(double* frame, uint32_t ySize, uint32_t xSize, double delta, int rank, int real_rank_size = 0; if(rank == ROOT) { - size_t my_calc_size = ceil((ySize - 2) * 1.0 / size); + size_t my_calc_size = ceil((ySize) * 1.0 / size); // if proc_rank > ceil(ySize / my_calc_size) it will do nothing - real_rank_size = ceil((ySize - 2) * 1.0 / my_calc_size); - size_t now_size = 1; + real_rank_size = ceil((ySize) * 1.0 / my_calc_size); + size_t now_size = 0; new_frame = (double*)calloc(xSize*ySize, sizeof(double)); @@ -35,22 +35,24 @@ void calc(double* frame, uint32_t ySize, uint32_t xSize, double delta, int rank, send_range = (int*)calloc(size, sizeof(int)); for(int i = 0; i < real_rank_size; ++i) { - recv_dist[i] = i * xSize * my_calc_size + xSize; - recv_range[i] = xSize * std::min(my_calc_size, ySize - 1 - now_size); - now_size += std::min(my_calc_size, ySize - 1 - now_size); + recv_dist[i] = i * xSize * my_calc_size; + recv_range[i] = xSize * std::min(my_calc_size, ySize - now_size); + now_size += std::min(my_calc_size, ySize - now_size); } for(int i = 0; i < real_rank_size; ++i) { - send_range[i] = recv_range[i] + 2*xSize; - send_dist[i] = recv_dist[i] - xSize; + if(real_rank_size == 1) { + continue; + } else if(i == 0) { + send_range[i] = recv_range[i] + xSize; + } else if(i == real_rank_size - 1) { + send_range[i] = recv_range[i] + xSize; + send_dist[i] = recv_dist[i] - xSize; + } else { + send_range[i] = recv_range[i] + 2*xSize; + send_dist[i] = recv_dist[i] - xSize; + } } - delta++; - /* - printf("xSize = %u, ySize = %u\n", xSize, ySize); - for(int i = 0; i < real_rank_size; ++i) { - printf("send_range = %d, send_dist = %d, recv_range = %d, recv_dist = %d\n", - send_range[i], send_dist[i], recv_range[i], recv_dist[i]); - }*/ } int send_step = 0; @@ -59,47 +61,59 @@ void calc(double* frame, uint32_t ySize, uint32_t xSize, double delta, int rank, // Bug with MPI <- i hate it! really! MPI_Scatter( - send_range, 1, MPI_INT, - &send_step, size, MPI_INT, - ROOT, MPI_COMM_WORLD); + send_range, 1, MPI_INT, + &send_step, size, MPI_INT, + ROOT, MPI_COMM_WORLD); MPI_Scatter( - recv_range, 1, MPI_INT, - &recv_step, size, MPI_INT, - ROOT, MPI_COMM_WORLD); - + recv_range, 1, MPI_INT, + &recv_step, size, MPI_INT, + ROOT, MPI_COMM_WORLD); + double* my_calc = (double*)calloc(send_step, sizeof(double)); double* recv_calc = (double*)calloc(send_step, sizeof(double)); - + printf("[%d] send_step = %d\n", rank, send_step / xSize); double diff = 0; + int stop = 0; do { MPI_Scatterv( frame, send_range, send_dist, MPI_DOUBLE, my_calc, send_step, MPI_DOUBLE, ROOT, MPI_COMM_WORLD); - for(size_t y = 1; y < send_step * 1.0 / xSize - 1; ++y) { for(size_t x = 1; x < xSize - 1; ++x) { recv_calc[y * xSize + x] = (my_calc[(y + 1) * xSize + x] +\ - my_calc[(y - 1) * xSize + x] +\ - my_calc[y * xSize + x + 1] +\ - my_calc[y * xSize + x - 1]) / 4.0; + my_calc[(y - 1) * xSize + x] +\ + my_calc[y * xSize + x + 1] +\ + my_calc[y * xSize + x - 1]) / 4.0; } } MPI_Gatherv( - my_calc, recv_step, MPI_DOUBLE, + recv_calc, recv_step, MPI_DOUBLE, new_frame, recv_range, recv_dist, MPI_DOUBLE, ROOT, MPI_COMM_WORLD); + if(rank == ROOT) { - for(size_t i = 0; i < xSize * ySize; ++i) { - diff += std::abs(new_frame[i] - frame[i]); + for (uint32_t y = 1; y < ySize - 1; y++) { + for (uint32_t x = 1; x < xSize - 1; x++) { + diff += std::abs(new_frame[y*xSize + x] - frame[y*xSize + x]); + } } - memcpy(frame, new_frame, sizeof(double) * xSize * ySize); + if(diff <= delta) { + stop = 1; + } else { + stop = 0; + } + for (uint32_t y = 1; y < ySize - 1; y++) { + for (uint32_t x = 1; x < xSize - 1; x++) { + frame[y*xSize + x] = new_frame[y*xSize + x]; + } + } } - MPI_Bcast(&diff, 1, MPI_DOUBLE, ROOT, MPI_COMM_WORLD); + MPI_Bcast(&stop, 1, MPI_INT, ROOT, MPI_COMM_WORLD); //printf("[%d] diff = %lf\n", rank, diff); - } while(diff > delta); - printf("here\n"); + } while(!stop); + free(my_calc); free(recv_calc); if(rank == ROOT) { @@ -112,45 +126,45 @@ void calc(double* frame, uint32_t ySize, uint32_t xSize, double delta, int rank, int main(int argc, char** argv) { - int rank = 0, size = 0, status = 0; - double delta = 0; - uint32_t ySize = 0, xSize = 0; - double* frame = 0; + int rank = 0, size = 0, status = 0; + double delta = 0; + uint32_t ySize = 0, xSize = 0; + double* frame = 0; - MPI_Init(&argc, &argv); - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - MPI_Comm_size(MPI_COMM_WORLD, &size); + MPI_Init(&argc, &argv); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); - if (rank == 0) - { - // Check arguments - if (argc != 3) + if (rank == 0) { - std::cout << "[Error] Usage \n"; - status = 1; - MPI_Bcast(&status, 1, MPI_INT, 0, MPI_COMM_WORLD); - return 1; - } + // Check arguments + if (argc != 3) + { + std::cout << "[Error] Usage \n"; + status = 1; + MPI_Bcast(&status, 1, MPI_INT, 0, MPI_COMM_WORLD); + return 1; + } - // Prepare input file - std::ifstream input(argv[1]); - if (!input.is_open()) - { - std::cout << "[Error] Can't open " << argv[1] << " for write\n"; - status = 1; - MPI_Bcast(&status, 1, MPI_INT, 0, MPI_COMM_WORLD); - return 1; - } + // Prepare input file + std::ifstream input(argv[1]); + if (!input.is_open()) + { + std::cout << "[Error] Can't open " << argv[1] << " for write\n"; + status = 1; + MPI_Bcast(&status, 1, MPI_INT, 0, MPI_COMM_WORLD); + return 1; + } - // Read arguments from input - input >> ySize >> xSize >> delta; - MPI_Bcast(&status, 1, MPI_INT, 0, MPI_COMM_WORLD); + // Read arguments from input + input >> ySize >> xSize >> delta; + MPI_Bcast(&status, 1, MPI_INT, 0, MPI_COMM_WORLD); - frame = new double[ySize * xSize]; + frame = new double[ySize * xSize]; - for (uint32_t y = 0; y < ySize; y++) - { - for (uint32_t x = 0; x < xSize; x++) + for (uint32_t y = 0; y < ySize; y++) + { + for (uint32_t x = 0; x < xSize; x++) { input >> frame[y*xSize + x]; } From 4c96eaae19c088d88bee49078506f4ef2a59f58a Mon Sep 17 00:00:00 2001 From: Extra5enS Date: Sat, 14 Nov 2020 17:03:24 +0300 Subject: [PATCH 5/6] done --- CompMath2/src/main.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/CompMath2/src/main.cpp b/CompMath2/src/main.cpp index a0daf06..06e6f04 100644 --- a/CompMath2/src/main.cpp +++ b/CompMath2/src/main.cpp @@ -42,7 +42,7 @@ void calc(double* frame, uint32_t ySize, uint32_t xSize, double delta, int rank, for(int i = 0; i < real_rank_size; ++i) { if(real_rank_size == 1) { - continue; + send_range[i] = recv_range[i]; } else if(i == 0) { send_range[i] = recv_range[i] + xSize; } else if(i == real_rank_size - 1) { @@ -53,6 +53,8 @@ void calc(double* frame, uint32_t ySize, uint32_t xSize, double delta, int rank, send_dist[i] = recv_dist[i] - xSize; } } + recv_dist[0] += xSize; + recv_range[0] -= xSize; } int send_step = 0; @@ -71,7 +73,6 @@ void calc(double* frame, uint32_t ySize, uint32_t xSize, double delta, int rank, double* my_calc = (double*)calloc(send_step, sizeof(double)); double* recv_calc = (double*)calloc(send_step, sizeof(double)); - printf("[%d] send_step = %d\n", rank, send_step / xSize); double diff = 0; int stop = 0; do { @@ -89,7 +90,7 @@ void calc(double* frame, uint32_t ySize, uint32_t xSize, double delta, int rank, } MPI_Gatherv( - recv_calc, recv_step, MPI_DOUBLE, + recv_calc + xSize, recv_step, MPI_DOUBLE, new_frame, recv_range, recv_dist, MPI_DOUBLE, ROOT, MPI_COMM_WORLD); @@ -104,6 +105,7 @@ void calc(double* frame, uint32_t ySize, uint32_t xSize, double delta, int rank, } else { stop = 0; } + diff = 0; for (uint32_t y = 1; y < ySize - 1; y++) { for (uint32_t x = 1; x < xSize - 1; x++) { frame[y*xSize + x] = new_frame[y*xSize + x]; From 7476b826e1f4c9259b6c916d8808a5ff039a4a02 Mon Sep 17 00:00:00 2001 From: Extra5enS Date: Mon, 16 Nov 2020 18:36:01 +0300 Subject: [PATCH 6/6] I impl --- CompMath1/src/main.cpp | 119 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 113 insertions(+), 6 deletions(-) diff --git a/CompMath1/src/main.cpp b/CompMath1/src/main.cpp index 7e114bd..3cfe51a 100644 --- a/CompMath1/src/main.cpp +++ b/CompMath1/src/main.cpp @@ -5,13 +5,12 @@ #include #include -double acceleration(double t) -{ - return sin(t); -} +#define ROOT 0 -void calc(double* trace, uint32_t traceSize, double t0, double dt, double y0, double y1, int rank, int size) -{ +double acceleration(double t) { + return sin(t); +} +/* // Sighting shot double v0 = 0; if (rank == 0 && size > 0) @@ -35,7 +34,115 @@ void calc(double* trace, uint32_t traceSize, double t0, double dt, double y0, do trace[i] = dt*dt*acceleration(t0 + (i - 1)*dt) + 2*trace[i - 1] - trace[i - 2]; } } + + + */ + +void calc(double* trace, uint32_t traceSize, double t0, double dt, double y0, double y1, int rank, int size) +{ + int* recv_dist = NULL; + int* recv_range = NULL; + + int real_rank_size = 0; + + if(rank == ROOT) { + size_t my_calc_size = std::max(ceil((traceSize) * 1.0 / size), 3.0); + // if proc_rank > ceil(traceSize / my_calc_size) it will do nothing + real_rank_size = ceil((traceSize) * 1.0 / my_calc_size); + size_t now_size = 0; + + recv_dist = (int*)calloc(size, sizeof(int)); + recv_range = (int*)calloc(size, sizeof(int)); + + for(int i = 0; i < real_rank_size; ++i) { + recv_dist[i] = i * my_calc_size; + recv_range[i] = std::min(my_calc_size, traceSize - now_size); + now_size += std::min(my_calc_size, traceSize - now_size); + } + + for(int i = 1; i < real_rank_size; ++i) { + recv_dist[i] -= 1; + recv_range[i] += 1; + } + for(int i = 0; i < real_rank_size - 1; ++i) { + recv_range[i] += 1; + } + } + int recv_step = 0; + int my_delta_t = 0; + + MPI_Scatter( + recv_range, 1, MPI_INT, + &recv_step, size, MPI_INT, + ROOT, MPI_COMM_WORLD); + + MPI_Scatter( + recv_dist, 1, MPI_INT, + &my_delta_t, size, MPI_INT, + ROOT, MPI_COMM_WORLD); + double* my_trace = (double*)calloc(recv_step, sizeof(double)); + // [0](math)(start_cond) -> [1](math)(start_cond) -> [2](math(start_cond)) -> ... + + // Sighting shot + double my_y0 = 0; + double my_y1 = 0; + + printf("[%d] step = %d\n", rank, recv_step); + + if(rank == ROOT) { + MPI_Send(&y0, 1, MPI_DOUBLE, ROOT, 0, MPI_COMM_WORLD); + MPI_Send(&y0, 1, MPI_DOUBLE, ROOT, 0, MPI_COMM_WORLD); + } + + MPI_Recv(&my_y0, 1, MPI_DOUBLE, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, NULL); + MPI_Recv(&my_y1, 1, MPI_DOUBLE, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, NULL); + my_trace[0] = my_y0; + my_trace[1] = my_y1; + for (uint32_t i = 2; i < (uint32_t)recv_step; i++) { + my_trace[i] = dt*dt*acceleration(t0 + (my_delta_t + i - 1)*dt) + 2*my_trace[i - 1] - my_trace[i - 2]; + } + if(rank != size - 1) { + MPI_Send(&my_trace[recv_step - 2], 1, MPI_DOUBLE, rank + 1, 0, MPI_COMM_WORLD); + MPI_Send(&my_trace[recv_step - 1], 1, MPI_DOUBLE, rank + 1, 0, MPI_COMM_WORLD); + } else { + // send smth in y1 place! + MPI_Send(&my_trace[recv_step - 1], 1, MPI_DOUBLE, ROOT, 0, MPI_COMM_WORLD); + } + + // The final shot + double last_y = 0; + if(rank == ROOT) { + MPI_Recv(&last_y, 1, MPI_DOUBLE, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, NULL); + + MPI_Send(&y0, 1, MPI_DOUBLE, ROOT, 0, MPI_COMM_WORLD); + next_y0 = y0 + (y1 - last_y)/(1.0 * traceSize); + MPI_Send(&next_y0, 1, MPI_DOUBLE, ROOT, 0, MPI_COMM_WORLD); + } + + MPI_Recv(&my_y0, 1, MPI_DOUBLE, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, NULL); + MPI_Recv(&my_y1, 1, MPI_DOUBLE, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, NULL); + my_trace[0] = my_y0; + my_trace[1] = my_y1; + + for (uint32_t i = 2; i < (uint32_t)recv_step; i++) { + my_trace[i] = dt*dt*acceleration(t0 + (my_delta_t + i - 1)*dt) + 2*my_trace[i - 1] - my_trace[i - 2]; + } + if(rank != size - 1) { + MPI_Send(&my_trace[recv_step - 2], 1, MPI_DOUBLE, rank + 1, 0, MPI_COMM_WORLD); + MPI_Send(&my_trace[recv_step - 1], 1, MPI_DOUBLE, rank + 1, 0, MPI_COMM_WORLD); + } + + MPI_Gatherv( + my_trace, recv_step, MPI_DOUBLE, + trace, recv_range, recv_dist, MPI_DOUBLE, + ROOT, MPI_COMM_WORLD); + + free(my_trace); + if(rank == ROOT) { + free(recv_range); + free(recv_dist); + } } int main(int argc, char** argv)