GCC Code Coverage Report


Directory: ./
File: tasks/sannikov_i_integrals_rectangle_method/tbb/src/ops_tbb.cpp
Date: 2026-05-11 08:26:31
Exec Total Coverage
Lines: 53 56 94.6%
Functions: 7 7 100.0%
Branches: 37 60 61.7%

Line Branch Exec Source
1 #include "sannikov_i_integrals_rectangle_method/tbb/include/ops_tbb.hpp"
2
3 #include <cmath>
4 #include <cstddef>
5 #include <cstdint>
6 #include <functional>
7 #include <utility>
8 #include <vector>
9
10 #include "oneapi/tbb/blocked_range.h"
11 #include "oneapi/tbb/parallel_reduce.h"
12 #include "sannikov_i_integrals_rectangle_method/common/include/common.hpp"
13
14 namespace sannikov_i_integrals_rectangle_method {
15
16
1/2
✓ Branch 1 taken 92 times.
✗ Branch 2 not taken.
92 SannikovIIntegralsRectangleMethodTBB::SannikovIIntegralsRectangleMethodTBB(const InType &in) {
17 SetTypeOfTask(GetStaticTypeOfTask());
18 GetInput() = in;
19 92 GetOutput() = 0.0;
20 92 }
21
22
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 92 times.
92 bool SannikovIIntegralsRectangleMethodTBB::ValidationImpl() {
23 const auto &[func, borders, n] = GetInput();
24
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 92 times.
92 if (borders.empty()) {
25 return false;
26 }
27
2/2
✓ Branch 0 taken 160 times.
✓ Branch 1 taken 92 times.
252 for (const auto &[left_border, right_border] : borders) {
28
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 160 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 160 times.
160 if (!std::isfinite(left_border) || !std::isfinite(right_border)) {
29 return false;
30 }
31
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 160 times.
160 if (left_border >= right_border) {
32 return false;
33 }
34 }
35
36
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 92 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 92 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 92 times.
92 return func && (n > 0) && (GetOutput() == 0.0);
37 }
38
39 92 bool SannikovIIntegralsRectangleMethodTBB::PreProcessingImpl() {
40 92 GetOutput() = 0.0;
41 92 return true;
42 }
43
44 namespace {
45
46 13040 bool ComputeSlice(const std::function<double(const std::vector<double> &)> &f,
47 const std::vector<std::pair<double, double>> &brd, const std::vector<double> &h,
48 std::size_t outer_dim, int64_t inner_cells, int num_splits, int outer, std::vector<int> &idx,
49 std::vector<double> &x, double &local_sum) {
50
2/2
✓ Branch 0 taken 6360 times.
✓ Branch 1 taken 13040 times.
19400 for (std::size_t i = 0; i < outer_dim; ++i) {
51 6360 idx[i] = 0;
52 }
53 13040 idx[outer_dim] = outer;
54 13040 x[outer_dim] = brd[outer_dim].first + ((static_cast<double>(outer) + 0.5) * h[outer_dim]);
55
56
2/2
✓ Branch 0 taken 10203000 times.
✓ Branch 1 taken 13040 times.
10216040 for (int64_t cell = 0; cell < inner_cells; ++cell) {
57
2/2
✓ Branch 0 taken 22979200 times.
✓ Branch 1 taken 10203000 times.
33182200 for (std::size_t i = 0; i < outer_dim; ++i) {
58 22979200 x[i] = brd[i].first + ((static_cast<double>(idx[i]) + 0.5) * h[i]);
59 }
60
61 const double fx = f(x);
62
1/2
✓ Branch 0 taken 10203000 times.
✗ Branch 1 not taken.
10203000 if (!std::isfinite(fx)) {
63 return false;
64 }
65
66 10203000 local_sum += fx;
67
68
2/2
✓ Branch 0 taken 10378800 times.
✓ Branch 1 taken 13040 times.
10391840 for (std::size_t pos = 0; pos < outer_dim; ++pos) {
69
2/2
✓ Branch 0 taken 188840 times.
✓ Branch 1 taken 10189960 times.
10378800 if (++idx[pos] < num_splits) {
70 break;
71 }
72 188840 idx[pos] = 0;
73 }
74 }
75 return true;
76 }
77
78 } // namespace
79
80 92 bool SannikovIIntegralsRectangleMethodTBB::RunImpl() {
81 const auto &[func, borders, n] = GetInput();
82 92 const std::size_t dim = borders.size();
83
84 const auto &f = func;
85 const auto &brd = borders;
86 92 const int num_splits = n;
87
88 92 std::vector<double> h(dim);
89 double cell_v = 1.0;
90
91
2/2
✓ Branch 0 taken 160 times.
✓ Branch 1 taken 92 times.
252 for (std::size_t i = 0; i < dim; ++i) {
92
1/2
✓ Branch 0 taken 160 times.
✗ Branch 1 not taken.
160 h[i] = (brd[i].second - brd[i].first) / static_cast<double>(num_splits);
93
2/4
✓ Branch 0 taken 160 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 160 times.
160 if (!(h[i] > 0.0) || !std::isfinite(h[i])) {
94 return false;
95 }
96 160 cell_v *= h[i];
97 }
98
99 92 const std::size_t outer_dim = dim - 1;
100
101 92 int64_t inner_cells = 1;
102
2/2
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 92 times.
160 for (std::size_t i = 0; i < outer_dim; ++i) {
103 68 inner_cells *= num_splits;
104 }
105
106 92 bool error_flag = false;
107
108 184 double sum = tbb::parallel_reduce(tbb::blocked_range<int>(0, num_splits), 0.0,
109
1/2
✓ Branch 1 taken 92 times.
✗ Branch 2 not taken.
92 [&](const tbb::blocked_range<int> &range, double partial_sum) -> double {
110 13040 std::vector<int> idx(dim, 0);
111
1/4
✓ Branch 1 taken 13040 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
13040 std::vector<double> x(dim);
112
113
2/2
✓ Branch 0 taken 13040 times.
✓ Branch 1 taken 13040 times.
26080 for (int outer = range.begin(); outer < range.end(); ++outer) {
114
1/2
✓ Branch 0 taken 13040 times.
✗ Branch 1 not taken.
13040 if (error_flag) {
115 break;
116 }
117
118 13040 double local_sum = 0.0;
119
2/4
✓ Branch 1 taken 13040 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 13040 times.
13040 if (!ComputeSlice(f, brd, h, outer_dim, inner_cells, num_splits, outer, idx, x, local_sum)) {
120 error_flag = true;
121 break;
122 }
123 13040 partial_sum += local_sum;
124 }
125
126 13040 return partial_sum;
127 }, std::plus<>());
128
129
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 92 times.
92 if (error_flag) {
130 return false;
131 }
132
133 92 GetOutput() = sum * cell_v;
134 92 return std::isfinite(GetOutput());
135 }
136
137 92 bool SannikovIIntegralsRectangleMethodTBB::PostProcessingImpl() {
138 92 return std::isfinite(GetOutput());
139 }
140
141 } // namespace sannikov_i_integrals_rectangle_method
142