GCC Code Coverage Report


Directory: ./
File: tasks/kulik_a_mat_mul_double_ccs/stl/src/ops_stl.cpp
Date: 2026-06-04 20:25:32
Exec Total Coverage
Lines: 73 73 100.0%
Functions: 9 9 100.0%
Branches: 42 62 67.7%

Line Branch Exec Source
1 #include "kulik_a_mat_mul_double_ccs/stl/include/ops_stl.hpp"
2
3 #include <algorithm>
4 #include <cstddef>
5 #include <functional>
6 #include <thread>
7 #include <tuple>
8 #include <vector>
9
10 #include "kulik_a_mat_mul_double_ccs/common/include/common.hpp"
11
12 namespace kulik_a_mat_mul_double_ccs {
13
14 namespace {
15
16 48 inline void ProcessColumn(size_t j, const CCS &a, const CCS &b, std::vector<double> &accum,
17 std::vector<bool> &nz_elem_rows, std::vector<size_t> &nnz_rows,
18 std::vector<std::vector<double>> &local_values,
19 std::vector<std::vector<size_t>> &local_rows) {
20
2/2
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 48 times.
120 for (size_t k = b.col_ind[j]; k < b.col_ind[j + 1]; ++k) {
21 72 size_t ind = b.row[k];
22 72 double b_val = b.value[k];
23
2/2
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 72 times.
184 for (size_t zc = a.col_ind[ind]; zc < a.col_ind[ind + 1]; ++zc) {
24 112 size_t i = a.row[zc];
25
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 112 times.
112 double a_val = a.value[zc];
26
27
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 112 times.
112 accum[i] += a_val * b_val;
28
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 16 times.
112 if (!nz_elem_rows[i]) {
29 nz_elem_rows[i] = true;
30 nnz_rows.push_back(i);
31 }
32 }
33 }
34
35 std::ranges::sort(nnz_rows);
36
37
3/4
✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 96 times.
✓ Branch 3 taken 48 times.
144 for (size_t i : nnz_rows) {
38
1/2
✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
96 if (accum[i] != 0.0) {
39 local_rows[j].push_back(i);
40 local_values[j].push_back(accum[i]);
41 }
42
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96 times.
96 accum[i] = 0.0;
43 nz_elem_rows[i] = false;
44 }
45 nnz_rows.clear();
46 48 }
47
48 48 inline void CopyColumn(size_t j, CCS &c, const std::vector<std::vector<double>> &local_values,
49 const std::vector<std::vector<size_t>> &local_rows) {
50 48 size_t offset = c.col_ind[j];
51 size_t col_nz = local_values[j].size();
52
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 48 times.
144 for (size_t k = 0; k < col_nz; ++k) {
53 96 c.value[offset + k] = local_values[j][k];
54 96 c.row[offset + k] = local_rows[j][k];
55 }
56 48 }
57
58 32 void ProcessColumnsRange(size_t jstart, size_t jend, const CCS &a, const CCS &b,
59 std::vector<std::vector<double>> &local_values, std::vector<std::vector<size_t>> &local_rows) {
60 32 std::vector<double> accum(a.n, 0.0);
61
1/4
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
32 std::vector<bool> nz_elem_rows(a.n, false);
62 32 std::vector<size_t> nnz_rows;
63
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 nnz_rows.reserve(a.n);
64
65
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 32 times.
80 for (size_t j = jstart; j < jend; ++j) {
66
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 ProcessColumn(j, a, b, accum, nz_elem_rows, nnz_rows, local_values, local_rows);
67 }
68 32 }
69
70 32 void CopyColumnsRange(size_t jstart, size_t jend, CCS &c, const std::vector<std::vector<double>> &local_values,
71 const std::vector<std::vector<size_t>> &local_rows) {
72
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 32 times.
80 for (size_t j = jstart; j < jend; ++j) {
73 48 CopyColumn(j, c, local_values, local_rows);
74 }
75 32 }
76
77 } // namespace
78
79
1/2
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
8 KulikAMatMulDoubleCcsSTL::KulikAMatMulDoubleCcsSTL(const InType &in) {
80 SetTypeOfTask(GetStaticTypeOfTask());
81 GetInput() = in;
82 8 }
83
84 8 bool KulikAMatMulDoubleCcsSTL::ValidationImpl() {
85 const auto &a = std::get<0>(GetInput());
86 const auto &b = std::get<1>(GetInput());
87 8 return (a.m == b.n);
88 }
89
90 8 bool KulikAMatMulDoubleCcsSTL::PreProcessingImpl() {
91 8 return true;
92 }
93
94 8 bool KulikAMatMulDoubleCcsSTL::RunImpl() {
95 const auto &a = std::get<0>(GetInput());
96 const auto &b = std::get<1>(GetInput());
97 OutType &c = GetOutput();
98
99 8 c.n = a.n;
100 8 c.m = b.m;
101 8 c.col_ind.assign(c.m + 1, 0);
102
103 8 std::vector<std::vector<double>> local_values(b.m);
104
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 std::vector<std::vector<size_t>> local_rows(b.m);
105
106 8 const size_t num_threads_raw = std::thread::hardware_concurrency();
107 8 const size_t num_threads = std::max<size_t>(1, num_threads_raw == 0 ? 1 : num_threads_raw);
108
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 const size_t threads_count = std::min(num_threads, b.m == 0 ? static_cast<size_t>(1) : b.m);
109
110 8 std::vector<std::thread> threads;
111
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 threads.reserve(threads_count);
112
113
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 8 times.
40 for (size_t tid = 0; tid < threads_count; ++tid) {
114 32 const size_t jstart = (tid * b.m) / threads_count;
115 32 const size_t jend = ((tid + 1) * b.m) / threads_count;
116
117 64 threads.emplace_back(ProcessColumnsRange, jstart, jend, std::cref(a), std::cref(b), std::ref(local_values),
118
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 std::ref(local_rows));
119 }
120
121
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 8 times.
40 for (auto &th : threads) {
122
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 th.join();
123 }
124
125 size_t total_nz = 0;
126
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 8 times.
56 for (size_t j = 0; j < b.m; ++j) {
127 48 c.col_ind[j] = total_nz;
128 48 total_nz += local_values[j].size();
129 }
130 8 c.col_ind[b.m] = total_nz;
131 8 c.nz = total_nz;
132
133
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 c.value.resize(total_nz);
134
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 c.row.resize(total_nz);
135
136 8 threads.clear();
137
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 8 times.
40 for (size_t tid = 0; tid < threads_count; ++tid) {
138 32 const size_t jstart = (tid * b.m) / threads_count;
139 32 const size_t jend = ((tid + 1) * b.m) / threads_count;
140
141
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 threads.emplace_back(CopyColumnsRange, jstart, jend, std::ref(c), std::cref(local_values), std::cref(local_rows));
142 }
143
144
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 8 times.
40 for (auto &th : threads) {
145
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 th.join();
146 }
147
148 8 return true;
149 8 }
150
151 8 bool KulikAMatMulDoubleCcsSTL::PostProcessingImpl() {
152 8 return true;
153 }
154
155 } // namespace kulik_a_mat_mul_double_ccs
156