GCC Code Coverage Report


Directory: ./
File: tasks/redkina_a_integral_simpson/stl/src/ops_stl.cpp
Date: 2026-05-11 08:26:31
Exec Total Coverage
Lines: 86 87 98.9%
Functions: 11 11 100.0%
Branches: 55 84 65.5%

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 namespace {
15
16 160 std::vector<std::vector<double>> PrecomputeWeights(const std::vector<int> &n) {
17 const size_t dim = n.size();
18 160 std::vector<std::vector<double>> weights(dim);
19
2/2
✓ Branch 0 taken 304 times.
✓ Branch 1 taken 160 times.
464 for (size_t i = 0; i < dim; ++i) {
20
1/2
✓ Branch 1 taken 304 times.
✗ Branch 2 not taken.
304 const int ni = n[i];
21
1/2
✓ Branch 1 taken 304 times.
✗ Branch 2 not taken.
304 weights[i].resize(ni + 1);
22
2/2
✓ Branch 0 taken 19248 times.
✓ Branch 1 taken 304 times.
19552 for (int idx = 0; idx <= ni; ++idx) {
23
2/2
✓ Branch 0 taken 608 times.
✓ Branch 1 taken 18640 times.
19248 if (idx == 0 || idx == ni) {
24 608 weights[i][idx] = 1.0;
25
2/2
✓ Branch 0 taken 9472 times.
✓ Branch 1 taken 9168 times.
18640 } else if (idx % 2 == 1) {
26 9472 weights[i][idx] = 4.0;
27 } else {
28 9168 weights[i][idx] = 2.0;
29 }
30 }
31 }
32 160 return weights;
33 }
34
35 160 std::vector<size_t> ComputeStrides(const std::vector<int> &n) {
36 const size_t dim = n.size();
37 160 std::vector<size_t> strides(dim);
38
1/2
✓ Branch 0 taken 160 times.
✗ Branch 1 not taken.
160 if (dim == 0) {
39 return strides;
40 }
41 160 strides[dim - 1] = 1;
42
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 160 times.
304 for (size_t i = dim - 1; i > 0; --i) {
43 144 strides[i - 1] = strides[i] * static_cast<size_t>(n[i] + 1);
44 }
45 return strides;
46 }
47
48 608 double ComputeRangeSum(size_t start, size_t end, const std::vector<double> &a, const std::vector<double> &h,
49 const std::vector<std::vector<double>> &weights, const std::vector<size_t> &strides,
50 const std::function<double(const std::vector<double> &)> &func, size_t dim) {
51 608 std::vector<int> indices(dim);
52
1/4
✓ Branch 1 taken 608 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
608 std::vector<double> point(dim);
53 double local_sum = 0.0;
54
2/2
✓ Branch 0 taken 1850272 times.
✓ Branch 1 taken 608 times.
1850880 for (size_t idx = start; idx < end; ++idx) {
55 size_t remainder = idx;
56
2/2
✓ Branch 0 taken 4247856 times.
✓ Branch 1 taken 1850272 times.
6098128 for (size_t dim_idx = 0; dim_idx < dim; ++dim_idx) {
57 4247856 indices[dim_idx] = static_cast<int>(remainder / strides[dim_idx]);
58 4247856 remainder %= strides[dim_idx];
59 }
60 double w_prod = 1.0;
61
2/2
✓ Branch 0 taken 4247856 times.
✓ Branch 1 taken 1850272 times.
6098128 for (size_t dim_idx = 0; dim_idx < dim; ++dim_idx) {
62 4247856 const int i_idx = indices[dim_idx];
63 4247856 point[dim_idx] = a[dim_idx] + (static_cast<double>(i_idx) * h[dim_idx]);
64 4247856 w_prod *= weights[dim_idx][i_idx];
65 }
66 1850272 local_sum += w_prod * func(point);
67 }
68 608 return local_sum;
69 }
70
71 // Вспомогательная функция для создания асинхронных задач
72 160 void LaunchTasks(std::vector<std::future<double>> &futures, const std::vector<double> &a, const std::vector<double> &h,
73 const std::vector<std::vector<double>> &weights, const std::vector<size_t> &strides,
74 const std::function<double(const std::vector<double> &)> &func, size_t dim, size_t total_points) {
75 160 unsigned int num_threads = std::thread::hardware_concurrency();
76
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 160 times.
160 if (num_threads == 0) {
77 num_threads = 2;
78 }
79
80 160 const size_t block_size = total_points / num_threads;
81 160 const size_t rem = total_points % num_threads;
82
83 size_t start = 0;
84
1/2
✓ Branch 0 taken 608 times.
✗ Branch 1 not taken.
608 for (unsigned int thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
85
3/4
✓ Branch 0 taken 320 times.
✓ Branch 1 taken 288 times.
✓ Branch 2 taken 608 times.
✗ Branch 3 not taken.
928 const size_t end = std::min(start + block_size + (thread_idx < rem ? 1 : 0), total_points);
86
1/2
✓ Branch 0 taken 608 times.
✗ Branch 1 not taken.
608 if (start >= end) {
87 break;
88 }
89
90 608 futures.push_back(std::async(std::launch::async, [=, &a, &h, &weights, &strides, &func]() {
91 608 return ComputeRangeSum(start, end, a, h, weights, strides, func, dim);
92 }));
93
94 start = end;
95
2/2
✓ Branch 0 taken 448 times.
✓ Branch 1 taken 160 times.
608 if (start >= total_points) {
96 break;
97 }
98 }
99 160 }
100
101 160 double ParallelSum(const std::vector<double> &a, const std::vector<double> &h,
102 const std::vector<std::vector<double>> &weights, const std::vector<size_t> &strides,
103 size_t total_points, const std::function<double(const std::vector<double> &)> &func, size_t dim) {
104 160 std::vector<std::future<double>> futures;
105
1/2
✓ Branch 1 taken 160 times.
✗ Branch 2 not taken.
160 LaunchTasks(futures, a, h, weights, strides, func, dim, total_points);
106
107 double total = 0.0;
108
2/2
✓ Branch 0 taken 608 times.
✓ Branch 1 taken 160 times.
768 for (auto &f : futures) {
109
1/2
✓ Branch 1 taken 608 times.
✗ Branch 2 not taken.
608 total += f.get();
110 }
111 160 return total;
112 160 }
113
114 } // namespace
115
116
1/2
✓ Branch 1 taken 160 times.
✗ Branch 2 not taken.
160 RedkinaAIntegralSimpsonSTL::RedkinaAIntegralSimpsonSTL(const InType &in) {
117 SetTypeOfTask(GetStaticTypeOfTask());
118
1/2
✓ Branch 1 taken 160 times.
✗ Branch 2 not taken.
160 GetInput() = in;
119 160 }
120
121
1/2
✓ Branch 0 taken 160 times.
✗ Branch 1 not taken.
160 bool RedkinaAIntegralSimpsonSTL::ValidationImpl() {
122 const auto &in = GetInput();
123 size_t dim = in.a.size();
124
125
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) {
126 return false;
127 }
128
2/2
✓ Branch 0 taken 304 times.
✓ Branch 1 taken 160 times.
464 for (size_t i = 0; i < dim; ++i) {
129
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 304 times.
304 if (in.a[i] >= in.b[i]) {
130 return false;
131 }
132
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) {
133 return false;
134 }
135 }
136 160 return static_cast<bool>(in.func);
137 }
138
139 160 bool RedkinaAIntegralSimpsonSTL::PreProcessingImpl() {
140 const auto &in = GetInput();
141 160 func_ = in.func;
142 160 a_ = in.a;
143 160 b_ = in.b;
144 160 n_ = in.n;
145 160 result_ = 0.0;
146 160 return true;
147 }
148
149
1/2
✓ Branch 0 taken 160 times.
✗ Branch 1 not taken.
160 bool RedkinaAIntegralSimpsonSTL::RunImpl() {
150
1/2
✓ Branch 0 taken 160 times.
✗ Branch 1 not taken.
160 if (!func_) {
151 return false;
152 }
153 const size_t dim = a_.size();
154
1/2
✓ Branch 0 taken 160 times.
✗ Branch 1 not taken.
160 if (dim == 0) {
155 return false;
156 }
157
158 160 std::vector<double> h(dim);
159 double h_prod = 1.0;
160
2/2
✓ Branch 0 taken 304 times.
✓ Branch 1 taken 160 times.
464 for (size_t i = 0; i < dim; ++i) {
161 304 h[i] = (b_[i] - a_[i]) / static_cast<double>(n_[i]);
162 304 h_prod *= h[i];
163 }
164
165
1/2
✓ Branch 1 taken 160 times.
✗ Branch 2 not taken.
160 const auto weights = PrecomputeWeights(n_);
166
1/2
✓ Branch 1 taken 160 times.
✗ Branch 2 not taken.
160 const auto strides = ComputeStrides(n_);
167
1/2
✓ Branch 0 taken 160 times.
✗ Branch 1 not taken.
160 if (strides.empty()) {
168 return false;
169 }
170
171
1/2
✓ Branch 1 taken 160 times.
✗ Branch 2 not taken.
160 const size_t total_points = strides[0] * static_cast<size_t>(n_[0] + 1);
172
173
1/2
✓ Branch 1 taken 160 times.
✗ Branch 2 not taken.
160 const double sum = ParallelSum(a_, h, weights, strides, total_points, func_, dim);
174
175 double denominator = 1.0;
176
2/2
✓ Branch 0 taken 304 times.
✓ Branch 1 taken 160 times.
464 for (size_t i = 0; i < dim; ++i) {
177 304 denominator *= 3.0;
178 }
179
180 160 result_ = (h_prod / denominator) * sum;
181 160 return true;
182 160 }
183
184 160 bool RedkinaAIntegralSimpsonSTL::PostProcessingImpl() {
185 160 GetOutput() = result_;
186 160 return true;
187 }
188
189 } // namespace redkina_a_integral_simpson
190