GCC Code Coverage Report


Directory: ./
File: tasks/lobanov_d_multi_matrix_crs/omp/src/ops_omp.cpp
Date: 2026-04-02 17:12:27
Exec Total Coverage
Lines: 0 39 0.0%
Functions: 0 5 0.0%
Branches: 0 44 0.0%

Line Branch Exec Source
1 #include "lobanov_d_multi_matrix_crs/omp/include/ops_omp.hpp"
2
3 #include <cmath>
4 #include <cstddef>
5 #include <map>
6 #include <vector>
7
8 #include "lobanov_d_multi_matrix_crs/common/include/common.hpp"
9 #include "util/include/util.hpp"
10
11 namespace lobanov_d_multi_matrix_crs {
12
13 LobanovMultyMatrixOMP::LobanovMultyMatrixOMP(const InType &in) {
14 SetTypeOfTask(GetStaticTypeOfTask());
15 GetInput() = in;
16 GetOutput() = CompressedRowMatrix{};
17 }
18
19 bool LobanovMultyMatrixOMP::ValidationImpl() {
20 const auto &matrix_a = GetInput().first;
21 const auto &matrix_b = GetInput().second;
22
23 if (matrix_a.row_count <= 0 || matrix_b.row_count <= 0 || matrix_a.column_count <= 0 || matrix_b.column_count <= 0) {
24 return false;
25 }
26 if (matrix_a.column_count != matrix_b.row_count) {
27 return false;
28 }
29 if (matrix_a.row_pointer_data.size() != static_cast<size_t>(matrix_a.row_count) + 1 ||
30 matrix_b.row_pointer_data.size() != static_cast<size_t>(matrix_b.row_count) + 1) {
31 return false;
32 }
33 if (static_cast<size_t>(matrix_a.non_zero_count) != matrix_a.value_data.size() ||
34 static_cast<size_t>(matrix_a.non_zero_count) != matrix_a.column_index_data.size() ||
35 static_cast<size_t>(matrix_b.non_zero_count) != matrix_b.value_data.size() ||
36 static_cast<size_t>(matrix_b.non_zero_count) != matrix_b.column_index_data.size()) {
37 return false;
38 }
39 return true;
40 }
41
42 bool LobanovMultyMatrixOMP::PreProcessingImpl() {
43 const auto &matrix_a = GetInput().first;
44 const auto &matrix_b = GetInput().second;
45
46 auto &result = GetOutput();
47 result.row_count = matrix_a.row_count;
48 result.column_count = matrix_b.column_count;
49 result.non_zero_count = 0;
50 result.value_data.clear();
51 result.column_index_data.clear();
52 result.row_pointer_data.assign(static_cast<size_t>(result.row_count) + 1, 0);
53 return true;
54 }
55
56 bool LobanovMultyMatrixOMP::RunImpl() {
57 const auto &matrix_a = GetInput().first;
58 const auto &matrix_b = GetInput().second;
59 auto &result = GetOutput();
60
61 const int rows_a = matrix_a.row_count;
62
63 std::vector<std::map<int, double>> row_results(static_cast<size_t>(rows_a));
64
65 #pragma omp parallel for default(none) shared(matrix_a, matrix_b, row_results, rows_a) \
66 num_threads(ppc::util::GetNumThreads()) schedule(dynamic)
67 for (int i = 0; i < rows_a; ++i) {
68 const int a_start = matrix_a.row_pointer_data[static_cast<size_t>(i)];
69 const int a_end = matrix_a.row_pointer_data[static_cast<size_t>(i) + 1];
70
71 for (int a_idx = a_start; a_idx < a_end; ++a_idx) {
72 const int k = matrix_a.column_index_data[static_cast<size_t>(a_idx)];
73 const double a_val = matrix_a.value_data[static_cast<size_t>(a_idx)];
74
75 if (k >= matrix_b.row_count) {
76 continue;
77 }
78
79 const int b_start = matrix_b.row_pointer_data[static_cast<size_t>(k)];
80 const int b_end = matrix_b.row_pointer_data[static_cast<size_t>(k) + 1];
81
82 for (int b_idx = b_start; b_idx < b_end; ++b_idx) {
83 const int j = matrix_b.column_index_data[static_cast<size_t>(b_idx)];
84 const double b_val = matrix_b.value_data[static_cast<size_t>(b_idx)];
85
86 row_results[static_cast<size_t>(i)][j] += a_val * b_val;
87 }
88 }
89 }
90
91 int offset = 0;
92 result.row_pointer_data[0] = 0;
93 for (int i = 0; i < rows_a; ++i) {
94 const auto &row = row_results[static_cast<size_t>(i)];
95 for (const auto &[col, val] : row) {
96 if (std::abs(val) > 1e-12) {
97 result.column_index_data.push_back(col);
98 result.value_data.push_back(val);
99 ++offset;
100 }
101 }
102 result.row_pointer_data[static_cast<size_t>(i) + 1] = offset;
103 }
104 result.non_zero_count = static_cast<int>(result.value_data.size());
105
106 return true;
107 }
108
109 bool LobanovMultyMatrixOMP::PostProcessingImpl() {
110 return true;
111 }
112
113 } // namespace lobanov_d_multi_matrix_crs
114