GCC Code Coverage Report


Directory: ./
File: tasks/alekseev_a_mult_matrix_crs/stl/src/ops_stl.cpp
Date: 2026-06-04 20:25:32
Exec Total Coverage
Lines: 57 57 100.0%
Functions: 7 7 100.0%
Branches: 42 64 65.6%

Line Branch Exec Source
1 #include "alekseev_a_mult_matrix_crs/stl/include/ops_stl.hpp"
2
3 #include <algorithm>
4 #include <cmath>
5 #include <cstddef>
6 #include <thread>
7 #include <utility>
8 #include <vector>
9
10 #include "alekseev_a_mult_matrix_crs/common/include/common.hpp"
11
12 namespace alekseev_a_mult_matrix_crs {
13
14
1/2
✓ Branch 2 taken 48 times.
✗ Branch 3 not taken.
48 AlekseevAMultMatrixCRSSTL::AlekseevAMultMatrixCRSSTL(const InType &in) {
15 SetTypeOfTask(GetStaticTypeOfTask());
16 GetInput() = in;
17 48 }
18
19 48 bool AlekseevAMultMatrixCRSSTL::ValidationImpl() {
20 const auto &a = std::get<0>(GetInput());
21 const auto &b = std::get<1>(GetInput());
22
3/6
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 48 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 48 times.
48 return a.cols == b.rows && !a.row_ptr.empty() && !b.row_ptr.empty();
23 }
24
25 48 bool AlekseevAMultMatrixCRSSTL::PreProcessingImpl() {
26 48 GetOutput() = {};
27 48 return true;
28 }
29
30 96 void AlekseevAMultMatrixCRSSTL::ProcessRow(std::size_t i, const CRSMatrix &a, const CRSMatrix &b,
31 std::vector<double> &temp_v, std::vector<std::size_t> &temp_c,
32 std::vector<double> &accum, std::vector<int> &touched_flag,
33 std::vector<std::size_t> &touched_cols) {
34
2/2
✓ Branch 0 taken 104 times.
✓ Branch 1 taken 96 times.
200 for (std::size_t pos_a = a.row_ptr[i]; pos_a < a.row_ptr[i + 1]; ++pos_a) {
35 104 std::size_t k = a.col_indices[pos_a];
36 104 double val_a = a.values[pos_a];
37
38
2/2
✓ Branch 0 taken 160 times.
✓ Branch 1 taken 104 times.
264 for (std::size_t pos_b = b.row_ptr[k]; pos_b < b.row_ptr[k + 1]; ++pos_b) {
39
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 120 times.
160 std::size_t j = b.col_indices[pos_b];
40
41
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 120 times.
160 if (std::cmp_not_equal(touched_flag[j], i)) {
42
1/2
✓ Branch 0 taken 120 times.
✗ Branch 1 not taken.
120 touched_flag[j] = static_cast<int>(i);
43 touched_cols.push_back(j);
44 120 accum[j] = 0.0;
45 }
46 160 accum[j] += val_a * b.values[pos_b];
47 }
48 }
49
50 std::ranges::sort(touched_cols);
51
52
3/4
✓ Branch 0 taken 120 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 120 times.
✓ Branch 3 taken 96 times.
216 for (auto col : touched_cols) {
53
1/2
✓ Branch 0 taken 120 times.
✗ Branch 1 not taken.
120 if (std::abs(accum[col]) > 1e-15) {
54 temp_v.push_back(accum[col]);
55 temp_c.push_back(col);
56 }
57 }
58 touched_cols.clear();
59 96 }
60
61 48 bool AlekseevAMultMatrixCRSSTL::RunImpl() {
62 const auto &a = std::get<0>(GetInput());
63 const auto &b = std::get<1>(GetInput());
64 auto &c = GetOutput();
65
66 48 c.rows = a.rows;
67 48 c.cols = b.cols;
68 48 c.row_ptr.assign(c.rows + 1, 0);
69
70 48 std::vector<std::vector<double>> temp_values(c.rows);
71
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 std::vector<std::vector<std::size_t>> temp_cols(c.rows);
72
73 48 unsigned int num_threads = std::thread::hardware_concurrency();
74
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 if (num_threads == 0) {
75 num_threads = 2;
76 }
77
78 48 std::vector<std::thread> threads;
79
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 threads.reserve(num_threads);
80 48 std::size_t chunk_size = (c.rows + num_threads - 1) / num_threads;
81
82
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 for (unsigned int thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
83 144 std::size_t start_row = thread_idx * chunk_size;
84
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 48 times.
144 std::size_t end_row = std::min(start_row + chunk_size, c.rows);
85
86
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 48 times.
144 if (start_row >= end_row) {
87 break;
88 }
89
90
1/2
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
96 threads.emplace_back([&, start_row, end_row]() {
91 96 std::vector<double> accum(c.cols, 0.0);
92
1/4
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
96 std::vector<int> touched_flag(c.cols, -1);
93 96 std::vector<std::size_t> touched_cols;
94
1/2
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
96 touched_cols.reserve(c.cols);
95
96
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 96 times.
192 for (std::size_t i = start_row; i < end_row; ++i) {
97
1/2
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
96 ProcessRow(i, a, b, temp_values[i], temp_cols[i], accum, touched_flag, touched_cols);
98 }
99 96 });
100 }
101
102
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 48 times.
144 for (auto &thread : threads) {
103
1/2
✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
96 if (thread.joinable()) {
104
1/2
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
96 thread.join();
105 }
106 }
107
108
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 48 times.
144 for (std::size_t i = 0; i < c.rows; ++i) {
109 96 c.row_ptr[i + 1] = c.row_ptr[i] + temp_values[i].size();
110 }
111
112
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 c.values.reserve(c.row_ptr[c.rows]);
113
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 c.col_indices.reserve(c.row_ptr[c.rows]);
114
115
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 48 times.
144 for (std::size_t i = 0; i < c.rows; ++i) {
116
1/2
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
96 c.values.insert(c.values.end(), temp_values[i].begin(), temp_values[i].end());
117 96 c.col_indices.insert(c.col_indices.end(), temp_cols[i].begin(), temp_cols[i].end());
118 }
119
120 48 return true;
121 48 }
122
123 48 bool AlekseevAMultMatrixCRSSTL::PostProcessingImpl() {
124 48 return true;
125 }
126
127 } // namespace alekseev_a_mult_matrix_crs
128