GCC Code Coverage Report


Directory: ./
File: tasks/dolov_v_crs_mat_mult/stl/src/ops_stl.cpp
Date: 2026-05-11 08:26:31
Exec Total Coverage
Lines: 87 89 97.8%
Functions: 9 9 100.0%
Branches: 57 80 71.2%

Line Branch Exec Source
1 #include "dolov_v_crs_mat_mult/stl/include/ops_stl.hpp"
2
3 #include <cmath>
4 #include <thread>
5 #include <utility>
6 #include <vector>
7
8 #include "dolov_v_crs_mat_mult/common/include/common.hpp"
9 #include "util/include/util.hpp"
10
11 namespace dolov_v_crs_mat_mult {
12
13 namespace {
14 56 SparseMatrix AssembleResult(int rows, int cols, const std::vector<std::vector<double>> &temp_values,
15 const std::vector<std::vector<int>> &temp_cols) {
16 56 SparseMatrix res;
17 56 res.num_rows = rows;
18 56 res.num_cols = cols;
19
1/2
✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
56 res.row_pointers.assign(rows + 1, 0);
20
21
2/2
✓ Branch 0 taken 1120 times.
✓ Branch 1 taken 56 times.
1176 for (int i = 0; i < rows; ++i) {
22 1120 res.row_pointers[i + 1] = res.row_pointers[i] + static_cast<int>(temp_values[i].size());
23 }
24
25
1/2
✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
56 int total_nz = res.row_pointers[rows];
26
1/2
✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
56 res.values.reserve(total_nz);
27
1/2
✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
56 res.col_indices.reserve(total_nz);
28
29
2/2
✓ Branch 0 taken 1120 times.
✓ Branch 1 taken 56 times.
1176 for (int i = 0; i < rows; ++i) {
30
2/4
✓ Branch 1 taken 1120 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1120 times.
✗ Branch 5 not taken.
1120 res.values.insert(res.values.end(), temp_values[i].begin(), temp_values[i].end());
31 1120 res.col_indices.insert(res.col_indices.end(), temp_cols[i].begin(), temp_cols[i].end());
32 }
33
34 56 return res;
35 }
36 } // namespace
37
38
1/2
✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
56 DolovVCrsMatMultStl::DolovVCrsMatMultStl(const InType &in) {
39 SetTypeOfTask(GetStaticTypeOfTask());
40
1/2
✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
56 GetInput() = in;
41 56 }
42
43
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
56 bool DolovVCrsMatMultStl::ValidationImpl() {
44 const auto &input_data = GetInput();
45
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
56 if (input_data.size() != 2) {
46 return false;
47 }
48 const auto &matrix_a = input_data[0];
49 const auto &matrix_b = input_data[1];
50
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 56 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 56 times.
56 return matrix_a.num_cols == matrix_b.num_rows && matrix_a.num_rows > 0 && matrix_b.num_cols > 0;
51 }
52
53 56 bool DolovVCrsMatMultStl::PreProcessingImpl() {
54 56 return true;
55 }
56
57 56 SparseMatrix DolovVCrsMatMultStl::TransposeMatrix(const SparseMatrix &matrix) {
58 56 SparseMatrix transposed;
59 56 transposed.num_rows = matrix.num_cols;
60 56 transposed.num_cols = matrix.num_rows;
61
1/2
✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
56 transposed.row_pointers.assign(transposed.num_rows + 1, 0);
62
63
2/2
✓ Branch 0 taken 2384 times.
✓ Branch 1 taken 56 times.
2440 for (int col_idx : matrix.col_indices) {
64 2384 transposed.row_pointers[col_idx + 1]++;
65 }
66
2/2
✓ Branch 0 taken 1080 times.
✓ Branch 1 taken 56 times.
1136 for (int i = 0; i < transposed.num_rows; ++i) {
67 1080 transposed.row_pointers[i + 1] += transposed.row_pointers[i];
68 }
69
70
1/2
✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
56 transposed.values.resize(matrix.values.size());
71
1/2
✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
56 transposed.col_indices.resize(matrix.col_indices.size());
72
73
1/2
✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
56 std::vector<int> current_pos = transposed.row_pointers;
74
2/2
✓ Branch 0 taken 1832 times.
✓ Branch 1 taken 56 times.
1888 for (int i = 0; i < matrix.num_rows; ++i) {
75
2/2
✓ Branch 0 taken 2384 times.
✓ Branch 1 taken 1832 times.
4216 for (int j = matrix.row_pointers[i]; j < matrix.row_pointers[i + 1]; ++j) {
76 2384 int col = matrix.col_indices[j];
77 2384 int dest_idx = current_pos[col]++;
78 2384 transposed.values[dest_idx] = matrix.values[j];
79 2384 transposed.col_indices[dest_idx] = i;
80 }
81 }
82 56 return transposed;
83 }
84
85 83488 double DolovVCrsMatMultStl::DotProduct(const SparseMatrix &matrix_a, int row_a, const SparseMatrix &matrix_b_t,
86 int row_b) {
87 double sum = 0.0;
88 83488 int ptr_a = matrix_a.row_pointers[row_a];
89 83488 int ptr_b = matrix_b_t.row_pointers[row_b];
90 83488 const int end_a = matrix_a.row_pointers[row_a + 1];
91 83488 const int end_b = matrix_b_t.row_pointers[row_b + 1];
92
93
2/2
✓ Branch 0 taken 201752 times.
✓ Branch 1 taken 83488 times.
285240 while (ptr_a < end_a && ptr_b < end_b) {
94
2/2
✓ Branch 0 taken 4936 times.
✓ Branch 1 taken 196816 times.
201752 if (matrix_a.col_indices[ptr_a] == matrix_b_t.col_indices[ptr_b]) {
95 4936 sum += matrix_a.values[ptr_a] * matrix_b_t.values[ptr_b];
96 4936 ptr_a++;
97 4936 ptr_b++;
98
2/2
✓ Branch 0 taken 105400 times.
✓ Branch 1 taken 91416 times.
196816 } else if (matrix_a.col_indices[ptr_a] < matrix_b_t.col_indices[ptr_b]) {
99 105400 ptr_a++;
100 } else {
101 91416 ptr_b++;
102 }
103 }
104 83488 return sum;
105 }
106
107 56 bool DolovVCrsMatMultStl::RunImpl() {
108 const auto &matrix_a = GetInput()[0];
109 const auto &matrix_b = GetInput()[1];
110
111 56 SparseMatrix matrix_b_t = TransposeMatrix(matrix_b);
112 56 int rows = matrix_a.num_rows;
113
114
1/2
✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
56 std::vector<std::vector<double>> temp_values(rows);
115
1/2
✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
56 std::vector<std::vector<int>> temp_cols(rows);
116
117
1/2
✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
56 int num_threads = ppc::util::GetNumThreads();
118 56 std::vector<std::thread> threads;
119
120 114 auto worker = [&](int start_row, int end_row) {
121
2/2
✓ Branch 0 taken 1120 times.
✓ Branch 1 taken 114 times.
1234 for (int i = start_row; i < end_row; ++i) {
122 1120 std::vector<double> local_vals;
123 1120 std::vector<int> local_cols;
124
2/2
✓ Branch 0 taken 83488 times.
✓ Branch 1 taken 1120 times.
84608 for (int j = 0; j < matrix_b_t.num_rows; ++j) {
125
2/2
✓ Branch 0 taken 4504 times.
✓ Branch 1 taken 78984 times.
83488 double sum = DolovVCrsMatMultStl::DotProduct(matrix_a, i, matrix_b_t, j);
126
2/2
✓ Branch 0 taken 4504 times.
✓ Branch 1 taken 78984 times.
83488 if (std::abs(sum) > 1e-15) {
127 local_vals.push_back(sum);
128 local_cols.push_back(j);
129 }
130 }
131 1120 temp_values[i] = std::move(local_vals);
132 1120 temp_cols[i] = std::move(local_cols);
133 }
134 114 };
135
136 56 int chunk_size = rows / num_threads;
137 56 int remainder = rows % num_threads;
138 56 int current_start = 0;
139
140
2/2
✓ Branch 0 taken 140 times.
✓ Branch 1 taken 56 times.
196 for (int thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
141
2/2
✓ Branch 0 taken 100 times.
✓ Branch 1 taken 40 times.
140 int current_end = current_start + chunk_size + (thread_idx < remainder ? 1 : 0);
142
2/2
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 26 times.
140 if (current_start < current_end) {
143
1/2
✓ Branch 1 taken 114 times.
✗ Branch 2 not taken.
114 threads.emplace_back(worker, current_start, current_end);
144 }
145 140 current_start = current_end;
146 }
147
148
2/2
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 56 times.
170 for (auto &thread : threads) {
149
1/2
✓ Branch 1 taken 114 times.
✗ Branch 2 not taken.
114 thread.join();
150 }
151
152
1/2
✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
56 GetOutput() = AssembleResult(rows, matrix_b.num_cols, temp_values, temp_cols);
153
154 56 return true;
155 56 }
156
157 56 bool DolovVCrsMatMultStl::PostProcessingImpl() {
158 56 return true;
159 }
160
161 } // namespace dolov_v_crs_mat_mult
162