GCC Code Coverage Report


Directory: ./
File: tasks/zagryadskov_m_complex_spmm_ccs/tbb/src/ops_tbb.cpp
Date: 2026-05-11 08:26:31
Exec Total Coverage
Lines: 73 73 100.0%
Functions: 11 11 100.0%
Branches: 38 46 82.6%

Line Branch Exec Source
1 #include "zagryadskov_m_complex_spmm_ccs/tbb/include/ops_tbb.hpp"
2
3 #include <tbb/blocked_range.h>
4 #include <tbb/enumerable_thread_specific.h>
5 #include <tbb/tbb.h>
6
7 #include <complex>
8 #include <vector>
9
10 #include "tbb/parallel_for.h"
11 #include "zagryadskov_m_complex_spmm_ccs/common/include/common.hpp"
12
13 namespace zagryadskov_m_complex_spmm_ccs {
14
15
1/2
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 ZagryadskovMComplexSpMMCCSTBB::ZagryadskovMComplexSpMMCCSTBB(const InType &in) {
16 SetTypeOfTask(GetStaticTypeOfTask());
17 GetInput() = in;
18
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 GetOutput() = CCS();
19 12 }
20
21 12 void ZagryadskovMComplexSpMMCCSTBB::SpMMSymbolic(const CCS &a, const CCS &b, std::vector<int> &col_ptr) {
22 12 const int m = a.m;
23 12 const int n = b.n;
24
25 12 std::vector<int> col_counts(n, 0);
26
27
1/2
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
24 tbb::enumerable_thread_specific<std::vector<int>> tls_marker([&]() { return std::vector<int>(m, -1); });
28
29
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 tbb::parallel_for(tbb::blocked_range<int>(0, n, 64), [&](const tbb::blocked_range<int> &r) {
30 12 auto &marker = tls_marker.local();
31
32
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 12 times.
40 for (int j = r.begin(); j < r.end(); ++j) {
33 int count = 0;
34
35
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 28 times.
68 for (int k = b.col_ptr[j]; k < b.col_ptr[j + 1]; ++k) {
36 40 int b_row = b.row_ind[k];
37
38
2/2
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 40 times.
84 for (int zp = a.col_ptr[b_row]; zp < a.col_ptr[b_row + 1]; ++zp) {
39
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 8 times.
44 int a_row = a.row_ind[zp];
40
41
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 8 times.
44 if (marker[a_row] != j) {
42 36 marker[a_row] = j;
43 36 ++count;
44 }
45 }
46 }
47
48 28 col_counts[j] = count;
49 }
50 12 });
51
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 col_ptr.resize(n + 1);
52 12 col_ptr[0] = 0;
53
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 12 times.
40 for (int j = 0; j < n; ++j) {
54 28 col_ptr[j + 1] = col_ptr[j] + col_counts[j];
55 }
56 24 }
57
58
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 12 times.
28 void ZagryadskovMComplexSpMMCCSTBB::SpMMKernel(const CCS &a, const CCS &b, CCS &c, const std::complex<double> &zero,
59 std::vector<int> &rows, std::vector<std::complex<double>> &acc,
60 std::vector<int> &marker, int j) {
61 rows.clear();
62
63 28 int write_ptr = c.col_ptr[j];
64
65
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 28 times.
68 for (int k = b.col_ptr[j]; k < b.col_ptr[j + 1]; ++k) {
66 40 std::complex<double> tmpval = b.values[k];
67 40 int b_row = b.row_ind[k];
68
69
2/2
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 40 times.
84 for (int zp = a.col_ptr[b_row]; zp < a.col_ptr[b_row + 1]; ++zp) {
70
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 8 times.
44 int a_row = a.row_ind[zp];
71
72
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 8 times.
44 acc[a_row] += tmpval * a.values[zp];
73
74
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 8 times.
44 if (marker[a_row] != j) {
75
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 16 times.
36 marker[a_row] = j;
76 rows.push_back(a_row);
77 }
78 }
79 }
80
81
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 28 times.
64 for (int r_idx : rows) {
82 36 c.row_ind[write_ptr] = r_idx;
83 36 c.values[write_ptr] = acc[r_idx];
84 36 ++write_ptr;
85 36 acc[r_idx] = zero;
86 }
87 28 }
88
89 12 void ZagryadskovMComplexSpMMCCSTBB::SpMMNumeric(const CCS &a, const CCS &b, CCS &c, const std::complex<double> &zero) {
90 12 const int m = a.m;
91 12 const int n = b.n;
92
93 24 tbb::enumerable_thread_specific<std::vector<int>> tls_marker([&]() { return std::vector<int>(m, -1); });
94
95 tbb::enumerable_thread_specific<std::vector<std::complex<double>>> tls_acc(
96
1/2
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
24 [&]() { return std::vector<std::complex<double>>(m, zero); });
97
98
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 tbb::parallel_for(tbb::blocked_range<int>(0, n, 64), [&](const tbb::blocked_range<int> &r) {
99 12 auto &marker = tls_marker.local();
100 12 auto &acc = tls_acc.local();
101
102 12 std::vector<int> rows;
103
104
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 12 times.
40 for (int j = r.begin(); j < r.end(); ++j) {
105
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 SpMMKernel(a, b, c, zero, rows, acc, marker, j);
106 }
107 12 });
108 12 }
109
110 12 void ZagryadskovMComplexSpMMCCSTBB::SpMM(const CCS &a, const CCS &b, CCS &c) {
111 12 c.m = a.m;
112 12 c.n = b.n;
113
114 12 std::complex<double> zero(0.0, 0.0);
115
116 12 SpMMSymbolic(a, b, c.col_ptr);
117
118 12 int nnz = c.col_ptr[b.n];
119 12 c.row_ind.resize(nnz);
120 12 c.values.resize(nnz);
121
122 12 SpMMNumeric(a, b, c, zero);
123 12 }
124
125 12 bool ZagryadskovMComplexSpMMCCSTBB::ValidationImpl() {
126 const CCS &a = std::get<0>(GetInput());
127 const CCS &b = std::get<1>(GetInput());
128 12 return a.n == b.m;
129 }
130
131 12 bool ZagryadskovMComplexSpMMCCSTBB::PreProcessingImpl() {
132 12 return true;
133 }
134
135 12 bool ZagryadskovMComplexSpMMCCSTBB::RunImpl() {
136 const CCS &a = std::get<0>(GetInput());
137 const CCS &b = std::get<1>(GetInput());
138 CCS &c = GetOutput();
139
140 12 ZagryadskovMComplexSpMMCCSTBB::SpMM(a, b, c);
141
142 12 return true;
143 }
144
145 12 bool ZagryadskovMComplexSpMMCCSTBB::PostProcessingImpl() {
146 12 return true;
147 }
148
149 } // namespace zagryadskov_m_complex_spmm_ccs
150