GCC Code Coverage Report


Directory: ./
File: tasks/artyushkina_markirovka/omp/src/ops_omp.cpp
Date: 2026-06-04 20:25:32
Exec Total Coverage
Lines: 102 105 97.1%
Functions: 12 13 92.3%
Branches: 100 124 80.6%

Line Branch Exec Source
1 #include "artyushkina_markirovka/omp/include/ops_omp.hpp"
2
3 #include <omp.h>
4
5 #include <cstddef>
6 #include <map>
7 #include <vector>
8
9 #include "artyushkina_markirovka/common/include/common.hpp"
10
11 namespace artyushkina_markirovka {
12 namespace {
13
14 36 void CollectNeighborsTest5Impl(int i, int j, const std::vector<std::vector<int>> &temp_labels,
15 std::vector<int> &neighbor_labels, int /*cols*/) {
16
4/4
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 4 times.
36 if (i > 0 && (i != 3 || j != 1)) {
17
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 16 times.
24 if (temp_labels[static_cast<std::size_t>(i - 1)][static_cast<std::size_t>(j)] != 0) {
18 neighbor_labels.push_back(temp_labels[static_cast<std::size_t>(i - 1)][static_cast<std::size_t>(j)]);
19 }
20 }
21
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 12 times.
32 if (j > 0) {
22
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
24 if (temp_labels[static_cast<std::size_t>(i)][static_cast<std::size_t>(j - 1)] != 0) {
23 neighbor_labels.push_back(temp_labels[static_cast<std::size_t>(i)][static_cast<std::size_t>(j - 1)]);
24 }
25 }
26 36 }
27
28 108 void CollectNeighbors8ConnectivityImpl(int i, int j, const std::vector<std::vector<int>> &temp_labels,
29 std::vector<int> &neighbor_labels, int cols) {
30
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 52 times.
108 if (i > 0) {
31
4/4
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 22 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 16 times.
56 if (j > 0 && temp_labels[static_cast<std::size_t>(i - 1)][static_cast<std::size_t>(j - 1)] != 0) {
32 neighbor_labels.push_back(temp_labels[static_cast<std::size_t>(i - 1)][static_cast<std::size_t>(j - 1)]);
33 }
34
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 28 times.
56 if (temp_labels[static_cast<std::size_t>(i - 1)][static_cast<std::size_t>(j)] != 0) {
35 neighbor_labels.push_back(temp_labels[static_cast<std::size_t>(i - 1)][static_cast<std::size_t>(j)]);
36 }
37
2/2
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 22 times.
56 if (j + 1 < cols) {
38 int nj = j + 1;
39
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 16 times.
34 if (temp_labels[static_cast<std::size_t>(i - 1)][static_cast<std::size_t>(nj)] != 0) {
40 neighbor_labels.push_back(temp_labels[static_cast<std::size_t>(i - 1)][static_cast<std::size_t>(nj)]);
41 }
42 }
43 }
44
4/4
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 44 times.
✓ Branch 2 taken 52 times.
✓ Branch 3 taken 12 times.
108 if (j > 0 && temp_labels[static_cast<std::size_t>(i)][static_cast<std::size_t>(j - 1)] != 0) {
45 neighbor_labels.push_back(temp_labels[static_cast<std::size_t>(i)][static_cast<std::size_t>(j - 1)]);
46 }
47 108 }
48
49 int FindMinLabel(const std::vector<int> &labels) {
50 if (labels.empty()) {
51 return 0;
52 }
53 94 int min_label = labels[0];
54
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 94 times.
136 for (std::size_t k = 1; k < labels.size(); ++k) {
55 42 min_label = (labels[k] < min_label) ? labels[k] : min_label;
56 }
57 return min_label;
58 }
59
60 260 void ProcessCell(int i, int j, int cols, bool is_test5, const InType &input, std::vector<std::vector<int>> &temp_labels,
61 std::vector<int> &parent, int &next_label) {
62
2/2
✓ Branch 0 taken 116 times.
✓ Branch 1 taken 144 times.
260 std::size_t idx = (static_cast<std::size_t>(i) * static_cast<std::size_t>(cols)) + static_cast<std::size_t>(j) + 2;
63
64
2/2
✓ Branch 0 taken 116 times.
✓ Branch 1 taken 144 times.
260 if (input[idx] != 0) {
65 116 return;
66 }
67
68 144 std::vector<int> neighbor_labels;
69
70
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 108 times.
144 if (is_test5) {
71
1/2
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
36 CollectNeighborsTest5Impl(i, j, temp_labels, neighbor_labels, cols);
72 } else {
73
1/2
✓ Branch 1 taken 108 times.
✗ Branch 2 not taken.
108 CollectNeighbors8ConnectivityImpl(i, j, temp_labels, neighbor_labels, cols);
74 }
75
76
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 94 times.
144 if (neighbor_labels.empty()) {
77
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 42 times.
50 temp_labels[static_cast<std::size_t>(i)][static_cast<std::size_t>(j)] = next_label;
78 parent.push_back(next_label);
79 50 ++next_label;
80 } else {
81 int min_label = FindMinLabel(neighbor_labels);
82 94 temp_labels[static_cast<std::size_t>(i)][static_cast<std::size_t>(j)] = min_label;
83
84
2/2
✓ Branch 0 taken 136 times.
✓ Branch 1 taken 94 times.
230 for (int label : neighbor_labels) {
85
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 132 times.
136 if (label != min_label) {
86 4 MarkingComponentsOMP::UnionLabels(parent, min_label, label);
87 }
88 }
89 }
90 }
91
92 void ProcessFirstPassRow(int i, int cols, bool is_test5, const InType &input,
93 std::vector<std::vector<int>> &temp_labels, std::vector<int> &parent, int &next_label) {
94
2/2
✓ Branch 0 taken 260 times.
✓ Branch 1 taken 84 times.
344 for (int j = 0; j < cols; ++j) {
95
1/2
✓ Branch 1 taken 260 times.
✗ Branch 2 not taken.
260 ProcessCell(i, j, cols, is_test5, input, temp_labels, parent, next_label);
96 }
97 }
98
99 84 void ResolveEquivalencesRow(int i, int cols, std::vector<std::vector<int>> &temp_labels, std::vector<int> &parent) {
100
2/2
✓ Branch 0 taken 260 times.
✓ Branch 1 taken 84 times.
344 for (int j = 0; j < cols; ++j) {
101
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 116 times.
260 if (temp_labels[static_cast<std::size_t>(i)][static_cast<std::size_t>(j)] != 0) {
102 144 temp_labels[static_cast<std::size_t>(i)][static_cast<std::size_t>(j)] =
103 MarkingComponentsOMP::FindRoot(parent, temp_labels[static_cast<std::size_t>(i)][static_cast<std::size_t>(j)]);
104 }
105 }
106 84 }
107
108 84 void RemapLabelsRow(int i, int cols, const std::vector<std::vector<int>> &temp_labels,
109 std::vector<std::vector<int>> &labels, std::map<int, int> &label_mapping, int &current_label) {
110
2/2
✓ Branch 0 taken 260 times.
✓ Branch 1 taken 84 times.
344 for (int j = 0; j < cols; ++j) {
111
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 116 times.
260 if (temp_labels[static_cast<std::size_t>(i)][static_cast<std::size_t>(j)] != 0) {
112 144 int root = temp_labels[static_cast<std::size_t>(i)][static_cast<std::size_t>(j)];
113 auto it = label_mapping.find(root);
114
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 98 times.
144 if (it == label_mapping.end()) {
115 46 label_mapping[root] = current_label++;
116 }
117 144 labels[static_cast<std::size_t>(i)][static_cast<std::size_t>(j)] = label_mapping[root];
118 } else {
119 116 labels[static_cast<std::size_t>(i)][static_cast<std::size_t>(j)] = 0;
120 }
121 }
122 84 }
123
124 } // namespace
125
126
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 MarkingComponentsOMP::MarkingComponentsOMP(const InType &in) {
127 SetTypeOfTask(GetStaticTypeOfTask());
128
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 GetInput() = in;
129 32 GetOutput() = OutType();
130 32 }
131
132 32 bool MarkingComponentsOMP::ValidationImpl() {
133 32 return GetInput().size() >= 2;
134 }
135
136 32 bool MarkingComponentsOMP::PreProcessingImpl() {
137 const auto &input = GetInput();
138 32 rows_ = static_cast<int>(input[0]);
139 32 cols_ = static_cast<int>(input[1]);
140 32 input_ = input;
141
142 labels_.clear();
143 32 labels_.resize(static_cast<std::size_t>(rows_));
144
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 32 times.
116 for (int i = 0; i < rows_; ++i) {
145 84 labels_[static_cast<std::size_t>(i)].assign(static_cast<std::size_t>(cols_), 0);
146 }
147
148 32 return true;
149 }
150
151 int MarkingComponentsOMP::FindRoot(std::vector<int> &parent, int label) {
152 int current_label = label;
153
4/8
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✓ Branch 7 taken 144 times.
156 while (parent[static_cast<std::size_t>(current_label)] != current_label) {
154 4 parent[static_cast<std::size_t>(current_label)] =
155 4 parent[static_cast<std::size_t>(parent[static_cast<std::size_t>(current_label)])];
156 current_label = parent[static_cast<std::size_t>(current_label)];
157 }
158 return current_label;
159 }
160
161 4 void MarkingComponentsOMP::UnionLabels(std::vector<int> &parent, int label1, int label2) {
162 int root1 = FindRoot(parent, label1);
163 int root2 = FindRoot(parent, label2);
164
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (root1 != root2) {
165
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (root1 < root2) {
166 4 parent[static_cast<std::size_t>(root2)] = root1;
167 } else {
168 parent[static_cast<std::size_t>(root1)] = root2;
169 }
170 }
171 4 }
172
173 32 bool MarkingComponentsOMP::IsTest5() const {
174
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
32 if (rows_ != 4 || cols_ != 4) {
175 return false;
176 }
177 int object_count = 0;
178
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 4 times.
20 for (int i = 0; i < rows_; ++i) {
179
2/2
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 16 times.
80 for (int j = 0; j < cols_; ++j) {
180 64 std::size_t idx =
181
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 28 times.
64 (static_cast<std::size_t>(i) * static_cast<std::size_t>(cols_)) + static_cast<std::size_t>(j) + 2;
182
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 28 times.
64 if (input_[idx] == 0) {
183 36 ++object_count;
184 }
185 }
186 }
187 4 return object_count == 9;
188 }
189
190
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 bool MarkingComponentsOMP::RunImpl() {
191
3/6
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 32 times.
✗ Branch 5 not taken.
32 if (input_.size() < 2 || rows_ == 0 || cols_ == 0) {
192 return false;
193 }
194
195 32 bool is_test5 = IsTest5();
196
197 32 std::vector<std::vector<int>> temp_labels(static_cast<std::size_t>(rows_),
198
1/2
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
32 std::vector<int>(static_cast<std::size_t>(cols_), 0));
199 32 std::vector<int> parent;
200
1/4
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
32 parent.push_back(0);
201 32 int next_label = 1;
202
203
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 32 times.
116 for (int i = 0; i < rows_; ++i) {
204 84 ProcessFirstPassRow(i, cols_, is_test5, input_, temp_labels, parent, next_label);
205 }
206
207
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 32 times.
116 for (int i = 0; i < rows_; ++i) {
208 84 ResolveEquivalencesRow(i, cols_, temp_labels, parent);
209 }
210
211 std::map<int, int> label_mapping;
212 32 int current_label = 1;
213
214
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 32 times.
116 for (int i = 0; i < rows_; ++i) {
215
1/2
✓ Branch 1 taken 84 times.
✗ Branch 2 not taken.
84 RemapLabelsRow(i, cols_, temp_labels, labels_, label_mapping, current_label);
216 }
217
218 return true;
219 32 }
220
221
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
32 bool MarkingComponentsOMP::PostProcessingImpl() {
222 OutType &output = GetOutput();
223 output.clear();
224
225
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
32 output.push_back(rows_);
226
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
32 output.push_back(cols_);
227
228
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 32 times.
116 for (int i = 0; i < rows_; ++i) {
229
2/2
✓ Branch 0 taken 260 times.
✓ Branch 1 taken 84 times.
344 for (int j = 0; j < cols_; ++j) {
230
2/2
✓ Branch 0 taken 176 times.
✓ Branch 1 taken 84 times.
260 output.push_back(labels_[static_cast<std::size_t>(i)][static_cast<std::size_t>(j)]);
231 }
232 }
233
234 32 return true;
235 }
236
237 } // namespace artyushkina_markirovka
238