GCC Code Coverage Report


Directory: ./
File: tasks/sizov_d_sparse_crs_mult/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 46 63.0%

Line Branch Exec Source
1 #include "sizov_d_sparse_crs_mult/omp/include/ops_omp.hpp"
2
3 #include <algorithm>
4 #include <cmath>
5 #include <cstddef>
6 #include <cstdint>
7 #include <utility>
8 #include <vector>
9
10 #include "sizov_d_sparse_crs_mult/common/include/common.hpp"
11
12 namespace sizov_d_sparse_crs_mult {
13
14 namespace {
15
16 48 void AccumulateRowProducts(std::size_t row_idx, const CRSMatrix &a, const CRSMatrix &b, std::vector<double> &accum,
17 std::vector<unsigned char> &touched, std::vector<std::size_t> &touched_cols) {
18
2/2
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 48 times.
100 for (std::size_t a_idx = a.row_ptr[row_idx]; a_idx < a.row_ptr[row_idx + 1]; ++a_idx) {
19 52 const std::size_t k = a.col_indices[a_idx];
20 52 const double a_val = a.values[a_idx];
21
22
2/2
✓ Branch 0 taken 80 times.
✓ Branch 1 taken 52 times.
132 for (std::size_t b_idx = b.row_ptr[k]; b_idx < b.row_ptr[k + 1]; ++b_idx) {
23
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 20 times.
80 const std::size_t j = b.col_indices[b_idx];
24
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 20 times.
80 if (touched[j] == 0U) {
25
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 touched[j] = 1U;
26 touched_cols.push_back(j);
27 }
28 80 accum[j] += a_val * b.values[b_idx];
29 }
30 }
31 48 }
32
33 48 void FlushRowToEntries(std::vector<double> &accum, std::vector<unsigned char> &touched,
34 std::vector<std::size_t> &touched_cols, std::vector<std::pair<std::size_t, double>> &row) {
35 std::ranges::sort(touched_cols);
36 row.clear();
37 48 row.reserve(touched_cols.size());
38
3/4
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 60 times.
✓ Branch 3 taken 48 times.
108 for (std::size_t col : touched_cols) {
39
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 const double value = accum[col];
40
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 if (std::abs(value) > 1e-12) {
41 60 row.emplace_back(col, value);
42 }
43 60 accum[col] = 0.0;
44 60 touched[col] = 0U;
45 }
46 touched_cols.clear();
47 48 }
48
49 } // namespace
50
51
1/2
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
24 SizovDSparseCRSMultOMP::SizovDSparseCRSMultOMP(const InType &in) {
52 SetTypeOfTask(GetStaticTypeOfTask());
53 GetInput() = in;
54 24 }
55
56 24 bool SizovDSparseCRSMultOMP::ValidationImpl() {
57 const auto &input = GetInput();
58 const auto &a = std::get<0>(input);
59 const auto &b = std::get<1>(input);
60
61
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 if (a.cols != b.rows) {
62 return false;
63 }
64
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 if (a.row_ptr.size() != a.rows + 1) {
65 return false;
66 }
67
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 if (b.row_ptr.size() != b.rows + 1) {
68 return false;
69 }
70
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 if (a.values.size() != a.col_indices.size()) {
71 return false;
72 }
73
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 if (b.values.size() != b.col_indices.size()) {
74 return false;
75 }
76
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 if (a.row_ptr.back() != a.values.size()) {
77 return false;
78 }
79
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 if (b.row_ptr.back() != b.values.size()) {
80 return false;
81 }
82
83 return true;
84 }
85
86 24 bool SizovDSparseCRSMultOMP::PreProcessingImpl() {
87 24 GetOutput() = CRSMatrix{};
88 24 return true;
89 }
90
91
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 bool SizovDSparseCRSMultOMP::RunImpl() {
92 const auto &input = GetInput();
93 const auto &a = std::get<0>(input);
94 const auto &b = std::get<1>(input);
95
96 24 CRSMatrix c;
97 24 c.rows = a.rows;
98 24 c.cols = b.cols;
99
100
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 std::vector<std::vector<std::pair<std::size_t, double>>> row_entries(c.rows);
101
102 24 #pragma omp parallel default(none) shared(a, b, c, row_entries)
103 {
104 std::vector<double> accum(c.cols, 0.0);
105 std::vector<unsigned char> touched(c.cols, 0);
106 std::vector<std::size_t> touched_cols;
107 touched_cols.reserve(256);
108
109 const auto rows_end = static_cast<int64_t>(a.rows);
110 #pragma omp for schedule(dynamic, 16)
111 for (int64_t i = 0; i < rows_end; ++i) {
112 const auto row_idx = static_cast<std::size_t>(i);
113 auto &row = row_entries[row_idx];
114 AccumulateRowProducts(row_idx, a, b, accum, touched, touched_cols);
115 FlushRowToEntries(accum, touched, touched_cols, row);
116 }
117 }
118
119
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 c.row_ptr.resize(c.rows + 1, 0);
120
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 24 times.
72 for (std::size_t i = 0; i < c.rows; ++i) {
121 48 c.row_ptr[i + 1] = c.row_ptr[i] + row_entries[i].size();
122 }
123
124
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 c.values.resize(c.row_ptr.back());
125
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 c.col_indices.resize(c.row_ptr.back());
126
127 24 #pragma omp parallel for default(none) shared(c, row_entries)
128 for (std::size_t i = 0; i < c.rows; ++i) {
129 std::size_t out_pos = c.row_ptr[i];
130 for (const auto &[col, value] : row_entries[i]) {
131 c.col_indices[out_pos] = col;
132 c.values[out_pos] = value;
133 ++out_pos;
134 }
135 }
136
137 24 GetOutput() = std::move(c);
138 24 return true;
139 24 }
140
141 24 bool SizovDSparseCRSMultOMP::PostProcessingImpl() {
142 24 return true;
143 }
144
145 } // namespace sizov_d_sparse_crs_mult
146