GCC Code Coverage Report


Directory: ./
File: tasks/timur_a_cannon/omp/src/ops_omp.cpp
Date: 2026-04-02 17:12:27
Exec Total Coverage
Lines: 36 43 83.7%
Functions: 6 10 60.0%
Branches: 31 52 59.6%

Line Branch Exec Source
1 #include "timur_a_cannon/omp/include/ops_omp.hpp"
2
3 #include <omp.h>
4
5 #include <cstddef>
6 #include <utility>
7 #include <vector>
8
9 #include "timur_a_cannon/common/include/common.hpp"
10
11 namespace timur_a_cannon {
12
13
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 TimurACannonMatrixMultiplicationOMP::TimurACannonMatrixMultiplicationOMP(const InType &in) {
14 SetTypeOfTask(GetStaticTypeOfTask());
15 GetInput() = in;
16 32 }
17
18 32 bool TimurACannonMatrixMultiplicationOMP::ValidationImpl() {
19 const auto &input = GetInput();
20 32 int b_size = std::get<0>(input);
21 const auto &mat_a = std::get<1>(input);
22 const auto &mat_b = std::get<2>(input);
23
24
4/8
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 32 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 32 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 32 times.
32 return b_size > 0 && !mat_a.empty() && !mat_b.empty() && mat_a.size() == mat_a[0].size() &&
25
2/4
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 32 times.
64 mat_a.size() == mat_b.size() && mat_a.size() % static_cast<size_t>(b_size) == 0;
26 }
27
28
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
32 bool TimurACannonMatrixMultiplicationOMP::PreProcessingImpl() {
29 GetOutput().clear();
30 32 return true;
31 }
32
33 304 void TimurACannonMatrixMultiplicationOMP::BlockMultiplyAccumulate(const std::vector<std::vector<double>> &a,
34 const std::vector<std::vector<double>> &b,
35 std::vector<std::vector<double>> &c, int b_size) {
36
2/2
✓ Branch 0 taken 784 times.
✓ Branch 1 taken 304 times.
1088 for (int i = 0; i < b_size; ++i) {
37
2/2
✓ Branch 0 taken 2224 times.
✓ Branch 1 taken 784 times.
3008 for (int k = 0; k < b_size; ++k) {
38 2224 double temp = a[i][k];
39
2/2
✓ Branch 0 taken 6736 times.
✓ Branch 1 taken 2224 times.
8960 for (int j = 0; j < b_size; ++j) {
40 6736 c[i][j] += temp * b[k][j];
41 }
42 }
43 }
44 304 }
45
46 void TimurACannonMatrixMultiplicationOMP::DistributeData(
47 const std::vector<std::vector<double>> &src_a, const std::vector<std::vector<double>> &src_b,
48 std::vector<std::vector<std::vector<std::vector<double>>>> &bl_a,
49 std::vector<std::vector<std::vector<std::vector<double>>>> &bl_b, int b_size, int grid_sz) {
50 32 #pragma omp parallel for collapse(2) default(none) shared(src_a, src_b, bl_a, bl_b, b_size, grid_sz)
51 for (int i = 0; i < grid_sz; ++i) {
52 for (int j = 0; j < grid_sz; ++j) {
53 int shift = (i + j) % grid_sz;
54 for (int row = 0; row < b_size; ++row) {
55 for (int col = 0; col < b_size; ++col) {
56 bl_a[i][j][row][col] = src_a[(i * b_size) + row][((shift)*b_size) + col];
57 bl_b[i][j][row][col] = src_b[((shift)*b_size) + row][(j * b_size) + col];
58 }
59 }
60 }
61 }
62 }
63
64 void TimurACannonMatrixMultiplicationOMP::CollectResult(
65 const std::vector<std::vector<std::vector<std::vector<double>>>> &bl_c, std::vector<std::vector<double>> &res,
66 int b_size, int grid_sz) {
67 32 #pragma omp parallel for collapse(2) default(none) shared(bl_c, res, b_size, grid_sz)
68 for (int i = 0; i < grid_sz; ++i) {
69 for (int j = 0; j < grid_sz; ++j) {
70 for (int row = 0; row < b_size; ++row) {
71 for (int col = 0; col < b_size; ++col) {
72 res[(i * b_size) + row][(j * b_size) + col] = bl_c[i][j][row][col];
73 }
74 }
75 }
76 }
77 }
78
79 void TimurACannonMatrixMultiplicationOMP::RotateBlocksA(
80 std::vector<std::vector<std::vector<std::vector<double>>>> &blocks, int grid_sz) {
81 32 #pragma omp parallel for default(none) shared(blocks, grid_sz)
82 for (int i = 0; i < grid_sz; ++i) {
83 auto first_block = std::move(blocks[i][0]);
84 for (int j = 0; j < grid_sz - 1; ++j) {
85 blocks[i][j] = std::move(blocks[i][j + 1]);
86 }
87 blocks[i][grid_sz - 1] = std::move(first_block);
88 }
89 }
90
91 void TimurACannonMatrixMultiplicationOMP::RotateBlocksB(
92 std::vector<std::vector<std::vector<std::vector<double>>>> &blocks, int grid_sz) {
93 32 #pragma omp parallel for default(none) shared(blocks, grid_sz)
94 for (int j = 0; j < grid_sz; ++j) {
95 auto first_block = std::move(blocks[0][j]);
96 for (int i = 0; i < grid_sz - 1; ++i) {
97 blocks[i][j] = std::move(blocks[i + 1][j]);
98 }
99 blocks[grid_sz - 1][j] = std::move(first_block);
100 }
101 32 }
102
103 32 bool TimurACannonMatrixMultiplicationOMP::RunImpl() {
104 const auto &input = GetInput();
105 32 int b_size = std::get<0>(input);
106 32 int n = static_cast<int>(std::get<1>(input).size());
107 32 int grid_sz = n / b_size;
108
109 using Matrix = std::vector<std::vector<double>>;
110 using BlockGrid = std::vector<std::vector<Matrix>>;
111
112
3/6
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 32 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 32 times.
✗ Branch 9 not taken.
32 BlockGrid bl_a(grid_sz, std::vector<Matrix>(grid_sz, Matrix(b_size, std::vector<double>(b_size))));
113
4/8
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 32 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 32 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 32 times.
✗ Branch 11 not taken.
32 BlockGrid bl_b(grid_sz, std::vector<Matrix>(grid_sz, Matrix(b_size, std::vector<double>(b_size))));
114
4/8
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 32 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 32 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 32 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))));
115
116 DistributeData(std::get<1>(input), std::get<2>(input), bl_a, bl_b, b_size, grid_sz);
117
118
2/2
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 32 times.
96 for (int step = 0; step < grid_sz; ++step) {
119 64 #pragma omp parallel for collapse(2) default(none) shared(bl_a, bl_b, bl_c, b_size, grid_sz)
120 for (int i = 0; i < grid_sz; ++i) {
121 for (int j = 0; j < grid_sz; ++j) {
122 BlockMultiplyAccumulate(bl_a[i][j], bl_b[i][j], bl_c[i][j], b_size);
123 }
124 }
125
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 32 times.
64 if (step < grid_sz - 1) {
126 RotateBlocksA(bl_a, grid_sz);
127 RotateBlocksB(bl_b, grid_sz);
128 }
129 }
130
131
2/4
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 32 times.
✗ Branch 5 not taken.
64 Matrix res_mat(n, std::vector<double>(n));
132 CollectResult(bl_c, res_mat, b_size, grid_sz);
133
134 32 GetOutput() = std::move(res_mat);
135 32 return true;
136 32 }
137
138 32 bool TimurACannonMatrixMultiplicationOMP::PostProcessingImpl() {
139 32 return true;
140 }
141
142 } // namespace timur_a_cannon
143