diff --git a/CompMath1/src/main.cpp b/CompMath1/src/main.cpp index 7e114bd..78ba2f6 100644 --- a/CompMath1/src/main.cpp +++ b/CompMath1/src/main.cpp @@ -12,30 +12,127 @@ double acceleration(double t) void calc(double* trace, uint32_t traceSize, double t0, double dt, double y0, double y1, int rank, int size) { + int count, pre_count; + int mod; + double v, u; + double start_t; + // Sighting shot - double v0 = 0; + MPI_Bcast(&dt, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); if (rank == 0 && size > 0) { - trace[0] = y0; - trace[1] = y0 + dt*v0; - for (uint32_t i = 2; i < traceSize; i++) + count = traceSize / size; + mod = traceSize % size; + + ++count; + for(int i = 0; i < mod; ++i) + { + start_t = t0 + dt * ((count - 1) + i * count); + MPI_Send(&count, 1 , MPI_INT, i + 1, 0, MPI_COMM_WORLD); + MPI_Send(&start_t, 1 , MPI_DOUBLE, i + 1, 0, MPI_COMM_WORLD); + } + + --count; + for(int i = mod; i < size - 1; ++i) { - trace[i] = dt*dt*acceleration(t0 + (i - 1)*dt) + 2*trace[i - 1] - trace[i - 2]; + start_t = t0 + dt * (count + mod + i * count); + MPI_Send(&count, 1 , MPI_INT, i + 1, 0, MPI_COMM_WORLD); + MPI_Send(&start_t, 1 , MPI_DOUBLE, i + 1, 0, MPI_COMM_WORLD); } + start_t = t0; + + } + if (rank != 0 && size > 0) + { + MPI_Recv(&count, 1 , MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(&start_t, 1 , MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); } - // The final shot + v = 0; + double* local_array = new double[count + 1]; + if (rank != 0 && size > 0) + local_array[0] = 0; if (rank == 0 && size > 0) + local_array[0] = y0; + local_array[1] = local_array[0] + dt * v; + for (int i = 2; i < (count + 1); i++) + local_array[i] = dt*dt*acceleration(start_t + (i - 1)*dt) + 2*local_array[i - 1] - local_array[i - 2]; + u = (local_array[count] - local_array[count - 1]) / dt; // b = local_array[count] + + double tmp_a, tmp_b, tmp_u, tmp_v; + + if (rank != 0 && size > 0) + { + MPI_Recv(&pre_count, 1 , MPI_INT, rank - 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(&tmp_a, 1 , MPI_DOUBLE, rank - 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(&tmp_b, 1 , MPI_DOUBLE, rank - 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(&tmp_u, 1 , MPI_DOUBLE, rank - 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(&tmp_v, 1 , MPI_DOUBLE, rank - 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + local_array[0] = tmp_a + tmp_b + dt * pre_count * tmp_v; + v = tmp_u + tmp_v; + } + if ((rank != size - 1) && size > 1) + { + MPI_Send(&count, 1 , MPI_INT, rank + 1, 0, MPI_COMM_WORLD); + MPI_Send(&local_array[0], 1 , MPI_DOUBLE, rank + 1, 0, MPI_COMM_WORLD); + MPI_Send(&local_array[count], 1 , MPI_DOUBLE, rank + 1, 0, MPI_COMM_WORLD); + MPI_Send(&u, 1 , MPI_DOUBLE, rank + 1, 0, MPI_COMM_WORLD); + MPI_Send(&v, 1 , MPI_DOUBLE, rank + 1, 0, MPI_COMM_WORLD); + } + if (rank == size - 1) { - v0 = (y1 - trace[traceSize - 1])/(dt*traceSize); - trace[0] = y0; - trace[1] = y0 + dt*v0; - for (uint32_t i = 2; i < traceSize; i++) + if (size > 1) { - trace[i] = dt*dt*acceleration(t0 + (i - 1)*dt) + 2*trace[i - 1] - trace[i - 2]; + double tmp_y1_miss = local_array[0] + local_array[count - 1] + dt * (count - 1) * v; //because we dont need local_array[count] + MPI_Send(&tmp_y1_miss, 1 , MPI_DOUBLE, 0, 0, MPI_COMM_WORLD); } } + + // The final shot + if (rank == 0 && size > 0) + { + double y1_miss; + if (size > 1) + MPI_Recv(&y1_miss, 1 , MPI_DOUBLE, size - 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + else + y1_miss = local_array[0] + local_array[count - 1] + dt * (count - 1) * v; + printf("y1_miss: %f\n", y1_miss); + v = (y1 - y1_miss) / (dt * traceSize); + local_array[0] = y0; + } + if (rank != 0 && size > 0) + { + double tmp_a_2, tmp_v_2; + MPI_Recv(&tmp_a_2, 1 , MPI_DOUBLE, rank - 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(&tmp_v_2, 1 , MPI_DOUBLE, rank - 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + local_array[0] = tmp_b + tmp_a_2 + dt * pre_count * tmp_v_2; + v = tmp_u + tmp_v_2; + } + if ((rank != size - 1) && size > 0) + { + MPI_Send(&local_array[0], 1 , MPI_DOUBLE, rank + 1, 0, MPI_COMM_WORLD); + MPI_Send(&v, 1 , MPI_DOUBLE, rank + 1, 0, MPI_COMM_WORLD); + } + local_array[1] = local_array[0] + dt * v; + for(int i = 2; i < count; ++i) + local_array[i] = dt*dt*acceleration(start_t + (i - 1)*dt) + 2*local_array[i - 1] - local_array[i - 2]; + + if (rank != 0 && size > 0) + MPI_Send(local_array, count , MPI_DOUBLE, 0, 0, MPI_COMM_WORLD); + if (rank == 0 && size > 0) + { + for(int i = 0; i < count; ++i) + trace[i] = local_array[i]; + ++count; + for(int i = 0; i < mod; ++i) + MPI_Recv(&trace[(count - 1) + i * count], count , MPI_DOUBLE, i + 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + --count; + for(int i = mod; i < size - 1; ++i) + MPI_Recv(&trace[count + mod + i * count], count , MPI_DOUBLE, i + 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + + } + delete local_array; } int main(int argc, char** argv) diff --git a/CompMath2/src/main.cpp b/CompMath2/src/main.cpp index 5c4527a..227549a 100644 --- a/CompMath2/src/main.cpp +++ b/CompMath2/src/main.cpp @@ -7,62 +7,108 @@ void calc(double* frame, uint32_t ySize, uint32_t xSize, double delta, int rank, int size) { + int count, mod; + double* local_array; + MPI_Bcast(&xSize, 1, MPI_INT, 0, MPI_COMM_WORLD); + if (rank == 0 && size > 0) { - double diff = 0; - double* tmpFrame = new double[ySize * xSize]; - // Prepare tmpFrame - for (uint32_t y = 0; y < ySize; y++) + count = (ySize - 2) / size; + mod = (ySize - 2) % size; + + ++count; + for(int i = 0; i < mod; ++i) { - tmpFrame[y*xSize] = frame[y*xSize]; - tmpFrame[y*xSize + xSize - 1] = frame[y*xSize + xSize - 1]; + MPI_Send(&count, 1 , MPI_INT, i + 1, 0, MPI_COMM_WORLD); + MPI_Send(&frame[(1 + (count - 1) + i * count - 1) * xSize], (count + 2) * xSize , MPI_DOUBLE, i + 1, 0, MPI_COMM_WORLD); } - for (uint32_t x = 1; x < xSize - 1; x++) + + --count; + for(int i = mod; i < size - 1; ++i) { - 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]); - } + MPI_Send(&count, 1 , MPI_INT, i + 1, 0, MPI_COMM_WORLD); + MPI_Send(&frame[(1 + count + mod + i * count - 1) * xSize], (count + 2) * xSize , MPI_DOUBLE, i + 1, 0, MPI_COMM_WORLD); } - double* currFrame = tmpFrame; - double* nextFrame = frame; - uint32_t iteration = 1; - // Calculate frames - while (diff > delta) + local_array = frame; + } + + if (rank != 0 && size > 0) + { + MPI_Recv(&count, 1 , MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + local_array = new double[(count + 2) * xSize]; + MPI_Recv(local_array, (count + 2) * xSize , MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + } + + double* up_string = new double[xSize - 2]; //up_string is what was upper + double* tmp_string = new double[xSize - 1]; //tmp_string[0] is what was lefter + int is_calculate = 1; + double diff; + double diff_sum; + double* diff_recv; + if (rank == 0 && size > 0) + diff_recv = new double[size]; + while(is_calculate) + { + diff = 0; + for(uint32_t x = 1; x < xSize - 1; ++x) + up_string[x - 1] = local_array[x]; + for(int y = 1; y < count + 1; ++y) { - diff = 0; - for (uint32_t y = 1; y < ySize - 1; y++) + tmp_string[0] = local_array[y * xSize]; + for(uint32_t x = 1; x < xSize - 1; ++x) { - 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]); - } + tmp_string[x] = local_array[y*xSize + x]; + local_array[y*xSize + x] = (up_string[x - 1] + local_array[(y + 1)*xSize + x] +\ + local_array[y*xSize + x + 1] + tmp_string[x - 1])/4.0; + up_string[x - 1] = tmp_string[x]; + diff += std::abs(local_array[y*xSize + x] - tmp_string[x]); } - std::swap(currFrame, nextFrame); - iteration++; } - // Copy result from tmp - if (iteration % 2 == 1) + //0--->ySize + if (rank != 0 && size > 0) + MPI_Recv(&local_array[1], xSize - 2 , MPI_DOUBLE, rank - 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + if ((rank != size - 1) && size > 0) + MPI_Send(&local_array[count * xSize + 1], xSize - 2 , MPI_DOUBLE, rank + 1, 0, MPI_COMM_WORLD); + //0<---ySize + if ((rank != size - 1) && size > 0) + MPI_Recv(&local_array[(count + 1) * xSize + 1], xSize - 2 , MPI_DOUBLE, rank + 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + if (rank != 0 && size > 0) + MPI_Send(&local_array[1 * xSize + 1], xSize - 2 , MPI_DOUBLE, rank - 1, 0, MPI_COMM_WORLD); + + MPI_Gather(&diff, 1, MPI_DOUBLE, diff_recv, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); + if (rank == 0 && size > 0) { - for (uint32_t i = 0; i < xSize*ySize; i++) - { - frame[i] = tmpFrame[i]; - } + diff_sum = 0; + for(int i = 0; i < size; ++i) + diff_sum += diff_recv[i]; + if (diff_sum <= delta) + is_calculate = 0; } - delete tmpFrame; + MPI_Bcast(&is_calculate, 1, MPI_INT, 0, MPI_COMM_WORLD); + + } + if (rank != 0 && size > 0) + { + MPI_Send(&local_array[1 * xSize], xSize * count , MPI_DOUBLE, 0, 0, MPI_COMM_WORLD); } + if (rank == 0 && size > 0) + { + ++count; + for(int i = 0; i < mod; ++i) + MPI_Recv(&frame[(1 + (count - 1) + i * count) * xSize], count * xSize , MPI_DOUBLE, i + 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + --count; + for(int i = mod; i < size - 1; ++i) + MPI_Recv(&frame[(1 + count + mod + i * count) * xSize], count * xSize, MPI_DOUBLE, i + 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + } + + if (rank == 0 && size > 0) + delete diff_recv; + if (rank != 0 && size > 0) + delete local_array; + delete up_string; + delete tmp_string; } int main(int argc, char** argv) diff --git a/HeatMap/HeatMap.png b/HeatMap/HeatMap.png new file mode 100644 index 0000000..bcbb2b0 Binary files /dev/null and b/HeatMap/HeatMap.png differ diff --git a/HeatMap/heatTable.txt b/HeatMap/heatTable.txt new file mode 100644 index 0000000..04ce872 --- /dev/null +++ b/HeatMap/heatTable.txt @@ -0,0 +1,21 @@ +20 +31 198 731 3648 1011 3895 1003 1505 3436 5708 5575 1976 8865 2671 6557 6471 3060 4438 8459 1477 +346 5352 11736 398 7494 708 4300 963 1133 6373 8475 1442 7438 1801 2078 2188 2805 2612 6445 2944 +10818 8034 8029 4536 6274 1732 8252 13360 8665 5327 2470 2398 8017 2939 15942 6134 8930 4149 5846 7492 +23766 405 649 18906 4963 24127 10445 17795 14682 19266 14095 3769 5068 21338 28790 18090 6962 21272 8195 9011 +8124 396 782 1102 1633 2201 2510 3109 3477 3980 4463 4872 5318 6002 7154 6594 6445 8290 8324 9220 +469 792 1033 1434 1765 2587 2649 3605 4049 4500 5839 5471 6858 7297 7009 8888 9119 9208 10303 10391 +1485 627 1229 2079 2148 3131 3464 5134 5395 5761 5852 6829 7778 7099 8375 10947 10161 10248 11622 13279 +278 705 1464 2130 2677 3850 3734 4576 5590 7335 7339 7917 9369 10698 9974 11534 11427 12512 11933 15186 +635 844 1762 2371 3704 4052 4793 5485 6791 7309 7692 8676 11193 10083 13067 12791 13603 14201 15126 14959 +454 1690 1952 2936 3741 3918 5817 7170 6532 8341 9256 9934 10487 11588 13339 13755 15170 14416 16875 17437 +1788 1048 2131 3289 4117 5830 6097 7116 7702 9438 10021 11780 15343 17228 14928 16738 15380 19516 19116 19515 +936 1246 2181 3441 4353 5444 6357 7756 8099 10237 10897 12335 13945 14255 16192 16348 17530 19667 21263 20902 +1085 1574 2262 3904 5133 5257 7822 8176 10062 11145 12811 12844 14524 15079 17572 16432 21341 20594 22159 22960 +1387 1555 2727 3970 5057 6648 8134 8780 8979 12353 13642 12450 16476 16438 18175 19565 20487 23751 24442 24206 +1754 1697 2794 4079 5202 7710 8314 9654 11377 12675 13937 15338 17062 18702 20160 20176 23363 23697 24503 25357 +1625 1814 2906 4423 6252 7488 8995 10806 12119 12953 15484 15556 18054 20370 19738 21299 25678 25434 26377 29035 +821 1781 3229 4816 6435 7936 9117 11509 13764 14647 16420 15889 20705 21097 22463 23801 34761 27085 28386 29914 +645 2486 3389 5013 6631 8569 9919 12519 12134 15579 17534 18479 18981 20165 23039 25437 25876 31150 28725 32798 +898 2271 3929 5242 7372 8370 10788 12644 14565 16055 18651 19608 21929 23051 24408 27094 28413 29583 33296 33799 +2439 2085 4009 5593 7193 9305 11484 13168 15106 18024 18288 20107 21020 26085 26508 28744 30182 32361 32827 36708 diff --git a/HeatMap/main.cpp b/HeatMap/main.cpp new file mode 100644 index 0000000..4721bb1 --- /dev/null +++ b/HeatMap/main.cpp @@ -0,0 +1,44 @@ +#include +#include +#include +#include +#include +#include + +#define TABLE_SIZE 20 + + +int main(int argc, char** argv) +{ + omp_set_nested(1); + + clock_t start_time, end_time; + clock_t arr_time[TABLE_SIZE][TABLE_SIZE]; + + std::ofstream fout("heatTable.txt"); + fout << TABLE_SIZE << '\n'; + + for(int i = 1; i <= TABLE_SIZE; ++i) + for(int j = 1; j <= TABLE_SIZE; ++j) + { + start_time = clock(); + #pragma omp parallel num_threads(i) + { + #pragma omp parallel num_threads(j) + { + usleep(10); + } + } + end_time = clock(); + arr_time[i - 1][j - 1] = end_time - start_time; + } + + for(int i = 0; i < TABLE_SIZE; ++i) + { + for(int j = 0; j < TABLE_SIZE; ++j) + fout << arr_time[i][j] << ' '; + fout << '\n'; + } + fout.close(); + return 0; +} diff --git a/HeatMap/map_builder.py b/HeatMap/map_builder.py new file mode 100644 index 0000000..62943bb --- /dev/null +++ b/HeatMap/map_builder.py @@ -0,0 +1,8 @@ +import matplotlib.pyplot as plt +import numpy as np + +with open('heatTable.txt', 'r') as f: + table_size = f.readline() + data = np.loadtxt('heatTable.txt', skiprows=1) + plt.imshow(data, cmap='hot', interpolation='nearest') + plt.show() diff --git a/Loop1/src/main.cpp b/Loop1/src/main.cpp index 318f940..af47ecf 100644 --- a/Loop1/src/main.cpp +++ b/Loop1/src/main.cpp @@ -7,16 +7,58 @@ void calc(double* arr, uint32_t ySize, uint32_t xSize, int rank, int size) { + int count; + uint64_t xySize; + int mod; + double* local_array; if (rank == 0 && size > 0) { - for (uint32_t y = 0; y < ySize; y++) + xySize = xSize * ySize; + int div = xySize / size; + mod = xySize % size; + + count = div + 1; + for(int i = 0; i < mod; ++i) { - for (uint32_t x = 0; x < xSize; x++) - { - arr[y*xSize + x] = sin(0.00001*arr[y*xSize + x]); - } + MPI_Send(&count, 1 , MPI_INT, i + 1, 0, MPI_COMM_WORLD); + MPI_Send(&arr[(count - 1) + i * count], count , MPI_DOUBLE, i + 1, 0, MPI_COMM_WORLD); } + + --count; + for(int i = mod; i < size - 1; ++i) + { + MPI_Send(&count, 1 , MPI_INT, i + 1, 0, MPI_COMM_WORLD); + MPI_Send(&arr[count + i * count + mod], count, MPI_DOUBLE, i + 1, 0, MPI_COMM_WORLD); + } + + local_array = arr; + } + if (rank != 0 && size > 0) + { + MPI_Recv(&count, 1 , MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + local_array = new double[count]; + MPI_Recv(local_array, count, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); } + + for(int i = 0; i < count; ++i) + local_array[i] = sin(0.00001*(local_array[i])); + + if (rank != 0 && size > 0) + { + MPI_Send(local_array, count, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD); + } + + if (rank == 0 && size > 0) + { + ++count; + for(int i = 0; i < mod; ++i) + MPI_Recv(&arr[(count - 1) + i * count], count, MPI_DOUBLE, i + 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + --count; + for(int i = mod; i < size - 1; ++i) + MPI_Recv(&arr[count + i * count + mod], count, MPI_DOUBLE, i + 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + } + if (rank != 0 && size > 0) + delete local_array; } int main(int argc, char** argv) @@ -73,7 +115,7 @@ int main(int argc, char** argv) } calc(arr, ySize, xSize, rank, size); - + if (rank == 0) { // Prepare output file diff --git a/Loop2/src/main.cpp b/Loop2/src/main.cpp index 51ea220..e63218b 100644 --- a/Loop2/src/main.cpp +++ b/Loop2/src/main.cpp @@ -5,20 +5,75 @@ #include #include +//arr[y*xSize + x] = sin(0.00001*arr[(y + 1)*xSize + x - 3]); void calc(double* arr, uint32_t ySize, uint32_t xSize, int rank, int size) { + int count; + int mod; + double* local_array; + double* send_array; if (rank == 0 && size > 0) { - for (uint32_t y = 0; y < ySize - 1; y++) + uint64_t xySize; + xSize -= 3; + ySize -= 1; + xySize = xSize * ySize; + int div = xySize / size; + mod = xySize % size; + send_array = new double[xySize]; + + for(uint32_t i = 0; i < ySize; ++i) + for(uint32_t j = 0; j < xSize; ++j) + send_array[i * xSize + j] = arr[(i + 1) * (xSize + 3) + j]; + + count = div + 1; + for(int i = 0; i < mod; ++i) { - for (uint32_t x = 3; x < xSize; x++) - { - arr[y*xSize + x] = sin(0.00001*arr[(y + 1)*xSize + x - 3]); - } + MPI_Send(&count, 1 , MPI_INT, i + 1, 0, MPI_COMM_WORLD); + MPI_Send(&send_array[(count - 1) + i * count], count , MPI_DOUBLE, i + 1, 0, MPI_COMM_WORLD); + } + + --count; + for(int i = mod; i < size - 1; ++i) + { + MPI_Send(&count, 1 , MPI_INT, i + 1, 0, MPI_COMM_WORLD); + MPI_Send(&send_array[count + i * count + mod], count, MPI_DOUBLE, i + 1, 0, MPI_COMM_WORLD); } + + local_array = send_array; + } + if (rank != 0 && size > 0) + { + MPI_Recv(&count, 1 , MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + local_array = new double[count]; + MPI_Recv(local_array, count, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + } + + for(int i = 0; i < count; ++i) + local_array[i] = sin(0.00001*(local_array[i])); + + if (rank != 0 && size > 0) + { + MPI_Send(local_array, count, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD); + delete local_array; + } + + if (rank == 0 && size > 0) + { + ++count; + for(int i = 0; i < mod; ++i) + MPI_Recv(&send_array[(count - 1) + i * count], count, MPI_DOUBLE, i + 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + --count; + for(int i = mod; i < size - 1; ++i) + MPI_Recv(&send_array[count + i * count + mod], count, MPI_DOUBLE, i + 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + for(uint32_t i = 0; i < ySize; ++i) + for(uint32_t j = 0; j < xSize; ++j) + arr[i * (xSize + 3) + (j + 3)] = send_array[i * xSize + j]; + delete send_array; } } + int main(int argc, char** argv) { int rank = 0, size = 0, buf = 0; diff --git a/Loop3/src/main.cpp b/Loop3/src/main.cpp index 43cce1f..d6a97aa 100644 --- a/Loop3/src/main.cpp +++ b/Loop3/src/main.cpp @@ -7,18 +7,102 @@ void calc(double* arr, uint32_t ySize, uint32_t xSize, int rank, int size) { + int count; + int chain_size; //Some threads might needs chain_size-2 calculations. But for easier coding, we will always calculate chain_size-1 calculations + int mod; + double* local_array; + double* send_array; + + if(rank == 0 && size > 0) + { + chain_size = ySize / 4 + 1; + if (ySize % 4 == 0) + --chain_size; + } + MPI_Bcast(&chain_size, 1, MPI_INT, 0, MPI_COMM_WORLD); + if (rank == 0 && size > 0) { - for (uint32_t y = 4; y < ySize; y++) + uint64_t startSize; + startSize = xSize * 4; + int div = startSize / size; + mod = startSize % size; + send_array = new double[(div + 1) * chain_size]; + count = div + 1; + for(int i = 0; i < mod; ++i) { - for (uint32_t x = 0; x < xSize; x++) - { - arr[y*xSize + x] = sin(arr[(y - 4)*xSize + x]); - } + MPI_Send(&count, 1 , MPI_INT, i + 1, 0, MPI_COMM_WORLD); + for(int j = 0; j < chain_size; ++j) + for(int k = 0; k < count; ++k) + send_array[j * count + k] = arr[(count - 1) + i * count + j * 4 * xSize + k]; + MPI_Send(send_array, count * chain_size, MPI_DOUBLE, i + 1, 0, MPI_COMM_WORLD); + } + + --count; + for(int i = mod; i < size - 1; ++i) + { + MPI_Send(&count, 1 , MPI_INT, i + 1, 0, MPI_COMM_WORLD); + for(int j = 0; j < chain_size; ++j) + for(int k = 0; k < count; ++k) + send_array[j * count + k] = arr[count + mod + i * count + j * 4 * xSize + k]; + MPI_Send(send_array, count * chain_size, MPI_DOUBLE, i + 1, 0, MPI_COMM_WORLD); } + + local_array = new double[count * chain_size]; + for(int j = 0; j < chain_size; ++j) + for(int k = 0; k < count; ++k) + local_array[j * count + k] = arr[j * 4 * xSize + k]; + } + + if (rank != 0 && size > 0) + { + MPI_Recv(&count, 1 , MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + local_array = new double[count * chain_size]; + MPI_Recv(local_array, count * chain_size, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); } + + for(int i = 0; i < count; ++i) + for(int j = 0; j < chain_size - 1; ++j) + local_array[i + (j + 1) * count] = sin(local_array[i + j * count]); + + if (rank != 0 && size > 0) + { + MPI_Send(local_array, count * chain_size, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD); + } + + if (rank == 0 && size > 0) + { + int xySize = xSize * ySize; + int ind; + ++count; + for(int i = 0; i < mod; ++i) + { + MPI_Recv(send_array, count * chain_size, MPI_DOUBLE, i + 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + for(int j = 0; j < chain_size; ++j) + for(int k = 0; k < count; ++k) + if ((ind = (count - 1) + i * count + j * 4 * xSize + k) < xySize) + arr[ind] = send_array[j * count + k]; + } + --count; + for(int i = mod; i < size - 1; ++i) + { + MPI_Recv(send_array, count * chain_size, MPI_DOUBLE, i + 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + for(int j = 0; j < chain_size; ++j) + for(int k = 0; k < count; ++k) + if ((ind = count + mod + i * count + j * 4 * xSize + k) < xySize) + arr[ind] = send_array[j * count + k]; + } + for(int j = 0; j < chain_size; ++j) + for(int k = 0; k < count; ++k) + if((ind = j * 4 * xSize + k) < xySize) + arr[j * 4 * xSize + k] = local_array[j * count + k]; + delete send_array; + } + + delete local_array; } + int main(int argc, char** argv) { int rank = 0, size = 0, buf = 0; diff --git a/Loop4/src/main.cpp b/Loop4/src/main.cpp index d958d54..c8916f5 100644 --- a/Loop4/src/main.cpp +++ b/Loop4/src/main.cpp @@ -4,18 +4,176 @@ #include #include #include +#include //Add this for NaN in border_checker + +double border_checker(double* array, int xSize, int ySize, int zSize, int x, int y, int z) +{ + if((x < xSize) && (x >= 0) && (y < ySize) && (y >= 0) && (z < zSize) && (z >= 0)) + return array[z * xSize * ySize + y * xSize + x]; + else + return std::numeric_limits::quiet_NaN(); +} void calc(double* arr, uint32_t zSize, uint32_t ySize, uint32_t xSize, int rank, int size) { - if (rank == 0 && size > 0) { - for (uint32_t z = 1; z < zSize; z++) { - for (uint32_t y = 0; y < ySize - 1; y++) { - for (uint32_t x = 0; x < xSize - 1; x++) { - arr[z*ySize*xSize + y*xSize + x] = sin(arr[(z - 1)*ySize*xSize + (y + 1)*xSize + x + 1]); - } + int count; + int chain_size; //Some threads might needs chain_size-2 calculations. But for easier coding, we will always calculate chain_size-1 calculations + int mod; + double* local_array; + double* send_array; + int* root_x; + int* root_y; + int* root_z; + if(rank == 0 && size > 0) + { + chain_size = std::min(std::min(xSize, ySize), zSize); //it's max chain size + } + MPI_Bcast(&chain_size, 1, MPI_INT, 0, MPI_COMM_WORLD); + + if (rank == 0 && size > 0) + { //roots: z = 0; x = xSize; y = ySize; 3 sides, sideSize - 1 + uint64_t startSize = (xSize - 1) * (ySize - 1) + (xSize - 1) * (zSize - 2) + (ySize - 2) * (zSize - 2); + root_x = new int[startSize]; + root_y = new int[startSize]; + root_z = new int[startSize]; + int index = 0; + for(uint32_t i = 1; i < xSize; ++i) + for(uint32_t j = 1; j < ySize; ++j) + { + root_x[index] = i; + root_y[index] = j; + root_z[index] = 0; + ++index; + } + for(uint32_t i = 1; i < xSize; ++i) + for(uint32_t j = 1; j < zSize - 1; ++j) + { + root_x[index] = i; + root_y[index] = ySize - 1; + root_z[index] = j; + ++index; } + for(uint32_t i = 1; i < ySize - 1; ++i) + for(uint32_t j = 1; j < zSize - 1; ++j) + { + root_x[index] = xSize - 1; + root_y[index] = i; + root_z[index] = j; + ++index; + } + int div = startSize / size; + mod = startSize % size; + send_array = new double[(div + 1) * chain_size]; + count = div + 1; + for(int i = 0; i < mod; ++i) + { + MPI_Send(&count, 1 , MPI_INT, i + 1, 0, MPI_COMM_WORLD); + for(int j = 0; j < chain_size; ++j) + for(int k = 0; k < count; ++k) + send_array[j * count + k] = border_checker(arr, xSize, ySize, zSize, + root_x[(count - 1) + i * count + k] - j * 1, + root_y[(count - 1) + i * count + k] - j * 1, + root_z[(count - 1) + i * count + k] + j * 1); + MPI_Send(send_array, count * chain_size, MPI_DOUBLE, i + 1, 0, MPI_COMM_WORLD); + } + + --count; + for(int i = mod; i < size - 1; ++i) + { + MPI_Send(&count, 1 , MPI_INT, i + 1, 0, MPI_COMM_WORLD); + for(int j = 0; j < chain_size; ++j) + for(int k = 0; k < count; ++k) + send_array[j * count + k] = border_checker(arr, xSize, ySize, zSize, + root_x[count + mod + i * count + k] - j * 1, + root_y[count + mod + i * count + k] - j * 1, + root_z[count + mod + i * count + k] + j * 1); + + MPI_Send(send_array, count * chain_size, MPI_DOUBLE, i + 1, 0, MPI_COMM_WORLD); + } + + local_array = new double[count * chain_size]; + for(int j = 0; j < chain_size; ++j) + for(int k = 0; k < count; ++k) + local_array[j * count + k] = border_checker(arr, xSize, ySize, zSize, + root_x[k] - j * 1, + root_y[k] - j * 1, + root_z[k] + j * 1); + + } + + if (rank != 0 && size > 0) + { + MPI_Recv(&count, 1 , MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + local_array = new double[count * chain_size]; + MPI_Recv(local_array, count * chain_size, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + } + + for(int i = 0; i < count; ++i) + for(int j = 0; j < chain_size - 1; ++j) + { + if(local_array[i + (j + 1) * count] == local_array[i + (j + 1) * count]) //Check if not NaN + local_array[i + (j + 1) * count] = sin(local_array[i + j * count]); + else + j = chain_size; //End calculating for this chain + } + + if (rank != 0 && size > 0) + { + MPI_Send(local_array, count * chain_size, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD); + } + + if (rank == 0 && size > 0) + { + double tmp; + ++count; + for(int i = 0; i < mod; ++i) + { + MPI_Recv(send_array, count * chain_size, MPI_DOUBLE, i + 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + for(int k = 0; k < count; ++k) + for(int j = 0; j < chain_size; ++j) + { + if((tmp = send_array[j * count + k]) == (send_array[j * count + k])) //Check if not NaN + arr[(root_x[(count - 1) + i * count + k] - j * 1) + + (root_y[(count - 1) + i * count + k] - j * 1) * xSize + + (root_z[(count - 1) + i * count + k] + j * 1) * xSize * ySize] = tmp; + else + j = chain_size; + } } + --count; + for(int i = mod; i < size - 1; ++i) + { + MPI_Recv(send_array, count * chain_size, MPI_DOUBLE, i + 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + for(int k = 0; k < count; ++k) + for(int j = 0; j < chain_size; ++j) + { + if((tmp = send_array[j * count + k]) == (send_array[j * count + k])) //Check if not NaN + arr[(root_x[count + mod + i * count + k] - j * 1) + + (root_y[count + mod + i * count + k] - j * 1) * xSize + + (root_z[count + mod + i * count + k] + j * 1) * xSize * ySize] = tmp; + else + j = chain_size; + } + + } + for(int k = 0; k < count; ++k) + for(int j = 0; j < chain_size; ++j) + { + if((tmp = local_array[j * count + k]) == (local_array[j * count + k])) //Check if not NaN + arr[(root_x[k] - j * 1) + + (root_y[k] - j * 1) * xSize + + (root_z[k] + j * 1) * xSize * ySize] = tmp; + else + j = chain_size; + } + + delete send_array; + delete root_x; + delete root_y; + delete root_z; } + + delete local_array; } int main(int argc, char** argv) diff --git a/OpenMP2/src/main.cpp b/OpenMP2/src/main.cpp index 8dab215..ebe18f7 100644 --- a/OpenMP2/src/main.cpp +++ b/OpenMP2/src/main.cpp @@ -3,9 +3,16 @@ #include #include -double calc(uint32_t x_last, uint32_t num_threads) -{ - return 0; +double calc(uint32_t x_last, uint32_t num_threads) //Fails at TEST04 in last number(sometimes pre-last number). +{ //The strange thing is that my sum little bigger than test sum. + double sum = 0.0; //May be parallel calc is more accuracy? + double* arr_sum = new double[x_last]; + #pragma omp parallel for num_threads(num_threads) //reduction(+:sum) + for(uint32_t i = x_last; i > 0; i--) + arr_sum[i - 1] += 1.0 / i; + for(uint32_t i = x_last; i > 0; --i) + sum += arr_sum[i - 1]; + return sum; } int main(int argc, char** argv) diff --git a/OpenMP3/src/main.cpp b/OpenMP3/src/main.cpp index 416ee06..9fa854b 100644 --- a/OpenMP3/src/main.cpp +++ b/OpenMP3/src/main.cpp @@ -11,7 +11,13 @@ double func(double x) double calc(double x0, double x1, double dx, uint32_t num_threads) { - return 0; + int steps_num = round((x1 - x0) / dx); + double sum = (- func(x0) / 2.0 + func(x0 + steps_num * dx) / 2.0) * dx; //<-*dx + #pragma omp parallel for num_threads(num_threads) reduction(+:sum) + for(int i = 0; i < steps_num; ++i) + sum += func(x0 + i * dx) * dx; //<--*dx + //sum *= dx; //At first, i used this, and without "* dx" in marked "<--*dx" strings. But tests 06 and 07 were failed (1.99999999 != 2) + return sum; } int main(int argc, char** argv) diff --git a/OpenMP4/src/main.cpp b/OpenMP4/src/main.cpp index 036d8e3..2428abb 100644 --- a/OpenMP4/src/main.cpp +++ b/OpenMP4/src/main.cpp @@ -3,9 +3,32 @@ #include #include -double calc(uint32_t x_last, uint32_t num_threads) +double calc(uint32_t x_last, uint32_t num_threads) //Failed at Test05, the last number is 5, but in test it is 6 { - return 0; + double sum = 0.0; + double pre_sum = 0.0; + double arr_sum[num_threads]; + double k = 1.0; + double arr_k[num_threads]; + #pragma omp parallel num_threads(num_threads) firstprivate(k, pre_sum) shared(arr_sum, arr_k) + { + #pragma omp for + for(uint32_t i = 0; i < x_last; ++i) + { + pre_sum += k; + k /= i + 1.0; + } + int thread_id = omp_get_thread_num(); + arr_k[thread_id] = k; + arr_sum[thread_id] = pre_sum; + } + for(uint32_t i = 1; i < num_threads - 1; ++i) //the last of arr_k isn't necessary + arr_k[i] *= arr_k[i - 1]; + #pragma omp parallel for num_threads(num_threads) reduction(+:sum) + for(uint32_t i = num_threads - 1; i > 0; --i) + sum += arr_sum[i] * arr_k[i - 1]; + sum += arr_sum[0]; + return sum; } int main(int argc, char** argv) diff --git a/OpenMP5/src/main.cpp b/OpenMP5/src/main.cpp index bf042c5..20980ea 100644 --- a/OpenMP5/src/main.cpp +++ b/OpenMP5/src/main.cpp @@ -1,3 +1,5 @@ +//:set tabstop=2 + #include #include #include @@ -5,7 +7,56 @@ void calc(uint32_t xSize, uint32_t ySize, uint32_t iterations, uint32_t num_threads, uint8_t* inputFrame, uint8_t* outputFrame) { + uint8_t* neighbours_map[xSize + 2][ySize + 2]; //to easy understand who is neighbour + #pragma omp parallel for num_threads(num_threads) shared(neighbours_map, inputFrame) + for(uint64_t i = 0; i < xSize * ySize; ++i) + { + uint32_t tmp_x = i % xSize; + uint32_t tmp_y = i / xSize; + neighbours_map[tmp_x + 1][tmp_y + 1] = &inputFrame[i]; + } + #pragma omp parallel for num_threads(num_threads) shared(neighbours_map, inputFrame) + for(uint32_t i = 0; i < xSize; ++i) + { + neighbours_map[i + 1][0] = &inputFrame[i + (ySize-1)*xSize]; + neighbours_map[i + 1][ySize + 1] = &inputFrame[i + 0*xSize]; + } + #pragma omp parallel for num_threads(num_threads) shared(neighbours_map, inputFrame) + for(uint32_t i = 0; i < ySize; ++i) + { + neighbours_map[0][i + 1] = &inputFrame[(xSize-1) + i*xSize]; + neighbours_map[xSize + 1][i + 1] = &inputFrame[0 + i*xSize]; + } + neighbours_map[0][0] = &inputFrame[(xSize-1)+(ySize-1)*xSize]; + neighbours_map[0][ySize + 1] = &inputFrame[(xSize-1) + 0*xSize]; + neighbours_map[xSize + 1][0] = &inputFrame[0 + (ySize-1)*xSize]; + neighbours_map[xSize + 1][ySize + 1] = &inputFrame[0 + 0*xSize]; + + if(iterations == 0) // little kostil + #pragma omp parallel for num_threads(num_threads) shared(inputFrame, outputFrame) + for(uint64_t i = 0; i < xSize*ySize; ++i) + outputFrame[i] = inputFrame[i]; + for(uint32_t iter = 0; iter < iterations; ++iter) + { + #pragma omp parallel for num_threads(num_threads) shared(neighbours_map, inputFrame, outputFrame) + for(uint64_t i = 0; i < xSize*ySize; ++i) + { + uint32_t x = i % xSize; + uint32_t y = i / xSize; + uint8_t neighbours_sum = *neighbours_map[x][y] + *neighbours_map[x+1][y] + //123 (1,2) + *neighbours_map[x+2][y] + *neighbours_map[x][y+1] + *neighbours_map[x+2][y+1] + //4X5 (3,4,5) + *neighbours_map[x][y+2] + *neighbours_map[x+1][y+2] + *neighbours_map[x+2][y+2]; //678 (6,7,8) + if((inputFrame[i] == 0 && neighbours_sum == 3) || \ + (inputFrame[i] == 1 && (neighbours_sum == 2 || neighbours_sum == 3))) + outputFrame[i] = 1; + else + outputFrame[i] = 0; + } + #pragma omp parallel for num_threads(num_threads) shared(inputFrame, outputFrame) + for(uint64_t i = 0; i < xSize*ySize; ++i) + inputFrame[i] = outputFrame[i]; + } } int main(int argc, char** argv)