GCC Code Coverage Report


Directory: ./
File: tasks/shkrebko_m_calc_of_integral_rect/all/src/ops_all.cpp
Date: 2026-06-04 20:25:32
Exec Total Coverage
Lines: 78 80 97.5%
Functions: 8 8 100.0%
Branches: 40 60 66.7%

Line Branch Exec Source
1 #include "shkrebko_m_calc_of_integral_rect/all/include/ops_all.hpp"
2
3 #include <mpi.h>
4 #include <omp.h>
5
6 #include <algorithm>
7 #include <cmath>
8 #include <cstddef>
9 #include <utility>
10 #include <vector>
11
12 #include "shkrebko_m_calc_of_integral_rect/common/include/common.hpp"
13 #include "util/include/util.hpp"
14
15 namespace shkrebko_m_calc_of_integral_rect {
16
17
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 ShkrebkoMCalcOfIntegralRectALL::ShkrebkoMCalcOfIntegralRectALL(const InType &in) {
18 SetTypeOfTask(GetStaticTypeOfTask());
19
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 GetInput() = in;
20 20 GetOutput() = 0.0;
21 20 }
22
23
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 bool ShkrebkoMCalcOfIntegralRectALL::ValidationImpl() {
24 const auto &input = GetInput();
25
3/6
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 20 times.
20 if (!input.func || input.limits.empty() || input.limits.size() != input.n_steps.size()) {
26 return false;
27 }
28
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 20 times.
50 for (std::size_t i = 0; i < input.n_steps.size(); ++i) {
29
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 30 times.
30 if (input.n_steps[i] <= 0 || input.limits[i].first >= input.limits[i].second) {
30 return false;
31 }
32 }
33 return true;
34 }
35
36 20 bool ShkrebkoMCalcOfIntegralRectALL::PreProcessingImpl() {
37 20 local_input_ = GetInput();
38 20 res_ = 0.0;
39 20 return true;
40 }
41
42 20 void ShkrebkoMCalcOfIntegralRectALL::BroadcastCommonData(int rank) {
43
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
20 if (!ppc::util::IsUnderMpirun()) {
44 return;
45 }
46
47 std::size_t dims = local_input_.limits.size();
48 20 int dims_int = static_cast<int>(dims);
49 20 MPI_Bcast(&dims_int, 1, MPI_INT, 0, MPI_COMM_WORLD);
50 20 dims = static_cast<std::size_t>(dims_int);
51
52
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
20 if (rank != 0) {
53 10 local_input_.limits.resize(dims);
54 10 local_input_.n_steps.resize(dims);
55 }
56
57
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 20 times.
30 for (std::size_t i = 1; i < dims; ++i) {
58 10 MPI_Bcast(&local_input_.limits[i].first, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
59 10 MPI_Bcast(&local_input_.limits[i].second, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
60 10 MPI_Bcast(&local_input_.n_steps[i], 1, MPI_INT, 0, MPI_COMM_WORLD);
61 }
62 }
63
64
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 void ShkrebkoMCalcOfIntegralRectALL::AssignMpiSlice(int rank, int size, double &local_left, double &local_right,
65 int &local_steps, int &local_offset) {
66 20 const double global_left = local_input_.limits[0].first;
67 20 const double global_right = local_input_.limits[0].second;
68 20 const int global_steps = local_input_.n_steps[0];
69
70 20 const int base = global_steps / size;
71 20 const int remainder = global_steps % size;
72
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 local_steps = base + (rank < remainder ? 1 : 0);
73 20 local_offset = (rank * base) + std::min(rank, remainder);
74
75 20 const double step = (global_right - global_left) / static_cast<double>(global_steps);
76 20 local_left = global_left + (static_cast<double>(local_offset) * step);
77 20 local_right = local_left + (static_cast<double>(local_steps) * step);
78 20 }
79
80
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 8 times.
20 double ShkrebkoMCalcOfIntegralRectALL::ComputeSliceSum(double left0, double right0, int steps0,
81 const std::vector<double> &h_other,
82 const std::vector<std::pair<double, double>> &limits_other,
83 const std::vector<int> &n_steps_other) const {
84 const std::size_t other_dims = limits_other.size();
85
86
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 8 times.
20 if (other_dims == 0) {
87 12 const double h0 = (right0 - left0) / static_cast<double>(steps0);
88 double sum = 0.0;
89
2/2
✓ Branch 0 taken 1000 times.
✓ Branch 1 taken 12 times.
1012 for (int i = 0; i < steps0; ++i) {
90 1000 const double x0 = left0 + ((static_cast<double>(i) + 0.5) * h0);
91
1/2
✓ Branch 1 taken 1000 times.
✗ Branch 2 not taken.
3000 sum += local_input_.func({x0});
92 }
93 12 return sum * h0;
94 }
95
96 8 const double h0 = (right0 - left0) / static_cast<double>(steps0);
97 double total = 0.0;
98
99 8 #pragma omp parallel for default(none) shared(left0, h0, steps0, h_other, limits_other, n_steps_other, other_dims) \
100 reduction(+ : total) schedule(static)
101 for (int i = 0; i < steps0; ++i) {
102 const double x0 = left0 + ((static_cast<double>(i) + 0.5) * h0);
103
104 std::vector<int> indices(other_dims, 0);
105 double local_sum = 0.0;
106
107 std::size_t total_other_points = 1;
108 for (std::size_t dim = 0; dim < other_dims; ++dim) {
109 total_other_points *= static_cast<std::size_t>(n_steps_other[dim]);
110 }
111
112 for (std::size_t idx = 0; idx < total_other_points; ++idx) {
113 std::vector<double> point(other_dims + 1);
114 point[0] = x0;
115 std::size_t tmp = idx;
116 for (int dim = static_cast<int>(other_dims) - 1; dim >= 0; --dim) {
117 const int coord = static_cast<int>(tmp % static_cast<std::size_t>(n_steps_other[dim]));
118 tmp /= static_cast<std::size_t>(n_steps_other[dim]);
119 point[dim + 1] = limits_other[dim].first + ((static_cast<double>(coord) + 0.5) * h_other[dim]);
120 }
121 local_sum += local_input_.func(point);
122 }
123 total += local_sum;
124 }
125
126 double volume_other = 1.0;
127
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 8 times.
18 for (double h : h_other) {
128 10 volume_other *= h;
129 }
130 8 return total * h0 * volume_other;
131 }
132
133 20 bool ShkrebkoMCalcOfIntegralRectALL::RunImpl() {
134 20 int rank = 0;
135 20 int size = 1;
136 20 const bool is_mpi = ppc::util::IsUnderMpirun();
137
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 if (is_mpi) {
138 20 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
139 20 MPI_Comm_size(MPI_COMM_WORLD, &size);
140 }
141
142 20 BroadcastCommonData(rank);
143
144 const std::size_t dims = local_input_.limits.size();
145
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 if (dims == 0) {
146 return false;
147 }
148
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 if (!local_input_.func) {
149 return false;
150 }
151
152 double my_left = 0.0;
153 double my_right = 0.0;
154 20 int my_steps = 0;
155 int my_offset = 0;
156 20 AssignMpiSlice(rank, size, my_left, my_right, my_steps, my_offset);
157
158 20 std::vector<double> h_other;
159 20 std::vector<std::pair<double, double>> limits_other;
160 20 std::vector<int> n_steps_other;
161
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 20 times.
30 for (std::size_t i = 1; i < dims; ++i) {
162 limits_other.push_back(local_input_.limits[i]);
163 n_steps_other.push_back(local_input_.n_steps[i]);
164 const double h =
165
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 (local_input_.limits[i].second - local_input_.limits[i].first) / static_cast<double>(local_input_.n_steps[i]);
166 h_other.push_back(h);
167 }
168
169
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 const double local_slice = ComputeSliceSum(my_left, my_right, my_steps, h_other, limits_other, n_steps_other);
170
171 20 double global_integral = 0.0;
172
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 if (is_mpi) {
173
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 MPI_Reduce(&local_slice, &global_integral, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
174
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
20 if (rank == 0) {
175 10 res_ = global_integral;
176 }
177 } else {
178 res_ = local_slice;
179 }
180
181 return true;
182 }
183
184 20 bool ShkrebkoMCalcOfIntegralRectALL::PostProcessingImpl() {
185 20 int rank = 0;
186
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 if (ppc::util::IsUnderMpirun()) {
187 20 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
188 }
189
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
20 if (rank == 0) {
190 10 GetOutput() = res_;
191 }
192 20 return true;
193 }
194
195 } // namespace shkrebko_m_calc_of_integral_rect
196