GCC Code Coverage Report


Directory: ./
File: tasks/redkina_a_integral_simpson/stl/src/ops_stl.cpp
Date: 2026-04-02 17:12:27
Exec Total Coverage
Lines: 71 71 100.0%
Functions: 8 8 100.0%
Branches: 58 90 64.4%

Line Branch Exec Source
1 #include "redkina_a_integral_simpson/stl/include/ops_stl.hpp"
2
3 #include <algorithm>
4 #include <cmath>
5 #include <cstddef>
6 #include <functional>
7 #include <future>
8 #include <thread>
9 #include <vector>
10
11 #include "redkina_a_integral_simpson/common/include/common.hpp"
12
13 namespace redkina_a_integral_simpson {
14
15 namespace {
16
17
1/2
✓ Branch 0 taken 1850272 times.
✗ Branch 1 not taken.
1850272 double ComputeNodeContribution(size_t linear_idx, const std::vector<double> &a, const std::vector<double> &h,
18 const std::vector<int> &n, const std::vector<size_t> &strides,
19 const std::function<double(const std::vector<double> &)> &func) {
20
1/2
✓ Branch 0 taken 1850272 times.
✗ Branch 1 not taken.
1850272 if (!func) {
21 return 0.0;
22 }
23
24 size_t dim = a.size();
25 1850272 std::vector<double> point(dim);
26 size_t remainder = linear_idx;
27
1/4
✓ Branch 1 taken 1850272 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1850272 std::vector<int> indices(dim);
28
29
2/2
✓ Branch 0 taken 4247856 times.
✓ Branch 1 taken 1850272 times.
6098128 for (size_t i = 0; i < dim; ++i) {
30 4247856 indices[i] = static_cast<int>(remainder / strides[i]);
31 4247856 remainder %= strides[i];
32 }
33
34 double w_prod = 1.0;
35
2/2
✓ Branch 0 taken 4247856 times.
✓ Branch 1 taken 1850272 times.
6098128 for (size_t i = 0; i < dim; ++i) {
36
2/2
✓ Branch 0 taken 4193536 times.
✓ Branch 1 taken 54320 times.
4247856 int idx = indices[i];
37 4247856 point[i] = a[i] + (static_cast<double>(idx) * h[i]);
38
39 int w = 0;
40
4/4
✓ Branch 0 taken 4193536 times.
✓ Branch 1 taken 54320 times.
✓ Branch 2 taken 4139216 times.
✓ Branch 3 taken 54320 times.
4247856 if (idx == 0 || idx == n[i]) {
41 w = 1;
42
2/2
✓ Branch 0 taken 2042448 times.
✓ Branch 1 taken 2096768 times.
4139216 } else if (idx % 2 == 1) {
43 w = 4;
44 } else {
45 w = 2;
46 }
47 4247856 w_prod *= static_cast<double>(w);
48 }
49
1/2
✓ Branch 0 taken 1850272 times.
✗ Branch 1 not taken.
1850272 return w_prod * func(point);
50 }
51
52 160 double ParallelSum(const std::vector<double> &a, const std::vector<double> &h, const std::vector<int> &n,
53 const std::vector<size_t> &strides, const std::function<double(const std::vector<double> &)> &func,
54 size_t total_points) {
55 160 unsigned int num_threads = std::thread::hardware_concurrency();
56
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 160 times.
160 if (num_threads == 0) {
57 num_threads = 2;
58 }
59
60 160 size_t block_size = total_points / num_threads;
61 160 size_t remainder = total_points % num_threads;
62
63 160 std::vector<std::future<double>> futures;
64 size_t start = 0;
65
66
1/2
✓ Branch 0 taken 608 times.
✗ Branch 1 not taken.
608 for (unsigned int thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
67
3/4
✓ Branch 0 taken 320 times.
✓ Branch 1 taken 288 times.
✓ Branch 2 taken 608 times.
✗ Branch 3 not taken.
928 size_t end = std::min(start + block_size + (thread_idx < remainder ? 1 : 0), total_points);
68
1/2
✓ Branch 0 taken 608 times.
✗ Branch 1 not taken.
608 if (start >= end) {
69 break;
70 }
71
72
1/2
✓ Branch 1 taken 608 times.
✗ Branch 2 not taken.
608 futures.push_back(std::async(std::launch::async, [=, &a, &h, &n, &strides, &func]() {
73 double local_sum = 0.0;
74
2/2
✓ Branch 0 taken 1850272 times.
✓ Branch 1 taken 608 times.
1850880 for (size_t idx = start; idx < end; ++idx) {
75 1850272 local_sum += ComputeNodeContribution(idx, a, h, n, strides, func);
76 }
77 608 return local_sum;
78 }));
79
80 start = end;
81
2/2
✓ Branch 0 taken 448 times.
✓ Branch 1 taken 160 times.
608 if (start >= total_points) {
82 break;
83 }
84 }
85
86 double total = 0.0;
87
2/2
✓ Branch 0 taken 608 times.
✓ Branch 1 taken 160 times.
768 for (auto &f : futures) {
88
1/2
✓ Branch 1 taken 608 times.
✗ Branch 2 not taken.
608 total += f.get();
89 }
90 160 return total;
91 160 }
92
93 } // namespace
94
95
1/2
✓ Branch 1 taken 160 times.
✗ Branch 2 not taken.
160 RedkinaAIntegralSimpsonSTL::RedkinaAIntegralSimpsonSTL(const InType &in) {
96 SetTypeOfTask(GetStaticTypeOfTask());
97
1/2
✓ Branch 1 taken 160 times.
✗ Branch 2 not taken.
160 GetInput() = in;
98 160 }
99
100
1/2
✓ Branch 0 taken 160 times.
✗ Branch 1 not taken.
160 bool RedkinaAIntegralSimpsonSTL::ValidationImpl() {
101 const auto &in = GetInput();
102 size_t dim = in.a.size();
103
104
3/6
✓ Branch 0 taken 160 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 160 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 160 times.
160 if (dim == 0 || in.b.size() != dim || in.n.size() != dim) {
105 return false;
106 }
107
108
2/2
✓ Branch 0 taken 304 times.
✓ Branch 1 taken 160 times.
464 for (size_t i = 0; i < dim; ++i) {
109
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 304 times.
304 if (in.a[i] >= in.b[i]) {
110 return false;
111 }
112
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 304 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 304 times.
304 if (in.n[i] <= 0 || in.n[i] % 2 != 0) {
113 return false;
114 }
115 }
116
117 160 return static_cast<bool>(in.func);
118 }
119
120 160 bool RedkinaAIntegralSimpsonSTL::PreProcessingImpl() {
121 const auto &in = GetInput();
122 160 func_ = in.func;
123 160 a_ = in.a;
124 160 b_ = in.b;
125 160 n_ = in.n;
126 160 result_ = 0.0;
127 160 return true;
128 }
129
130
1/2
✓ Branch 0 taken 160 times.
✗ Branch 1 not taken.
160 bool RedkinaAIntegralSimpsonSTL::RunImpl() {
131
1/2
✓ Branch 0 taken 160 times.
✗ Branch 1 not taken.
160 if (!func_) {
132 return false;
133 }
134 size_t dim = a_.size();
135
1/2
✓ Branch 0 taken 160 times.
✗ Branch 1 not taken.
160 if (dim == 0) {
136 return false;
137 }
138
139 160 std::vector<double> h(dim);
140
2/2
✓ Branch 0 taken 304 times.
✓ Branch 1 taken 160 times.
464 for (size_t i = 0; i < dim; ++i) {
141 304 h[i] = (b_[i] - a_[i]) / static_cast<double>(n_[i]);
142 }
143
144 double h_prod = 1.0;
145
2/2
✓ Branch 0 taken 304 times.
✓ Branch 1 taken 160 times.
464 for (size_t i = 0; i < dim; ++i) {
146 304 h_prod *= h[i];
147 }
148
149
1/4
✓ Branch 1 taken 160 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
160 std::vector<int> dim_sizes(dim);
150 size_t total_points = 1;
151
2/2
✓ Branch 0 taken 304 times.
✓ Branch 1 taken 160 times.
464 for (size_t i = 0; i < dim; ++i) {
152 304 dim_sizes[i] = n_[i] + 1;
153 304 total_points *= static_cast<size_t>(dim_sizes[i]);
154 }
155
156
1/4
✓ Branch 1 taken 160 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
160 std::vector<size_t> strides(dim);
157 160 strides[dim - 1] = 1;
158
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 160 times.
304 for (size_t i = dim - 1; i > 0; --i) {
159 144 strides[i - 1] = strides[i] * static_cast<size_t>(dim_sizes[i]);
160 }
161
162
1/2
✓ Branch 1 taken 160 times.
✗ Branch 2 not taken.
160 double sum = ParallelSum(a_, h, n_, strides, func_, total_points);
163
164 double denominator = 1.0;
165
2/2
✓ Branch 0 taken 304 times.
✓ Branch 1 taken 160 times.
464 for (size_t i = 0; i < dim; ++i) {
166 304 denominator *= 3.0;
167 }
168
169
1/2
✓ Branch 0 taken 160 times.
✗ Branch 1 not taken.
160 result_ = (h_prod / denominator) * sum;
170 return true;
171 }
172
173 160 bool RedkinaAIntegralSimpsonSTL::PostProcessingImpl() {
174 160 GetOutput() = result_;
175 160 return true;
176 }
177
178 } // namespace redkina_a_integral_simpson
179