GCC Code Coverage Report


Directory: ./
File: tasks/galkin_d_multidim_integrals_rectangles/stl/src/ops_stl.cpp
Date: 2026-06-04 20:25:32
Exec Total Coverage
Lines: 59 59 100.0%
Functions: 7 7 100.0%
Branches: 44 74 59.5%

Line Branch Exec Source
1 #include "galkin_d_multidim_integrals_rectangles/stl/include/ops_stl.hpp"
2
3 #include <algorithm>
4 #include <climits>
5 #include <cmath>
6 #include <cstddef>
7 #include <cstdint>
8 #include <limits>
9 #include <thread>
10 #include <utility>
11 #include <vector>
12
13 #include "galkin_d_multidim_integrals_rectangles/common/include/common.hpp"
14 #include "util/include/util.hpp"
15
16 namespace {
17
18 using Borders = std::vector<std::pair<double, double>>;
19
20 184 bool ComputeGridParams(const Borders &borders, int n, std::vector<double> &h, double &cell_v) {
21
2/2
✓ Branch 0 taken 320 times.
✓ Branch 1 taken 184 times.
504 for (std::size_t i = 0; i < borders.size(); ++i) {
22
1/2
✓ Branch 0 taken 320 times.
✗ Branch 1 not taken.
320 h[i] = (borders[i].second - borders[i].first) / static_cast<double>(n);
23
2/4
✓ Branch 0 taken 320 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 320 times.
✗ Branch 3 not taken.
320 if (!(h[i] > 0.0) || !std::isfinite(h[i])) {
24 return false;
25 }
26 320 cell_v *= h[i];
27 }
28 return true;
29 }
30
31 bool ComputeTotalCells(std::size_t dim, int n, std::int64_t &out) {
32 std::size_t total = 1;
33
2/2
✓ Branch 0 taken 320 times.
✓ Branch 1 taken 184 times.
504 for (std::size_t i = 0; i < dim; ++i) {
34
1/2
✓ Branch 0 taken 320 times.
✗ Branch 1 not taken.
320 if (total > (std::numeric_limits<std::size_t>::max() / static_cast<std::size_t>(n))) {
35 return false;
36 }
37 320 total *= static_cast<std::size_t>(n);
38 }
39
1/2
✓ Branch 0 taken 184 times.
✗ Branch 1 not taken.
184 if (total > static_cast<std::size_t>(LLONG_MAX)) {
40 return false;
41 }
42 out = static_cast<std::int64_t>(total);
43 return true;
44 }
45
46 } // namespace
47
48 namespace galkin_d_multidim_integrals_rectangles {
49
50
1/2
✓ Branch 1 taken 184 times.
✗ Branch 2 not taken.
184 GalkinDMultidimIntegralsRectanglesSTL::GalkinDMultidimIntegralsRectanglesSTL(const InType &in) {
51 SetTypeOfTask(GetStaticTypeOfTask());
52 GetInput() = in;
53 184 GetOutput() = 0.0;
54 184 }
55
56
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 184 times.
184 bool GalkinDMultidimIntegralsRectanglesSTL::ValidationImpl() {
57 const auto &[func, borders, n] = GetInput();
58
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 184 times.
184 if (borders.empty()) {
59 return false;
60 }
61
62
2/2
✓ Branch 0 taken 320 times.
✓ Branch 1 taken 184 times.
504 for (const auto &[left_border, right_border] : borders) {
63
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 320 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 320 times.
320 if (!std::isfinite(left_border) || !std::isfinite(right_border)) {
64 return false;
65 }
66
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 320 times.
320 if (left_border >= right_border) {
67 return false;
68 }
69 }
70
71
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 184 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 184 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 184 times.
184 return func && (n > 0) && (GetOutput() == 0.0);
72 }
73
74 184 bool GalkinDMultidimIntegralsRectanglesSTL::PreProcessingImpl() {
75 184 GetOutput() = 0.0;
76 184 return true;
77 }
78
79 184 bool GalkinDMultidimIntegralsRectanglesSTL::RunImpl() {
80 const auto &[func, borders, n] = GetInput();
81 184 const std::size_t dim = borders.size();
82
83 184 std::vector<double> h(dim);
84 184 double cell_v = 1.0;
85
1/2
✓ Branch 1 taken 184 times.
✗ Branch 2 not taken.
184 if (!ComputeGridParams(borders, n, h, cell_v)) {
86 return false;
87 }
88
89 std::int64_t total_i64 = 0;
90 184 if (!ComputeTotalCells(dim, n, total_i64)) {
91 return false;
92 }
93
1/2
✓ Branch 1 taken 184 times.
✗ Branch 2 not taken.
184 const int requested = ppc::util::GetNumThreads();
94 184 const int positive = (requested > 0) ? requested : 1;
95
1/2
✓ Branch 1 taken 184 times.
✗ Branch 2 not taken.
184 const int cap = (total_i64 > static_cast<std::int64_t>(std::numeric_limits<int>::max()))
96
1/2
✓ Branch 0 taken 184 times.
✗ Branch 1 not taken.
184 ? std::numeric_limits<int>::max()
97 : static_cast<int>(total_i64);
98 const int num_threads = std::min(positive, cap);
99
100
1/4
✓ Branch 1 taken 184 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
184 std::vector<double> partial_sums(num_threads, 0.0);
101 184 const std::int64_t chunk = total_i64 / num_threads;
102 184 const std::int64_t remainder = total_i64 % num_threads;
103
104 460 auto worker = [&](int tid) {
105 const std::int64_t begin =
106
2/2
✓ Branch 0 taken 212 times.
✓ Branch 1 taken 248 times.
460 (static_cast<std::int64_t>(tid) * chunk) + std::min(static_cast<std::int64_t>(tid), remainder);
107
2/2
✓ Branch 0 taken 396 times.
✓ Branch 1 taken 64 times.
460 const std::int64_t end = begin + chunk + (static_cast<std::int64_t>(tid) < remainder ? 1 : 0);
108 460 std::vector<double> x(dim);
109 double local_sum = 0.0;
110
2/2
✓ Branch 0 taken 20406000 times.
✓ Branch 1 taken 460 times.
20406460 for (std::int64_t linear_idx = begin; linear_idx < end; ++linear_idx) {
111 20406000 auto tmp = static_cast<std::size_t>(linear_idx);
112
2/2
✓ Branch 0 taken 66364400 times.
✓ Branch 1 taken 20406000 times.
86770400 for (std::size_t i = 0; i < dim; ++i) {
113 66364400 const std::size_t idx_i = tmp % static_cast<std::size_t>(n);
114 66364400 tmp /= static_cast<std::size_t>(n);
115 66364400 x[i] = borders[i].first + ((static_cast<double>(idx_i) + 0.5) * h[i]);
116 }
117
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20406000 times.
40812000 local_sum += func(x);
118 }
119
1/2
✓ Branch 0 taken 460 times.
✗ Branch 1 not taken.
460 partial_sums[tid] = local_sum;
120 460 };
121
122
1/4
✓ Branch 1 taken 184 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
184 std::vector<std::thread> threads(num_threads - 1);
123
2/2
✓ Branch 0 taken 276 times.
✓ Branch 1 taken 184 times.
460 for (int ti = 1; ti < num_threads; ++ti) {
124
2/4
✓ Branch 1 taken 276 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 276 times.
276 threads[ti - 1] = std::thread(worker, ti);
125 }
126
1/2
✓ Branch 1 taken 184 times.
✗ Branch 2 not taken.
184 worker(0);
127
128 184 double sum = partial_sums[0];
129
2/2
✓ Branch 0 taken 276 times.
✓ Branch 1 taken 184 times.
460 for (int ti = 1; ti < num_threads; ++ti) {
130
1/2
✓ Branch 1 taken 276 times.
✗ Branch 2 not taken.
276 threads[ti - 1].join();
131 276 sum += partial_sums[ti];
132 }
133
134 184 GetOutput() = sum * cell_v;
135 return std::isfinite(GetOutput());
136 184 }
137
138 184 bool GalkinDMultidimIntegralsRectanglesSTL::PostProcessingImpl() {
139 184 return std::isfinite(GetOutput());
140 }
141
142 } // namespace galkin_d_multidim_integrals_rectangles
143