GCC Code Coverage Report


Directory: ./
File: tasks/viderman_a_sparse_matrix_mult_crs_complex/omp/src/ops_omp.cpp
Date: 2026-06-04 20:25:32
Exec Total Coverage
Lines: 47 47 100.0%
Functions: 7 7 100.0%
Branches: 30 46 65.2%

Line Branch Exec Source
1 #include "viderman_a_sparse_matrix_mult_crs_complex/omp/include/ops_omp.hpp"
2
3 #include <algorithm>
4 #include <cmath>
5 #include <complex>
6 #include <cstddef>
7 #include <vector>
8
9 #include "viderman_a_sparse_matrix_mult_crs_complex/common/include/common.hpp"
10
11 namespace viderman_a_sparse_matrix_mult_crs_complex {
12 namespace {
13
14
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 38 times.
40 void ProcessRow(const CRSMatrix &a, const CRSMatrix &b, int row, std::vector<std::complex<double>> &accumulator,
15 std::vector<int> &marker, std::vector<int> &current_row_indices, std::vector<int> &dst_cols,
16 std::vector<Complex> &dst_vals) {
17 current_row_indices.clear();
18
19
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 40 times.
68 for (int j = a.row_ptr[row]; j < a.row_ptr[row + 1]; ++j) {
20 28 const int col_a = a.col_indices[j];
21 28 const std::complex<double> val_a = a.values[j];
22
23
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 28 times.
56 for (int k = b.row_ptr[col_a]; k < b.row_ptr[col_a + 1]; ++k) {
24
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 const int col_b = b.col_indices[k];
25
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 accumulator[col_b] += val_a * b.values[k];
26
27
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 if (marker[col_b] != row) {
28 current_row_indices.push_back(col_b);
29 28 marker[col_b] = row;
30 }
31 }
32 }
33
34 std::ranges::sort(current_row_indices);
35
36 dst_cols.clear();
37 dst_vals.clear();
38 40 dst_cols.reserve(current_row_indices.size());
39 40 dst_vals.reserve(current_row_indices.size());
40
41
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 40 times.
68 for (const int idx : current_row_indices) {
42
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 if (std::abs(accumulator[idx]) > kEpsilon) {
43 dst_cols.push_back(idx);
44 dst_vals.push_back(accumulator[idx]);
45 }
46 28 accumulator[idx] = std::complex<double>(0.0, 0.0);
47 }
48 40 }
49
50 } // namespace
51
52
1/2
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
24 VidermanASparseMatrixMultCRSComplexOMP::VidermanASparseMatrixMultCRSComplexOMP(const InType &in) {
53 SetTypeOfTask(GetStaticTypeOfTask());
54 GetInput() = in;
55 24 GetOutput() = CRSMatrix();
56 24 }
57
58
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 bool VidermanASparseMatrixMultCRSComplexOMP::ValidationImpl() {
59 const auto &input = GetInput();
60 const auto &a = std::get<0>(input);
61 const auto &b = std::get<1>(input);
62
63
2/4
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
24 if (!a.IsValid() || !b.IsValid()) {
64 return false;
65 }
66
67
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 20 times.
24 if (a.cols != b.rows) {
68 4 return false;
69 }
70
71 return true;
72 }
73
74 20 bool VidermanASparseMatrixMultCRSComplexOMP::PreProcessingImpl() {
75 const auto &input = GetInput();
76
77 20 A_ = &std::get<0>(input);
78 20 B_ = &std::get<1>(input);
79
80 20 return true;
81 }
82
83 20 void VidermanASparseMatrixMultCRSComplexOMP::Multiply(const CRSMatrix &a, const CRSMatrix &b, CRSMatrix &c) {
84 20 c.rows = a.rows;
85 20 c.cols = b.cols;
86
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
20 c.row_ptr.assign(a.rows + 1, 0);
87 c.col_indices.clear();
88 c.values.clear();
89
90 20 std::vector<std::vector<int>> row_cols(a.rows);
91
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 std::vector<std::vector<Complex>> row_vals(a.rows);
92
93 20 #pragma omp parallel default(none) shared(a, b, row_cols, row_vals, kEpsilon)
94 {
95 std::vector<std::complex<double>> accumulator(b.cols, std::complex<double>(0.0, 0.0));
96 std::vector<int> marker(b.cols, -1);
97 std::vector<int> current_row_indices;
98
99 #pragma omp for schedule(static)
100 for (int i = 0; i < a.rows; ++i) {
101 auto &dst_cols = row_cols[i];
102 auto &dst_vals = row_vals[i];
103 ProcessRow(a, b, i, accumulator, marker, current_row_indices, dst_cols, dst_vals);
104 }
105 }
106
107
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 20 times.
60 for (int i = 0; i < a.rows; ++i) {
108 40 c.row_ptr[i + 1] = c.row_ptr[i] + static_cast<int>(row_cols[i].size());
109 }
110
111
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 c.col_indices.reserve(static_cast<std::size_t>(c.row_ptr[a.rows]));
112
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 c.values.reserve(static_cast<std::size_t>(c.row_ptr[a.rows]));
113
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 20 times.
60 for (int i = 0; i < a.rows; ++i) {
114
2/4
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 40 times.
✗ Branch 5 not taken.
40 c.col_indices.insert(c.col_indices.end(), row_cols[i].begin(), row_cols[i].end());
115 40 c.values.insert(c.values.end(), row_vals[i].begin(), row_vals[i].end());
116 }
117 20 }
118
119 20 bool VidermanASparseMatrixMultCRSComplexOMP::RunImpl() {
120
2/4
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
20 if (A_ == nullptr || B_ == nullptr) {
121 return false;
122 }
123
124 CRSMatrix &c = GetOutput();
125 20 Multiply(*A_, *B_, c);
126
127 20 return true;
128 }
129
130 20 bool VidermanASparseMatrixMultCRSComplexOMP::PostProcessingImpl() {
131 CRSMatrix &c = GetOutput();
132 20 return c.IsValid();
133 }
134
135 } // namespace viderman_a_sparse_matrix_mult_crs_complex
136