GCC Code Coverage Report


Directory: ./
File: tasks/kulik_a_mat_mul_double_ccs/tbb/src/ops_tbb.cpp
Date: 2026-06-04 20:25:32
Exec Total Coverage
Lines: 63 63 100.0%
Functions: 9 9 100.0%
Branches: 36 44 81.8%

Line Branch Exec Source
1 #include "kulik_a_mat_mul_double_ccs/tbb/include/ops_tbb.hpp"
2
3 #include <tbb/blocked_range.h>
4 #include <tbb/enumerable_thread_specific.h>
5 #include <tbb/parallel_for.h>
6
7 #include <algorithm>
8 #include <cstddef>
9 #include <limits>
10 #include <tuple>
11 #include <vector>
12
13 #include "kulik_a_mat_mul_double_ccs/common/include/common.hpp"
14
15 namespace kulik_a_mat_mul_double_ccs {
16
17 namespace {
18
19 24 inline void MatMultPhase1(size_t j, const CCS &a, const CCS &b, std::vector<size_t> &was,
20 std::vector<size_t> &col_nnz) {
21 size_t count = 0;
22
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 24 times.
60 for (size_t k = b.col_ind[j]; k < b.col_ind[j + 1]; ++k) {
23 36 const size_t b_row = b.row[k];
24
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 36 times.
92 for (size_t zc = a.col_ind[b_row]; zc < a.col_ind[b_row + 1]; ++zc) {
25
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 8 times.
56 const size_t a_row = a.row[zc];
26
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 8 times.
56 if (was[a_row] != j) {
27 48 was[a_row] = j;
28 48 ++count;
29 }
30 }
31 }
32 24 col_nnz[j] = count;
33 24 }
34
35
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 6 times.
24 inline void MatMultPhase2(size_t j, const CCS &a, const CCS &b, CCS &c, size_t stamp, std::vector<size_t> &was,
36 std::vector<double> &accum, std::vector<size_t> &rows) {
37 rows.clear();
38
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 24 times.
60 for (size_t k = b.col_ind[j]; k < b.col_ind[j + 1]; ++k) {
39 36 const double b_val = b.value[k];
40 36 const size_t b_row = b.row[k];
41
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 36 times.
92 for (size_t zc = a.col_ind[b_row]; zc < a.col_ind[b_row + 1]; ++zc) {
42 56 const size_t a_row = a.row[zc];
43
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 8 times.
56 accum[a_row] += a.value[zc] * b_val;
44
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 8 times.
56 if (was[a_row] != stamp) {
45
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 18 times.
48 was[a_row] = stamp;
46 rows.push_back(a_row);
47 }
48 }
49 }
50 std::ranges::sort(rows);
51 24 size_t write = c.col_ind[j];
52
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 24 times.
72 for (const size_t i : rows) {
53 48 c.row[write] = i;
54 48 c.value[write] = accum[i];
55 48 accum[i] = 0.0;
56 48 ++write;
57 }
58 24 }
59
60 } // namespace
61
62
1/2
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 KulikAMatMulDoubleCcsTBB::KulikAMatMulDoubleCcsTBB(const InType &in) {
63 SetTypeOfTask(GetStaticTypeOfTask());
64 GetInput() = in;
65 4 }
66
67 4 bool KulikAMatMulDoubleCcsTBB::ValidationImpl() {
68 const auto &a = std::get<0>(GetInput());
69 const auto &b = std::get<1>(GetInput());
70 4 return (a.m == b.n);
71 }
72
73 4 bool KulikAMatMulDoubleCcsTBB::PreProcessingImpl() {
74 4 return true;
75 }
76
77 4 bool KulikAMatMulDoubleCcsTBB::RunImpl() {
78 const auto &a = std::get<0>(GetInput());
79 const auto &b = std::get<1>(GetInput());
80 OutType &c = GetOutput();
81 4 c.n = a.n;
82 4 c.m = b.m;
83 4 c.col_ind.assign(c.m + 1, 0);
84
85 4 std::vector<size_t> col_nnz(b.m, 0);
86
87 tbb::enumerable_thread_specific<std::vector<size_t>> tls_was(
88
1/2
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
10 [&]() { return std::vector<size_t>(a.n, std::numeric_limits<size_t>::max()); });
89
90
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 tbb::parallel_for(tbb::blocked_range<size_t>(0, b.m), [&](const tbb::blocked_range<size_t> &r) {
91 24 auto &was = tls_was.local();
92
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 24 times.
48 for (size_t j = r.begin(); j != r.end(); ++j) {
93 24 MatMultPhase1(j, a, b, was, col_nnz);
94 }
95 24 });
96
97 size_t total_nz = 0;
98
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 4 times.
28 for (size_t j = 0; j < b.m; ++j) {
99 24 c.col_ind[j] = total_nz;
100 24 total_nz += col_nnz[j];
101 }
102 4 c.col_ind[b.m] = total_nz;
103 4 c.nz = total_nz;
104
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 c.value.resize(total_nz);
105
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 c.row.resize(total_nz);
106
107
1/2
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
10 tbb::enumerable_thread_specific<std::vector<double>> tls_accum([&]() { return std::vector<double>(a.n, 0.0); });
108
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 tbb::enumerable_thread_specific<std::vector<size_t>> tls_rows;
109
110
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 tbb::parallel_for(tbb::blocked_range<size_t>(0, b.m), [&](const tbb::blocked_range<size_t> &r) {
111 24 auto &was = tls_was.local();
112 24 auto &accum = tls_accum.local();
113 24 auto &rows = tls_rows.local();
114
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 24 times.
48 for (size_t j = r.begin(); j != r.end(); ++j) {
115 24 MatMultPhase2(j, a, b, c, b.m + j, was, accum, rows);
116 }
117 24 });
118
119 4 return true;
120 4 }
121
122 4 bool KulikAMatMulDoubleCcsTBB::PostProcessingImpl() {
123 4 return true;
124 }
125
126 } // namespace kulik_a_mat_mul_double_ccs
127