GCC Code Coverage Report


Directory: ./
File: tasks/artyushkina_markirovka/tbb/src/ops_tbb.cpp
Date: 2026-06-04 20:25:32
Exec Total Coverage
Lines: 80 94 85.1%
Functions: 11 17 64.7%
Branches: 65 78 83.3%

Line Branch Exec Source
1 #include "artyushkina_markirovka/tbb/include/ops_tbb.hpp"
2
3 #include <tbb/parallel_for.h>
4 #include <tbb/spin_mutex.h>
5
6 #include <algorithm>
7 #include <cstddef>
8 #include <cstdint>
9 #include <ranges>
10 #include <vector>
11
12 #include "artyushkina_markirovka/common/include/common.hpp"
13
14 namespace artyushkina_markirovka {
15
16
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 MarkingComponentsTBB::MarkingComponentsTBB(const InType &in) {
17 SetTypeOfTask(GetStaticTypeOfTask());
18
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 GetInput() = in;
19 28 GetOutput() = OutType();
20 28 }
21
22 28 bool MarkingComponentsTBB::ValidationImpl() {
23 28 return GetInput().size() >= 2;
24 }
25
26 28 bool MarkingComponentsTBB::PreProcessingImpl() {
27 const auto &input = GetInput();
28 28 rows_ = static_cast<int>(input[0]);
29 28 cols_ = static_cast<int>(input[1]);
30 28 input_ = input;
31
32 28 int total_pixels = rows_ * cols_;
33 28 labels_.assign(total_pixels, 0);
34 28 parent_.resize(total_pixels + 1);
35
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 28 times.
252 for (int i = 0; i <= total_pixels; ++i) {
36 224 parent_[i] = i;
37 }
38
39 28 current_label_ = 0;
40 28 return true;
41 }
42
43 int MarkingComponentsTBB::FindRoot(int label) {
44 int root = label;
45
6/8
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 108 times.
✓ Branch 2 taken 50 times.
✓ Branch 3 taken 106 times.
✓ Branch 4 taken 38 times.
✓ Branch 5 taken 106 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
486 while (parent_[root] != root) {
46 root = parent_[root];
47 }
48 int current = label;
49
6/8
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 108 times.
✓ Branch 2 taken 50 times.
✓ Branch 3 taken 106 times.
✓ Branch 4 taken 38 times.
✓ Branch 5 taken 106 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
486 while (parent_[current] != current) {
50 int next = parent_[current];
51 166 parent_[current] = root;
52 current = next;
53 }
54 return root;
55 }
56
57 106 void MarkingComponentsTBB::UnionLabels(int label1, int label2) {
58 106 tbb::spin_mutex::scoped_lock lock(dsu_mutex_);
59 int root1 = FindRoot(label1);
60 int root2 = FindRoot(label2);
61
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 28 times.
106 if (root1 != root2) {
62
1/2
✓ Branch 0 taken 78 times.
✗ Branch 1 not taken.
78 if (root1 < root2) {
63 78 parent_[root2] = root1;
64 } else {
65 parent_[root1] = root2;
66 }
67 }
68 106 }
69
70 void MarkingComponentsTBB::InitLabelsTbb() {
71 int total_pixels = rows_ * cols_;
72 28 tbb::parallel_for(0, total_pixels, [this](int idx) {
73 196 size_t input_idx = static_cast<size_t>(idx) + 2;
74
2/2
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 88 times.
196 if (input_[input_idx] == 0) {
75 108 labels_[idx] = idx + 1;
76 }
77 });
78 }
79
80 void MarkingComponentsTBB::MergeHorizontalPairsTbb() {
81 28 tbb::parallel_for(0, rows_, [this](int y_coord) {
82
2/2
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 68 times.
196 for (int x_coord = 0; x_coord < cols_ - 1; ++x_coord) {
83 128 int idx = (y_coord * cols_) + x_coord;
84
4/4
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 52 times.
✓ Branch 3 taken 20 times.
128 if (labels_[idx] != 0 && labels_[idx + 1] != 0) {
85 52 UnionLabels(labels_[idx], labels_[idx + 1]);
86 }
87 }
88 68 });
89 }
90
91 void MarkingComponentsTBB::MergeVerticalPairsTbb() {
92 28 tbb::parallel_for(0, rows_ - 1, [this](int y_coord) {
93
2/2
✓ Branch 0 taken 118 times.
✓ Branch 1 taken 40 times.
158 for (int x_coord = 0; x_coord < cols_; ++x_coord) {
94 118 int idx = (y_coord * cols_) + x_coord;
95
4/4
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 54 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 36 times.
118 if (labels_[idx] != 0 && labels_[idx + cols_] != 0) {
96 28 UnionLabels(labels_[idx], labels_[idx + cols_]);
97 }
98 }
99 40 });
100 }
101
102 void MarkingComponentsTBB::MergeDiagonalPairsTbb() {
103 28 tbb::parallel_for(0, rows_ - 1, [this](int y_coord) {
104
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 40 times.
118 for (int x_coord = 0; x_coord < cols_ - 1; ++x_coord) {
105 78 int idx = (y_coord * cols_) + x_coord;
106
4/4
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 28 times.
78 if (labels_[idx] != 0 && labels_[idx + cols_ + 1] != 0) {
107 18 UnionLabels(labels_[idx], labels_[idx + cols_ + 1]);
108 }
109
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 40 times.
78 if (x_coord > 0) {
110
4/4
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 22 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 8 times.
38 if (labels_[idx] != 0 && labels_[idx + cols_ - 1] != 0) {
111 8 UnionLabels(labels_[idx], labels_[idx + cols_ - 1]);
112 }
113 }
114 }
115 40 });
116 }
117
118 void MarkingComponentsTBB::FinalizeRootsTbb() {
119 28 int total_pixels = rows_ * cols_;
120 28 tbb::parallel_for(0, total_pixels, [this](int i) {
121
2/2
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 88 times.
196 if (labels_[i] != 0) {
122 108 labels_[i] = FindRoot(labels_[i]);
123 }
124 196 });
125 }
126
127 28 void MarkingComponentsTBB::NormalizeLabelsTbb() {
128 28 int total_pixels = rows_ * cols_;
129 28 std::vector<int> unique_roots;
130
2/2
✓ Branch 0 taken 196 times.
✓ Branch 1 taken 28 times.
224 for (int i = 0; i < total_pixels; ++i) {
131
2/2
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 88 times.
196 if (labels_[i] != 0) {
132 unique_roots.push_back(labels_[i]);
133 }
134 }
135
136
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 22 times.
28 if (unique_roots.empty()) {
137 return;
138 }
139
140 std::ranges::sort(unique_roots);
141 auto last = std::ranges::unique(unique_roots);
142 unique_roots.erase(last.begin(), last.end());
143
144
1/4
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
22 std::vector<int> mapping(total_pixels + 1, 0);
145 int next_id = 1;
146
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 22 times.
52 for (int root : unique_roots) {
147 30 mapping[root] = next_id++;
148 }
149
150
2/2
✓ Branch 0 taken 160 times.
✓ Branch 1 taken 22 times.
182 for (int i = 0; i < total_pixels; ++i) {
151
2/2
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 52 times.
160 if (labels_[i] != 0) {
152 108 labels_[i] = mapping[labels_[i]];
153 }
154 }
155
1/2
✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
22 current_label_ = next_id - 1;
156 }
157
158 28 bool MarkingComponentsTBB::RunImpl() {
159 28 int total_pixels = rows_ * cols_;
160
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 if (total_pixels <= 0) {
161 return true;
162 }
163
164 InitLabelsTbb();
165 MergeHorizontalPairsTbb();
166 MergeVerticalPairsTbb();
167 MergeDiagonalPairsTbb();
168 FinalizeRootsTbb();
169 28 NormalizeLabelsTbb();
170
171 28 return true;
172 }
173
174
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
28 bool MarkingComponentsTBB::PostProcessingImpl() {
175 OutType &output = GetOutput();
176 output.clear();
177
178 28 output.push_back(static_cast<uint8_t>(rows_));
179 28 output.push_back(static_cast<uint8_t>(cols_));
180
181
2/2
✓ Branch 0 taken 196 times.
✓ Branch 1 taken 28 times.
224 for (int label : labels_) {
182 196 output.push_back(static_cast<uint8_t>(label));
183 }
184
185 28 return true;
186 }
187
188 } // namespace artyushkina_markirovka
189