GCC Code Coverage Report


Directory: ./
File: tasks/cheremkhin_a_matr_mult_cannon_alg/tbb/src/ops_tbb.cpp
Date: 2026-05-11 08:26:31
Exec Total Coverage
Lines: 63 63 100.0%
Functions: 9 9 100.0%
Branches: 30 48 62.5%

Line Branch Exec Source
1 #include "cheremkhin_a_matr_mult_cannon_alg/tbb/include/ops_tbb.hpp"
2
3 #include <cmath>
4 #include <cstddef>
5 #include <cstdint>
6 #include <utility>
7 #include <vector>
8
9 #include "cheremkhin_a_matr_mult_cannon_alg/common/include/common.hpp"
10 #include "oneapi/tbb/blocked_range2d.h"
11 #include "oneapi/tbb/global_control.h"
12 #include "oneapi/tbb/parallel_for.h"
13 #include "util/include/util.hpp"
14
15 namespace cheremkhin_a_matr_mult_cannon_alg {
16
17 namespace {
18
19 inline std::size_t Idx(std::size_t n, std::size_t r, std::size_t c) {
20 3232 return (r * n) + c;
21 }
22
23 std::size_t ChooseQ(std::size_t n) {
24 28 if (n <= 1) {
25 return 1;
26 }
27
28 24 const auto root = static_cast<std::size_t>(std::sqrt(static_cast<double>(n)));
29
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 return (root == 0) ? 1 : root;
30 }
31
32 std::size_t CeilDiv(std::size_t a, std::size_t b) {
33 28 return (a + b - 1) / b;
34 }
35
36 292 void MulAddBlock(const std::vector<double> &a, const std::vector<double> &b, std::vector<double> &c, std::size_t n,
37 std::size_t bs, std::size_t bi, std::size_t bk, std::size_t bj) {
38 292 const std::size_t i0 = bi * bs;
39 292 const std::size_t k0 = bk * bs;
40 292 const std::size_t j0 = bj * bs;
41 292 const auto bs64 = static_cast<std::int64_t>(bs);
42
43
2/2
✓ Branch 0 taken 1188 times.
✓ Branch 1 taken 292 times.
1480 for (std::size_t ii = 0; ii < bs; ++ii) {
44 1188 const std::size_t i = i0 + ii;
45 1188 const std::size_t a_row = i * n;
46 const std::size_t c_row = i * n;
47 1188 double *c_block = c.data() + c_row + j0;
48
2/2
✓ Branch 0 taken 5124 times.
✓ Branch 1 taken 1188 times.
6312 for (std::size_t kk = 0; kk < bs; ++kk) {
49 5124 const std::size_t k = k0 + kk;
50 5124 const double aik = a[a_row + k];
51 5124 const double *b_block = b.data() + (k * n) + j0;
52
2/2
✓ Branch 0 taken 22860 times.
✓ Branch 1 taken 5124 times.
27984 for (std::int64_t jj = 0; jj < bs64; ++jj) {
53 22860 c_block[jj] += aik * b_block[jj];
54 }
55 }
56 }
57 292 }
58
59 } // namespace
60
61
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 CheremkhinAMatrMultCannonAlgTBB::CheremkhinAMatrMultCannonAlgTBB(const InType &in) {
62 SetTypeOfTask(GetStaticTypeOfTask());
63 GetInput() = in;
64 GetOutput() = {};
65 28 }
66
67 28 bool CheremkhinAMatrMultCannonAlgTBB::ValidationImpl() {
68 28 const std::size_t n = std::get<0>(GetInput());
69 const auto &a = std::get<1>(GetInput());
70 const auto &b = std::get<2>(GetInput());
71
3/6
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 28 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 28 times.
28 return n > 0 && a.size() == n * n && b.size() == n * n;
72 }
73
74 28 bool CheremkhinAMatrMultCannonAlgTBB::PreProcessingImpl() {
75 GetOutput() = {};
76 28 return true;
77 }
78
79 28 bool CheremkhinAMatrMultCannonAlgTBB::RunImpl() {
80 28 const std::size_t n = std::get<0>(GetInput());
81 const auto &a_in = std::get<1>(GetInput());
82 const auto &b_in = std::get<2>(GetInput());
83 28 const int requested_threads = ppc::util::GetNumThreads();
84
85
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 24 times.
28 const std::size_t q = ChooseQ(n);
86 28 const std::size_t bs = CeilDiv(n, q);
87 28 const std::size_t np = q * bs;
88 28 const auto n64 = static_cast<std::int64_t>(n);
89 28 const auto q64 = static_cast<std::int64_t>(q);
90
91 28 std::vector<double> a(np * np, 0.0);
92
1/4
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
28 std::vector<double> b(np * np, 0.0);
93
1/4
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
28 std::vector<double> c(np * np, 0.0);
94
95
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 oneapi::tbb::global_control control(oneapi::tbb::global_control::max_allowed_parallelism, requested_threads);
96
97
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 oneapi::tbb::parallel_for(std::int64_t{0}, n64, [&](std::int64_t i) {
98 168 const auto row = static_cast<std::size_t>(i);
99
2/2
✓ Branch 0 taken 1616 times.
✓ Branch 1 taken 168 times.
1784 for (std::size_t j = 0; j < n; ++j) {
100 1616 a[Idx(np, row, j)] = a_in[Idx(n, row, j)];
101 1616 b[Idx(np, row, j)] = b_in[Idx(n, row, j)];
102 }
103 168 });
104
105 28 oneapi::tbb::parallel_for(oneapi::tbb::blocked_range2d<std::int64_t>(0, q64, 0, q64),
106
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
144 [&](const oneapi::tbb::blocked_range2d<std::int64_t> &range) {
107
2/2
✓ Branch 0 taken 116 times.
✓ Branch 1 taken 116 times.
232 for (std::int64_t bi = range.rows().begin(); bi != range.rows().end(); ++bi) {
108
2/2
✓ Branch 0 taken 116 times.
✓ Branch 1 taken 116 times.
232 for (std::int64_t bj = range.cols().begin(); bj != range.cols().end(); ++bj) {
109
2/2
✓ Branch 0 taken 292 times.
✓ Branch 1 taken 116 times.
408 for (std::size_t step = 0; step < q; ++step) {
110 292 const std::size_t bk = (static_cast<std::size_t>(bi) + static_cast<std::size_t>(bj) + step) % q;
111 292 MulAddBlock(a, b, c, np, bs, static_cast<std::size_t>(bi), bk, static_cast<std::size_t>(bj));
112 }
113 }
114 }
115 116 });
116
117
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 std::vector<double> out(n * n, 0.0);
118
119
1/4
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
28 oneapi::tbb::parallel_for(std::int64_t{0}, n64, [&](std::int64_t i) {
120 168 const auto row = static_cast<std::size_t>(i);
121
2/2
✓ Branch 0 taken 1616 times.
✓ Branch 1 taken 168 times.
1784 for (std::size_t j = 0; j < n; ++j) {
122 1616 out[Idx(n, row, j)] = c[Idx(np, row, j)];
123 }
124 168 });
125
126 GetOutput() = std::move(out);
127 28 return true;
128 }
129
130 28 bool CheremkhinAMatrMultCannonAlgTBB::PostProcessingImpl() {
131 28 return true;
132 }
133
134 } // namespace cheremkhin_a_matr_mult_cannon_alg
135