GCC Code Coverage Report


Directory: ./
File: tasks/kapanova_s_sparse_matrix_mult_ccs/omp/src/ops_omp.cpp
Date: 2026-05-11 08:26:31
Exec Total Coverage
Lines: 73 74 98.6%
Functions: 8 8 100.0%
Branches: 47 74 63.5%

Line Branch Exec Source
1 #include "kapanova_s_sparse_matrix_mult_ccs/omp/include/ops_omp.hpp"
2
3 #include <omp.h>
4
5 #include <algorithm>
6 #include <cstddef>
7 #include <vector>
8
9 #include "kapanova_s_sparse_matrix_mult_ccs/common/include/common.hpp"
10
11 namespace kapanova_s_sparse_matrix_mult_ccs {
12
13
1/2
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
20 KapanovaSSparseMatrixMultCCSOMP::KapanovaSSparseMatrixMultCCSOMP(const InType &in) {
14 SetTypeOfTask(GetStaticTypeOfTask());
15 GetInput() = in;
16 20 }
17
18 20 bool KapanovaSSparseMatrixMultCCSOMP::ValidationImpl() {
19 const auto &a = std::get<0>(GetInput());
20 const auto &b = std::get<1>(GetInput());
21
22
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 if (a.cols != b.rows) {
23 return false;
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.rows == 0 || a.cols == 0 || b.rows == 0 || b.cols == 0) {
26 return false;
27 }
28
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 if (a.col_ptrs.size() != static_cast<size_t>(a.cols + 1)) {
29 return false;
30 }
31
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 if (b.col_ptrs.size() != static_cast<size_t>(b.cols + 1)) {
32 return false;
33 }
34
2/4
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
20 if (a.col_ptrs[0] != 0 || b.col_ptrs[0] != 0) {
35 return false;
36 }
37
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 if (a.col_ptrs[a.cols] != a.nnz) {
38 return false;
39 }
40
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 if (b.col_ptrs[b.cols] != b.nnz) {
41 return false;
42 }
43
2/4
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
20 if (a.values.size() != static_cast<size_t>(a.nnz) || a.row_indices.size() != static_cast<size_t>(a.nnz)) {
44 return false;
45 }
46
2/4
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 20 times.
20 if (b.values.size() != static_cast<size_t>(b.nnz) || b.row_indices.size() != static_cast<size_t>(b.nnz)) {
47 return false;
48 }
49
50 return true;
51 }
52
53 20 bool KapanovaSSparseMatrixMultCCSOMP::PreProcessingImpl() {
54 20 return true;
55 }
56
57 48 void KapanovaSSparseMatrixMultCCSOMP::ProcessColumn(int j, const CCSMatrix &a, const CCSMatrix &b,
58 std::vector<std::vector<double>> &thread_accum,
59 std::vector<std::vector<bool>> &thread_row_mask,
60 std::vector<std::vector<size_t>> &thread_active_rows,
61 std::vector<std::vector<std::vector<size_t>>> &thread_col_rows,
62 std::vector<std::vector<std::vector<double>>> &thread_col_vals) {
63 48 int tid = omp_get_thread_num();
64
65
2/2
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 48 times.
120 for (size_t k = b.col_ptrs[j]; k < b.col_ptrs[j + 1]; ++k) {
66 72 size_t row_b = b.row_indices[k];
67 72 double val_b = b.values[k];
68
69
2/2
✓ Branch 0 taken 88 times.
✓ Branch 1 taken 72 times.
160 for (size_t zc = a.col_ptrs[row_b]; zc < a.col_ptrs[row_b + 1]; ++zc) {
70 88 size_t i = a.row_indices[zc];
71 88 double val_a = a.values[zc];
72
73
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
88 thread_accum[tid][i] += val_a * val_b;
74
2/2
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 24 times.
88 if (!thread_row_mask[tid][i]) {
75 thread_row_mask[tid][i] = true;
76 thread_active_rows[tid].push_back(i);
77 }
78 }
79 }
80
81 48 std::sort(thread_active_rows[tid].begin(), thread_active_rows[tid].end());
82
83
3/4
✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 64 times.
✓ Branch 3 taken 48 times.
112 for (size_t i : thread_active_rows[tid]) {
84
1/2
✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
64 if (thread_accum[tid][i] != 0.0) {
85 thread_col_rows[tid][j].push_back(i);
86 thread_col_vals[tid][j].push_back(thread_accum[tid][i]);
87 }
88
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 64 times.
64 thread_accum[tid][i] = 0.0;
89 thread_row_mask[tid][i] = false;
90 }
91 thread_active_rows[tid].clear();
92 48 }
93
94 20 void KapanovaSSparseMatrixMultCCSOMP::ComputeColumnSizes(
95 int num_threads, size_t cols, const std::vector<std::vector<std::vector<size_t>>> &thread_col_rows,
96 std::vector<size_t> &col_sizes) {
97
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 20 times.
70 for (int tid = 0; tid < num_threads; ++tid) {
98
2/2
✓ Branch 0 taken 120 times.
✓ Branch 1 taken 50 times.
170 for (size_t j = 0; j < cols; ++j) {
99 120 col_sizes[j] += thread_col_rows[tid][j].size();
100 }
101 }
102 20 }
103
104 20 void KapanovaSSparseMatrixMultCCSOMP::MergeThreadResults(
105 int num_threads, size_t cols, CCSMatrix &c, const std::vector<std::vector<std::vector<size_t>>> &thread_col_rows,
106 const std::vector<std::vector<std::vector<double>>> &thread_col_vals) {
107 20 std::vector<size_t> current_pos(cols, 0);
108
109
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 20 times.
70 for (int tid = 0; tid < num_threads; ++tid) {
110
2/2
✓ Branch 0 taken 120 times.
✓ Branch 1 taken 50 times.
170 for (size_t j = 0; j < cols; ++j) {
111 120 size_t start = c.col_ptrs[j] + current_pos[j];
112 120 size_t num_elements = thread_col_rows[tid][j].size();
113
114
2/2
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 120 times.
184 for (size_t idx = 0; idx < num_elements; ++idx) {
115 64 size_t pos = start + idx;
116 64 c.row_indices[pos] = thread_col_rows[tid][j][idx];
117 64 c.values[pos] = thread_col_vals[tid][j][idx];
118 }
119 120 current_pos[j] += num_elements;
120 }
121 }
122 20 }
123
124 20 bool KapanovaSSparseMatrixMultCCSOMP::RunImpl() {
125 const auto &a = std::get<0>(GetInput());
126 const auto &b = std::get<1>(GetInput());
127 OutType &c = GetOutput();
128
129 20 c.rows = a.rows;
130 20 c.cols = b.cols;
131 20 c.col_ptrs.assign(c.cols + 1, 0);
132 20 c.nnz = 0;
133
134 20 int num_threads = omp_get_max_threads();
135
136 20 std::vector<std::vector<double>> thread_accum(num_threads);
137
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 std::vector<std::vector<bool>> thread_row_mask(num_threads);
138
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 std::vector<std::vector<size_t>> thread_active_rows(num_threads);
139
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 std::vector<std::vector<std::vector<size_t>>> thread_col_rows(num_threads);
140
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 std::vector<std::vector<std::vector<double>>> thread_col_vals(num_threads);
141
142 20 #pragma omp parallel default(none) \
143 shared(a, c, num_threads, thread_accum, thread_row_mask, thread_col_rows, thread_col_vals)
144 {
145 int tid = omp_get_thread_num();
146 thread_accum[tid].assign(a.rows, 0.0);
147 thread_row_mask[tid].assign(a.rows, false);
148 thread_col_rows[tid].resize(c.cols);
149 thread_col_vals[tid].resize(c.cols);
150 }
151
152 20 #pragma omp parallel for schedule(dynamic) default(none) \
153 shared(a, b, c, thread_accum, thread_row_mask, thread_active_rows, thread_col_rows, thread_col_vals)
154 for (size_t j = 0; j < c.cols; ++j) {
155 ProcessColumn(static_cast<int>(j), a, b, thread_accum, thread_row_mask, thread_active_rows, thread_col_rows,
156 thread_col_vals);
157 }
158
159
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 std::vector<size_t> col_sizes(c.cols, 0);
160 20 ComputeColumnSizes(num_threads, c.cols, thread_col_rows, col_sizes);
161
162 size_t offset = 0;
163
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 20 times.
68 for (size_t j = 0; j < c.cols; ++j) {
164 48 c.col_ptrs[j] = offset;
165 48 offset += col_sizes[j];
166 }
167 20 c.col_ptrs[c.cols] = offset;
168 20 c.nnz = offset;
169
170
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 c.values.resize(c.nnz);
171
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 c.row_indices.resize(c.nnz);
172
173
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 MergeThreadResults(num_threads, c.cols, c, thread_col_rows, thread_col_vals);
174
175 20 return true;
176 20 }
177
178 20 bool KapanovaSSparseMatrixMultCCSOMP::PostProcessingImpl() {
179 20 return true;
180 }
181
182 } // namespace kapanova_s_sparse_matrix_mult_ccs
183