GCC Code Coverage Report


Directory: ./
File: tasks/barkalova_m_mult_matrix_ccs/stl/src/ops_stl.cpp
Date: 2026-06-04 20:25:32
Exec Total Coverage
Lines: 94 98 95.9%
Functions: 8 8 100.0%
Branches: 70 114 61.4%

Line Branch Exec Source
1 #include "barkalova_m_mult_matrix_ccs/stl/include/ops_stl.hpp"
2
3 #include <algorithm>
4 #include <cmath>
5 #include <complex>
6 #include <cstddef>
7 #include <exception>
8 #include <functional>
9 #include <future>
10 #include <thread>
11 #include <utility>
12 #include <vector>
13
14 #include "barkalova_m_mult_matrix_ccs/common/include/common.hpp"
15
16 namespace barkalova_m_mult_matrix_ccs {
17
18
1/2
✓ Branch 2 taken 48 times.
✗ Branch 3 not taken.
48 BarkalovaMMultMatrixCcsSTL::BarkalovaMMultMatrixCcsSTL(const InType &in) {
19 SetTypeOfTask(GetStaticTypeOfTask());
20 GetInput() = in;
21 48 GetOutput() = CCSMatrix{};
22 48 }
23
24 48 bool BarkalovaMMultMatrixCcsSTL::ValidationImpl() {
25 const auto &[A, B] = GetInput();
26
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 if (A.cols != B.rows) {
27 return false;
28 }
29
3/6
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 48 times.
✗ Branch 5 not taken.
48 if (A.rows <= 0 || A.cols <= 0 || B.rows <= 0 || B.cols <= 0) {
30 return false;
31 }
32
2/4
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
✗ Branch 3 not taken.
48 if (A.col_ptrs.size() != static_cast<size_t>(A.cols) + 1 || B.col_ptrs.size() != static_cast<size_t>(B.cols) + 1) {
33 return false;
34 }
35
4/8
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 48 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 48 times.
✗ Branch 7 not taken.
48 if (A.col_ptrs.empty() || A.col_ptrs[0] != 0 || B.col_ptrs.empty() || B.col_ptrs[0] != 0) {
36 return false;
37 }
38
2/4
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
✗ Branch 3 not taken.
96 if (std::cmp_not_equal(A.nnz, A.values.size()) || std::cmp_not_equal(B.nnz, B.values.size())) {
39 return false;
40 }
41 return true;
42 }
43
44 48 bool BarkalovaMMultMatrixCcsSTL::PreProcessingImpl() {
45 48 return true;
46 }
47
48 namespace {
49 constexpr double kEpsilon = 1e-10;
50
51 48 void TransponirMatr(const CCSMatrix &a, CCSMatrix &at) {
52 48 at.rows = a.cols;
53 48 at.cols = a.rows;
54 48 at.nnz = a.nnz;
55
56
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 if (a.nnz == 0) {
57 at.values.clear();
58 at.row_indices.clear();
59 at.col_ptrs.assign(at.cols + 1, 0);
60 return;
61 }
62
63 48 std::vector<int> row_count(at.cols, 0);
64
2/2
✓ Branch 0 taken 136 times.
✓ Branch 1 taken 48 times.
184 for (int i = 0; i < a.nnz; i++) {
65 136 row_count[a.row_indices[i]]++;
66 }
67
68
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 at.col_ptrs.resize(at.cols + 1);
69 48 at.col_ptrs[0] = 0;
70
2/2
✓ Branch 0 taken 120 times.
✓ Branch 1 taken 48 times.
168 for (int i = 0; i < at.cols; i++) {
71 120 at.col_ptrs[i + 1] = at.col_ptrs[i] + row_count[i];
72 }
73
74
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 at.values.resize(a.nnz);
75
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 at.row_indices.resize(a.nnz);
76
77
1/4
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
48 std::vector<int> current_pos(at.cols, 0);
78
2/2
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 48 times.
160 for (int col = 0; col < a.cols; col++) {
79
2/2
✓ Branch 0 taken 136 times.
✓ Branch 1 taken 112 times.
248 for (int i = a.col_ptrs[col]; i < a.col_ptrs[col + 1]; i++) {
80 136 int row = a.row_indices[i];
81 136 Complex val = a.values[i];
82
83 136 int pos = at.col_ptrs[row] + current_pos[row];
84 136 at.values[pos] = val;
85 136 at.row_indices[pos] = col;
86 136 current_pos[row]++;
87 }
88 }
89 }
90
91 bool IsNonZero(const Complex &val) {
92
3/4
✓ Branch 0 taken 120 times.
✓ Branch 1 taken 232 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 120 times.
352 return std::abs(val.real()) > kEpsilon || std::abs(val.imag()) > kEpsilon;
93 }
94
95 352 Complex ComputeScalarProduct(const CCSMatrix &at, const CCSMatrix &b, int row_a, int col_b) {
96 Complex sum = Complex(0.0, 0.0);
97
98 352 int ks = at.col_ptrs[row_a];
99 352 int ls = b.col_ptrs[col_b];
100 352 int kf = at.col_ptrs[row_a + 1];
101 352 int lf = b.col_ptrs[col_b + 1];
102
103
2/2
✓ Branch 0 taken 472 times.
✓ Branch 1 taken 352 times.
824 while ((ks < kf) && (ls < lf)) {
104
2/2
✓ Branch 0 taken 88 times.
✓ Branch 1 taken 384 times.
472 if (at.row_indices[ks] < b.row_indices[ls]) {
105 88 ks++;
106
2/2
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 272 times.
384 } else if (at.row_indices[ks] > b.row_indices[ls]) {
107 112 ls++;
108 } else {
109 sum += at.values[ks] * b.values[ls];
110 272 ks++;
111 272 ls++;
112 }
113 }
114
115 352 return sum;
116 }
117
118 struct ColumnResult {
119 std::vector<int> rows;
120 std::vector<Complex> values;
121 };
122
123 136 void ProcessColumnRange(int start_col, int end_col, const CCSMatrix &at, const CCSMatrix &b,
124 std::vector<std::vector<int>> &col_rows, std::vector<std::vector<Complex>> &col_vals) {
125
2/2
✓ Branch 0 taken 136 times.
✓ Branch 1 taken 136 times.
272 for (int col = start_col; col < end_col; ++col) {
126 136 std::vector<int> rows;
127 136 std::vector<Complex> vals;
128
1/2
✓ Branch 1 taken 136 times.
✗ Branch 2 not taken.
136 rows.reserve(100);
129
1/2
✓ Branch 1 taken 136 times.
✗ Branch 2 not taken.
136 vals.reserve(100);
130
131
2/2
✓ Branch 0 taken 352 times.
✓ Branch 1 taken 136 times.
488 for (int i = 0; i < at.cols; i++) {
132
2/2
✓ Branch 0 taken 120 times.
✓ Branch 1 taken 232 times.
352 Complex sum = ComputeScalarProduct(at, b, i, col);
133 if (IsNonZero(sum)) {
134 rows.push_back(i);
135 vals.push_back(sum);
136 }
137 }
138
139 136 col_rows[col] = std::move(rows);
140 col_vals[col] = std::move(vals);
141 }
142 136 }
143
144 } // namespace
145
146 48 bool BarkalovaMMultMatrixCcsSTL::RunImpl() {
147 48 const auto &a = GetInput().first;
148 48 const auto &b = GetInput().second;
149
150 try {
151 48 CCSMatrix at;
152
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 TransponirMatr(a, at);
153 48 CCSMatrix c;
154 48 c.rows = a.rows;
155 48 c.cols = b.cols;
156
157 const int total_cols = c.cols;
158
1/2
✓ Branch 2 taken 48 times.
✗ Branch 3 not taken.
48 unsigned int hardware_threads = std::thread::hardware_concurrency();
159 const unsigned int num_threads = std::max(1U, hardware_threads);
160
161
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 std::vector<std::vector<int>> col_rows(total_cols);
162
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 std::vector<std::vector<Complex>> col_vals(total_cols);
163 48 std::vector<std::future<void>> futures;
164
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 futures.reserve(num_threads);
165
166 48 int cols_per_thread = total_cols / static_cast<int>(num_threads);
167 48 int remainder = total_cols % static_cast<int>(num_threads);
168 int current_start = 0;
169
170
2/2
✓ Branch 0 taken 176 times.
✓ Branch 1 taken 8 times.
184 for (unsigned int thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
171
2/2
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 104 times.
176 int cols_for_thread = cols_per_thread + (std::cmp_less(thread_idx, remainder) ? 1 : 0);
172 176 int start = current_start;
173 176 int end = current_start + cols_for_thread;
174 current_start = end;
175
2/2
✓ Branch 0 taken 136 times.
✓ Branch 1 taken 40 times.
176 if (start >= total_cols) {
176 break;
177 }
178
179 272 futures.push_back(std::async(std::launch::async, ProcessColumnRange, start, end, std::cref(at), std::cref(b),
180
1/2
✓ Branch 1 taken 136 times.
✗ Branch 2 not taken.
272 std::ref(col_rows), std::ref(col_vals)));
181 }
182
2/2
✓ Branch 0 taken 136 times.
✓ Branch 1 taken 48 times.
184 for (auto &future : futures) {
183
1/2
✓ Branch 1 taken 136 times.
✗ Branch 2 not taken.
136 future.get();
184 }
185
186
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 std::vector<int> col_ptrs = {0};
187 48 std::vector<int> row_indices;
188 48 std::vector<Complex> values;
189
190
2/2
✓ Branch 0 taken 136 times.
✓ Branch 1 taken 48 times.
184 for (int j = 0; j < total_cols; ++j) {
191
2/4
✓ Branch 1 taken 136 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 136 times.
✗ Branch 5 not taken.
136 row_indices.insert(row_indices.end(), col_rows[j].begin(), col_rows[j].end());
192
1/2
✓ Branch 1 taken 136 times.
✗ Branch 2 not taken.
136 values.insert(values.end(), col_vals[j].begin(), col_vals[j].end());
193
1/4
✓ Branch 1 taken 136 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
136 col_ptrs.push_back(static_cast<int>(values.size()));
194 }
195
196 c.values = std::move(values);
197 c.row_indices = std::move(row_indices);
198 c.col_ptrs = std::move(col_ptrs);
199
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 c.nnz = static_cast<int>(c.values.size());
200
201
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 GetOutput() = c;
202 return true;
203
204
0/2
✗ Branch 10 not taken.
✗ Branch 11 not taken.
48 } catch (const std::exception &) {
205 return false;
206 }
207 }
208
209 48 bool BarkalovaMMultMatrixCcsSTL::PostProcessingImpl() {
210 const auto &c = GetOutput();
211
3/6
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 48 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 48 times.
48 return c.rows > 0 && c.cols > 0 && c.col_ptrs.size() == static_cast<size_t>(c.cols) + 1;
212 }
213
214 } // namespace barkalova_m_mult_matrix_ccs
215