GCC Code Coverage Report


Directory: ./
File: tasks/posternak_a_crs_mul_complex_matrix/tbb/src/ops_tbb.cpp
Date: 2026-05-11 08:26:31
Exec Total Coverage
Lines: 67 67 100.0%
Functions: 10 10 100.0%
Branches: 45 84 53.6%

Line Branch Exec Source
1 #include "posternak_a_crs_mul_complex_matrix/tbb/include/ops_tbb.hpp"
2
3 #include <tbb/tbb.h>
4
5 #include <algorithm>
6 #include <cmath>
7 #include <complex>
8 #include <cstddef>
9 #include <unordered_map>
10 #include <utility>
11 #include <vector>
12
13 #include "posternak_a_crs_mul_complex_matrix/common/include/common.hpp"
14
15 namespace {
16
17 40 size_t ComputeRowNoZeroCount(const posternak_a_crs_mul_complex_matrix::CRSMatrix &a,
18 const posternak_a_crs_mul_complex_matrix::CRSMatrix &b, int row, double threshold) {
19 std::unordered_map<int, std::complex<double>> row_sum;
20
21
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 40 times.
88 for (int idx_a = a.index_row[row]; idx_a < a.index_row[row + 1]; ++idx_a) {
22 48 int col_a = a.index_col[idx_a];
23 48 auto val_a = a.values[idx_a];
24
25
2/2
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 48 times.
116 for (int idx_b = b.index_row[col_a]; idx_b < b.index_row[col_a + 1]; ++idx_b) {
26
1/2
✓ Branch 1 taken 68 times.
✗ Branch 2 not taken.
68 int col_b = b.index_col[idx_b];
27
1/2
✓ Branch 1 taken 68 times.
✗ Branch 2 not taken.
68 auto val_b = b.values[idx_b];
28 row_sum[col_b] += val_a * val_b;
29 }
30 }
31
32 size_t local = 0;
33
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 40 times.
96 for (const auto &[col, val] : row_sum) {
34
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 if (std::abs(val) > threshold) {
35 56 ++local;
36 }
37 }
38 40 return local;
39 }
40
41 16 void BuildResultStructure(posternak_a_crs_mul_complex_matrix::CRSMatrix &res, std::vector<size_t> &row_prefix) {
42
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 16 times.
40 for (int i = 1; i < res.rows; ++i) {
43 24 row_prefix[i] += row_prefix[i - 1];
44 }
45
46
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 const size_t total = row_prefix.empty() ? 0 : row_prefix.back();
47 16 res.values.resize(total);
48 16 res.index_col.resize(total);
49 16 res.index_row.resize(res.rows + 1);
50
51
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 16 times.
72 for (int i = 0; i <= res.rows; ++i) {
52
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 16 times.
56 res.index_row[i] = (i == 0 ? 0 : static_cast<int>(row_prefix[i - 1]));
53 }
54 16 }
55
56 40 void ComputeAndWriteRow(const posternak_a_crs_mul_complex_matrix::CRSMatrix &a,
57 const posternak_a_crs_mul_complex_matrix::CRSMatrix &b,
58 posternak_a_crs_mul_complex_matrix::CRSMatrix &res, int row, double threshold) {
59 std::unordered_map<int, std::complex<double>> row_sum;
60
61
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 40 times.
88 for (int idx_a = a.index_row[row]; idx_a < a.index_row[row + 1]; ++idx_a) {
62 48 int col_a = a.index_col[idx_a];
63 48 auto val_a = a.values[idx_a];
64
65
2/2
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 48 times.
116 for (int idx_b = b.index_row[col_a]; idx_b < b.index_row[col_a + 1]; ++idx_b) {
66
1/2
✓ Branch 1 taken 68 times.
✗ Branch 2 not taken.
68 int col_b = b.index_col[idx_b];
67
1/2
✓ Branch 1 taken 68 times.
✗ Branch 2 not taken.
68 auto val_b = b.values[idx_b];
68 row_sum[col_b] += val_a * val_b;
69 }
70 }
71
72
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 std::vector<std::pair<int, std::complex<double>>> sorted(row_sum.begin(), row_sum.end());
73
74
1/22
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 16 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
16 std::ranges::sort(sorted, [](const auto &p1, const auto &p2) { return p1.first < p2.first; });
75
76 40 size_t pos = res.index_row[row];
77
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 40 times.
96 for (const auto &[col_idx, value] : sorted) {
78
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 if (std::abs(value) > threshold) {
79 56 res.values[pos] = value;
80 56 res.index_col[pos] = col_idx;
81 56 ++pos;
82 }
83 }
84 40 }
85
86 } // namespace
87
88 namespace posternak_a_crs_mul_complex_matrix {
89
90
1/2
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
24 PosternakACRSMulComplexMatrixTBB::PosternakACRSMulComplexMatrixTBB(const InType &in) {
91 SetTypeOfTask(GetStaticTypeOfTask());
92 GetInput() = in;
93 24 GetOutput() = CRSMatrix{};
94 24 }
95
96 24 bool PosternakACRSMulComplexMatrixTBB::ValidationImpl() {
97 const auto &input = GetInput();
98 24 const auto &a = input.first;
99 24 const auto &b = input.second;
100
3/6
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 24 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 24 times.
24 return a.IsValid() && b.IsValid() && a.cols == b.rows;
101 }
102
103 24 bool PosternakACRSMulComplexMatrixTBB::PreProcessingImpl() {
104 const auto &input = GetInput();
105 const auto &a = input.first;
106 const auto &b = input.second;
107 auto &res = GetOutput();
108
109 24 res.rows = a.rows;
110 24 res.cols = b.cols;
111 24 return true;
112 }
113
114 24 bool PosternakACRSMulComplexMatrixTBB::RunImpl() {
115 const auto &input = GetInput();
116 24 const auto &a = input.first;
117
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 4 times.
24 const auto &b = input.second;
118 auto &res = GetOutput();
119
120
4/4
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 16 times.
24 if (a.values.empty() || b.values.empty()) {
121 res.values.clear();
122 res.index_col.clear();
123 8 res.index_row.assign(res.rows + 1, 0);
124 8 return true;
125 }
126
127 constexpr double kThreshold = 1e-12;
128 16 std::vector<size_t> no_zero_rows(res.rows, 0);
129
130
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
56 tbb::parallel_for(tbb::blocked_range<int>(0, res.rows), [&](const tbb::blocked_range<int> &range) {
131
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 40 times.
80 for (int row = range.begin(); row != range.end(); ++row) {
132 40 no_zero_rows[row] = ComputeRowNoZeroCount(a, b, row, kThreshold);
133 }
134 40 });
135
136
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 BuildResultStructure(res, no_zero_rows);
137
138
1/4
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
56 tbb::parallel_for(tbb::blocked_range<int>(0, res.rows), [&](const tbb::blocked_range<int> &range) {
139
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 40 times.
80 for (int row = range.begin(); row != range.end(); ++row) {
140 40 ComputeAndWriteRow(a, b, res, row, kThreshold);
141 }
142 40 });
143
144
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 return res.IsValid();
145 }
146
147 24 bool PosternakACRSMulComplexMatrixTBB::PostProcessingImpl() {
148 24 return GetOutput().IsValid();
149 }
150
151 } // namespace posternak_a_crs_mul_complex_matrix
152