GCC Code Coverage Report


Directory: ./
File: tasks/zyazeva_s_matrix_mult_cannon_alg/stl/src/ops_stl.cpp
Date: 2026-06-04 20:25:32
Exec Total Coverage
Lines: 112 113 99.1%
Functions: 20 20 100.0%
Branches: 68 102 66.7%

Line Branch Exec Source
1 #include "zyazeva_s_matrix_mult_cannon_alg/stl/include/ops_stl.hpp"
2
3 #include <algorithm>
4 #include <cmath>
5 #include <cstddef>
6 #include <functional>
7 #include <thread>
8 #include <utility>
9 #include <vector>
10
11 #include "zyazeva_s_matrix_mult_cannon_alg/common/include/common.hpp"
12
13 namespace {
14
15 96 void ParallelFor(size_t count, const std::function<void(size_t)> &func) {
16 96 size_t threads_count = std::thread::hardware_concurrency();
17
18
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96 times.
96 if (threads_count == 0) {
19 threads_count = 4;
20 }
21
22 96 threads_count = std::min<size_t>(threads_count, count);
23
24 96 std::vector<std::thread> threads(threads_count);
25
26 96 size_t block_size = count / threads_count;
27 96 size_t remainder = count % threads_count;
28
29 size_t begin = 0;
30
31
2/2
✓ Branch 0 taken 336 times.
✓ Branch 1 taken 96 times.
432 for (size_t th = 0; th < threads_count; ++th) {
32
2/2
✓ Branch 0 taken 272 times.
✓ Branch 1 taken 64 times.
336 size_t end = begin + block_size + (th < remainder ? 1 : 0);
33
34 336 threads[th] = std::thread([begin, end, &func]() {
35
2/2
✓ Branch 0 taken 496 times.
✓ Branch 1 taken 336 times.
832 for (size_t i = begin; i < end; ++i) {
36
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 496 times.
992 func(i);
37 }
38
1/2
✓ Branch 1 taken 336 times.
✗ Branch 2 not taken.
336 });
39
40 begin = end;
41 }
42
43
2/2
✓ Branch 0 taken 336 times.
✓ Branch 1 taken 96 times.
432 for (auto &th : threads) {
44
1/2
✓ Branch 1 taken 336 times.
✗ Branch 2 not taken.
336 th.join();
45 }
46 96 }
47
48 64 void MulBlock(const std::vector<double> &a, const std::vector<double> &b, std::vector<double> &c, size_t bs) {
49
2/2
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 64 times.
192 for (size_t i = 0; i < bs; ++i) {
50
2/2
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 128 times.
384 for (size_t k = 0; k < bs; ++k) {
51 256 double v = a[(i * bs) + k];
52
53
2/2
✓ Branch 0 taken 512 times.
✓ Branch 1 taken 256 times.
768 for (size_t j = 0; j < bs; ++j) {
54 512 c[(i * bs) + j] += v * b[(k * bs) + j];
55 }
56 }
57 }
58 64 }
59
60 48 void RegularMultiplication(const std::vector<double> &a, const std::vector<double> &b, std::vector<double> &c,
61 size_t n) {
62
1/2
✓ Branch 2 taken 48 times.
✗ Branch 3 not taken.
48 ParallelFor(n, [&](size_t i) {
63
2/2
✓ Branch 0 taken 3104 times.
✓ Branch 1 taken 304 times.
3408 for (size_t j = 0; j < n; ++j) {
64 double s = 0.0;
65
66
2/2
✓ Branch 0 taken 38032 times.
✓ Branch 1 taken 3104 times.
41136 for (size_t k = 0; k < n; ++k) {
67 38032 s += a[(i * n) + k] * b[(k * n) + j];
68 }
69
70 3104 c[(i * n) + j] = s;
71 }
72 304 });
73 48 }
74
75 8 void InitializeBlocks(const std::vector<double> &a, const std::vector<double> &b, std::vector<std::vector<double>> &ba,
76 std::vector<std::vector<double>> &bb, size_t g, size_t bs, size_t n) {
77
1/2
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
8 ParallelFor(g * g, [&](size_t id) {
78 32 size_t i = id / g;
79 32 size_t j = id % g;
80
81 32 ba[id].assign(bs * bs, 0.0);
82 32 bb[id].assign(bs * bs, 0.0);
83
84
2/2
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 32 times.
96 for (size_t bi = 0; bi < bs; ++bi) {
85
2/2
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 64 times.
192 for (size_t bj = 0; bj < bs; ++bj) {
86 128 size_t gi = (i * bs) + bi;
87 128 size_t gj = (j * bs) + bj;
88 128 size_t li = (bi * bs) + bj;
89
90 128 ba[id][li] = a[(gi * n) + gj];
91 128 bb[id][li] = b[(gi * n) + gj];
92 }
93 }
94 32 });
95 8 }
96
97 8 void AlignBlocks(const std::vector<std::vector<double>> &ba, const std::vector<std::vector<double>> &bb,
98 std::vector<std::vector<double>> &aa, std::vector<std::vector<double>> &ab, size_t g) {
99
1/2
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
8 ParallelFor(g * g, [&](size_t id) {
100 32 size_t i = id / g;
101 32 size_t j = id % g;
102
103 32 aa[id] = ba[(i * g) + ((j + i) % g)];
104 32 ab[id] = bb[(((i + j) % g) * g) + j];
105 32 });
106 8 }
107
108 16 void CannonStep(std::vector<std::vector<double>> &a, std::vector<std::vector<double>> &b,
109 std::vector<std::vector<double>> &c, size_t g, size_t bs) {
110
1/2
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
80 ParallelFor(g * g, [&](size_t id) { MulBlock(a[id], b[id], c[id], bs); });
111 16 }
112
113 8 void Shift(std::vector<std::vector<double>> &a, std::vector<std::vector<double>> &b,
114 std::vector<std::vector<double>> &na, std::vector<std::vector<double>> &nb, size_t g) {
115
1/2
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
8 ParallelFor(g * g, [&](size_t id) {
116 32 size_t i = id / g;
117 32 size_t j = id % g;
118
119 32 na[id] = a[(i * g) + ((j + 1) % g)];
120 32 nb[id] = b[(((i + 1) % g) * g) + j];
121 32 });
122 8 }
123
124 8 void Assemble(const std::vector<std::vector<double>> &c, std::vector<double> &r, size_t g, size_t bs, size_t n) {
125
1/2
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
8 ParallelFor(g * g, [&](size_t id) {
126 32 size_t i = id / g;
127 32 size_t j = id % g;
128
129
2/2
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 32 times.
96 for (size_t bi = 0; bi < bs; ++bi) {
130
2/2
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 64 times.
192 for (size_t bj = 0; bj < bs; ++bj) {
131 128 size_t gi = (i * bs) + bi;
132 128 size_t gj = (j * bs) + bj;
133
134 128 r[(gi * n) + gj] = c[id][(bi * bs) + bj];
135 }
136 }
137 32 });
138 8 }
139
140 } // namespace
141
142 namespace zyazeva_s_matrix_mult_cannon_alg {
143
144
1/2
✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
56 ZyazevaSMatrixMultCannonAlgSTL::ZyazevaSMatrixMultCannonAlgSTL(const InType &in) {
145 SetTypeOfTask(GetStaticTypeOfTask());
146 GetInput() = in;
147 GetOutput() = {};
148 56 }
149
150 56 bool ZyazevaSMatrixMultCannonAlgSTL::ValidationImpl() {
151 56 auto sz = std::get<0>(GetInput());
152
153 auto &a = std::get<1>(GetInput());
154 auto &b = std::get<2>(GetInput());
155
156
3/6
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 56 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 56 times.
56 return sz > 0 && a.size() == static_cast<size_t>(sz * sz) && b.size() == static_cast<size_t>(sz * sz);
157 }
158
159
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
56 bool ZyazevaSMatrixMultCannonAlgSTL::PreProcessingImpl() {
160 GetOutput().clear();
161 56 return true;
162 }
163
164 56 bool ZyazevaSMatrixMultCannonAlgSTL::RunImpl() {
165 56 size_t n = std::get<0>(GetInput());
166
167 auto &a = std::get<1>(GetInput());
168 auto &b = std::get<2>(GetInput());
169
170
2/2
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 24 times.
56 std::vector<double> res(n * n, 0.0);
171
172 56 auto g = static_cast<size_t>(std::sqrt(n));
173
174
5/6
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 24 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 8 times.
56 if (g <= 1 || g * g != n || n % g != 0) {
175
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 RegularMultiplication(a, b, res, n);
176
177
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 GetOutput() = res;
178 return true;
179 }
180
181 8 size_t bs = n / g;
182
183
1/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
8 std::vector<std::vector<double>> ba(g * g);
184
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 std::vector<std::vector<double>> bb(g * g);
185
186
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 std::vector<std::vector<double>> aa(g * g);
187
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 std::vector<std::vector<double>> ab(g * g);
188
189
2/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
8 std::vector<std::vector<double>> c(g * g, std::vector<double>(bs * bs, 0.0));
190
191
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 InitializeBlocks(a, b, ba, bb, g, bs, n);
192
193
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 AlignBlocks(ba, bb, aa, ab, g);
194
195
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 8 times.
24 for (size_t step = 0; step < g; ++step) {
196
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 CannonStep(aa, ab, c, g, bs);
197
198
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 if (step < g - 1) {
199
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 std::vector<std::vector<double>> na(g * g);
200
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 std::vector<std::vector<double>> nb(g * g);
201
202
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 Shift(aa, ab, na, nb, g);
203
204 8 aa = std::move(na);
205 8 ab = std::move(nb);
206 8 }
207 }
208
209
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 Assemble(c, res, g, bs, n);
210
211
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 GetOutput() = res;
212
213 return true;
214 8 }
215
216 56 bool ZyazevaSMatrixMultCannonAlgSTL::PostProcessingImpl() {
217 56 return true;
218 }
219
220 } // namespace zyazeva_s_matrix_mult_cannon_alg
221