GCC Code Coverage Report


Directory: ./
File: tasks/kichanova_k_lin_system_by_conjug_grad/omp/src/ops_omp.cpp
Date: 2026-04-02 17:12:27
Exec Total Coverage
Lines: 37 38 97.4%
Functions: 5 5 100.0%
Branches: 15 32 46.9%

Line Branch Exec Source
1 #include "kichanova_k_lin_system_by_conjug_grad/omp/include/ops_omp.hpp"
2
3 #include <cmath>
4 #include <cstddef>
5 #include <vector>
6
7 #include "kichanova_k_lin_system_by_conjug_grad/common/include/common.hpp"
8
9 namespace kichanova_k_lin_system_by_conjug_grad {
10
11 namespace {
12 double ComputeDotProductOMP(const std::vector<double> &a, const std::vector<double> &b, int n) {
13 double result = 0.0;
14 480 #pragma omp parallel for default(none) shared(a, b, n) reduction(+ : result) schedule(static)
15 for (int i = 0; i < n; ++i) {
16 result += a[i] * b[i];
17 }
18 return result;
19 }
20
21 void ComputeMatrixVectorProductOMP(const std::vector<double> &a, const std::vector<double> &v,
22 std::vector<double> &result, int n) {
23 const auto stride = static_cast<size_t>(n);
24
1/2
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
216 #pragma omp parallel for default(none) shared(a, v, result, n, stride) schedule(static)
25 for (int i = 0; i < n; ++i) {
26 double sum = 0.0;
27 const double *a_row = &a[static_cast<size_t>(i) * stride];
28 for (int j = 0; j < n; ++j) {
29 sum += a_row[j] * v[j];
30 }
31 result[i] = sum;
32 }
33 }
34
35 void UpdateSolutionOMP(std::vector<double> &x, const std::vector<double> &p, double alpha, int n) {
36 216 #pragma omp parallel for default(none) shared(x, p, alpha, n) schedule(static)
37 for (int i = 0; i < n; ++i) {
38 x[i] += alpha * p[i];
39 }
40 }
41
42 void UpdateResidualOMP(std::vector<double> &r, const std::vector<double> &ap, double alpha, int n) {
43 216 #pragma omp parallel for default(none) shared(r, ap, alpha, n) schedule(static)
44 for (int i = 0; i < n; ++i) {
45 r[i] -= alpha * ap[i];
46 }
47 }
48
49 void UpdateSearchDirectionOMP(std::vector<double> &p, const std::vector<double> &r, double beta, int n) {
50 168 #pragma omp parallel for default(none) shared(p, r, beta, n) schedule(static)
51 for (int i = 0; i < n; ++i) {
52 p[i] = r[i] + (beta * p[i]);
53 }
54 }
55 } // namespace
56
57
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 KichanovaKLinSystemByConjugGradOMP::KichanovaKLinSystemByConjugGradOMP(const InType &in) {
58 SetTypeOfTask(GetStaticTypeOfTask());
59
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 GetInput() = in;
60 48 GetOutput() = OutType();
61 48 }
62
63 48 bool KichanovaKLinSystemByConjugGradOMP::ValidationImpl() {
64 const InType &input_data = GetInput();
65
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 if (input_data.n <= 0) {
66 return false;
67 }
68
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 if (input_data.A.size() != static_cast<size_t>(input_data.n) * static_cast<size_t>(input_data.n)) {
69 return false;
70 }
71
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 if (input_data.b.size() != static_cast<size_t>(input_data.n)) {
72 return false;
73 }
74 return true;
75 }
76
77 48 bool KichanovaKLinSystemByConjugGradOMP::PreProcessingImpl() {
78 48 GetOutput().assign(GetInput().n, 0.0);
79 48 return true;
80 }
81
82
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 bool KichanovaKLinSystemByConjugGradOMP::RunImpl() {
83 const InType &input_data = GetInput();
84 OutType &x = GetOutput();
85
86 48 int n = input_data.n;
87
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 if (n == 0) {
88 return false;
89 }
90
91 48 const std::vector<double> &a = input_data.A;
92 48 const std::vector<double> &b = input_data.b;
93 48 double epsilon = input_data.epsilon;
94
95 48 std::vector<double> r(n);
96
1/4
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
48 std::vector<double> p(n);
97
1/4
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
48 std::vector<double> ap(n);
98
99 48 #pragma omp parallel for default(none) shared(r, b, p, n) schedule(static)
100 for (int i = 0; i < n; i++) {
101 r[i] = b[i];
102 p[i] = r[i];
103 }
104
105 double rr_old = ComputeDotProductOMP(r, r, n);
106 48 double residual_norm = std::sqrt(rr_old);
107
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 if (residual_norm < epsilon) {
108 return true;
109 }
110
111 48 int max_iter = n * 1000;
112
113
1/2
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
216 for (int iter = 0; iter < max_iter; iter++) {
114 ComputeMatrixVectorProductOMP(a, p, ap, n);
115
116 double p_ap = ComputeDotProductOMP(p, ap, n);
117
1/2
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
216 if (std::abs(p_ap) < 1e-30) {
118 break;
119 }
120
121 216 double alpha = rr_old / p_ap;
122
123 UpdateSolutionOMP(x, p, alpha, n);
124
125 UpdateResidualOMP(r, ap, alpha, n);
126
127 double rr_new = ComputeDotProductOMP(r, r, n);
128 216 residual_norm = std::sqrt(rr_new);
129
2/2
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 48 times.
216 if (residual_norm < epsilon) {
130 break;
131 }
132
133 168 double beta = rr_new / rr_old;
134
135 UpdateSearchDirectionOMP(p, r, beta, n);
136
137 rr_old = rr_new;
138 }
139
140 return true;
141 }
142
143 48 bool KichanovaKLinSystemByConjugGradOMP::PostProcessingImpl() {
144 48 return true;
145 }
146
147 } // namespace kichanova_k_lin_system_by_conjug_grad
148