GCC Code Coverage Report


Directory: ./
File: tasks/baranov_a_mult_matrix_fox_algorithm/omp/src/ops_omp.cpp
Date: 2026-05-11 08:26:31
Exec Total Coverage
Lines: 40 41 97.6%
Functions: 7 8 87.5%
Branches: 16 20 80.0%

Line Branch Exec Source
1 #include "baranov_a_mult_matrix_fox_algorithm/omp/include/ops_omp.hpp"
2
3 #include <omp.h>
4
5 #include <algorithm>
6 #include <cmath>
7 #include <cstddef>
8 #include <vector>
9
10 #include "baranov_a_mult_matrix_fox_algorithm/common/include/common.hpp"
11
12 namespace {
13
14 228 void ProcessBlock(const std::vector<double> &matrix_a, const std::vector<double> &matrix_b, std::vector<double> &output,
15 size_t n, size_t i_start, size_t i_end, size_t j_start, size_t j_end, size_t k_start, size_t k_end) {
16
2/2
✓ Branch 0 taken 7584 times.
✓ Branch 1 taken 228 times.
7812 for (size_t i = i_start; i < i_end; ++i) {
17
2/2
✓ Branch 0 taken 261120 times.
✓ Branch 1 taken 7584 times.
268704 for (size_t j = j_start; j < j_end; ++j) {
18 double sum = 0.0;
19
2/2
✓ Branch 0 taken 9535488 times.
✓ Branch 1 taken 261120 times.
9796608 for (size_t k = k_start; k < k_end; ++k) {
20 9535488 sum += matrix_a[(i * n) + k] * matrix_b[(k * n) + j];
21 }
22 261120 #pragma omp atomic
23 261120 output[(i * n) + j] += sum;
24 }
25 }
26 228 }
27
28 } // namespace
29
30 namespace baranov_a_mult_matrix_fox_algorithm_omp {
31
32 80 BaranovAMultMatrixFoxAlgorithmOMP::BaranovAMultMatrixFoxAlgorithmOMP(
33
1/2
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
80 const baranov_a_mult_matrix_fox_algorithm::InType &in) {
34 SetTypeOfTask(GetStaticTypeOfTask());
35 GetInput() = in;
36 80 GetOutput() = std::vector<double>();
37 80 }
38
39 80 bool BaranovAMultMatrixFoxAlgorithmOMP::ValidationImpl() {
40 const auto &input = GetInput();
41 80 size_t matrix_size = std::get<0>(input);
42 const auto &matrix_a = std::get<1>(input);
43 const auto &matrix_b = std::get<2>(input);
44
45
3/6
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 80 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 80 times.
80 return matrix_size > 0 && matrix_a.size() == matrix_size * matrix_size &&
46 80 matrix_b.size() == matrix_size * matrix_size;
47 }
48
49 80 bool BaranovAMultMatrixFoxAlgorithmOMP::PreProcessingImpl() {
50 const auto &input = GetInput();
51 80 size_t matrix_size = std::get<0>(input);
52
53 80 GetOutput() = std::vector<double>(matrix_size * matrix_size, 0.0);
54 80 return true;
55 }
56
57 void BaranovAMultMatrixFoxAlgorithmOMP::StandardMultiplication(size_t n) {
58 const auto &input = GetInput();
59 const auto &matrix_a = std::get<1>(input);
60 const auto &matrix_b = std::get<2>(input);
61 auto &output = GetOutput();
62
63 69 #pragma omp parallel for collapse(2) default(none) shared(matrix_a, matrix_b, output, n)
64 for (size_t i = 0; i < n; ++i) {
65 for (size_t j = 0; j < n; ++j) {
66 double sum = 0.0;
67 for (size_t k = 0; k < n; ++k) {
68 sum += matrix_a[(i * n) + k] * matrix_b[(k * n) + j];
69 }
70 output[(i * n) + j] = sum;
71 }
72 }
73 69 }
74
75 11 void BaranovAMultMatrixFoxAlgorithmOMP::FoxBlockMultiplication(size_t n, size_t block_size) {
76 const auto &input = GetInput();
77 const auto &matrix_a = std::get<1>(input);
78 const auto &matrix_b = std::get<2>(input);
79 auto &output = GetOutput();
80
81 11 size_t num_blocks = (n + block_size - 1) / block_size;
82
83 11 #pragma omp parallel for default(none) shared(output, n)
84 for (size_t idx = 0; idx < n * n; ++idx) {
85 output[idx] = 0.0;
86 }
87
88
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 11 times.
35 for (size_t bk = 0; bk < num_blocks; ++bk) {
89 24 #pragma omp parallel for collapse(2) default(none) shared(matrix_a, matrix_b, output, n, block_size, num_blocks, bk)
90 for (size_t bi = 0; bi < num_blocks; ++bi) {
91 for (size_t bj = 0; bj < num_blocks; ++bj) {
92 size_t broadcast_block = (bi + bk) % num_blocks;
93
94 size_t i_start = bi * block_size;
95 size_t i_end = std::min(i_start + block_size, n);
96 size_t j_start = bj * block_size;
97 size_t j_end = std::min(j_start + block_size, n);
98 size_t k_start = broadcast_block * block_size;
99 size_t k_end = std::min(k_start + block_size, n);
100
101 ProcessBlock(matrix_a, matrix_b, output, n, i_start, i_end, j_start, j_end, k_start, k_end);
102 }
103 }
104 }
105 11 }
106
107 80 bool BaranovAMultMatrixFoxAlgorithmOMP::RunImpl() {
108 const auto &input = GetInput();
109 80 size_t n = std::get<0>(input);
110
111 80 int num_threads = omp_get_max_threads();
112 80 size_t block_size = 64;
113
114
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 20 times.
80 if (num_threads > 1) {
115 60 block_size = std::max(static_cast<size_t>(32), n / static_cast<size_t>(num_threads * 2));
116 60 block_size = std::min(block_size, static_cast<size_t>(128));
117 }
118
119
2/2
✓ Branch 0 taken 69 times.
✓ Branch 1 taken 11 times.
80 if (n < block_size) {
120 StandardMultiplication(n);
121 } else {
122 11 FoxBlockMultiplication(n, block_size);
123 }
124
125 80 return true;
126 }
127
128 80 bool BaranovAMultMatrixFoxAlgorithmOMP::PostProcessingImpl() {
129 80 return true;
130 }
131
132 } // namespace baranov_a_mult_matrix_fox_algorithm_omp
133