GCC Code Coverage Report


Directory: ./
File: tasks/galkin_d_multidim_integrals_rectangles/omp/src/ops_omp.cpp
Date: 2026-05-11 08:26:31
Exec Total Coverage
Lines: 35 35 100.0%
Functions: 5 5 100.0%
Branches: 23 40 57.5%

Line Branch Exec Source
1 #include "galkin_d_multidim_integrals_rectangles/omp/include/ops_omp.hpp"
2
3 #include <climits>
4 #include <cmath>
5 #include <cstddef>
6 #include <cstdint>
7 #include <limits>
8 #include <tuple>
9 #include <utility>
10 #include <vector>
11
12 #include "galkin_d_multidim_integrals_rectangles/common/include/common.hpp"
13 #include "util/include/util.hpp"
14
15 namespace galkin_d_multidim_integrals_rectangles {
16
17
1/2
✓ Branch 1 taken 92 times.
✗ Branch 2 not taken.
92 GalkinDMultidimIntegralsRectanglesOMP::GalkinDMultidimIntegralsRectanglesOMP(const InType &in) {
18 SetTypeOfTask(GetStaticTypeOfTask());
19 GetInput() = in;
20 92 GetOutput() = 0.0;
21 92 }
22
23
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 92 times.
92 bool GalkinDMultidimIntegralsRectanglesOMP::ValidationImpl() {
24 const auto &[func, borders, n] = GetInput();
25
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 92 times.
92 if (borders.empty()) {
26 return false;
27 }
28
29
2/2
✓ Branch 0 taken 160 times.
✓ Branch 1 taken 92 times.
252 for (const auto &[left_border, right_border] : borders) {
30
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 160 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 160 times.
160 if (!std::isfinite(left_border) || !std::isfinite(right_border)) {
31 return false;
32 }
33
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 160 times.
160 if (left_border >= right_border) {
34 return false;
35 }
36 }
37
38
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 92 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 92 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 92 times.
92 return func && (n > 0) && (GetOutput() == 0.0);
39 }
40
41 92 bool GalkinDMultidimIntegralsRectanglesOMP::PreProcessingImpl() {
42 92 GetOutput() = 0.0;
43 92 return true;
44 }
45
46 92 bool GalkinDMultidimIntegralsRectanglesOMP::RunImpl() {
47 const InType &input = GetInput();
48 const auto &func = std::get<0>(input);
49 const auto &borders = std::get<1>(input);
50 92 const int n = std::get<2>(input);
51 const std::size_t dim = borders.size();
52
53 92 std::vector<double> h(dim);
54 double cell_v = 1.0;
55
56
2/2
✓ Branch 0 taken 160 times.
✓ Branch 1 taken 92 times.
252 for (std::size_t i = 0; i < dim; ++i) {
57 160 const double left_border = borders[i].first;
58 160 const double right_border = borders[i].second;
59
60
1/2
✓ Branch 0 taken 160 times.
✗ Branch 1 not taken.
160 h[i] = (right_border - left_border) / static_cast<double>(n);
61
2/4
✓ Branch 0 taken 160 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 160 times.
160 if (!(h[i] > 0.0) || !std::isfinite(h[i])) {
62 return false;
63 }
64
65 160 cell_v *= h[i];
66 }
67
68 std::size_t total_cells = 1;
69
2/2
✓ Branch 0 taken 160 times.
✓ Branch 1 taken 92 times.
252 for (std::size_t i = 0; i < dim; ++i) {
70
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 160 times.
160 if (total_cells > (std::numeric_limits<std::size_t>::max() / static_cast<std::size_t>(n))) {
71 return false;
72 }
73 160 total_cells *= static_cast<std::size_t>(n);
74 }
75
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 92 times.
92 if (total_cells > static_cast<std::size_t>(LLONG_MAX)) {
76 return false;
77 }
78
79 double sum = 0.0;
80
1/2
✓ Branch 1 taken 92 times.
✗ Branch 2 not taken.
92 const int requested_threads = ppc::util::GetNumThreads();
81 92 const int positive_threads = (requested_threads > 0) ? requested_threads : 1;
82 const int max_threads_by_work = (total_cells > static_cast<std::size_t>(std::numeric_limits<int>::max()))
83
1/2
✓ Branch 0 taken 92 times.
✗ Branch 1 not taken.
92 ? std::numeric_limits<int>::max()
84 : static_cast<int>(total_cells);
85 const int num_threads =
86 92 std::cmp_greater(positive_threads, max_threads_by_work) ? max_threads_by_work : positive_threads;
87
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 92 times.
92 if (num_threads <= 0) {
88 return false;
89 }
90 const auto total_cells_i64 = static_cast<std::int64_t>(total_cells);
91
92 92 #pragma omp parallel for default(none) shared(borders, h, dim, func, n, total_cells_i64, num_threads) \
93 reduction(+ : sum) schedule(static) num_threads(num_threads)
94 for (std::int64_t linear_idx = 0; linear_idx < total_cells_i64; ++linear_idx) {
95 std::vector<double> x(dim);
96 auto tmp = static_cast<std::size_t>(linear_idx);
97
98 for (std::size_t i = 0; i < dim; ++i) {
99 const std::size_t idx_i = tmp % static_cast<std::size_t>(n);
100 tmp /= static_cast<std::size_t>(n);
101 x[i] = borders[i].first + ((static_cast<double>(idx_i) + 0.5) * h[i]);
102 }
103
104 sum += func(x);
105 }
106
107 92 GetOutput() = sum * cell_v;
108
109 92 return std::isfinite(GetOutput());
110 }
111
112 92 bool GalkinDMultidimIntegralsRectanglesOMP::PostProcessingImpl() {
113 92 return std::isfinite(GetOutput());
114 }
115
116 } // namespace galkin_d_multidim_integrals_rectangles
117