GCC Code Coverage Report


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

Line Branch Exec Source
1 #include "agafonov_i_matrix_ccs_seq/omp/include/ops_omp.hpp"
2
3 #include <omp.h>
4
5 #include <algorithm>
6 #include <cmath>
7 #include <cstddef>
8 #include <vector>
9
10 #include "agafonov_i_matrix_ccs_seq/common/include/common.hpp"
11 #include "util/include/util.hpp"
12
13 namespace agafonov_i_matrix_ccs_seq {
14
15 AgafonovIMatrixCCSOMP::AgafonovIMatrixCCSOMP(const InType &in) {
16 SetTypeOfTask(GetStaticTypeOfTask());
17 GetInput() = in;
18 }
19
20 bool AgafonovIMatrixCCSOMP::ValidationImpl() {
21 const auto &left = GetInput().first;
22 const auto &right = GetInput().second;
23
24 return (left.cols_num == right.rows_num) && (left.col_ptrs.size() == left.cols_num + 1) &&
25 (right.col_ptrs.size() == right.cols_num + 1);
26 }
27
28 bool AgafonovIMatrixCCSOMP::PreProcessingImpl() {
29 GetOutput().vals.clear();
30 GetOutput().row_inds.clear();
31 return true;
32 }
33
34 void AgafonovIMatrixCCSOMP::ProcessColumn(size_t j, const InType::first_type &a, const InType::second_type &b,
35 std::vector<double> &accumulator, std::vector<size_t> &active_rows,
36 std::vector<bool> &row_mask, std::vector<double> &local_v,
37 std::vector<int> &local_r) {
38 const auto b_col_start = static_cast<size_t>(b.col_ptrs[j]);
39 const auto b_col_end = static_cast<size_t>(b.col_ptrs[j + 1]);
40
41 if (b_col_start == b_col_end) {
42 return;
43 }
44
45 for (size_t kb = b_col_start; kb < b_col_end; ++kb) {
46 const auto k = static_cast<size_t>(b.row_inds[kb]);
47 const double v_b = b.vals[kb];
48 const auto a_col_start = static_cast<size_t>(a.col_ptrs[k]);
49 const auto a_col_end = static_cast<size_t>(a.col_ptrs[k + 1]);
50
51 for (size_t ka = a_col_start; ka < a_col_end; ++ka) {
52 const auto i = static_cast<size_t>(a.row_inds[ka]);
53 if (!row_mask[i]) {
54 row_mask[i] = true;
55 active_rows.push_back(i);
56 }
57 accumulator[i] += a.vals[ka] * v_b;
58 }
59 }
60
61 std::ranges::sort(active_rows);
62
63 for (const auto row_idx : active_rows) {
64 if (std::abs(accumulator[row_idx]) > 1e-15) {
65 local_v.push_back(accumulator[row_idx]);
66 local_r.push_back(static_cast<int>(row_idx));
67 }
68 row_mask[row_idx] = false;
69 accumulator[row_idx] = 0.0;
70 }
71 active_rows.clear();
72 }
73
74 // Обновленный RunImpl
75 bool AgafonovIMatrixCCSOMP::RunImpl() {
76 const auto &a = GetInput().first;
77 const auto &b = GetInput().second;
78 auto &c = GetOutput();
79
80 c.rows_num = a.rows_num;
81 c.cols_num = b.cols_num;
82 c.col_ptrs.assign(c.cols_num + 1, 0);
83
84 std::vector<std::vector<double>> local_vals(b.cols_num);
85 std::vector<std::vector<int>> local_rows(b.cols_num);
86
87 #pragma omp parallel num_threads(ppc::util::GetNumThreads()) default(none) \
88 shared(a, b, local_vals, local_rows, std::ranges::sort)
89 {
90 std::vector<double> accumulator(a.rows_num, 0.0);
91 std::vector<size_t> active_rows;
92 std::vector<bool> row_mask(a.rows_num, false);
93
94 #pragma omp for
95 for (size_t j = 0; j < b.cols_num; ++j) {
96 ProcessColumn(j, a, b, accumulator, active_rows, row_mask, local_vals[j], local_rows[j]);
97 }
98 }
99
100 // ... (дальше код без изменений до конца функции)
101 size_t total_nnz = 0;
102 for (const auto &v : local_vals) {
103 total_nnz += v.size();
104 }
105 c.vals.reserve(total_nnz);
106 c.row_inds.reserve(total_nnz);
107
108 int current_nnz = 0;
109 for (size_t j = 0; j < b.cols_num; ++j) {
110 c.col_ptrs[j] = current_nnz;
111 c.vals.insert(c.vals.end(), local_vals[j].begin(), local_vals[j].end());
112 c.row_inds.insert(c.row_inds.end(), local_rows[j].begin(), local_rows[j].end());
113 current_nnz += static_cast<int>(local_vals[j].size());
114 }
115 c.col_ptrs[b.cols_num] = current_nnz;
116 c.nnz = current_nnz;
117 return true;
118 }
119
120 bool AgafonovIMatrixCCSOMP::PostProcessingImpl() {
121 return true;
122 }
123
124 } // namespace agafonov_i_matrix_ccs_seq
125