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) diff --git a/CompMath2/src/main.cpp b/CompMath2/src/main.cpp index 5c4527a..06e6f04 100644 --- a/CompMath2/src/main.cpp +++ b/CompMath2/src/main.cpp @@ -5,107 +5,168 @@ #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) * 1.0 / size); + // if proc_rank > ceil(ySize / my_calc_size) it will do nothing + real_rank_size = ceil((ySize) * 1.0 / my_calc_size); + size_t now_size = 0; + + 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; + recv_range[i] = xSize * std::min(my_calc_size, ySize - now_size); + now_size += std::min(my_calc_size, ySize - now_size); } - } - std::swap(currFrame, nextFrame); - iteration++; + + for(int i = 0; i < real_rank_size; ++i) { + if(real_rank_size == 1) { + send_range[i] = recv_range[i]; + } 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; + } + } + recv_dist[0] += xSize; + recv_range[0] -= xSize; } - // 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; + 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; + } + } + + MPI_Gatherv( + recv_calc + xSize, recv_step, MPI_DOUBLE, + new_frame, recv_range, recv_dist, MPI_DOUBLE, + ROOT, MPI_COMM_WORLD); + + if(rank == ROOT) { + 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]); + } + } + if(diff <= delta) { + stop = 1; + } 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]; + } + } + } + MPI_Bcast(&stop, 1, MPI_INT, ROOT, MPI_COMM_WORLD); + //printf("[%d] diff = %lf\n", rank, diff); + } while(!stop); + + 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) { - 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]; } diff --git a/OpenMP2/src/main.cpp b/OpenMP2/src/main.cpp index 8dab215..cfe430c 100644 --- a/OpenMP2/src/main.cpp +++ b/OpenMP2/src/main.cpp @@ -3,9 +3,20 @@ #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) { + res_buf[i - 1] = 1.0 / i; + } + } + for(int i = x_last; i > 0; --i) { + res += res_buf[i - 1]; + } + return res; } int main(int argc, char** argv) 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)