GCC Code Coverage Report


Directory: ./
File: tasks/remizov_k_dense_matrix_multiplication_cannon_algorithm/omp/src/ops_omp.cpp
Date: 2026-04-02 17:12:27
Exec Total Coverage
Lines: 61 65 93.8%
Functions: 9 11 81.8%
Branches: 39 60 65.0%

Line Branch Exec Source
1 #include "remizov_k_dense_matrix_multiplication_cannon_algorithm/omp/include/ops_omp.hpp"
2
3 #include <cstddef>
4 #include <utility>
5 #include <vector>
6
7 #ifdef _OPENMP
8 # include <omp.h>
9 #endif
10
11 #include "remizov_k_dense_matrix_multiplication_cannon_algorithm/common/include/common.hpp"
12
13 namespace remizov_k_dense_matrix_multiplication_cannon_algorithm {
14
15 32 RemizovKDenseMatrixMultiplicationCannonAlgorithmOmp::RemizovKDenseMatrixMultiplicationCannonAlgorithmOmp(
16
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 const InType &in) {
17 SetTypeOfTask(GetStaticTypeOfTask());
18 GetInput() = in;
19 32 }
20
21 32 bool RemizovKDenseMatrixMultiplicationCannonAlgorithmOmp::ValidationImpl() {
22 const auto &input_data = GetInput();
23
24 32 int block_dim = std::get<0>(input_data);
25 const auto &mat_a = std::get<1>(input_data);
26 const auto &mat_b = std::get<2>(input_data);
27
28
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 if (block_dim <= 0) {
29 return false;
30 }
31
2/4
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
32 if (mat_a.empty() || mat_b.empty()) {
32 return false;
33 }
34
35 size_t n = mat_a.size();
36
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 if (n != mat_a[0].size()) {
37 return false;
38 }
39
2/4
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
32 if (n != mat_b.size() || n != mat_b[0].size()) {
40 return false;
41 }
42
43 32 return (n % static_cast<size_t>(block_dim) == 0);
44 }
45
46
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
32 bool RemizovKDenseMatrixMultiplicationCannonAlgorithmOmp::PreProcessingImpl() {
47 GetOutput().clear();
48 32 return true;
49 }
50
51 228 void RemizovKDenseMatrixMultiplicationCannonAlgorithmOmp::MultiplyBlock(const std::vector<std::vector<double>> &a,
52 const std::vector<std::vector<double>> &b,
53 std::vector<std::vector<double>> &c,
54 int block_size) {
55
2/2
✓ Branch 0 taken 492 times.
✓ Branch 1 taken 228 times.
720 for (int i = 0; i < block_size; ++i) {
56
2/2
✓ Branch 0 taken 1284 times.
✓ Branch 1 taken 492 times.
1776 for (int j = 0; j < block_size; ++j) {
57 double accumulator = 0.0;
58
2/2
✓ Branch 0 taken 3852 times.
✓ Branch 1 taken 1284 times.
5136 for (int k = 0; k < block_size; ++k) {
59 3852 accumulator += a[i][k] * b[k][j];
60 }
61 1284 c[i][j] += accumulator;
62 }
63 }
64 228 }
65
66 28 void RemizovKDenseMatrixMultiplicationCannonAlgorithmOmp::ShiftBlocksLeft(
67 std::vector<std::vector<std::vector<std::vector<double>>>> &matrix_blocks, int block_count) {
68
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 28 times.
84 for (int i = 0; i < block_count; ++i) {
69 56 auto first_element = std::move(matrix_blocks[i][0]);
70
71
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 56 times.
112 for (int j = 1; j < block_count; ++j) {
72 56 matrix_blocks[i][j - 1] = std::move(matrix_blocks[i][j]);
73 }
74
75 56 matrix_blocks[i][block_count - 1] = std::move(first_element);
76 56 }
77 28 }
78
79 28 void RemizovKDenseMatrixMultiplicationCannonAlgorithmOmp::ShiftBlocksUp(
80 std::vector<std::vector<std::vector<std::vector<double>>>> &matrix_blocks, int block_count) {
81
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 28 times.
84 for (int j = 0; j < block_count; ++j) {
82 56 auto first_element = std::move(matrix_blocks[0][j]);
83
84
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 56 times.
112 for (int i = 1; i < block_count; ++i) {
85 56 matrix_blocks[i - 1][j] = std::move(matrix_blocks[i][j]);
86 }
87
88 56 matrix_blocks[block_count - 1][j] = std::move(first_element);
89 56 }
90 28 }
91
92 32 void RemizovKDenseMatrixMultiplicationCannonAlgorithmOmp::RunCannonCycle(
93 std::vector<std::vector<std::vector<std::vector<double>>>> &a_blocks,
94 std::vector<std::vector<std::vector<std::vector<double>>>> &b_blocks,
95 std::vector<std::vector<std::vector<std::vector<double>>>> &c_blocks, int block_size, int block_count) {
96
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 32 times.
92 for (int step = 0; step < block_count; ++step) {
97 // Параллельное умножение блоков с явным указанием переменных
98 60 #pragma omp parallel for collapse(2) schedule(dynamic) default(none) \
99 shared(a_blocks, b_blocks, c_blocks, block_size, block_count)
100 for (int i = 0; i < block_count; ++i) {
101 for (int j = 0; j < block_count; ++j) {
102 RemizovKDenseMatrixMultiplicationCannonAlgorithmOmp::MultiplyBlock(a_blocks[i][j], b_blocks[i][j],
103 c_blocks[i][j], block_size);
104 }
105 }
106
107
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 32 times.
60 if (step < block_count - 1) {
108 28 RemizovKDenseMatrixMultiplicationCannonAlgorithmOmp::ShiftBlocksLeft(a_blocks, block_count);
109 28 RemizovKDenseMatrixMultiplicationCannonAlgorithmOmp::ShiftBlocksUp(b_blocks, block_count);
110 }
111 }
112 32 }
113
114 void RemizovKDenseMatrixMultiplicationCannonAlgorithmOmp::InitializeBlocks(
115 const std::vector<std::vector<double>> &matrix_a, const std::vector<std::vector<double>> &matrix_b,
116 std::vector<std::vector<std::vector<std::vector<double>>>> &a_blocks,
117 std::vector<std::vector<std::vector<std::vector<double>>>> &b_blocks, int block_size, int block_count) {
118 32 #pragma omp parallel for collapse(2) schedule(static) default(none) \
119 shared(matrix_a, matrix_b, a_blocks, b_blocks, block_size, block_count)
120 for (int i = 0; i < block_count; ++i) {
121 for (int j = 0; j < block_count; ++j) {
122 int shift_value = (i + j) % block_count;
123
124 for (int bi = 0; bi < block_size; ++bi) {
125 for (int bj = 0; bj < block_size; ++bj) {
126 a_blocks[i][j][bi][bj] = matrix_a[(i * block_size) + bi][(shift_value * block_size) + bj];
127 b_blocks[i][j][bi][bj] = matrix_b[(shift_value * block_size) + bi][(j * block_size) + bj];
128 }
129 }
130 }
131 }
132 }
133
134 void RemizovKDenseMatrixMultiplicationCannonAlgorithmOmp::AssembleOutput(
135 std::vector<std::vector<std::vector<std::vector<double>>>> &c_blocks, std::vector<std::vector<double>> &output,
136 int block_size, int block_count) {
137 32 #pragma omp parallel for collapse(2) schedule(static) default(none) shared(c_blocks, output, block_size, block_count)
138 for (int i = 0; i < block_count; ++i) {
139 for (int j = 0; j < block_count; ++j) {
140 for (int bi = 0; bi < block_size; ++bi) {
141 for (int bj = 0; bj < block_size; ++bj) {
142 output[(i * block_size) + bi][(j * block_size) + bj] = c_blocks[i][j][bi][bj];
143 }
144 }
145 }
146 }
147 }
148
149 32 bool RemizovKDenseMatrixMultiplicationCannonAlgorithmOmp::RunImpl() {
150 const auto &params = GetInput();
151
152 32 int block_dim = std::get<0>(params);
153 const auto &source_a = std::get<1>(params);
154 const auto &source_b = std::get<2>(params);
155
156 32 int matrix_size = static_cast<int>(source_a.size());
157 32 int blocks_per_dim = matrix_size / block_dim;
158
159 std::vector<std::vector<std::vector<std::vector<double>>>> blocks_a(
160 blocks_per_dim,
161 32 std::vector<std::vector<std::vector<double>>>(
162
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.
64 blocks_per_dim, std::vector<std::vector<double>>(block_dim, std::vector<double>(block_dim, 0.0))));
163
164 std::vector<std::vector<std::vector<std::vector<double>>>> blocks_b(
165 blocks_per_dim,
166 32 std::vector<std::vector<std::vector<double>>>(
167
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 blocks_per_dim, std::vector<std::vector<double>>(block_dim, std::vector<double>(block_dim, 0.0))));
168
169 std::vector<std::vector<std::vector<std::vector<double>>>> blocks_c(
170 blocks_per_dim,
171 32 std::vector<std::vector<std::vector<double>>>(
172
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 blocks_per_dim, std::vector<std::vector<double>>(block_dim, std::vector<double>(block_dim, 0.0))));
173
174 InitializeBlocks(source_a, source_b, blocks_a, blocks_b, block_dim, blocks_per_dim);
175 32 RunCannonCycle(blocks_a, blocks_b, blocks_c, block_dim, blocks_per_dim);
176
177
2/4
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 32 times.
✗ Branch 5 not taken.
64 std::vector<std::vector<double>> result(matrix_size, std::vector<double>(matrix_size, 0.0));
178 AssembleOutput(blocks_c, result, block_dim, blocks_per_dim);
179
180 32 GetOutput() = std::move(result);
181 32 return true;
182 32 }
183
184 32 bool RemizovKDenseMatrixMultiplicationCannonAlgorithmOmp::PostProcessingImpl() {
185 32 return true;
186 }
187
188 } // namespace remizov_k_dense_matrix_multiplication_cannon_algorithm
189