| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "barkalova_m_int_met_trapez/mpi/include/ops_mpi.hpp" | ||
| 2 | |||
| 3 | #include <mpi.h> | ||
| 4 | |||
| 5 | #include <algorithm> | ||
| 6 | // #include <numeric> | ||
| 7 | #include <vector> | ||
| 8 | |||
| 9 | #include "barkalova_m_int_met_trapez/common/include/common.hpp" | ||
| 10 | // #include "util/include/util.hpp" | ||
| 11 | |||
| 12 | namespace barkalova_m_int_met_trapez { | ||
| 13 | |||
| 14 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
16 | BarkalovaMIntMetTrapezMPI::BarkalovaMIntMetTrapezMPI(const InType &in) { |
| 15 | SetTypeOfTask(GetStaticTypeOfTask()); | ||
| 16 | GetInput() = in; | ||
| 17 | 16 | } | |
| 18 | |||
| 19 |
1/2✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
|
16 | bool BarkalovaMIntMetTrapezMPI::ValidationImpl() { |
| 20 | auto &data = GetInput(); | ||
| 21 |
2/4✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 16 times.
|
16 | return data.limits.size() >= 2 && data.n_i.size() >= 2; |
| 22 | } | ||
| 23 | |||
| 24 | 16 | bool BarkalovaMIntMetTrapezMPI::PreProcessingImpl() { | |
| 25 | 16 | GetOutput() = 0.0; | |
| 26 | 16 | return true; | |
| 27 | } | ||
| 28 | |||
| 29 | namespace { | ||
| 30 | struct BroadcastData { | ||
| 31 | int n_steps_x{0}; | ||
| 32 | int n_steps_y{0}; | ||
| 33 | double x1{0.0}, x2{0.0}, y1{0.0}, y2{0.0}; | ||
| 34 | |||
| 35 | BroadcastData() = default; | ||
| 36 | }; | ||
| 37 | |||
| 38 | template <typename Func> | ||
| 39 | 16 | double Calculation(const BroadcastData &data, int rank, int size, const Func &f) { | |
| 40 | 16 | double hx = (data.x2 - data.x1) / data.n_steps_x; | |
| 41 | 16 | double hy = (data.y2 - data.y1) / data.n_steps_y; | |
| 42 | |||
| 43 | 16 | int total_nodes_x = data.n_steps_x + 1; | |
| 44 | 16 | int count = total_nodes_x / size; | |
| 45 | 16 | int remainder = total_nodes_x % size; | |
| 46 | |||
| 47 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 7 times.
|
16 | int start_i = (rank * count) + std::min(rank, remainder); |
| 48 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 7 times.
|
16 | int end_i = start_i + count + (rank < remainder ? 1 : 0); |
| 49 | |||
| 50 | double local_sum = 0.0; | ||
| 51 | |||
| 52 |
2/2✓ Branch 0 taken 1069 times.
✓ Branch 1 taken 16 times.
|
1085 | for (int i = start_i; i < end_i; ++i) { |
| 53 | 1069 | double x = data.x1 + (i * hx); | |
| 54 |
4/4✓ Branch 0 taken 1061 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 1053 times.
|
1069 | double weight_x = (i == 0 || i == data.n_steps_x) ? 0.5 : 1.0; |
| 55 | |||
| 56 |
2/2✓ Branch 0 taken 294581 times.
✓ Branch 1 taken 1069 times.
|
295650 | for (int j = 0; j <= data.n_steps_y; ++j) { |
| 57 | 294581 | double y = data.y1 + (j * hy); | |
| 58 |
4/4✓ Branch 0 taken 293512 times.
✓ Branch 1 taken 1069 times.
✓ Branch 2 taken 1069 times.
✓ Branch 3 taken 292443 times.
|
294581 | double weight_y = (j == 0 || j == data.n_steps_y) ? 0.5 : 1.0; |
| 59 | |||
| 60 | 294581 | local_sum += f(x, y) * weight_x * weight_y; | |
| 61 | } | ||
| 62 | } | ||
| 63 | 16 | return local_sum * hx * hy; | |
| 64 | } | ||
| 65 | } // namespace | ||
| 66 | |||
| 67 | 16 | bool BarkalovaMIntMetTrapezMPI::RunImpl() { | |
| 68 | 16 | int rank = 0; | |
| 69 | 16 | int size = 0; | |
| 70 | 16 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); | |
| 71 | 16 | MPI_Comm_size(MPI_COMM_WORLD, &size); | |
| 72 | |||
| 73 | 16 | BroadcastData bcast_data{}; | |
| 74 | |||
| 75 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
|
16 | if (rank == 0) { |
| 76 | 8 | Integral data_local = GetInput(); | |
| 77 | |||
| 78 |
2/4✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
|
8 | if (data_local.n_i.size() >= 2 && data_local.limits.size() >= 2) { |
| 79 | 8 | bcast_data.n_steps_x = data_local.n_i[0]; | |
| 80 | 8 | bcast_data.n_steps_y = data_local.n_i[1]; | |
| 81 | 8 | bcast_data.x1 = data_local.limits[0].first; | |
| 82 | 8 | bcast_data.x2 = data_local.limits[0].second; | |
| 83 | 8 | bcast_data.y1 = data_local.limits[1].first; | |
| 84 | 8 | bcast_data.y2 = data_local.limits[1].second; | |
| 85 | } else { | ||
| 86 | ✗ | bcast_data.n_steps_x = 1; | |
| 87 | ✗ | bcast_data.n_steps_y = 1; | |
| 88 | ✗ | bcast_data.x1 = 0.0; | |
| 89 | ✗ | bcast_data.x2 = 1.0; | |
| 90 | ✗ | bcast_data.y1 = 0.0; | |
| 91 | ✗ | bcast_data.y2 = 1.0; | |
| 92 | } | ||
| 93 | 8 | } | |
| 94 | |||
| 95 | 16 | MPI_Bcast(&bcast_data.n_steps_x, 1, MPI_INT, 0, MPI_COMM_WORLD); | |
| 96 | 16 | MPI_Bcast(&bcast_data.n_steps_y, 1, MPI_INT, 0, MPI_COMM_WORLD); | |
| 97 | 16 | MPI_Bcast(&bcast_data.x1, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); | |
| 98 | 16 | MPI_Bcast(&bcast_data.x2, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); | |
| 99 | 16 | MPI_Bcast(&bcast_data.y1, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); | |
| 100 | 16 | MPI_Bcast(&bcast_data.y2, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); | |
| 101 | |||
| 102 | 16 | double local_result = 0.0; | |
| 103 | |||
| 104 |
2/4✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
|
16 | if (bcast_data.n_steps_x > 0 && bcast_data.n_steps_y > 0) { |
| 105 | 294597 | local_result = Calculation(bcast_data, rank, size, [](double x, double y) { return (x * x) + (y * y); }); | |
| 106 | } | ||
| 107 | |||
| 108 | 16 | double global_result = 0.0; | |
| 109 | 16 | MPI_Reduce(&local_result, &global_result, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); | |
| 110 | |||
| 111 | 16 | MPI_Bcast(&global_result, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); | |
| 112 | |||
| 113 | 16 | GetOutput() = global_result; | |
| 114 | |||
| 115 | 16 | return true; | |
| 116 | } | ||
| 117 | |||
| 118 | 16 | bool BarkalovaMIntMetTrapezMPI::PostProcessingImpl() { | |
| 119 | 16 | return true; | |
| 120 | } | ||
| 121 | |||
| 122 | } // namespace barkalova_m_int_met_trapez | ||
| 123 |