GCC Code Coverage Report


Directory: ./
File: tasks/dolov_v_crs_mat_mult/omp/src/ops_omp.cpp
Date: 2026-05-11 08:26:31
Exec Total Coverage
Lines: 64 65 98.5%
Functions: 7 7 100.0%
Branches: 36 54 66.7%

Line Branch Exec Source
1 #include "dolov_v_crs_mat_mult/omp/include/ops_omp.hpp"
2
3 #include <omp.h>
4
5 #include <cmath>
6 #include <utility>
7 #include <vector>
8
9 #include "dolov_v_crs_mat_mult/common/include/common.hpp"
10
11 namespace dolov_v_crs_mat_mult {
12
13
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 DolovVCrsMatMultOmp::DolovVCrsMatMultOmp(const InType &in) {
14 SetTypeOfTask(GetStaticTypeOfTask());
15
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 GetInput() = in;
16 28 }
17
18
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
28 bool DolovVCrsMatMultOmp::ValidationImpl() {
19 const auto &input_data = GetInput();
20
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
28 if (input_data.size() != 2) {
21 return false;
22 }
23 const auto &matrix_a = input_data[0];
24 const auto &matrix_b = input_data[1];
25
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 28 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 28 times.
28 return matrix_a.num_cols == matrix_b.num_rows && matrix_a.num_rows > 0 && matrix_b.num_cols > 0;
26 }
27
28 28 bool DolovVCrsMatMultOmp::PreProcessingImpl() {
29 28 return true;
30 }
31
32 28 SparseMatrix DolovVCrsMatMultOmp::TransposeMatrix(const SparseMatrix &matrix) {
33 28 SparseMatrix transposed;
34 28 transposed.num_rows = matrix.num_cols;
35 28 transposed.num_cols = matrix.num_rows;
36
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 transposed.row_pointers.assign(transposed.num_rows + 1, 0);
37
38
2/2
✓ Branch 0 taken 1192 times.
✓ Branch 1 taken 28 times.
1220 for (int col_idx : matrix.col_indices) {
39 1192 transposed.row_pointers[col_idx + 1]++;
40 }
41
2/2
✓ Branch 0 taken 540 times.
✓ Branch 1 taken 28 times.
568 for (int i = 0; i < transposed.num_rows; ++i) {
42 540 transposed.row_pointers[i + 1] += transposed.row_pointers[i];
43 }
44
45
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 transposed.values.resize(matrix.values.size());
46
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 transposed.col_indices.resize(matrix.col_indices.size());
47
48
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 std::vector<int> current_pos = transposed.row_pointers;
49
2/2
✓ Branch 0 taken 916 times.
✓ Branch 1 taken 28 times.
944 for (int i = 0; i < matrix.num_rows; ++i) {
50
2/2
✓ Branch 0 taken 1192 times.
✓ Branch 1 taken 916 times.
2108 for (int j = matrix.row_pointers[i]; j < matrix.row_pointers[i + 1]; ++j) {
51 1192 int col = matrix.col_indices[j];
52 1192 int dest_idx = current_pos[col]++;
53 1192 transposed.values[dest_idx] = matrix.values[j];
54 1192 transposed.col_indices[dest_idx] = i;
55 }
56 }
57 28 return transposed;
58 }
59
60 41744 double DolovVCrsMatMultOmp::DotProduct(const SparseMatrix &matrix_a, int row_a, const SparseMatrix &matrix_b_t,
61 int row_b) {
62 double sum = 0.0;
63 41744 int ptr_a = matrix_a.row_pointers[row_a];
64 41744 int ptr_b = matrix_b_t.row_pointers[row_b];
65 41744 const int end_a = matrix_a.row_pointers[row_a + 1];
66 41744 const int end_b = matrix_b_t.row_pointers[row_b + 1];
67
68
2/2
✓ Branch 0 taken 100876 times.
✓ Branch 1 taken 41744 times.
142620 while (ptr_a < end_a && ptr_b < end_b) {
69
2/2
✓ Branch 0 taken 2468 times.
✓ Branch 1 taken 98408 times.
100876 if (matrix_a.col_indices[ptr_a] == matrix_b_t.col_indices[ptr_b]) {
70 2468 sum += matrix_a.values[ptr_a] * matrix_b_t.values[ptr_b];
71 2468 ptr_a++;
72 2468 ptr_b++;
73
2/2
✓ Branch 0 taken 52700 times.
✓ Branch 1 taken 45708 times.
98408 } else if (matrix_a.col_indices[ptr_a] < matrix_b_t.col_indices[ptr_b]) {
74 52700 ptr_a++;
75 } else {
76 45708 ptr_b++;
77 }
78 }
79 41744 return sum;
80 }
81
82 28 bool DolovVCrsMatMultOmp::RunImpl() {
83 const auto &matrix_a = GetInput()[0];
84 const auto &matrix_b = GetInput()[1];
85
86 28 SparseMatrix matrix_b_t = TransposeMatrix(matrix_b);
87 28 int rows = matrix_a.num_rows;
88
89
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 std::vector<std::vector<double>> temp_values(rows);
90
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 std::vector<std::vector<int>> temp_cols(rows);
91
92 28 #pragma omp parallel for schedule(dynamic, 10) default(none) shared(matrix_a, matrix_b_t, temp_values, temp_cols, rows)
93 for (int i = 0; i < rows; ++i) {
94 std::vector<double> local_vals;
95 std::vector<int> local_cols;
96
97 for (int j = 0; j < matrix_b_t.num_rows; ++j) {
98 double sum = DolovVCrsMatMultOmp::DotProduct(matrix_a, i, matrix_b_t, j);
99 if (std::fabs(sum) > 1e-15) {
100 local_vals.push_back(sum);
101 local_cols.push_back(j);
102 }
103 }
104 temp_values[i] = std::move(local_vals);
105 temp_cols[i] = std::move(local_cols);
106 }
107
108 28 SparseMatrix res;
109 28 res.num_rows = rows;
110 28 res.num_cols = matrix_b.num_cols;
111
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 res.row_pointers.assign(rows + 1, 0);
112
113
2/2
✓ Branch 0 taken 560 times.
✓ Branch 1 taken 28 times.
588 for (int i = 0; i < rows; ++i) {
114 560 res.row_pointers[i + 1] = res.row_pointers[i] + static_cast<int>(temp_values[i].size());
115 }
116
117 28 int total_nz = res.row_pointers[rows];
118
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 res.values.reserve(total_nz);
119
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 res.col_indices.reserve(total_nz);
120
121
2/2
✓ Branch 0 taken 560 times.
✓ Branch 1 taken 28 times.
588 for (int i = 0; i < rows; ++i) {
122
2/4
✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
560 res.values.insert(res.values.end(), temp_values[i].begin(), temp_values[i].end());
123 560 res.col_indices.insert(res.col_indices.end(), temp_cols[i].begin(), temp_cols[i].end());
124 }
125
126 28 GetOutput() = std::move(res);
127 28 return true;
128 28 }
129
130 28 bool DolovVCrsMatMultOmp::PostProcessingImpl() {
131 28 return true;
132 }
133
134 } // namespace dolov_v_crs_mat_mult
135