GCC Code Coverage Report


Directory: ./
File: tasks/romanov_a_gauss_block/tbb/src/ops_tbb.cpp
Date: 2026-05-11 08:26:31
Exec Total Coverage
Lines: 61 61 100.0%
Functions: 11 11 100.0%
Branches: 35 44 79.5%

Line Branch Exec Source
1 #include "romanov_a_gauss_block/tbb/include/ops_tbb.hpp"
2
3 #include <oneapi/tbb/parallel_for.h>
4 #include <tbb/tbb.h>
5
6 #include <algorithm>
7 #include <array>
8 #include <cstddef>
9 #include <cstdint>
10 #include <tuple>
11 #include <vector>
12
13 #include "romanov_a_gauss_block/common/include/common.hpp"
14
15 namespace romanov_a_gauss_block {
16
17
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 RomanovAGaussBlockTBB::RomanovAGaussBlockTBB(const InType &in) {
18 SetTypeOfTask(GetStaticTypeOfTask());
19 GetInput() = in;
20 32 GetOutput() = std::vector<uint8_t>();
21 32 }
22
23 32 bool RomanovAGaussBlockTBB::ValidationImpl() {
24 32 return std::get<0>(GetInput()) * std::get<1>(GetInput()) * 3 == static_cast<int>(std::get<2>(GetInput()).size());
25 }
26
27 32 bool RomanovAGaussBlockTBB::PreProcessingImpl() {
28 32 return true;
29 }
30
31 namespace {
32
33 constexpr int kBlockSize = 32;
34
35 120336 int ApplyKernel(const std::vector<uint8_t> &img, int row, int col, int channel, int width, int height,
36 const std::array<std::array<int, 3>, 3> &kernel) {
37 int sum = 0;
38
2/2
✓ Branch 0 taken 361008 times.
✓ Branch 1 taken 120336 times.
481344 for (size_t kr = 0; kr < 3; ++kr) {
39
2/2
✓ Branch 0 taken 1083024 times.
✓ Branch 1 taken 361008 times.
1444032 for (size_t kc = 0; kc < 3; ++kc) {
40 1083024 int nr = row + static_cast<int>(kr) - 1;
41 1083024 int nc = col + static_cast<int>(kc) - 1;
42
4/4
✓ Branch 0 taken 1074744 times.
✓ Branch 1 taken 8280 times.
✓ Branch 2 taken 1066992 times.
✓ Branch 3 taken 7752 times.
1083024 if (nr >= 0 && nr < height && nc >= 0 && nc < width) {
43 1066992 size_t idx = (((static_cast<size_t>(nr) * width) + nc) * 3) + channel;
44 1066992 sum += (static_cast<int>(img[idx]) * kernel.at(kr).at(kc));
45 }
46 }
47 }
48 120336 return sum;
49 }
50
51 36 void ProcessFullBlock(const std::vector<uint8_t> &initial_picture, std::vector<uint8_t> &result_picture, int width,
52 int height, int start_row, int start_col) {
53 static constexpr std::array<std::array<int, 3>, 3> kKernel = {{{1, 2, 1}, {2, 4, 2}, {1, 2, 1}}};
54
55
2/2
✓ Branch 0 taken 1152 times.
✓ Branch 1 taken 36 times.
1188 for (int row = start_row; row < start_row + kBlockSize; ++row) {
56
2/2
✓ Branch 0 taken 36864 times.
✓ Branch 1 taken 1152 times.
38016 for (int col = start_col; col < start_col + kBlockSize; ++col) {
57
2/2
✓ Branch 0 taken 110592 times.
✓ Branch 1 taken 36864 times.
147456 for (int channel = 0; channel < 3; ++channel) {
58 110592 int sum = ApplyKernel(initial_picture, row, col, channel, width, height, kKernel);
59
1/2
✓ Branch 0 taken 110592 times.
✗ Branch 1 not taken.
110592 int result_value = (sum + 8) / 16;
60 result_value = std::clamp(result_value, 0, 255);
61 110592 auto idx = ((static_cast<size_t>(row) * width + col) * 3) + channel;
62 110592 result_picture[idx] = static_cast<uint8_t>(result_value);
63 }
64 }
65 }
66 36 }
67
68 56 void ProcessPartBlock(const std::vector<uint8_t> &initial_picture, std::vector<uint8_t> &result_picture, int width,
69 int height, int start_row, int start_col) {
70 static constexpr std::array<std::array<int, 3>, 3> kKernel = {{{1, 2, 1}, {2, 4, 2}, {1, 2, 1}}};
71
72 56 const int end_row = std::min(height, start_row + kBlockSize);
73 56 const int end_col = std::min(width, start_col + kBlockSize);
74
75
2/2
✓ Branch 0 taken 500 times.
✓ Branch 1 taken 56 times.
556 for (int row = start_row; row < end_row; ++row) {
76
2/2
✓ Branch 0 taken 3248 times.
✓ Branch 1 taken 500 times.
3748 for (int col = start_col; col < end_col; ++col) {
77
2/2
✓ Branch 0 taken 9744 times.
✓ Branch 1 taken 3248 times.
12992 for (int channel = 0; channel < 3; ++channel) {
78 9744 int sum = ApplyKernel(initial_picture, row, col, channel, width, height, kKernel);
79
1/2
✓ Branch 0 taken 9744 times.
✗ Branch 1 not taken.
9744 int result_value = (sum + 8) / 16;
80 result_value = std::clamp(result_value, 0, 255);
81 9744 auto idx = ((static_cast<size_t>(row) * width + col) * 3) + channel;
82 9744 result_picture[idx] = static_cast<uint8_t>(result_value);
83 }
84 }
85 }
86 56 }
87
88 } // namespace
89
90 32 bool RomanovAGaussBlockTBB::RunImpl() {
91 32 const int width = std::get<0>(GetInput());
92 32 const int height = std::get<1>(GetInput());
93
94 const std::vector<uint8_t> &initial_picture = std::get<2>(GetInput());
95 32 std::vector<uint8_t> result_picture(static_cast<size_t>(height * width * 3));
96
97 32 const int num_row_blocks = height / kBlockSize;
98 32 const int num_col_blocks = width / kBlockSize;
99
100
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
44 tbb::parallel_for(tbb::blocked_range<int>(0, num_row_blocks, 1), [&](const tbb::blocked_range<int> &r) {
101
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
24 for (int bi = r.begin(); bi != r.end(); ++bi) {
102
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 12 times.
48 for (int bj = 0; bj < num_col_blocks; ++bj) {
103 36 ProcessFullBlock(initial_picture, result_picture, width, height, bi * kBlockSize, bj * kBlockSize);
104 }
105 }
106 12 });
107
108
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
44 tbb::parallel_for(tbb::blocked_range<int>(0, num_row_blocks, 1), [&](const tbb::blocked_range<int> &r) {
109
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
24 for (int bi = r.begin(); bi != r.end(); ++bi) {
110 12 ProcessPartBlock(initial_picture, result_picture, width, height, bi * kBlockSize, width - (width % kBlockSize));
111 }
112 12 });
113
114
1/4
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
44 tbb::parallel_for(tbb::blocked_range<int>(0, num_col_blocks, 1), [&](const tbb::blocked_range<int> &r) {
115
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
24 for (int bj = r.begin(); bj != r.end(); ++bj) {
116 12 ProcessPartBlock(initial_picture, result_picture, width, height, height - (height % kBlockSize), bj * kBlockSize);
117 }
118 12 });
119
120 32 ProcessPartBlock(initial_picture, result_picture, width, height, height - (height % kBlockSize),
121 32 width - (width % kBlockSize));
122
123
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 GetOutput() = result_picture;
124 32 return true;
125 }
126
127 32 bool RomanovAGaussBlockTBB::PostProcessingImpl() {
128 32 return true;
129 }
130
131 } // namespace romanov_a_gauss_block
132