GCC Code Coverage Report


Directory: ./
File: tasks/iskhakov_d_trapezoidal_integration/mpi/src/ops_mpi.cpp
Date: 2026-01-27 01:59:34
Exec Total Coverage
Lines: 56 58 96.6%
Functions: 5 5 100.0%
Branches: 32 54 59.3%

Line Branch Exec Source
1 #include "iskhakov_d_trapezoidal_integration/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <cmath>
6 #include <cstddef>
7 #include <tuple>
8 #include <vector>
9
10 #include "iskhakov_d_trapezoidal_integration/common/include/common.hpp"
11
12 namespace iskhakov_d_trapezoidal_integration {
13
14
1/2
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
30 IskhakovDTrapezoidalIntegrationMPI::IskhakovDTrapezoidalIntegrationMPI(const InType &in) {
15 SetTypeOfTask(GetStaticTypeOfTask());
16 GetInput() = in;
17 30 GetOutput() = 0;
18 30 }
19
20 30 bool IskhakovDTrapezoidalIntegrationMPI::ValidationImpl() {
21 auto &input = GetInput();
22 30 double lower_level = std::get<0>(input);
23 30 double top_level = std::get<1>(input);
24 30 int number_steps = std::get<3>(input);
25
26
2/4
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 30 times.
30 return (lower_level < top_level) && (number_steps > 0);
27 }
28
29 30 bool IskhakovDTrapezoidalIntegrationMPI::PreProcessingImpl() {
30 30 return true;
31 }
32
33 30 bool IskhakovDTrapezoidalIntegrationMPI::RunImpl() {
34 30 int world_rank = 0;
35 30 MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
36
37 30 int world_size = 0;
38 30 MPI_Comm_size(MPI_COMM_WORLD, &world_size);
39
40 auto &input = GetInput();
41
42 30 double lower_level = 0.0;
43 30 double top_level = 0.0;
44 30 int number_steps = 0;
45
46
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 15 times.
30 if (world_rank == 0) {
47 15 lower_level = std::get<0>(input);
48 15 top_level = std::get<1>(input);
49 15 number_steps = std::get<3>(input);
50 }
51
52 30 MPI_Bcast(&lower_level, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
53 30 MPI_Bcast(&top_level, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
54 30 MPI_Bcast(&number_steps, 1, MPI_INT, 0, MPI_COMM_WORLD);
55
56
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 if (number_steps == 0) {
57 GetOutput() = 0.0;
58 return true;
59 }
60
61 30 auto input_function = std::get<2>(input);
62 30 double step = (top_level - lower_level) / static_cast<double>(number_steps);
63
64 30 int base_count = number_steps / world_size;
65 30 int remainder = number_steps % world_size;
66
67
1/4
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
30 std::vector<int> elements_per_proc(static_cast<std::size_t>(world_size));
68
1/4
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
30 std::vector<int> displacement(static_cast<std::size_t>(world_size));
69
70 int offset = 0;
71
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 30 times.
90 for (int process_id = 0; process_id < world_size; ++process_id) {
72
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
120 elements_per_proc[static_cast<std::size_t>(process_id)] = base_count + (process_id < remainder ? 1 : 0);
73 60 displacement[static_cast<std::size_t>(process_id)] = offset;
74 60 offset += elements_per_proc[static_cast<std::size_t>(process_id)];
75 }
76
77
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 15 times.
30 int local_count = elements_per_proc[static_cast<std::size_t>(world_rank)];
78
79 30 std::vector<double> all_points;
80
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 15 times.
30 if (world_rank == 0) {
81
1/2
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
15 all_points.resize(static_cast<std::size_t>(number_steps) + 1);
82
2/2
✓ Branch 0 taken 204015 times.
✓ Branch 1 taken 15 times.
204030 for (int step_index = 0; step_index <= number_steps; ++step_index) {
83 204015 all_points[static_cast<std::size_t>(step_index)] = lower_level + (static_cast<double>(step_index) * step);
84 }
85 }
86
87
2/6
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 30 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
30 std::vector<double> local_points(static_cast<std::size_t>(local_count));
88
1/2
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
30 MPI_Scatterv(all_points.data(), elements_per_proc.data(), displacement.data(), MPI_DOUBLE, local_points.data(),
89 local_count, MPI_DOUBLE, 0, MPI_COMM_WORLD);
90
91 30 double local_sum = 0.0;
92
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 204000 times.
✓ Branch 2 taken 204000 times.
✓ Branch 3 taken 30 times.
204030 for (double point : local_points) {
93 204000 local_sum += input_function(point);
94 }
95
96
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 15 times.
30 if (world_rank == 0) {
97
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
30 local_sum -= input_function(local_points.front()) * 0.5;
98 }
99
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 15 times.
30 if (world_rank == world_size - 1) {
100
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
30 local_sum -= input_function(local_points.back()) * 0.5;
101 }
102
103 30 double result = 0.0;
104
1/2
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
30 MPI_Allreduce(&local_sum, &result, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
105
106
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 GetOutput() = result * step;
107
108 return true;
109 }
110
111 30 bool IskhakovDTrapezoidalIntegrationMPI::PostProcessingImpl() {
112 30 return true;
113 }
114
115 } // namespace iskhakov_d_trapezoidal_integration
116