GCC Code Coverage Report


Directory: ./
File: tasks/maslova_u_mult_matr_crs/omp/src/ops_omp.cpp
Date: 2026-04-02 17:12:27
Exec Total Coverage
Lines: 49 50 98.0%
Functions: 7 7 100.0%
Branches: 29 36 80.6%

Line Branch Exec Source
1 #include "maslova_u_mult_matr_crs/omp/include/ops_omp.hpp"
2
3 #include <omp.h>
4
5 #include <algorithm>
6 #include <cmath>
7 #include <cstddef>
8 #include <vector>
9
10 #include "maslova_u_mult_matr_crs/common/include/common.hpp"
11 #include "util/include/util.hpp"
12
13 namespace maslova_u_mult_matr_crs {
14
15
1/2
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
20 MaslovaUMultMatrOMP::MaslovaUMultMatrOMP(const InType &in) {
16 SetTypeOfTask(GetStaticTypeOfTask());
17 GetInput() = in;
18 20 }
19
20 20 bool MaslovaUMultMatrOMP::ValidationImpl() {
21 const auto &input = GetInput();
22 const auto &a = std::get<0>(input);
23 const auto &b = std::get<1>(input);
24
25
3/6
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
20 if (a.cols != b.rows || a.rows <= 0 || b.cols <= 0) {
26 return false;
27 }
28
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 if (a.row_ptr.size() != static_cast<size_t>(a.rows) + 1) {
29 return false;
30 }
31
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
20 if (b.row_ptr.size() != static_cast<size_t>(b.rows) + 1) {
32 return false;
33 }
34 return true;
35 }
36
37 20 bool MaslovaUMultMatrOMP::PreProcessingImpl() {
38 const auto &a = std::get<0>(GetInput());
39 const auto &b = std::get<1>(GetInput());
40 auto &c = GetOutput();
41 20 c.rows = a.rows;
42 20 c.cols = b.cols;
43 20 return true;
44 }
45
46 32 int MaslovaUMultMatrOMP::GetRowNNZ(int i, const CRSMatrix &a, const CRSMatrix &b, std::vector<int> &marker) {
47 int row_nnz = 0;
48
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 32 times.
80 for (int j = a.row_ptr[i]; j < a.row_ptr[i + 1]; ++j) {
49 48 int col_a = a.col_ind[j];
50
2/2
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 48 times.
120 for (int k = b.row_ptr[col_a]; k < b.row_ptr[col_a + 1]; ++k) {
51
2/2
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 28 times.
72 int col_b = b.col_ind[k];
52
2/2
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 28 times.
72 if (marker[col_b] != i) {
53 44 marker[col_b] = i;
54 44 row_nnz++;
55 }
56 }
57 }
58 32 return row_nnz;
59 }
60
61
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 20 times.
32 void MaslovaUMultMatrOMP::FillRowValues(int i, const CRSMatrix &a, const CRSMatrix &b, CRSMatrix &c,
62 std::vector<double> &acc, std::vector<int> &marker, std::vector<int> &used) {
63 used.clear();
64
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 32 times.
80 for (int j = a.row_ptr[i]; j < a.row_ptr[i + 1]; ++j) {
65 48 int col_a = a.col_ind[j];
66 48 double val_a = a.values[j];
67
2/2
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 48 times.
120 for (int k = b.row_ptr[col_a]; k < b.row_ptr[col_a + 1]; ++k) {
68
2/2
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 28 times.
72 int col_b = b.col_ind[k];
69
2/2
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 28 times.
72 if (marker[col_b] != i) {
70
1/2
✓ Branch 0 taken 44 times.
✗ Branch 1 not taken.
44 marker[col_b] = i;
71 used.push_back(col_b);
72 44 acc[col_b] = val_a * b.values[k];
73 } else {
74 28 acc[col_b] += val_a * b.values[k];
75 }
76 }
77 }
78
79 std::ranges::sort(used);
80
81 32 int write_pos = c.row_ptr[i];
82
2/2
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 32 times.
76 for (int col : used) {
83 44 c.values[write_pos] = acc[col];
84 44 c.col_ind[write_pos] = col;
85 44 write_pos++;
86 44 acc[col] = 0.0;
87 }
88 32 }
89
90 20 bool MaslovaUMultMatrOMP::RunImpl() {
91 const auto &a = std::get<0>(GetInput());
92 const auto &b = std::get<1>(GetInput());
93 auto &c = GetOutput();
94
95 20 const int rows_a = a.rows;
96 20 const int cols_b = b.cols;
97 20 c.row_ptr.assign(static_cast<size_t>(rows_a) + 1, 0);
98
99 20 #pragma omp parallel default(none) shared(a, b, c, rows_a, cols_b) num_threads(ppc::util::GetNumThreads())
100 {
101 std::vector<int> marker(cols_b, -1);
102 #pragma omp for schedule(dynamic, 20)
103 for (int i = 0; i < rows_a; ++i) {
104 c.row_ptr[i + 1] = GetRowNNZ(i, a, b, marker);
105 }
106 }
107
108
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 20 times.
52 for (int i = 0; i < rows_a; ++i) {
109 32 c.row_ptr[i + 1] += c.row_ptr[i];
110 }
111
112 20 c.values.resize(c.row_ptr[rows_a]);
113 20 c.col_ind.resize(c.row_ptr[rows_a]);
114
115 20 #pragma omp parallel default(none) shared(a, b, c, rows_a, cols_b) num_threads(ppc::util::GetNumThreads())
116 {
117 std::vector<double> acc(cols_b, 0.0);
118 std::vector<int> marker(cols_b, -1);
119 std::vector<int> used;
120 used.reserve(cols_b);
121
122 #pragma omp for schedule(dynamic, 20)
123 for (int i = 0; i < rows_a; ++i) {
124 FillRowValues(i, a, b, c, acc, marker, used);
125 }
126 }
127
128 20 return true;
129 }
130
131 20 bool MaslovaUMultMatrOMP::PostProcessingImpl() {
132 20 return true;
133 }
134
135 } // namespace maslova_u_mult_matr_crs
136