GCC Code Coverage Report


Directory: ./
File: tasks/kutergin_a_multidim_trapezoid/stl/src/ops_stl.cpp
Date: 2026-06-04 20:25:32
Exec Total Coverage
Lines: 50 53 94.3%
Functions: 7 7 100.0%
Branches: 34 50 68.0%

Line Branch Exec Source
1 #include "kutergin_a_multidim_trapezoid/stl/include/ops_stl.hpp"
2
3 #include <algorithm>
4 #include <cmath>
5 #include <cstddef>
6 #include <numeric>
7 #include <thread>
8 #include <vector>
9
10 #include "kutergin_a_multidim_trapezoid/common/include/common.hpp"
11
12 namespace kutergin_a_multidim_trapezoid {
13
14
1/2
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
96 KuterginAMultidimTrapezoidSTL::KuterginAMultidimTrapezoidSTL(const InType &in) {
15 this->SetTypeOfTask(GetStaticTypeOfTask());
16 this->GetInput() = in;
17 96 this->GetOutput() = 0.0;
18 96 }
19
20
1/2
✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
96 bool KuterginAMultidimTrapezoidSTL::ValidationImpl() {
21 const auto &input = GetInput();
22
3/6
✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 96 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 96 times.
96 return std::get<0>(input) != nullptr && std::get<2>(input) > 0 && !std::get<1>(input).empty();
23 }
24
25 96 bool KuterginAMultidimTrapezoidSTL::PreProcessingImpl() {
26 96 res_ = 0.0;
27 96 return true;
28 }
29
30 96 bool KuterginAMultidimTrapezoidSTL::RunImpl() {
31 const auto &input = GetInput();
32 const auto &borders = std::get<1>(input);
33 96 const int n = std::get<2>(input);
34 const size_t dims = borders.size();
35
36 size_t total_nodes = 1;
37 96 std::vector<double> h(dims);
38 double cell_volume = 1.0;
39
40
2/2
✓ Branch 0 taken 160 times.
✓ Branch 1 taken 96 times.
256 for (size_t i = 0; i < dims; ++i) {
41 160 total_nodes *= (static_cast<size_t>(n) + 1);
42 160 h[i] = (borders[i].second - borders[i].first) / n;
43 160 cell_volume *= h[i];
44 }
45
46 96 unsigned int num_threads = std::thread::hardware_concurrency();
47
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96 times.
96 if (num_threads == 0) {
48 num_threads = 2;
49 }
50
51
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96 times.
96 if (total_nodes < static_cast<size_t>(num_threads)) {
52 num_threads = static_cast<unsigned int>(total_nodes);
53 }
54
55 96 std::vector<std::thread> threads;
56
1/2
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
96 std::vector<double> partial_sums(num_threads, 0.0);
57
58 96 const size_t chunk = total_nodes / num_threads;
59 96 const size_t remainder = total_nodes % num_threads;
60
61
2/2
✓ Branch 0 taken 384 times.
✓ Branch 1 taken 96 times.
480 for (unsigned int i = 0; i < num_threads; ++i) {
62
2/2
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 128 times.
384 const size_t start = (i * chunk) + std::min(static_cast<size_t>(i), remainder);
63
2/2
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 128 times.
384 const size_t end = start + chunk + (static_cast<size_t>(i) < remainder ? 1 : 0);
64
65
1/2
✓ Branch 0 taken 384 times.
✗ Branch 1 not taken.
384 if (start < end) {
66
1/4
✓ Branch 1 taken 384 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
384 threads.emplace_back([this, start, end, &h, &partial_sums, i]() noexcept {
67 try {
68
1/2
✓ Branch 1 taken 384 times.
✗ Branch 2 not taken.
384 partial_sums[i] = CalculateChunkSum(start, end, h);
69 } catch (...) {
70 (void)0;
71 }
72 384 });
73 }
74 }
75
76
2/2
✓ Branch 0 taken 384 times.
✓ Branch 1 taken 96 times.
480 for (auto &t : threads) {
77
1/2
✓ Branch 0 taken 384 times.
✗ Branch 1 not taken.
384 if (t.joinable()) {
78
1/2
✓ Branch 1 taken 384 times.
✗ Branch 2 not taken.
384 t.join();
79 }
80 }
81
82 const double total_weight_sum = std::accumulate(partial_sums.begin(), partial_sums.end(), 0.0);
83
1/2
✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
96 res_ = total_weight_sum * cell_volume;
84
85 96 return std::isfinite(res_);
86 96 }
87
88 96 bool KuterginAMultidimTrapezoidSTL::PostProcessingImpl() {
89 96 GetOutput() = res_;
90 96 return true;
91 }
92
93 384 double KuterginAMultidimTrapezoidSTL::CalculateChunkSum(size_t start_idx, size_t end_idx,
94 const std::vector<double> &h) {
95 const auto &input = GetInput();
96 const auto &func = std::get<0>(input);
97 const auto &borders = std::get<1>(input);
98 384 const int n = std::get<2>(input);
99 const size_t dims = borders.size();
100
101 384 std::vector<double> coords(dims);
102 double chunk_sum = 0.0;
103
104
2/2
✓ Branch 0 taken 2872096 times.
✓ Branch 1 taken 384 times.
2872480 for (size_t i = start_idx; i < end_idx; ++i) {
105 double weight = 1.0;
106 size_t temp_idx = i;
107
108
2/2
✓ Branch 0 taken 7551840 times.
✓ Branch 1 taken 2872096 times.
10423936 for (size_t dim_idx = 0; dim_idx < dims; ++dim_idx) {
109 7551840 const int coord_idx = static_cast<int>(temp_idx % (static_cast<size_t>(n) + 1));
110
2/2
✓ Branch 0 taken 206080 times.
✓ Branch 1 taken 7345760 times.
7551840 temp_idx /= (static_cast<size_t>(n) + 1);
111
112
2/2
✓ Branch 0 taken 206080 times.
✓ Branch 1 taken 7345760 times.
7551840 coords[dim_idx] = borders[dim_idx].first + (static_cast<double>(coord_idx) * h[dim_idx]);
113
114
2/2
✓ Branch 0 taken 206080 times.
✓ Branch 1 taken 7345760 times.
7551840 if (coord_idx == 0 || coord_idx == n) {
115 206080 weight *= 0.5;
116 }
117 }
118 2872096 chunk_sum += weight * func(coords);
119 }
120 384 return chunk_sum;
121 }
122
123 } // namespace kutergin_a_multidim_trapezoid
124