GCC Code Coverage Report


Directory: ./
File: tasks/eremin_v_hypercube/mpi/src/ops_mpi.cpp
Date: 2026-01-10 02:40:41
Exec Total Coverage
Lines: 57 58 98.3%
Functions: 6 6 100.0%
Branches: 26 40 65.0%

Line Branch Exec Source
1 #include "eremin_v_hypercube/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <cmath>
6 #include <tuple>
7
8 #include "eremin_v_hypercube/common/include/common.hpp"
9
10 namespace eremin_v_hypercube {
11
12
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 EreminVHypercubeMPI::EreminVHypercubeMPI(const InType &in) {
13 SetTypeOfTask(GetStaticTypeOfTask());
14 GetInput() = in;
15 12 GetOutput() = 0;
16 12 }
17
18 12 bool EreminVHypercubeMPI::ValidationImpl() {
19 auto &input = GetInput();
20
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 12 times.
12 return (std::get<0>(input) < std::get<1>(input)) && (std::get<2>(input) > 0) && (std::get<2>(input) <= 100000000) &&
21
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 12 times.
12 (std::get<0>(input) >= -1e9) && (std::get<0>(input) <= 1e9) && (std::get<1>(input) >= -1e9) &&
22
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
24 (std::get<1>(input) <= 1e9) && (GetOutput() == 0);
23 }
24
25 12 bool EreminVHypercubeMPI::PreProcessingImpl() {
26 12 return true;
27 }
28
29 12 bool EreminVHypercubeMPI::RunImpl() {
30 12 int world_rank = 0;
31 12 int world_size = 0;
32 12 MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
33 12 MPI_Comm_size(MPI_COMM_WORLD, &world_size);
34
35
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 int ndims = static_cast<int>(std::floor(std::log2(world_size)));
36 12 int hypercube_size = (1 << ndims);
37
38 12 double lower_bound = 0.0;
39 12 double upper_bound = 0.0;
40 12 double final_result = 0.0;
41 12 int steps = 0;
42
43
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 if (world_rank == 0) {
44 auto &input = GetInput();
45 6 lower_bound = std::get<0>(input);
46 6 upper_bound = std::get<1>(input);
47 6 steps = std::get<2>(input);
48 }
49
50
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (world_rank < hypercube_size) {
51 int cube_rank = world_rank;
52
53 12 BroadcastBoundsOverHypercube(cube_rank, ndims, lower_bound, upper_bound, steps);
54
55 12 const auto in_function = std::get<3>(GetInput());
56 12 double step_size = (upper_bound - lower_bound) / static_cast<double>(steps);
57 double local_result = 0.0;
58
59
2/2
✓ Branch 0 taken 311000 times.
✓ Branch 1 taken 12 times.
311012 for (int i = cube_rank; i < steps; i += hypercube_size) {
60
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 311000 times.
622000 local_result += in_function(lower_bound + ((static_cast<double>(i) + 0.5) * step_size));
61 }
62 12 local_result *= step_size;
63
64 12 double current_sum = local_result;
65
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
24 for (int dim = 0; dim < ndims; ++dim) {
66 12 int neighbor = cube_rank ^ (1 << dim);
67 12 double received_sum = 0.0;
68 MPI_Status status;
69
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 MPI_Sendrecv(&current_sum, 1, MPI_DOUBLE, neighbor, 10, &received_sum, 1, MPI_DOUBLE, neighbor, 10,
70 MPI_COMM_WORLD, &status);
71 12 current_sum += received_sum;
72 }
73
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 final_result = current_sum;
74 }
75
76 12 MPI_Bcast(&final_result, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
77
78 12 GetOutput() = final_result;
79 12 return true;
80 }
81
82 12 bool EreminVHypercubeMPI::PostProcessingImpl() {
83 12 return true;
84 }
85
86 12 void EreminVHypercubeMPI::BroadcastBoundsOverHypercube(int cube_rank, int ndims, double &lower_bound,
87 double &upper_bound, int &steps) {
88
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
24 for (int dim = ndims - 1; dim >= 0; --dim) {
89 12 int neighbor = cube_rank ^ (1 << dim);
90 12 const bool is_active = (cube_rank & ((1 << dim) - 1)) == 0;
91 12 const bool is_sender = (cube_rank & (1 << dim)) == 0;
92
93
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (!is_active) {
94 continue;
95 }
96
97
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 if (is_sender) {
98 6 MPI_Send(&lower_bound, 1, MPI_DOUBLE, neighbor, 0, MPI_COMM_WORLD);
99 6 MPI_Send(&upper_bound, 1, MPI_DOUBLE, neighbor, 1, MPI_COMM_WORLD);
100 6 MPI_Send(&steps, 1, MPI_INT, neighbor, 2, MPI_COMM_WORLD);
101 } else {
102 6 MPI_Recv(&lower_bound, 1, MPI_DOUBLE, neighbor, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
103 6 MPI_Recv(&upper_bound, 1, MPI_DOUBLE, neighbor, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
104 6 MPI_Recv(&steps, 1, MPI_INT, neighbor, 2, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
105 }
106 }
107 12 }
108
109 } // namespace eremin_v_hypercube
110