GCC Code Coverage Report


Directory: ./
File: tasks/nazyrov_a_multidim_integral_rectangle/stl/src/ops_stl.cpp
Date: 2026-06-04 20:25:32
Exec Total Coverage
Lines: 50 50 100.0%
Functions: 6 6 100.0%
Branches: 34 52 65.4%

Line Branch Exec Source
1 #include "nazyrov_a_multidim_integral_rectangle/stl/include/ops_stl.hpp"
2
3 #include <algorithm>
4 #include <cmath>
5 #include <cstddef>
6 #include <cstdint>
7 #include <thread>
8 #include <vector>
9
10 #include "nazyrov_a_multidim_integral_rectangle/common/include/common.hpp"
11 #include "util/include/util.hpp"
12
13 namespace nazyrov_a_multidim_integral_rectangle {
14
15
1/2
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
80 NazyrovAMultidimIntegralRectangleStl::NazyrovAMultidimIntegralRectangleStl(const InType &in) {
16 SetTypeOfTask(GetStaticTypeOfTask());
17 GetInput() = in;
18 80 GetOutput() = 0.0;
19 80 }
20
21 80 bool NazyrovAMultidimIntegralRectangleStl::ValidationImpl() {
22 const auto &func = std::get<0>(GetInput());
23 const auto &bounds = std::get<1>(GetInput());
24
1/2
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
80 const int n = std::get<2>(GetInput());
25
3/6
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 80 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 80 times.
✗ Branch 5 not taken.
80 return func && n > 0 && !bounds.empty() && std::ranges::all_of(bounds, [](const auto &bd) {
26
3/6
✓ Branch 0 taken 168 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 168 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 168 times.
✗ Branch 5 not taken.
168 return std::isfinite(bd.first) && std::isfinite(bd.second) && bd.first < bd.second;
27 80 });
28 }
29
30 80 bool NazyrovAMultidimIntegralRectangleStl::PreProcessingImpl() {
31 80 return true;
32 }
33
34 80 bool NazyrovAMultidimIntegralRectangleStl::RunImpl() {
35 const auto &func = std::get<0>(GetInput());
36 const auto &bounds = std::get<1>(GetInput());
37 80 const int n = std::get<2>(GetInput());
38
39 80 const int dim = static_cast<int>(bounds.size());
40
41 80 std::vector<double> h(static_cast<std::size_t>(dim));
42 double cell_vol = 1.0;
43
2/2
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 80 times.
248 for (int i = 0; i < dim; ++i) {
44 168 h[i] = (bounds[i].second - bounds[i].first) / n;
45 168 cell_vol *= h[i];
46 }
47
48 std::int64_t total = 1;
49
2/2
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 80 times.
248 for (int i = 0; i < dim; ++i) {
50 168 total *= n;
51 }
52
53
1/2
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
80 const int num_threads = std::max(1, ppc::util::GetNumThreads());
54
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 80 times.
✓ Branch 2 taken 60 times.
✓ Branch 3 taken 20 times.
80 const int actual_threads = std::max(1, std::min(num_threads, static_cast<int>(total)));
55
56
1/4
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
80 std::vector<double> partial_sums(static_cast<std::size_t>(actual_threads), 0.0);
57
58 200 auto worker = [&](int tid, std::int64_t begin, std::int64_t end) {
59 200 std::vector<double> point(static_cast<std::size_t>(dim));
60 double local_sum = 0.0;
61
2/2
✓ Branch 0 taken 11483200 times.
✓ Branch 1 taken 200 times.
11483400 for (std::int64_t cell = begin; cell < end; ++cell) {
62 std::int64_t tmp = cell;
63
2/2
✓ Branch 0 taken 33963200 times.
✓ Branch 1 taken 11483200 times.
45446400 for (int i = dim - 1; i >= 0; --i) {
64 33963200 const int ki = static_cast<int>(tmp % n);
65 33963200 tmp /= n;
66 33963200 const double coordinate = bounds[i].first + ((ki + 0.5) * h[i]);
67 33963200 point[i] = coordinate;
68 }
69
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11483200 times.
22966400 local_sum += func(point);
70 }
71
1/2
✓ Branch 0 taken 200 times.
✗ Branch 1 not taken.
200 partial_sums[tid] = local_sum;
72 200 };
73
74 80 const std::int64_t chunk = total / actual_threads;
75 80 const std::int64_t leftover = total % actual_threads;
76
77 80 std::vector<std::thread> threads;
78
1/2
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
80 threads.reserve(static_cast<std::size_t>(actual_threads));
79
80 std::int64_t cursor = 0;
81
2/2
✓ Branch 0 taken 200 times.
✓ Branch 1 taken 80 times.
280 for (int thread_idx = 0; thread_idx < actual_threads; ++thread_idx) {
82 200 const std::int64_t begin = cursor;
83
2/2
✓ Branch 0 taken 172 times.
✓ Branch 1 taken 28 times.
200 const std::int64_t end = begin + chunk + (static_cast<std::int64_t>(thread_idx) < leftover ? 1LL : 0LL);
84 cursor = end;
85
1/2
✓ Branch 1 taken 200 times.
✗ Branch 2 not taken.
200 threads.emplace_back(worker, thread_idx, begin, end);
86 }
87
2/2
✓ Branch 0 taken 200 times.
✓ Branch 1 taken 80 times.
280 for (auto &th : threads) {
88
1/2
✓ Branch 1 taken 200 times.
✗ Branch 2 not taken.
200 th.join();
89 }
90
91 double sum = 0.0;
92
2/2
✓ Branch 0 taken 200 times.
✓ Branch 1 taken 80 times.
280 for (double ps : partial_sums) {
93 200 sum += ps;
94 }
95
96 80 GetOutput() = sum * cell_vol;
97 80 return true;
98 80 }
99
100 80 bool NazyrovAMultidimIntegralRectangleStl::PostProcessingImpl() {
101 80 return true;
102 }
103
104 } // namespace nazyrov_a_multidim_integral_rectangle
105