GCC Code Coverage Report


Directory: ./
File: tasks/timur_a_cannon/stl/src/ops_stl.cpp
Date: 2026-04-02 17:12:27
Exec Total Coverage
Lines: 77 78 98.7%
Functions: 16 16 100.0%
Branches: 76 106 71.7%

Line Branch Exec Source
1 #include "timur_a_cannon/stl/include/ops_stl.hpp"
2
3 #include <algorithm>
4 #include <cstddef>
5 #include <thread>
6 #include <utility>
7 #include <vector>
8
9 #include "timur_a_cannon/common/include/common.hpp"
10 #include "util/include/util.hpp"
11
12 namespace timur_a_cannon {
13
14 namespace {
15
16 using Matrix = std::vector<std::vector<double>>;
17 using BlockGrid = std::vector<std::vector<Matrix>>;
18
19 template <typename Func>
20 768 void ParallelFor(int work_size, const Func &func) {
21
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 384 times.
768 if (work_size <= 0) {
22 return;
23 }
24
25
4/4
✓ Branch 1 taken 180 times.
✓ Branch 2 taken 204 times.
✓ Branch 3 taken 270 times.
✓ Branch 4 taken 114 times.
1128 const int num_threads = std::max(1, std::min(ppc::util::GetNumThreads(), work_size));
26 768 std::vector<std::thread> threads;
27
1/2
✓ Branch 1 taken 384 times.
✗ Branch 2 not taken.
768 threads.reserve(static_cast<std::size_t>(num_threads));
28
29
2/2
✓ Branch 0 taken 690 times.
✓ Branch 1 taken 384 times.
2148 for (int thread_id = 0; thread_id < num_threads; ++thread_id) {
30
1/2
✓ Branch 1 taken 690 times.
✗ Branch 2 not taken.
2760 threads.emplace_back([&, thread_id]() {
31
10/10
✓ Branch 0 taken 272 times.
✓ Branch 1 taken 230 times.
✓ Branch 2 taken 128 times.
✓ Branch 3 taken 110 times.
✓ Branch 4 taken 144 times.
✓ Branch 5 taken 120 times.
✓ Branch 6 taken 144 times.
✓ Branch 7 taken 120 times.
✓ Branch 8 taken 128 times.
✓ Branch 9 taken 110 times.
1506 for (int index = thread_id; index < work_size; index += num_threads) {
32 816 func(index);
33 }
34 });
35 }
36
37
2/2
✓ Branch 0 taken 690 times.
✓ Branch 1 taken 384 times.
2148 for (auto &thread : threads) {
38
1/2
✓ Branch 1 taken 690 times.
✗ Branch 2 not taken.
1380 thread.join();
39 }
40 768 }
41
42 void DistributeData(const Matrix &src_a, const Matrix &src_b, BlockGrid &bl_a, BlockGrid &bl_b, int b_size,
43 int grid_sz) {
44 256 ParallelFor(grid_sz, [&](int i) {
45
2/2
✓ Branch 0 taken 272 times.
✓ Branch 1 taken 128 times.
400 for (int j = 0; j < grid_sz; ++j) {
46 272 const int shift = (i + j) % grid_sz;
47
2/2
✓ Branch 0 taken 688 times.
✓ Branch 1 taken 272 times.
960 for (int row = 0; row < b_size; ++row) {
48
2/2
✓ Branch 0 taken 1936 times.
✓ Branch 1 taken 688 times.
2624 for (int col = 0; col < b_size; ++col) {
49 1936 bl_a[i][j][row][col] = src_a[(i * b_size) + row][(shift * b_size) + col];
50 1936 bl_b[i][j][row][col] = src_b[(shift * b_size) + row][(j * b_size) + col];
51 }
52 }
53 }
54 128 });
55 }
56
57 void RotateBlocksA(BlockGrid &blocks, int grid_sz) {
58
1/2
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
64 ParallelFor(grid_sz, [&](int i) {
59 144 Matrix first_block = std::move(blocks[i][0]);
60
2/2
✓ Branch 0 taken 192 times.
✓ Branch 1 taken 144 times.
336 for (int j = 0; j < grid_sz - 1; ++j) {
61 192 blocks[i][j] = std::move(blocks[i][j + 1]);
62 }
63 144 blocks[i][grid_sz - 1] = std::move(first_block);
64 144 });
65 }
66
67 void RotateBlocksB(BlockGrid &blocks, int grid_sz) {
68 272 ParallelFor(grid_sz, [&](int j) {
69 144 Matrix first_block = std::move(blocks[0][j]);
70
2/2
✓ Branch 0 taken 192 times.
✓ Branch 1 taken 144 times.
336 for (int i = 0; i < grid_sz - 1; ++i) {
71 192 blocks[i][j] = std::move(blocks[i + 1][j]);
72 }
73 144 blocks[grid_sz - 1][j] = std::move(first_block);
74 144 });
75 }
76
77 void CollectResult(const BlockGrid &bl_c, Matrix &result, int b_size, int grid_sz) {
78 256 ParallelFor(grid_sz, [&](int i) {
79
2/2
✓ Branch 0 taken 272 times.
✓ Branch 1 taken 128 times.
400 for (int j = 0; j < grid_sz; ++j) {
80
2/2
✓ Branch 0 taken 688 times.
✓ Branch 1 taken 272 times.
960 for (int row = 0; row < b_size; ++row) {
81
2/2
✓ Branch 0 taken 1936 times.
✓ Branch 1 taken 688 times.
2624 for (int col = 0; col < b_size; ++col) {
82 1936 result[(i * b_size) + row][(j * b_size) + col] = bl_c[i][j][row][col];
83 }
84 }
85 }
86 128 });
87 }
88
89 } // namespace
90
91
1/2
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
64 TimurACannonMatrixMultiplicationSTL::TimurACannonMatrixMultiplicationSTL(const InType &in) {
92 SetTypeOfTask(GetStaticTypeOfTask());
93 GetInput() = in;
94 64 }
95
96 64 bool TimurACannonMatrixMultiplicationSTL::ValidationImpl() {
97 const auto &input = GetInput();
98 64 int b_size = std::get<0>(input);
99 const auto &mat_a = std::get<1>(input);
100 const auto &mat_b = std::get<2>(input);
101
102
3/6
✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 64 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 64 times.
✗ Branch 5 not taken.
64 if (b_size <= 0 || mat_a.empty() || mat_b.empty()) {
103 return false;
104 }
105
106 const std::size_t n = mat_a.size();
107
2/4
✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 64 times.
✗ Branch 3 not taken.
64 if (mat_b.size() != n || (n % static_cast<std::size_t>(b_size) != 0)) {
108 return false;
109 }
110
111 const auto is_square_n = [n](const Matrix &matrix) {
112 return std::ranges::all_of(matrix, [n](const std::vector<double> &row) { return row.size() == n; });
113 };
114
115
1/2
✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
64 return is_square_n(mat_a) && is_square_n(mat_b);
116 }
117
118
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 64 times.
64 bool TimurACannonMatrixMultiplicationSTL::PreProcessingImpl() {
119 GetOutput().clear();
120 64 return true;
121 }
122
123 608 void TimurACannonMatrixMultiplicationSTL::BlockMultiplyAccumulate(const std::vector<std::vector<double>> &a,
124 const std::vector<std::vector<double>> &b,
125 std::vector<std::vector<double>> &c, int b_size) {
126
2/2
✓ Branch 0 taken 1568 times.
✓ Branch 1 taken 608 times.
2176 for (int i = 0; i < b_size; ++i) {
127
2/2
✓ Branch 0 taken 4448 times.
✓ Branch 1 taken 1568 times.
6016 for (int k = 0; k < b_size; ++k) {
128 4448 double temp = a[i][k];
129
2/2
✓ Branch 0 taken 13472 times.
✓ Branch 1 taken 4448 times.
17920 for (int j = 0; j < b_size; ++j) {
130 13472 c[i][j] += temp * b[k][j];
131 }
132 }
133 }
134 608 }
135
136 64 bool TimurACannonMatrixMultiplicationSTL::RunImpl() {
137 const auto &input = GetInput();
138 64 const int b_size = std::get<0>(input);
139 const auto &src_a = std::get<1>(input);
140 const auto &src_b = std::get<2>(input);
141 64 const int n = static_cast<int>(src_a.size());
142 64 const int grid_sz = n / b_size;
143
144
3/6
✓ Branch 2 taken 64 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 64 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 64 times.
✗ Branch 9 not taken.
64 BlockGrid bl_a(grid_sz, std::vector<Matrix>(grid_sz, Matrix(b_size, std::vector<double>(b_size))));
145
4/8
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 64 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 64 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 64 times.
✗ Branch 11 not taken.
64 BlockGrid bl_b(grid_sz, std::vector<Matrix>(grid_sz, Matrix(b_size, std::vector<double>(b_size))));
146
4/8
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 64 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 64 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 64 times.
✗ Branch 11 not taken.
64 BlockGrid bl_c(grid_sz, std::vector<Matrix>(grid_sz, Matrix(b_size, std::vector<double>(b_size, 0.0))));
147
148
1/2
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
64 DistributeData(src_a, src_b, bl_a, bl_b, b_size, grid_sz);
149
150
2/2
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 64 times.
192 for (int step = 0; step < grid_sz; ++step) {
151
1/2
✓ Branch 1 taken 128 times.
✗ Branch 2 not taken.
128 ParallelFor(grid_sz, [&](int i) {
152
2/2
✓ Branch 0 taken 608 times.
✓ Branch 1 taken 272 times.
880 for (int j = 0; j < grid_sz; ++j) {
153 608 BlockMultiplyAccumulate(bl_a[i][j], bl_b[i][j], bl_c[i][j], b_size);
154 }
155 272 });
156
157
2/2
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 64 times.
128 if (step < grid_sz - 1) {
158 64 RotateBlocksA(bl_a, grid_sz);
159
1/2
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
64 RotateBlocksB(bl_b, grid_sz);
160 }
161 }
162
163
2/4
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 64 times.
✗ Branch 5 not taken.
64 Matrix result(n, std::vector<double>(n));
164
1/2
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
64 CollectResult(bl_c, result, b_size, grid_sz);
165
166 64 GetOutput() = std::move(result);
167 64 return true;
168 64 }
169
170 64 bool TimurACannonMatrixMultiplicationSTL::PostProcessingImpl() {
171 64 return true;
172 }
173
174 } // namespace timur_a_cannon
175