GCC Code Coverage Report


Directory: ./
File: tasks/vinyaikina_e_multidimensional_integrals_simpson_method/tbb/src/ops_tbb.cpp
Date: 2026-04-02 17:12:27
Exec Total Coverage
Lines: 60 60 100.0%
Functions: 8 8 100.0%
Branches: 45 62 72.6%

Line Branch Exec Source
1 #include "vinyaikina_e_multidimensional_integrals_simpson_method/tbb/include/ops_tbb.hpp"
2
3 #include <tbb/blocked_range.h>
4 #include <tbb/parallel_reduce.h>
5
6 #include <cmath>
7 #include <cstdlib>
8 #include <cstring>
9 #include <functional>
10 #include <stack>
11 #include <utility>
12 #include <vector>
13
14 #include "util/include/util.hpp"
15 #include "vinyaikina_e_multidimensional_integrals_simpson_method/common/include/common.hpp"
16
17 namespace vinyaikina_e_multidimensional_integrals_simpson_method {
18 namespace {
19
20 192 double CustomRound(double value, double h) {
21 192 h *= 2;
22 192 int tmp = static_cast<int>(1 / h);
23 int decimal_places = 0;
24
3/4
✓ Branch 0 taken 540 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 348 times.
✓ Branch 3 taken 192 times.
540 while (tmp > 0 && tmp % 10 == 0) {
25 348 decimal_places++;
26 348 tmp /= 10;
27 }
28
29 double factor = std::pow(10.0, decimal_places);
30 192 return std::round(value * factor) / factor;
31 }
32
33 double Weight(int i, int steps_count) {
34 double weight = 2.0;
35
2/2
✓ Branch 0 taken 27404 times.
✓ Branch 1 taken 314 times.
27718 if (i == 0 || i == steps_count) {
36 weight = 1.0;
37
4/4
✓ Branch 0 taken 13777 times.
✓ Branch 1 taken 13627 times.
✓ Branch 2 taken 1184496 times.
✓ Branch 3 taken 1145304 times.
2357204 } else if (i % 2 != 0) {
38 weight = 4.0;
39 }
40 return weight;
41 }
42
43 160 double OuntNtIntegral(double left_border, double right_border, double simpson_factor,
44 const std::vector<std::pair<double, double>> &limits, const std::vector<double> &actual_step,
45 const std::function<double(const std::vector<double> &)> &function) {
46 std::stack<std::pair<std::vector<double>, double>> stack;
47 double res = 0.0;
48
49 160 int steps_count_0 = static_cast<int>(lround((right_border - left_border) / actual_step[0]));
50
51
2/2
✓ Branch 0 taken 27718 times.
✓ Branch 1 taken 160 times.
27878 for (int i0 = 0; i0 <= steps_count_0; ++i0) {
52
2/2
✓ Branch 0 taken 27404 times.
✓ Branch 1 taken 314 times.
27718 double x0 = left_border + (i0 * actual_step[0]);
53
54 27718 double weight_0 = Weight(i0, steps_count_0);
55
1/2
✓ Branch 1 taken 27718 times.
✗ Branch 2 not taken.
27718 stack.emplace(std::vector<double>{x0}, weight_0);
56
57
2/2
✓ Branch 0 taken 2435902 times.
✓ Branch 1 taken 27718 times.
2463620 while (!stack.empty()) {
58
1/2
✓ Branch 1 taken 2435902 times.
✗ Branch 2 not taken.
2435902 std::vector<double> point = stack.top().first;
59 2435902 double weight = stack.top().second;
60 stack.pop();
61
62
2/2
✓ Branch 0 taken 2396710 times.
✓ Branch 1 taken 39192 times.
2435902 if (point.size() == limits.size()) {
63
1/2
✓ Branch 0 taken 2396710 times.
✗ Branch 1 not taken.
2396710 res += function(point) * weight * simpson_factor;
64 continue;
65 }
66
67 size_t dim = point.size();
68 39192 double step = actual_step[dim];
69
70 39192 int steps_count = static_cast<int>(lround((limits[dim].second - limits[dim].first) / step));
71
72
2/2
✓ Branch 0 taken 2408184 times.
✓ Branch 1 taken 39192 times.
2447376 for (int i = 0; i <= steps_count; ++i) {
73
2/2
✓ Branch 0 taken 2329800 times.
✓ Branch 1 taken 78384 times.
2408184 double x = limits[dim].first + (i * step);
74
75 double dim_weight = Weight(i, steps_count);
76
77 point.push_back(x);
78
1/4
✓ Branch 1 taken 2408184 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
2408184 stack.emplace(point, weight * dim_weight);
79 point.pop_back();
80 }
81 }
82 }
83
84 160 return res;
85 }
86 }; // namespace
87
88
1/2
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
64 VinyaikinaEMultidimIntegrSimpsonTBB::VinyaikinaEMultidimIntegrSimpsonTBB(const InType &in) {
89 SetTypeOfTask(GetStaticTypeOfTask());
90 GetInput() = in;
91 64 }
92
93 64 bool VinyaikinaEMultidimIntegrSimpsonTBB::PreProcessingImpl() {
94 64 return true;
95 }
96
97
1/2
✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
64 bool VinyaikinaEMultidimIntegrSimpsonTBB::ValidationImpl() {
98 const auto &[h, limits, function] = GetInput();
99
3/6
✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 64 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 64 times.
64 return !limits.empty() && function && h <= 0.01;
100 }
101
102 64 bool VinyaikinaEMultidimIntegrSimpsonTBB::RunImpl() {
103 const auto &input = GetInput();
104 64 double h = std::get<0>(input);
105 const auto &limits = std::get<1>(input);
106 const auto &function = std::get<2>(input);
107
108 64 const int num_threads = ppc::util::GetNumThreads();
109
110 64 double delta = (limits[0].second - limits[0].first) / num_threads;
111
112 64 std::vector<double> actual_step(limits.size());
113 64 double simpson_factor = 1.0;
114
115
2/2
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 64 times.
176 for (size_t i = 0; i < limits.size(); i++) {
116 112 int quan_steps = static_cast<int>(lround((limits[i].second - limits[i].first) / h));
117
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 96 times.
112 if (quan_steps % 2 != 0) {
118 16 quan_steps++;
119 }
120 112 actual_step[i] = (limits[i].second - limits[i].first) / quan_steps;
121 112 simpson_factor *= actual_step[i] / 3.0;
122 }
123
124
1/2
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
64 tbb::blocked_range<int> range(0, num_threads);
125
126
1/2
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
224 I_res_ = tbb::parallel_reduce(range, 0.0, [&](const tbb::blocked_range<int> &r, double local_res) {
127
2/2
✓ Branch 0 taken 160 times.
✓ Branch 1 taken 160 times.
320 for (int i = r.begin(); i != r.end(); ++i) {
128
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 64 times.
160 double left_border = limits[0].first;
129 160 double right_border = limits[0].second;
130
131
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 64 times.
160 if (i != 0) {
132 96 left_border = CustomRound(limits[0].first + (delta * i), actual_step[0]);
133 }
134
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 64 times.
160 if (i != num_threads - 1) {
135 96 right_border = CustomRound(limits[0].second - (delta * (num_threads - i - 1)), actual_step[0]);
136 }
137
138 160 local_res += OuntNtIntegral(left_border, right_border, simpson_factor, limits, actual_step, function);
139 }
140 160 return local_res;
141
1/4
✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
64 }, std::plus<>());
142
143 64 return true;
144 }
145
146 64 bool VinyaikinaEMultidimIntegrSimpsonTBB::PostProcessingImpl() {
147 64 GetOutput() = I_res_;
148 64 return true;
149 }
150 } // namespace vinyaikina_e_multidimensional_integrals_simpson_method
151