GCC Code Coverage Report


Directory: ./
File: tasks/yakimov_i_mult_of_dense_matrices_fox_algorithm/stl/src/ops_stl.cpp
Date: 2026-06-04 20:25:32
Exec Total Coverage
Lines: 99 106 93.4%
Functions: 14 14 100.0%
Branches: 63 96 65.6%

Line Branch Exec Source
1 #include "yakimov_i_mult_of_dense_matrices_fox_algorithm/stl/include/ops_stl.hpp"
2
3 #include <algorithm>
4 #include <cstddef>
5 #include <fstream>
6 #include <string>
7 #include <thread>
8 #include <utility>
9 #include <vector>
10
11 #include "util/include/util.hpp"
12 #include "yakimov_i_mult_of_dense_matrices_fox_algorithm/common/include/common.hpp"
13
14 namespace yakimov_i_mult_of_dense_matrices_fox_algorithm {
15
16 namespace {
17
18 128 bool ReadDimensions(std::ifstream &file, DenseMatrix &matrix) {
19 128 file >> matrix.rows;
20 128 file >> matrix.cols;
21
2/4
✓ Branch 0 taken 128 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 128 times.
128 return matrix.rows > 0 && matrix.cols > 0;
22 }
23
24 128 bool ReadMatrixData(std::ifstream &file, DenseMatrix &matrix) {
25 128 auto total_elements = static_cast<std::size_t>(matrix.rows) * static_cast<std::size_t>(matrix.cols);
26 128 matrix.data.resize(total_elements, 0.0);
27
28
2/2
✓ Branch 0 taken 512 times.
✓ Branch 1 taken 128 times.
640 for (int i = 0; i < matrix.rows; ++i) {
29
2/2
✓ Branch 0 taken 4336 times.
✓ Branch 1 taken 512 times.
4848 for (int j = 0; j < matrix.cols; ++j) {
30
1/2
✓ Branch 1 taken 4336 times.
✗ Branch 2 not taken.
4336 if (!(file >> matrix(i, j))) {
31 return false;
32 }
33 }
34 }
35 return true;
36 }
37
38 128 bool ReadMatrixFromFileImpl(const std::string &filename, DenseMatrix &matrix) {
39 128 std::ifstream file(filename);
40
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 128 times.
128 if (!file.is_open()) {
41 return false;
42 }
43
44
2/4
✓ Branch 1 taken 128 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 128 times.
128 if (!ReadDimensions(file, matrix)) {
45 return false;
46 }
47
2/4
✓ Branch 1 taken 128 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 128 times.
128 if (!ReadMatrixData(file, matrix)) {
48 return false;
49 }
50
51
1/2
✓ Branch 1 taken 128 times.
✗ Branch 2 not taken.
128 file.close();
52 return true;
53 128 }
54
55 16 void SimpleMultiply(const DenseMatrix &a, const DenseMatrix &b, DenseMatrix &result) {
56 16 result.rows = a.rows;
57 16 result.cols = b.cols;
58 16 result.data.assign(static_cast<std::size_t>(result.rows) * result.cols, 0.0);
59
60
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 16 times.
48 for (int i = 0; i < a.rows; ++i) {
61
2/2
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 32 times.
96 for (int j = 0; j < b.cols; ++j) {
62 double sum = 0.0;
63
2/2
✓ Branch 0 taken 192 times.
✓ Branch 1 taken 64 times.
256 for (int k = 0; k < a.cols; ++k) {
64 192 sum += a(i, k) * b(k, j);
65 }
66 64 result(i, j) = sum;
67 }
68 }
69 16 }
70
71 48 void MultiplyBlock(const DenseMatrix &a, const DenseMatrix &b, DenseMatrix &result, int row_start, int col_start,
72 int block_size, int a_row_offset, int b_col_offset) {
73
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 48 times.
264 for (int i = 0; i < block_size; ++i) {
74
2/2
✓ Branch 0 taken 2072 times.
✓ Branch 1 taken 216 times.
2288 for (int j = 0; j < block_size; ++j) {
75 double sum = 0.0;
76
2/2
✓ Branch 0 taken 27864 times.
✓ Branch 1 taken 2072 times.
29936 for (int k = 0; k < block_size; ++k) {
77 27864 sum += a(row_start + i, a_row_offset + k) * b(b_col_offset + k, col_start + j);
78 }
79 2072 result(row_start + i, col_start + j) += sum;
80 }
81 }
82 48 }
83
84 48 void ProcessStage(const DenseMatrix &a, const DenseMatrix &b, DenseMatrix &result, int stage, int num_blocks,
85 int block_size) {
86
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 48 times.
96 for (int i = 0; i < num_blocks; ++i) {
87 48 int broadcast_block = (i + stage) % num_blocks;
88
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 48 times.
96 for (int j = 0; j < num_blocks; ++j) {
89 48 MultiplyBlock(a, b, result, i * block_size, j * block_size, block_size, broadcast_block * block_size,
90 j * block_size);
91 }
92 }
93 48 }
94
95 unsigned int CalculateNumThreads(int num_blocks) {
96 48 unsigned int hardware_threads = std::thread::hardware_concurrency();
97
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 unsigned int num_threads = (hardware_threads == 0U) ? 2U : hardware_threads;
98 48 unsigned int result = std::min(static_cast<unsigned int>(num_blocks), num_threads);
99 return result;
100 }
101
102 48 void LaunchThreads(const DenseMatrix &a, const DenseMatrix &b, DenseMatrix &result, int num_blocks, int block_size,
103 unsigned int num_threads) {
104 48 std::vector<std::thread> threads;
105
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 threads.reserve(num_threads);
106
107 48 int stages_per_thread = num_blocks / static_cast<int>(num_threads);
108 48 int remaining_stages = num_blocks % static_cast<int>(num_threads);
109 int stage_start = 0;
110
111
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 48 times.
96 for (unsigned int thread_index = 0U; thread_index < num_threads; ++thread_index) {
112 int stages_for_this_thread = stages_per_thread;
113
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 if (std::cmp_less(thread_index, remaining_stages)) {
114 stages_for_this_thread = stages_for_this_thread + 1;
115 }
116
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 if (stages_for_this_thread == 0) {
117 continue;
118 }
119
120 48 int stage_end = stage_start + stages_for_this_thread;
121
122
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 threads.emplace_back([&a, &b, &result, stage_start, stage_end, num_blocks, block_size]() {
123
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 48 times.
96 for (int stage = stage_start; stage < stage_end; ++stage) {
124 48 ProcessStage(a, b, result, stage, num_blocks, block_size);
125 }
126 48 });
127
128 stage_start = stage_end;
129 }
130
131
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 48 times.
96 for (std::thread &thread : threads) {
132
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 if (thread.joinable()) {
133
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 thread.join();
134 }
135 }
136 48 }
137
138 64 void FoxAlgorithmImpl(const DenseMatrix &a, const DenseMatrix &b, DenseMatrix &result, int block_size) {
139
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 48 times.
64 if (block_size <= 0) {
140 16 SimpleMultiply(a, b, result);
141 16 return;
142 }
143
144
3/6
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 48 times.
✗ Branch 5 not taken.
48 bool is_not_square = (a.rows != a.cols) || (b.rows != b.cols) || (a.rows != b.rows);
145 if (is_not_square) {
146 SimpleMultiply(a, b, result);
147 return;
148 }
149
150
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 if (a.rows % block_size != 0) {
151 SimpleMultiply(a, b, result);
152 return;
153 }
154
155 int n = a.rows;
156 48 int num_blocks = n / block_size;
157
158 48 result.rows = n;
159 48 result.cols = n;
160 48 auto total_elements = static_cast<std::size_t>(n) * static_cast<std::size_t>(n);
161 48 result.data.assign(total_elements, 0.0);
162
163 unsigned int num_threads = CalculateNumThreads(num_blocks);
164 48 LaunchThreads(a, b, result, num_blocks, block_size, num_threads);
165 }
166
167 } // namespace
168
169
1/2
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
64 YakimovIMultOfDenseMatricesFoxAlgorithmSTL::YakimovIMultOfDenseMatricesFoxAlgorithmSTL(const InType &in) {
170 this->SetTypeOfTask(YakimovIMultOfDenseMatricesFoxAlgorithmSTL::GetStaticTypeOfTask());
171 64 this->GetInput() = in;
172 this->GetOutput() = 0.0;
173
174
1/2
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
64 std::string task_name = "yakimov_i_mult_of_dense_matrices_fox_algorithm";
175
1/2
✓ Branch 2 taken 64 times.
✗ Branch 3 not taken.
128 this->matrix_a_filename_ = ppc::util::GetAbsoluteTaskPath(task_name, "A_" + std::to_string(in) + ".txt");
176
1/2
✓ Branch 2 taken 64 times.
✗ Branch 3 not taken.
192 this->matrix_b_filename_ = ppc::util::GetAbsoluteTaskPath(task_name, "B_" + std::to_string(in) + ".txt");
177 64 }
178
179 64 bool YakimovIMultOfDenseMatricesFoxAlgorithmSTL::ValidationImpl() {
180
2/4
✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 64 times.
64 return (this->GetInput() > 0) && (this->GetOutput() == 0.0);
181 }
182
183 64 bool YakimovIMultOfDenseMatricesFoxAlgorithmSTL::PreProcessingImpl() {
184
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 64 times.
64 if (!ReadMatrixFromFileImpl(this->matrix_a_filename_, this->matrix_a_)) {
185 return false;
186 }
187
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 64 times.
64 if (!ReadMatrixFromFileImpl(this->matrix_b_filename_, this->matrix_b_)) {
188 return false;
189 }
190
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 64 times.
64 if (this->matrix_a_.cols != this->matrix_b_.rows) {
191 return false;
192 }
193
194
3/4
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 48 times.
64 if (this->matrix_a_.rows != this->matrix_a_.cols || this->matrix_b_.rows != this->matrix_b_.cols ||
195 this->matrix_a_.rows != this->matrix_b_.rows) {
196 16 this->block_size_ = 0;
197 16 return true;
198 }
199
200 int n = this->matrix_a_.rows;
201 48 this->block_size_ = 64;
202
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
48 while (this->block_size_ * 2 <= n && this->block_size_ < 256) {
203 this->block_size_ *= 2;
204 }
205
206 48 this->block_size_ = std::min(this->block_size_, n);
207
208 48 return this->block_size_ > 0;
209 }
210
211 64 bool YakimovIMultOfDenseMatricesFoxAlgorithmSTL::RunImpl() {
212 64 FoxAlgorithmImpl(this->matrix_a_, this->matrix_b_, this->result_matrix_, this->block_size_);
213 64 return true;
214 }
215
216 64 bool YakimovIMultOfDenseMatricesFoxAlgorithmSTL::PostProcessingImpl() {
217 double sum = 0.0;
218
2/2
✓ Branch 0 taken 2136 times.
✓ Branch 1 taken 64 times.
2200 for (double val : this->result_matrix_.data) {
219 2136 sum += val;
220 }
221 64 this->GetOutput() = sum;
222 64 return true;
223 }
224
225 } // namespace yakimov_i_mult_of_dense_matrices_fox_algorithm
226