| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "gasenin_l_mult_int_mstep_trapez/mpi/include/ops_mpi.hpp" | ||
| 2 | |||
| 3 | #include <mpi.h> | ||
| 4 | |||
| 5 | #include <algorithm> | ||
| 6 | #include <cmath> | ||
| 7 | |||
| 8 | #include "gasenin_l_mult_int_mstep_trapez/common/include/common.hpp" | ||
| 9 | |||
| 10 | namespace gasenin_l_mult_int_mstep_trapez { | ||
| 11 | |||
| 12 | 34 | GaseninLMultIntMstepTrapezMPI::GaseninLMultIntMstepTrapezMPI(const InType &in) { | |
| 13 | SetTypeOfTask(GetStaticTypeOfTask()); | ||
| 14 | 34 | GetInput() = in; | |
| 15 | 34 | } | |
| 16 | |||
| 17 | 34 | bool GaseninLMultIntMstepTrapezMPI::ValidationImpl() { | |
| 18 |
3/6✓ Branch 0 taken 34 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 34 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 34 times.
|
34 | return GetInput().n_steps > 0 && GetInput().x2 > GetInput().x1 && GetInput().y2 > GetInput().y1; |
| 19 | } | ||
| 20 | |||
| 21 | 34 | bool GaseninLMultIntMstepTrapezMPI::PreProcessingImpl() { | |
| 22 | 34 | GetOutput() = 0.0; | |
| 23 | 34 | return true; | |
| 24 | } | ||
| 25 | |||
| 26 | namespace { | ||
| 27 | template <typename Func> | ||
| 28 | 68 | double RunKernel(const TaskData &data, int rank, int size, const Func &f) { | |
| 29 | 68 | double hx = (data.x2 - data.x1) / data.n_steps; | |
| 30 | 68 | double hy = (data.y2 - data.y1) / data.n_steps; | |
| 31 | |||
| 32 | 68 | int total_nodes_x = data.n_steps + 1; | |
| 33 | |||
| 34 | 68 | int count = total_nodes_x / size; | |
| 35 | 68 | int remainder = total_nodes_x % size; | |
| 36 | |||
| 37 |
2/2✓ Branch 0 taken 19 times.
✓ Branch 1 taken 15 times.
|
68 | int start_i = (rank * count) + std::min(rank, remainder); |
| 38 |
2/2✓ Branch 0 taken 19 times.
✓ Branch 1 taken 15 times.
|
68 | int end_i = start_i + count + (rank < remainder ? 1 : 0); |
| 39 | |||
| 40 | double local_sum = 0.0; | ||
| 41 | |||
| 42 |
2/2✓ Branch 0 taken 1637 times.
✓ Branch 1 taken 34 times.
|
3342 | for (int i = start_i; i < end_i; ++i) { |
| 43 | 3150 | double x = data.x1 + (i * hx); | |
| 44 |
4/4✓ Branch 0 taken 1620 times.
✓ Branch 1 taken 17 times.
✓ Branch 2 taken 17 times.
✓ Branch 3 taken 1603 times.
|
3274 | double weight_x = (i == 0 || i == data.n_steps) ? 0.5 : 1.0; |
| 45 | |||
| 46 |
2/2✓ Branch 0 taken 225879 times.
✓ Branch 1 taken 1637 times.
|
455032 | for (int j = 0; j <= data.n_steps; ++j) { |
| 47 | 446314 | double y = data.y1 + (j * hy); | |
| 48 |
4/4✓ Branch 0 taken 224242 times.
✓ Branch 1 taken 1637 times.
✓ Branch 2 taken 1637 times.
✓ Branch 3 taken 222605 times.
|
451758 | double weight_y = (j == 0 || j == data.n_steps) ? 0.5 : 1.0; |
| 49 | |||
| 50 | 451758 | local_sum += f(x, y) * weight_x * weight_y; | |
| 51 | } | ||
| 52 | } | ||
| 53 | |||
| 54 | 68 | return local_sum * hx * hy; | |
| 55 | } | ||
| 56 | } // namespace | ||
| 57 | |||
| 58 | 34 | bool GaseninLMultIntMstepTrapezMPI::RunImpl() { | |
| 59 | 34 | int rank = 0; | |
| 60 | 34 | int size = 0; | |
| 61 | 34 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); | |
| 62 | 34 | MPI_Comm_size(MPI_COMM_WORLD, &size); | |
| 63 | |||
| 64 | 34 | TaskData data{}; | |
| 65 |
2/2✓ Branch 0 taken 17 times.
✓ Branch 1 taken 17 times.
|
34 | if (rank == 0) { |
| 66 | 17 | data = GetInput(); | |
| 67 | } | ||
| 68 | |||
| 69 | 34 | MPI_Bcast(&data.n_steps, 1, MPI_INT, 0, MPI_COMM_WORLD); | |
| 70 | 34 | MPI_Bcast(&data.func_id, 1, MPI_INT, 0, MPI_COMM_WORLD); | |
| 71 | 34 | MPI_Bcast(&data.x1, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); | |
| 72 | 34 | MPI_Bcast(&data.x2, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); | |
| 73 | 34 | MPI_Bcast(&data.y1, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); | |
| 74 | 34 | MPI_Bcast(&data.y2, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); | |
| 75 | |||
| 76 | 34 | double local_result = 0.0; | |
| 77 | |||
| 78 |
6/6✓ Branch 0 taken 10 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 4 times.
|
34 | switch (data.func_id) { |
| 79 | 10 | case 0: | |
| 80 | 61024 | local_result = RunKernel(data, rank, size, [](double x, double y) { return x + y; }); | |
| 81 | 10 | break; | |
| 82 | 6 | case 1: | |
| 83 | 63686 | local_result = RunKernel(data, rank, size, [](double x, double y) { return (x * x) + (y * y); }); | |
| 84 | 6 | break; | |
| 85 | 6 | case 2: | |
| 86 | 35043 | local_result = RunKernel(data, rank, size, [](double x, double y) { return std::sin(x) * std::cos(y); }); | |
| 87 | 6 | break; | |
| 88 | 4 | case 3: | |
| 89 | 12806 | local_result = RunKernel(data, rank, size, [](double x, double y) { return std::exp(x + y); }); | |
| 90 | 4 | break; | |
| 91 | 4 | case 4: | |
| 92 | 50606 | local_result = RunKernel(data, rank, size, [](double x, double y) { return std::sqrt((x * x) + (y * y)); }); | |
| 93 | 4 | break; | |
| 94 | 4 | default: | |
| 95 | 4 | local_result = RunKernel(data, rank, size, [](double x, double y) { | |
| 96 | (void)x; | ||
| 97 | (void)y; | ||
| 98 | return 1.0; | ||
| 99 | }); | ||
| 100 | 4 | break; | |
| 101 | } | ||
| 102 | |||
| 103 | 34 | double global_result = 0.0; | |
| 104 | 34 | MPI_Reduce(&local_result, &global_result, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); | |
| 105 | |||
| 106 | 34 | MPI_Bcast(&global_result, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); | |
| 107 | |||
| 108 | 34 | GetOutput() = global_result; | |
| 109 | |||
| 110 | 34 | return true; | |
| 111 | } | ||
| 112 | |||
| 113 | 34 | bool GaseninLMultIntMstepTrapezMPI::PostProcessingImpl() { | |
| 114 | 34 | return true; | |
| 115 | } | ||
| 116 | |||
| 117 | } // namespace gasenin_l_mult_int_mstep_trapez | ||
| 118 |