GCC Code Coverage Report


Directory: ./
File: tasks/yakimov_i_mult_of_dense_matrices_fox_algorithm/omp/src/ops_omp.cpp
Date: 2026-06-04 20:25:32
Exec Total Coverage
Lines: 72 75 96.0%
Functions: 11 11 100.0%
Branches: 45 70 64.3%

Line Branch Exec Source
1 #include "yakimov_i_mult_of_dense_matrices_fox_algorithm/omp/include/ops_omp.hpp"
2
3 #include <algorithm>
4 #include <cstddef>
5 #include <fstream>
6 #include <string>
7 #include <vector>
8
9 #ifdef _OPENMP
10 # include <omp.h>
11 #endif
12
13 #include "util/include/util.hpp"
14 #include "yakimov_i_mult_of_dense_matrices_fox_algorithm/common/include/common.hpp"
15
16 namespace yakimov_i_mult_of_dense_matrices_fox_algorithm {
17
18 namespace {
19
20 64 bool ReadDimensions(std::ifstream &file, DenseMatrix &matrix) {
21 64 file >> matrix.rows;
22 64 file >> matrix.cols;
23
2/4
✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 64 times.
64 return matrix.rows > 0 && matrix.cols > 0;
24 }
25
26 64 bool ReadMatrixData(std::ifstream &file, DenseMatrix &matrix) {
27 64 auto total_elements = static_cast<std::size_t>(matrix.rows) * static_cast<std::size_t>(matrix.cols);
28 64 matrix.data.resize(total_elements, 0.0);
29
30
2/2
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 64 times.
320 for (int i = 0; i < matrix.rows; ++i) {
31
2/2
✓ Branch 0 taken 2168 times.
✓ Branch 1 taken 256 times.
2424 for (int j = 0; j < matrix.cols; ++j) {
32
1/2
✓ Branch 1 taken 2168 times.
✗ Branch 2 not taken.
2168 if (!(file >> matrix(i, j))) {
33 return false;
34 }
35 }
36 }
37 return true;
38 }
39
40 64 bool ReadMatrixFromFileImpl(const std::string &filename, DenseMatrix &matrix) {
41 64 std::ifstream file(filename);
42
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 64 times.
64 if (!file.is_open()) {
43 return false;
44 }
45
46
2/4
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 64 times.
64 if (!ReadDimensions(file, matrix)) {
47 return false;
48 }
49
2/4
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 64 times.
64 if (!ReadMatrixData(file, matrix)) {
50 return false;
51 }
52
53
1/2
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
64 file.close();
54 return true;
55 64 }
56
57 8 void SimpleMultiply(const DenseMatrix &a, const DenseMatrix &b, DenseMatrix &result) {
58 8 result.rows = a.rows;
59 8 result.cols = b.cols;
60 8 result.data.assign(static_cast<std::size_t>(result.rows) * result.cols, 0.0);
61
62
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 8 times.
24 for (int i = 0; i < a.rows; ++i) {
63
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 16 times.
48 for (int j = 0; j < b.cols; ++j) {
64 double sum = 0.0;
65
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 32 times.
128 for (int k = 0; k < a.cols; ++k) {
66 96 sum += a(i, k) * b(k, j);
67 }
68 32 result(i, j) = sum;
69 }
70 }
71 8 }
72
73 24 void MultiplyBlock(const DenseMatrix &a, const DenseMatrix &b, DenseMatrix &result, int row_start, int col_start,
74 int block_size, int a_row_offset, int b_col_offset) {
75
2/2
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 24 times.
132 for (int i = 0; i < block_size; ++i) {
76
2/2
✓ Branch 0 taken 1036 times.
✓ Branch 1 taken 108 times.
1144 for (int j = 0; j < block_size; ++j) {
77 double sum = 0.0;
78
2/2
✓ Branch 0 taken 13932 times.
✓ Branch 1 taken 1036 times.
14968 for (int k = 0; k < block_size; ++k) {
79 13932 sum += a(row_start + i, a_row_offset + k) * b(b_col_offset + k, col_start + j);
80 }
81 1036 #pragma omp atomic
82 1036 result(row_start + i, col_start + j) += sum;
83 }
84 }
85 24 }
86
87 32 void FoxAlgorithmImpl(const DenseMatrix &a, const DenseMatrix &b, DenseMatrix &result, int block_size) {
88
4/6
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 24 times.
32 if (a.rows != a.cols || b.rows != b.cols || a.rows != b.rows) {
89 8 SimpleMultiply(a, b, result);
90 8 return;
91 }
92
93
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 if (a.rows % block_size != 0) {
94 SimpleMultiply(a, b, result);
95 return;
96 }
97
98 int n = a.rows;
99 24 int num_blocks = n / block_size;
100 24 result.rows = n;
101 24 result.cols = n;
102 24 result.data.assign(static_cast<std::size_t>(n) * n, 0.0);
103
104 24 #pragma omp parallel for collapse(2) default(none) shared(a, b, result, num_blocks, block_size)
105 for (int stage = 0; stage < num_blocks; ++stage) {
106 for (int i = 0; i < num_blocks; ++i) {
107 int broadcast_block = (i + stage) % num_blocks;
108 for (int j = 0; j < num_blocks; ++j) {
109 MultiplyBlock(a, b, result, i * block_size, j * block_size, block_size, broadcast_block * block_size,
110 j * block_size);
111 }
112 }
113 }
114 }
115
116 } // namespace
117
118
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 YakimovIMultOfDenseMatricesFoxAlgorithmOMP::YakimovIMultOfDenseMatricesFoxAlgorithmOMP(const InType &in) {
119 this->SetTypeOfTask(YakimovIMultOfDenseMatricesFoxAlgorithmOMP::GetStaticTypeOfTask());
120 32 this->GetInput() = in;
121 this->GetOutput() = 0.0;
122
123
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 std::string task_name = "yakimov_i_mult_of_dense_matrices_fox_algorithm";
124
1/2
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
64 this->matrix_a_filename_ = ppc::util::GetAbsoluteTaskPath(task_name, "A_" + std::to_string(in) + ".txt");
125
1/2
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
96 this->matrix_b_filename_ = ppc::util::GetAbsoluteTaskPath(task_name, "B_" + std::to_string(in) + ".txt");
126 32 }
127
128 32 bool YakimovIMultOfDenseMatricesFoxAlgorithmOMP::ValidationImpl() {
129
2/4
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 32 times.
32 return (this->GetInput() > 0) && (this->GetOutput() == 0.0);
130 }
131
132 32 bool YakimovIMultOfDenseMatricesFoxAlgorithmOMP::PreProcessingImpl() {
133
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
32 if (!ReadMatrixFromFileImpl(this->matrix_a_filename_, this->matrix_a_)) {
134 return false;
135 }
136
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
32 if (!ReadMatrixFromFileImpl(this->matrix_b_filename_, this->matrix_b_)) {
137 return false;
138 }
139
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
32 if (this->matrix_a_.cols != this->matrix_b_.rows) {
140 return true;
141 }
142
143
3/4
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 24 times.
32 if (this->matrix_a_.rows != this->matrix_a_.cols || this->matrix_b_.rows != this->matrix_b_.cols ||
144 this->matrix_a_.rows != this->matrix_b_.rows) {
145 8 this->block_size_ = 0;
146 8 return true;
147 }
148
149 int n = this->matrix_a_.rows;
150 24 this->block_size_ = 64;
151
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
24 while (this->block_size_ * 2 <= n && this->block_size_ < 256) {
152 this->block_size_ *= 2;
153 }
154
155 24 this->block_size_ = std::min(this->block_size_, n);
156
157 24 return this->block_size_ > 0;
158 }
159
160 32 bool YakimovIMultOfDenseMatricesFoxAlgorithmOMP::RunImpl() {
161 32 FoxAlgorithmImpl(this->matrix_a_, this->matrix_b_, this->result_matrix_, this->block_size_);
162 32 return true;
163 }
164
165 32 bool YakimovIMultOfDenseMatricesFoxAlgorithmOMP::PostProcessingImpl() {
166 double sum = 0.0;
167
2/2
✓ Branch 0 taken 1068 times.
✓ Branch 1 taken 32 times.
1100 for (double val : this->result_matrix_.data) {
168 1068 sum += val;
169 }
170 32 this->GetOutput() = sum;
171 32 return true;
172 }
173
174 } // namespace yakimov_i_mult_of_dense_matrices_fox_algorithm
175