GCC Code Coverage Report


Directory: ./
File: tasks/redkina_a_integral_simpson/omp/src/ops_omp.cpp
Date: 2026-05-11 08:26:31
Exec Total Coverage
Lines: 56 57 98.2%
Functions: 7 7 100.0%
Branches: 34 52 65.4%

Line Branch Exec Source
1 #include "redkina_a_integral_simpson/omp/include/ops_omp.hpp"
2
3 #include <omp.h>
4
5 #include <cmath>
6 #include <cstddef>
7 #include <functional>
8 #include <vector>
9
10 #include "redkina_a_integral_simpson/common/include/common.hpp"
11
12 namespace redkina_a_integral_simpson {
13 namespace {
14
15 80 std::vector<std::vector<double>> PrecomputeWeights(const std::vector<int> &n) {
16 const size_t dim = n.size();
17 80 std::vector<std::vector<double>> weights(dim);
18
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 80 times.
232 for (size_t i = 0; i < dim; ++i) {
19
1/2
✓ Branch 1 taken 152 times.
✗ Branch 2 not taken.
152 const int ni = n[i];
20
1/2
✓ Branch 1 taken 152 times.
✗ Branch 2 not taken.
152 weights[i].resize(ni + 1);
21
2/2
✓ Branch 0 taken 9624 times.
✓ Branch 1 taken 152 times.
9776 for (int idx = 0; idx <= ni; ++idx) {
22
2/2
✓ Branch 0 taken 304 times.
✓ Branch 1 taken 9320 times.
9624 if (idx == 0 || idx == ni) {
23 304 weights[i][idx] = 1.0;
24
2/2
✓ Branch 0 taken 4736 times.
✓ Branch 1 taken 4584 times.
9320 } else if (idx % 2 == 1) {
25 4736 weights[i][idx] = 4.0;
26 } else {
27 4584 weights[i][idx] = 2.0;
28 }
29 }
30 }
31 80 return weights;
32 }
33
34 80 std::vector<size_t> ComputeStrides(const std::vector<int> &n) {
35 const size_t dim = n.size();
36 80 std::vector<size_t> strides(dim);
37
1/2
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
80 if (dim == 0) {
38 return strides;
39 }
40 80 strides[dim - 1] = 1;
41
2/2
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 80 times.
152 for (size_t i = dim - 1; i > 0; --i) {
42 72 strides[i - 1] = strides[i] * static_cast<size_t>(n[i] + 1);
43 }
44 return strides;
45 }
46
47 } // namespace
48
49
1/2
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
80 RedkinaAIntegralSimpsonOMP::RedkinaAIntegralSimpsonOMP(const InType &in) {
50 SetTypeOfTask(GetStaticTypeOfTask());
51
1/2
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
80 GetInput() = in;
52 80 }
53
54
1/2
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
80 bool RedkinaAIntegralSimpsonOMP::ValidationImpl() {
55 const auto &in = GetInput();
56 size_t dim = in.a.size();
57
58
3/6
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 80 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 80 times.
80 if (dim == 0 || in.b.size() != dim || in.n.size() != dim) {
59 return false;
60 }
61
62
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 80 times.
232 for (size_t i = 0; i < dim; ++i) {
63
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 152 times.
152 if (in.a[i] >= in.b[i]) {
64 return false;
65 }
66
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 152 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 152 times.
152 if (in.n[i] <= 0 || in.n[i] % 2 != 0) {
67 return false;
68 }
69 }
70 80 return static_cast<bool>(in.func);
71 }
72
73 80 bool RedkinaAIntegralSimpsonOMP::PreProcessingImpl() {
74 const auto &in = GetInput();
75 80 func_ = in.func;
76 80 a_ = in.a;
77 80 b_ = in.b;
78 80 n_ = in.n;
79 80 result_ = 0.0;
80 80 return true;
81 }
82
83
1/2
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
80 bool RedkinaAIntegralSimpsonOMP::RunImpl() {
84
1/2
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
80 if (!func_) {
85 return false;
86 }
87 const size_t dim = a_.size();
88
1/2
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
80 if (dim == 0) {
89 return false;
90 }
91
92 80 std::vector<double> h(dim);
93 double h_prod = 1.0;
94
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 80 times.
232 for (size_t i = 0; i < dim; ++i) {
95 152 h[i] = (b_[i] - a_[i]) / static_cast<double>(n_[i]);
96 152 h_prod *= h[i];
97 }
98
99
1/2
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
80 const auto weights = PrecomputeWeights(n_);
100
1/2
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
80 const auto strides = ComputeStrides(n_);
101
1/2
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
80 if (strides.empty()) {
102 return false;
103 }
104
105 80 const int total_nodes = static_cast<int>(strides[0] * static_cast<size_t>(n_[0] + 1));
106
107 double total_sum = 0.0;
108
109 80 const std::vector<double> &a_local = a_;
110 const std::vector<double> &h_local = h;
111 const auto &weights_local = weights;
112 const auto &strides_local = strides;
113 80 const auto &func_local = func_;
114
115 80 #pragma omp parallel default(none) \
116 shared(total_nodes, a_local, h_local, weights_local, strides_local, func_local, dim) reduction(+ : total_sum)
117 {
118 std::vector<int> indices(dim);
119 std::vector<double> point(dim);
120
121 #pragma omp for schedule(static)
122 for (int idx = 0; idx < total_nodes; ++idx) {
123 auto remainder = static_cast<size_t>(idx);
124 for (size_t dim_idx = 0; dim_idx < dim; ++dim_idx) {
125 indices[dim_idx] = static_cast<int>(remainder / strides_local[dim_idx]);
126 remainder %= strides_local[dim_idx];
127 }
128
129 double w_prod = 1.0;
130 for (size_t dim_idx = 0; dim_idx < dim; ++dim_idx) {
131 const int i_idx = indices[dim_idx];
132 point[dim_idx] = a_local[dim_idx] + (static_cast<double>(i_idx) * h_local[dim_idx]);
133 w_prod *= weights_local[dim_idx][i_idx];
134 }
135
136 total_sum += w_prod * func_local(point);
137 }
138 }
139
140 double denominator = 1.0;
141
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 80 times.
232 for (size_t i = 0; i < dim; ++i) {
142 152 denominator *= 3.0;
143 }
144
145 80 result_ = (h_prod / denominator) * total_sum;
146 80 return true;
147 80 }
148
149 80 bool RedkinaAIntegralSimpsonOMP::PostProcessingImpl() {
150 80 GetOutput() = result_;
151 80 return true;
152 }
153
154 } // namespace redkina_a_integral_simpson
155