GCC Code Coverage Report


Directory: ./
File: tasks/shkrebko_m_calc_of_integral_rect/stl/src/ops_stl.cpp
Date: 2026-05-11 08:26:31
Exec Total Coverage
Lines: 58 60 96.7%
Functions: 6 6 100.0%
Branches: 36 56 64.3%

Line Branch Exec Source
1 #include "shkrebko_m_calc_of_integral_rect/stl/include/ops_stl.hpp"
2
3 #include <algorithm>
4 #include <cmath>
5 #include <cstddef>
6 #include <thread>
7 #include <utility>
8 #include <vector>
9
10 #include "shkrebko_m_calc_of_integral_rect/common/include/common.hpp"
11 #include "util/include/util.hpp"
12
13 namespace shkrebko_m_calc_of_integral_rect {
14
15
1/2
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
80 ShkrebkoMCalcOfIntegralRectSTL::ShkrebkoMCalcOfIntegralRectSTL(const InType &in) {
16 SetTypeOfTask(GetStaticTypeOfTask());
17
1/2
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
80 GetInput() = in;
18 80 GetOutput() = 0.0;
19 80 }
20
21
1/2
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
80 bool ShkrebkoMCalcOfIntegralRectSTL::ValidationImpl() {
22 const auto &input = GetInput();
23
24
1/2
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
80 if (!input.func) {
25 return false;
26 }
27
2/4
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 80 times.
✗ Branch 3 not taken.
80 if (input.limits.size() != input.n_steps.size() || input.limits.empty()) {
28 return false;
29 }
30
1/2
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
80 if (!std::ranges::all_of(input.n_steps, [](int n) { return n > 0; })) {
31 return false;
32 }
33
1/2
✓ Branch 0 taken 120 times.
✗ Branch 1 not taken.
120 if (!std::ranges::all_of(input.limits, [](const auto &lim) { return lim.first < lim.second; })) {
34 return false;
35 }
36 return true;
37 }
38
39 80 bool ShkrebkoMCalcOfIntegralRectSTL::PreProcessingImpl() {
40 80 local_input_ = GetInput();
41 80 res_ = 0.0;
42 80 return true;
43 }
44
45 namespace {
46
47 struct ChunkData {
48 std::size_t start;
49 std::size_t end;
50 const std::vector<double> *h;
51 const InType *input;
52 double *output;
53 };
54
55
1/2
✓ Branch 0 taken 200 times.
✗ Branch 1 not taken.
200 void ComputeChunkSum(ChunkData data) {
56 const std::size_t dim = data.input->limits.size();
57 const auto &limits = data.input->limits;
58 const auto &n_steps = data.input->n_steps;
59 const auto &func = data.input->func;
60 200 const std::vector<double> &h = *data.h;
61
62
1/2
✓ Branch 0 taken 200 times.
✗ Branch 1 not taken.
200 thread_local std::vector<double> point;
63
1/2
✓ Branch 0 taken 200 times.
✗ Branch 1 not taken.
200 if (point.size() != dim) {
64 200 point.resize(dim);
65 }
66
67 double local_sum = 0.0;
68
2/2
✓ Branch 0 taken 702400 times.
✓ Branch 1 taken 200 times.
702600 for (std::size_t idx = data.start; idx < data.end; ++idx) {
69 std::size_t tmp = idx;
70
2/2
✓ Branch 0 taken 1908800 times.
✓ Branch 1 taken 702400 times.
2611200 for (int i = static_cast<int>(dim) - 1; i >= 0; --i) {
71 1908800 std::size_t coord_index = tmp % static_cast<std::size_t>(n_steps[i]);
72 1908800 tmp /= static_cast<std::size_t>(n_steps[i]);
73 1908800 point[i] = limits[i].first + ((static_cast<double>(coord_index) + 0.5) * h[i]);
74 }
75 702400 local_sum += func(point);
76 }
77 200 *data.output = local_sum;
78 200 }
79
80 } // namespace
81
82 80 bool ShkrebkoMCalcOfIntegralRectSTL::RunImpl() {
83 const std::size_t dim = local_input_.limits.size();
84 const auto &limits = local_input_.limits;
85 const auto &n_steps = local_input_.n_steps;
86
87 80 std::vector<double> h(dim);
88 double cell_volume = 1.0;
89 std::size_t total_points = 1;
90
2/2
✓ Branch 0 taken 120 times.
✓ Branch 1 taken 80 times.
200 for (std::size_t i = 0; i < dim; ++i) {
91 120 double left = limits[i].first;
92 120 double right = limits[i].second;
93 120 int steps = n_steps[i];
94 120 h[i] = (right - left) / static_cast<double>(steps);
95 120 cell_volume *= h[i];
96 120 total_points *= static_cast<std::size_t>(steps);
97 }
98
99
1/2
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
80 int thread_count = ppc::util::GetNumThreads();
100
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 80 times.
✓ Branch 2 taken 60 times.
✓ Branch 3 taken 20 times.
80 thread_count = std::max(1, std::min(thread_count, static_cast<int>(total_points)));
101
102 80 std::size_t chunk = total_points / thread_count;
103 80 std::size_t remainder = total_points % thread_count;
104 80 std::vector<std::thread> threads;
105
1/2
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
80 std::vector<double> partial_sums(thread_count, 0.0);
106
107 std::size_t start = 0;
108
2/2
✓ Branch 0 taken 200 times.
✓ Branch 1 taken 80 times.
280 for (int i = 0; i < thread_count; ++i) {
109
2/2
✓ Branch 0 taken 172 times.
✓ Branch 1 taken 28 times.
200 std::size_t extra = std::cmp_less(static_cast<std::size_t>(i), remainder) ? 1 : 0;
110 200 std::size_t end = start + chunk + extra;
111
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 200 times.
200 if (start >= end) {
112 partial_sums[i] = 0.0;
113 continue;
114 }
115
1/2
✓ Branch 1 taken 200 times.
✗ Branch 2 not taken.
200 ChunkData data = {.start = start, .end = end, .h = &h, .input = &local_input_, .output = &partial_sums[i]};
116
1/2
✓ Branch 1 taken 200 times.
✗ Branch 2 not taken.
200 threads.emplace_back(ComputeChunkSum, data);
117 start = end;
118 }
119
120
2/2
✓ Branch 0 taken 200 times.
✓ Branch 1 taken 80 times.
280 for (auto &t : threads) {
121
1/2
✓ Branch 0 taken 200 times.
✗ Branch 1 not taken.
200 if (t.joinable()) {
122
1/2
✓ Branch 1 taken 200 times.
✗ Branch 2 not taken.
200 t.join();
123 }
124 }
125
126 double total_sum = 0.0;
127
2/2
✓ Branch 0 taken 200 times.
✓ Branch 1 taken 80 times.
280 for (double s : partial_sums) {
128 200 total_sum += s;
129 }
130
131
1/2
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
80 res_ = total_sum * cell_volume;
132 80 return true;
133 80 }
134
135 80 bool ShkrebkoMCalcOfIntegralRectSTL::PostProcessingImpl() {
136 80 GetOutput() = res_;
137 80 return true;
138 }
139
140 } // namespace shkrebko_m_calc_of_integral_rect
141