GCC Code Coverage Report


Directory: ./
File: tasks/romanov_a_gauss_block/stl/src/ops_stl.cpp
Date: 2026-05-11 08:26:31
Exec Total Coverage
Lines: 69 69 100.0%
Functions: 9 9 100.0%
Branches: 40 48 83.3%

Line Branch Exec Source
1 #include "romanov_a_gauss_block/stl/include/ops_stl.hpp"
2
3 #include <algorithm>
4 #include <array>
5 #include <cstddef>
6 #include <cstdint>
7 #include <thread>
8 #include <tuple>
9 #include <vector>
10
11 #include "romanov_a_gauss_block/common/include/common.hpp"
12 #include "util/include/util.hpp"
13
14 namespace romanov_a_gauss_block {
15
16
1/2
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
64 RomanovAGaussBlockSTL::RomanovAGaussBlockSTL(const InType &in) {
17 SetTypeOfTask(GetStaticTypeOfTask());
18 GetInput() = in;
19 64 GetOutput() = std::vector<uint8_t>();
20 64 }
21
22 64 bool RomanovAGaussBlockSTL::ValidationImpl() {
23 64 return std::get<0>(GetInput()) * std::get<1>(GetInput()) * 3 == static_cast<int>(std::get<2>(GetInput()).size());
24 }
25
26 64 bool RomanovAGaussBlockSTL::PreProcessingImpl() {
27 64 return true;
28 }
29
30 namespace {
31
32 constexpr int kBlockSize = 32;
33
34 240672 int ApplyKernel(const std::vector<uint8_t> &img, int row, int col, int channel, int width, int height,
35 const std::array<std::array<int, 3>, 3> &kernel) {
36 int sum = 0;
37
2/2
✓ Branch 0 taken 722016 times.
✓ Branch 1 taken 240672 times.
962688 for (size_t kr = 0; kr < 3; ++kr) {
38
2/2
✓ Branch 0 taken 2166048 times.
✓ Branch 1 taken 722016 times.
2888064 for (size_t kc = 0; kc < 3; ++kc) {
39 2166048 int nr = row + static_cast<int>(kr) - 1;
40 2166048 int nc = col + static_cast<int>(kc) - 1;
41
4/4
✓ Branch 0 taken 2149488 times.
✓ Branch 1 taken 16560 times.
✓ Branch 2 taken 2133984 times.
✓ Branch 3 taken 15504 times.
2166048 if (nr >= 0 && nr < height && nc >= 0 && nc < width) {
42 2133984 size_t idx = (((static_cast<size_t>(nr) * width) + nc) * 3) + channel;
43 2133984 sum += (static_cast<int>(img[idx]) * kernel.at(kr).at(kc));
44 }
45 }
46 }
47 240672 return sum;
48 }
49
50 72 void ProcessFullBlock(const std::vector<uint8_t> &initial_picture, std::vector<uint8_t> &result_picture, int width,
51 int height, int start_row, int start_col) {
52 static constexpr std::array<std::array<int, 3>, 3> kKernel = {{{1, 2, 1}, {2, 4, 2}, {1, 2, 1}}};
53
54
2/2
✓ Branch 0 taken 2304 times.
✓ Branch 1 taken 72 times.
2376 for (int row = start_row; row < start_row + kBlockSize; ++row) {
55
2/2
✓ Branch 0 taken 73728 times.
✓ Branch 1 taken 2304 times.
76032 for (int col = start_col; col < start_col + kBlockSize; ++col) {
56
2/2
✓ Branch 0 taken 221184 times.
✓ Branch 1 taken 73728 times.
294912 for (int channel = 0; channel < 3; ++channel) {
57 221184 int sum = ApplyKernel(initial_picture, row, col, channel, width, height, kKernel);
58
1/2
✓ Branch 0 taken 221184 times.
✗ Branch 1 not taken.
221184 int result_value = (sum + 8) / 16;
59 result_value = std::clamp(result_value, 0, 255);
60 221184 auto idx = ((static_cast<size_t>(row) * width + col) * 3) + channel;
61 221184 result_picture[idx] = static_cast<uint8_t>(result_value);
62 }
63 }
64 }
65 72 }
66
67 112 void ProcessPartBlock(const std::vector<uint8_t> &initial_picture, std::vector<uint8_t> &result_picture, int width,
68 int height, int start_row, int start_col) {
69 static constexpr std::array<std::array<int, 3>, 3> kKernel = {{{1, 2, 1}, {2, 4, 2}, {1, 2, 1}}};
70
71 112 const int end_row = std::min(height, start_row + kBlockSize);
72 112 const int end_col = std::min(width, start_col + kBlockSize);
73
74
2/2
✓ Branch 0 taken 1000 times.
✓ Branch 1 taken 112 times.
1112 for (int row = start_row; row < end_row; ++row) {
75
2/2
✓ Branch 0 taken 6496 times.
✓ Branch 1 taken 1000 times.
7496 for (int col = start_col; col < end_col; ++col) {
76
2/2
✓ Branch 0 taken 19488 times.
✓ Branch 1 taken 6496 times.
25984 for (int channel = 0; channel < 3; ++channel) {
77 19488 int sum = ApplyKernel(initial_picture, row, col, channel, width, height, kKernel);
78
1/2
✓ Branch 0 taken 19488 times.
✗ Branch 1 not taken.
19488 int result_value = (sum + 8) / 16;
79 result_value = std::clamp(result_value, 0, 255);
80 19488 auto idx = ((static_cast<size_t>(row) * width + col) * 3) + channel;
81 19488 result_picture[idx] = static_cast<uint8_t>(result_value);
82 }
83 }
84 }
85 112 }
86
87 } // namespace
88
89 64 bool RomanovAGaussBlockSTL::RunImpl() {
90 64 const int width = std::get<0>(GetInput());
91 64 const int height = std::get<1>(GetInput());
92
93 const std::vector<uint8_t> &initial_picture = std::get<2>(GetInput());
94 64 std::vector<uint8_t> result_picture(static_cast<size_t>(height * width * 3));
95
96 64 const int num_row_blocks = height / kBlockSize;
97 64 const int num_col_blocks = width / kBlockSize;
98
99
1/2
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
64 const int num_threads = ppc::util::GetNumThreads();
100 64 std::vector<std::thread> threads;
101
1/2
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
64 threads.reserve(num_threads);
102
103 160 auto processing = [&](int current_part) {
104 160 int left_border_r = (num_row_blocks * current_part) / num_threads;
105 160 int right_border_r = (num_row_blocks * (current_part + 1)) / num_threads;
106
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 160 times.
184 for (int bi = left_border_r; bi < right_border_r; ++bi) {
107
2/2
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 24 times.
96 for (int bj = 0; bj < num_col_blocks; ++bj) {
108 72 ProcessFullBlock(initial_picture, result_picture, width, height, bi * kBlockSize, bj * kBlockSize);
109 }
110 }
111
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 160 times.
184 for (int bi = left_border_r; bi < right_border_r; ++bi) {
112 24 ProcessPartBlock(initial_picture, result_picture, width, height, bi * kBlockSize, width - (width % kBlockSize));
113 }
114 160 int left_border_l = (num_col_blocks * current_part) / num_threads;
115 160 int right_border_l = (num_col_blocks * (current_part + 1)) / num_threads;
116
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 160 times.
184 for (int bj = left_border_l; bj < right_border_l; ++bj) {
117 24 ProcessPartBlock(initial_picture, result_picture, width, height, height - (height % kBlockSize), bj * kBlockSize);
118 }
119 224 };
120
121
2/2
✓ Branch 0 taken 160 times.
✓ Branch 1 taken 64 times.
224 for (int tid = 0; tid < num_threads; tid++) {
122
1/2
✓ Branch 1 taken 160 times.
✗ Branch 2 not taken.
160 threads.emplace_back(processing, tid);
123 }
124
125
2/2
✓ Branch 0 taken 160 times.
✓ Branch 1 taken 64 times.
224 for (auto &th : threads) {
126
1/2
✓ Branch 1 taken 160 times.
✗ Branch 2 not taken.
160 th.join();
127 }
128
129 64 ProcessPartBlock(initial_picture, result_picture, width, height, height - (height % kBlockSize),
130 64 width - (width % kBlockSize));
131
132
1/2
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
64 GetOutput() = result_picture;
133 64 return true;
134 64 }
135
136 64 bool RomanovAGaussBlockSTL::PostProcessingImpl() {
137 64 return true;
138 }
139
140 } // namespace romanov_a_gauss_block
141