| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "ivanova_p_marking_components_on_binary_image/all/include/ops_all.hpp" | ||
| 2 | |||
| 3 | #include <mpi.h> | ||
| 4 | #include <tbb/tbb.h> | ||
| 5 | |||
| 6 | #include <algorithm> | ||
| 7 | #include <cstddef> | ||
| 8 | #include <string> | ||
| 9 | #include <vector> | ||
| 10 | |||
| 11 | #include "ivanova_p_marking_components_on_binary_image/common/include/common.hpp" | ||
| 12 | #include "ivanova_p_marking_components_on_binary_image/data/image_generator.hpp" | ||
| 13 | |||
| 14 | namespace ivanova_p_marking_components_on_binary_image { | ||
| 15 | |||
| 16 | 28 | IvanovaPMarkingComponentsOnBinaryImageALL::IvanovaPMarkingComponentsOnBinaryImageALL(const InType &in) { | |
| 17 | SetTypeOfTask(GetStaticTypeOfTask()); | ||
| 18 | 28 | GetInput() = in; | |
| 19 | 28 | GetOutput() = OutType(); | |
| 20 | |||
| 21 | 28 | test_image.width = 0; | |
| 22 |
2/2✓ Branch 0 taken 26 times.
✓ Branch 1 taken 2 times.
|
28 | test_image.height = 0; |
| 23 | test_image.data.clear(); | ||
| 24 | 28 | } | |
| 25 | |||
| 26 | 28 | bool IvanovaPMarkingComponentsOnBinaryImageALL::ValidationImpl() { | |
| 27 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
28 | if (test_image.width <= 0 || test_image.height <= 0) { |
| 28 | 28 | int test_case = GetInput(); | |
| 29 | |||
| 30 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 20 times.
|
28 | if (test_case >= 11 && test_case <= 14) { |
| 31 | std::string filename; | ||
| 32 |
4/4✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
|
8 | switch (test_case) { |
| 33 | case 11: | ||
| 34 | filename = "tasks/ivanova_p_marking_components_on_binary_image/data/image.txt"; | ||
| 35 | break; | ||
| 36 | case 12: | ||
| 37 | filename = "tasks/ivanova_p_marking_components_on_binary_image/data/image2.txt"; | ||
| 38 | break; | ||
| 39 | case 13: | ||
| 40 | filename = "tasks/ivanova_p_marking_components_on_binary_image/data/image3.txt"; | ||
| 41 | break; | ||
| 42 | case 14: | ||
| 43 | filename = "tasks/ivanova_p_marking_components_on_binary_image/data/image4.txt"; | ||
| 44 | break; | ||
| 45 | default: | ||
| 46 | filename = ""; | ||
| 47 | break; | ||
| 48 | } | ||
| 49 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
16 | test_image = LoadImageFromTxt(filename); |
| 50 | } else { | ||
| 51 | int size = ExtractImageSize(test_case); | ||
| 52 | 40 | test_image = CreateTestImage(size, size, test_case); | |
| 53 | } | ||
| 54 | } | ||
| 55 | |||
| 56 |
3/6✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 28 times.
✗ Branch 5 not taken.
|
28 | if (test_image.width <= 0 || test_image.height <= 0 || test_image.data.empty()) { |
| 57 | return false; | ||
| 58 | } | ||
| 59 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
|
28 | if (test_image.data.size() != static_cast<size_t>(test_image.width) * static_cast<size_t>(test_image.height)) { |
| 60 | ✗ | return false; | |
| 61 | } | ||
| 62 | return true; | ||
| 63 | } | ||
| 64 | |||
| 65 | 28 | bool IvanovaPMarkingComponentsOnBinaryImageALL::PreProcessingImpl() { | |
| 66 |
2/4✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 28 times.
|
28 | if (test_image.width <= 0 || test_image.height <= 0) { |
| 67 | // Дублирующий блок из оригинального кода оставлен для сохранения логики | ||
| 68 | ✗ | int test_case = GetInput(); | |
| 69 | ✗ | if (test_case >= 11 && test_case <= 14) { | |
| 70 | std::string filename; | ||
| 71 | ✗ | switch (test_case) { | |
| 72 | case 11: | ||
| 73 | filename = "tasks/ivanova_p_marking_components_on_binary_image/data/image.txt"; | ||
| 74 | break; | ||
| 75 | case 12: | ||
| 76 | filename = "tasks/ivanova_p_marking_components_on_binary_image/data/image2.txt"; | ||
| 77 | break; | ||
| 78 | case 13: | ||
| 79 | filename = "tasks/ivanova_p_marking_components_on_binary_image/data/image3.txt"; | ||
| 80 | break; | ||
| 81 | case 14: | ||
| 82 | filename = "tasks/ivanova_p_marking_components_on_binary_image/data/image4.txt"; | ||
| 83 | break; | ||
| 84 | default: | ||
| 85 | filename = ""; | ||
| 86 | break; | ||
| 87 | } | ||
| 88 | ✗ | test_image = LoadImageFromTxt(filename); | |
| 89 | } else { | ||
| 90 | int size = ExtractImageSize(test_case); | ||
| 91 | ✗ | test_image = CreateTestImage(size, size, test_case); | |
| 92 | } | ||
| 93 | } | ||
| 94 | |||
| 95 | input_image_ = test_image; | ||
| 96 | 28 | width_ = input_image_.width; | |
| 97 | 28 | height_ = input_image_.height; | |
| 98 | |||
| 99 | 28 | int total_pixels = width_ * height_; | |
| 100 | 28 | labels_.assign(total_pixels, 0); | |
| 101 | |||
| 102 | // Выделяем память под глобальный DSU с запасом на все потоки | ||
| 103 | int num_threads = tbb::this_task_arena::max_concurrency(); | ||
| 104 | 28 | parent_.resize((static_cast<size_t>(num_threads) * static_cast<size_t>(total_pixels)) + 1); | |
| 105 |
2/2✓ Branch 0 taken 400592 times.
✓ Branch 1 taken 28 times.
|
400620 | for (size_t i = 0; i < parent_.size(); ++i) { |
| 106 | 400592 | parent_[i] = static_cast<int>(i); | |
| 107 | } | ||
| 108 | |||
| 109 | 28 | current_label_ = 0; | |
| 110 | 28 | return true; | |
| 111 | } | ||
| 112 | |||
| 113 | ✗ | int IvanovaPMarkingComponentsOnBinaryImageALL::FindRoot(int label) { | |
| 114 | int root = label; | ||
| 115 |
5/8✓ Branch 0 taken 4280 times.
✓ Branch 1 taken 14776 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 314 times.
✓ Branch 4 taken 294 times.
✓ Branch 5 taken 314 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
19978 | while (parent_[root] != root) { |
| 116 | root = parent_[root]; | ||
| 117 | } | ||
| 118 | |||
| 119 | // Сжатие путей (Path compression) | ||
| 120 | int current = label; | ||
| 121 |
3/8✗ Branch 0 not taken.
✓ Branch 1 taken 14776 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 314 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 314 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
15404 | while (parent_[current] != root) { |
| 122 | int next = parent_[current]; | ||
| 123 | ✗ | parent_[current] = root; | |
| 124 | current = next; | ||
| 125 | } | ||
| 126 | ✗ | return root; | |
| 127 | } | ||
| 128 | |||
| 129 | 314 | void IvanovaPMarkingComponentsOnBinaryImageALL::UnionLabels(int label1, int label2) { | |
| 130 | int root1 = FindRoot(label1); | ||
| 131 | int root2 = FindRoot(label2); | ||
| 132 | |||
| 133 |
2/2✓ Branch 0 taken 20 times.
✓ Branch 1 taken 294 times.
|
314 | if (root1 != root2) { |
| 134 |
2/2✓ Branch 0 taken 18 times.
✓ Branch 1 taken 2 times.
|
20 | if (root1 < root2) { |
| 135 | 18 | parent_[root2] = root1; | |
| 136 | } else { | ||
| 137 | 2 | parent_[root1] = root2; | |
| 138 | } | ||
| 139 | } | ||
| 140 | 314 | } | |
| 141 | |||
| 142 | ✗ | void IvanovaPMarkingComponentsOnBinaryImageALL::ProcessPixel(int /*xx*/, int /*yy*/, int /*idx*/) { | |
| 143 | // Не используется в основном параллельном проходе, оставлено для интерфейса класса | ||
| 144 | ✗ | } | |
| 145 | |||
| 146 | ✗ | int IvanovaPMarkingComponentsOnBinaryImageALL::FindLocalRootAll(int label, const std::vector<int> &local_parent) { | |
| 147 | int root = label; | ||
| 148 |
3/10✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
14 | while (local_parent[static_cast<size_t>(root)] != root) { |
| 149 | root = local_parent[static_cast<size_t>(root)]; | ||
| 150 | } | ||
| 151 | ✗ | return root; | |
| 152 | } | ||
| 153 | |||
| 154 | ✗ | void IvanovaPMarkingComponentsOnBinaryImageALL::UnionLocalLabelsAll(int label1, int label2, | |
| 155 | std::vector<int> &local_parent) { | ||
| 156 | int root1 = FindLocalRootAll(label1, local_parent); | ||
| 157 | int root2 = FindLocalRootAll(label2, local_parent); | ||
| 158 |
2/4✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
8 | if (root1 != root2) { |
| 159 |
1/4✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
2 | if (root1 < root2) { |
| 160 | 2 | local_parent[static_cast<size_t>(root2)] = root1; | |
| 161 | } else { | ||
| 162 | ✗ | local_parent[static_cast<size_t>(root1)] = root2; | |
| 163 | } | ||
| 164 | } | ||
| 165 | ✗ | } | |
| 166 | |||
| 167 | 200282 | void IvanovaPMarkingComponentsOnBinaryImageALL::ProcessStripePixelAll(int xx, int yy, int idx, int start_row, | |
| 168 | std::vector<int> &local_parent, | ||
| 169 | int &local_label) { | ||
| 170 |
2/2✓ Branch 0 taken 14776 times.
✓ Branch 1 taken 185506 times.
|
200282 | if (input_image_.data[static_cast<size_t>(idx)] == 0) { |
| 171 | return; | ||
| 172 | } | ||
| 173 | |||
| 174 |
2/2✓ Branch 0 taken 14754 times.
✓ Branch 1 taken 22 times.
|
14776 | int left_label = (xx > 0) ? labels_[static_cast<size_t>(idx - 1)] : 0; |
| 175 |
2/2✓ Branch 0 taken 14240 times.
✓ Branch 1 taken 536 times.
|
14776 | int top_label = (yy > start_row) ? labels_[static_cast<size_t>(idx - width_)] : 0; |
| 176 | |||
| 177 | 14776 | bool left_exists = (left_label != 0); | |
| 178 | 14776 | bool top_exists = (top_label != 0); | |
| 179 | |||
| 180 |
2/2✓ Branch 0 taken 94 times.
✓ Branch 1 taken 14682 times.
|
14776 | if (!left_exists && !top_exists) { |
| 181 | 94 | local_label++; | |
| 182 | 94 | labels_[static_cast<size_t>(idx)] = local_label; | |
| 183 | } else { | ||
| 184 |
2/2✓ Branch 0 taken 932 times.
✓ Branch 1 taken 13750 times.
|
14682 | int label = left_exists ? left_label : top_label; |
| 185 | 14682 | labels_[static_cast<size_t>(idx)] = label; | |
| 186 | |||
| 187 |
4/4✓ Branch 0 taken 12626 times.
✓ Branch 1 taken 2056 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 12618 times.
|
14682 | if (left_exists && top_exists && left_label != top_label) { |
| 188 | UnionLocalLabelsAll(left_label, top_label, local_parent); | ||
| 189 | } | ||
| 190 | } | ||
| 191 | } | ||
| 192 | |||
| 193 | ✗ | void IvanovaPMarkingComponentsOnBinaryImageALL::InitializeLocalParent(std::vector<int> &local_parent, int max_labels) { | |
| 194 | 56 | local_parent.resize(static_cast<size_t>(max_labels)); | |
| 195 |
2/4✓ Branch 0 taken 801184 times.
✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
801240 | for (int i = 0; i < max_labels; ++i) { |
| 196 | 801184 | local_parent[static_cast<size_t>(i)] = i; | |
| 197 | } | ||
| 198 | ✗ | } | |
| 199 | |||
| 200 | 56 | void IvanovaPMarkingComponentsOnBinaryImageALL::ProcessStripe(int start_row, int end_row, | |
| 201 | std::vector<int> &local_parent, int &local_label) { | ||
| 202 |
2/2✓ Branch 0 taken 2046 times.
✓ Branch 1 taken 56 times.
|
2102 | for (int yy = start_row; yy < end_row; ++yy) { |
| 203 |
2/2✓ Branch 0 taken 200282 times.
✓ Branch 1 taken 2046 times.
|
202328 | for (int xx = 0; xx < width_; ++xx) { |
| 204 | 200282 | int idx = (yy * width_) + xx; | |
| 205 | 200282 | ProcessStripePixelAll(xx, yy, idx, start_row, local_parent, local_label); | |
| 206 | } | ||
| 207 | } | ||
| 208 | 56 | } | |
| 209 | |||
| 210 | 28 | void IvanovaPMarkingComponentsOnBinaryImageALL::MergeBoundaries(int num_threads, int rows_per_thread) { | |
| 211 |
2/2✓ Branch 0 taken 28 times.
✓ Branch 1 taken 28 times.
|
56 | for (int thread_id = 0; thread_id < num_threads - 1; ++thread_id) { |
| 212 | 28 | int boundary_row = (thread_id + 1) * rows_per_thread; | |
| 213 |
1/2✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
|
28 | if (boundary_row >= height_) { |
| 214 | ✗ | continue; | |
| 215 | } | ||
| 216 | |||
| 217 |
2/2✓ Branch 0 taken 2046 times.
✓ Branch 1 taken 28 times.
|
2074 | for (int xx = 0; xx < width_; ++xx) { |
| 218 | 2046 | int top_idx = ((boundary_row - 1) * width_) + xx; | |
| 219 | 2046 | int bottom_idx = (boundary_row * width_) + xx; | |
| 220 | |||
| 221 |
2/2✓ Branch 0 taken 312 times.
✓ Branch 1 taken 1734 times.
|
2046 | int top_label = labels_[static_cast<size_t>(top_idx)]; |
| 222 | 2046 | int bottom_label = labels_[static_cast<size_t>(bottom_idx)]; | |
| 223 | |||
| 224 |
3/4✓ Branch 0 taken 312 times.
✓ Branch 1 taken 1734 times.
✓ Branch 2 taken 312 times.
✗ Branch 3 not taken.
|
2046 | if (top_label != 0 && bottom_label != 0 && top_label != bottom_label) { |
| 225 | 312 | UnionLabels(top_label, bottom_label); | |
| 226 | } | ||
| 227 | } | ||
| 228 | } | ||
| 229 | 28 | } | |
| 230 | |||
| 231 | 28 | void IvanovaPMarkingComponentsOnBinaryImageALL::MergeLocalParents(const std::vector<std::vector<int>> &local_parents, | |
| 232 | const std::vector<int> &local_labels, int num_threads, | ||
| 233 | int total_pixels) { | ||
| 234 |
2/2✓ Branch 0 taken 56 times.
✓ Branch 1 taken 28 times.
|
84 | for (int thread_id = 0; thread_id < num_threads; ++thread_id) { |
| 235 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
|
56 | if (local_parents[static_cast<size_t>(thread_id)].empty()) { |
| 236 | ✗ | continue; | |
| 237 | } | ||
| 238 | |||
| 239 | 56 | int start_lbl = (thread_id * total_pixels) + 1; | |
| 240 | 56 | int end_lbl = local_labels[static_cast<size_t>(thread_id)]; | |
| 241 | |||
| 242 |
2/2✓ Branch 0 taken 94 times.
✓ Branch 1 taken 56 times.
|
150 | for (int label = start_lbl; label <= end_lbl; ++label) { |
| 243 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 92 times.
|
94 | int p = local_parents[static_cast<size_t>(thread_id)][static_cast<size_t>(label)]; |
| 244 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 92 times.
|
94 | if (p != label) { |
| 245 | 2 | UnionLabels(label, p); | |
| 246 | } | ||
| 247 | } | ||
| 248 | } | ||
| 249 | 28 | } | |
| 250 | |||
| 251 | 28 | void IvanovaPMarkingComponentsOnBinaryImageALL::FirstPass() { | |
| 252 | 28 | int num_threads = tbb::this_task_arena::max_concurrency(); | |
| 253 | 28 | int rows_per_thread = (height_ + num_threads - 1) / num_threads; | |
| 254 | 28 | int total_pixels = width_ * height_; | |
| 255 | |||
| 256 | 28 | std::vector<std::vector<int>> local_parents(static_cast<size_t>(num_threads)); | |
| 257 |
1/2✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
|
28 | std::vector<int> local_labels(static_cast<size_t>(num_threads), 0); |
| 258 | |||
| 259 | // Фаза 1: Параллельная обработка полос с TBB | ||
| 260 |
1/4✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
28 | tbb::parallel_for(0, num_threads, [&](int thread_id) { |
| 261 | 56 | int start_row = thread_id * rows_per_thread; | |
| 262 |
1/2✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
|
56 | int end_row = std::min(start_row + rows_per_thread, height_); |
| 263 |
1/2✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
|
56 | if (start_row >= height_) { |
| 264 | return; | ||
| 265 | } | ||
| 266 | |||
| 267 | 56 | int max_possible_labels = (num_threads * total_pixels) + 1; | |
| 268 | 56 | InitializeLocalParent(local_parents[static_cast<size_t>(thread_id)], max_possible_labels); | |
| 269 | |||
| 270 | 56 | int &local_label = local_labels[static_cast<size_t>(thread_id)]; | |
| 271 | 56 | local_label = thread_id * total_pixels; | |
| 272 | |||
| 273 | 56 | ProcessStripe(start_row, end_row, local_parents[static_cast<size_t>(thread_id)], local_label); | |
| 274 | }); | ||
| 275 | |||
| 276 | // Фаза 2: Последовательное объединение границ между полосами | ||
| 277 | 28 | MergeBoundaries(num_threads, rows_per_thread); | |
| 278 | |||
| 279 | // Фаза 3: Перенос локальных связей потоков в глобальный вектор DSU | ||
| 280 | 28 | MergeLocalParents(local_parents, local_labels, num_threads, total_pixels); | |
| 281 | |||
| 282 | 28 | current_label_ = 0; | |
| 283 |
2/2✓ Branch 0 taken 56 times.
✓ Branch 1 taken 28 times.
|
84 | for (int thread_id = 0; thread_id < num_threads; ++thread_id) { |
| 284 |
2/2✓ Branch 0 taken 50 times.
✓ Branch 1 taken 6 times.
|
106 | current_label_ = std::max(current_label_, local_labels[static_cast<size_t>(thread_id)]); |
| 285 | } | ||
| 286 | 28 | } | |
| 287 | |||
| 288 | 28 | void IvanovaPMarkingComponentsOnBinaryImageALL::SecondPass() { | |
| 289 | int num_threads = tbb::this_task_arena::max_concurrency(); | ||
| 290 | 28 | int total_pixels = width_ * height_; | |
| 291 | |||
| 292 | // Вектор вместо unordered_map для нормализации меток | ||
| 293 | 28 | std::vector<int> new_labels((static_cast<size_t>(num_threads) * static_cast<size_t>(total_pixels)) + 1, 0); | |
| 294 | int next_label = 1; | ||
| 295 | |||
| 296 |
2/2✓ Branch 0 taken 200282 times.
✓ Branch 1 taken 28 times.
|
200310 | for (int &label : labels_) { |
| 297 |
2/2✓ Branch 0 taken 14776 times.
✓ Branch 1 taken 185506 times.
|
200282 | if (label != 0) { |
| 298 | int root = FindRoot(label); | ||
| 299 | |||
| 300 |
2/2✓ Branch 0 taken 74 times.
✓ Branch 1 taken 14702 times.
|
14776 | if (new_labels[static_cast<size_t>(root)] == 0) { |
| 301 | 74 | new_labels[static_cast<size_t>(root)] = next_label++; | |
| 302 | } | ||
| 303 | |||
| 304 | 14776 | label = new_labels[static_cast<size_t>(root)]; | |
| 305 | } | ||
| 306 | } | ||
| 307 | |||
| 308 |
1/2✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
|
28 | current_label_ = next_label - 1; |
| 309 | 28 | } | |
| 310 | |||
| 311 | ✗ | void IvanovaPMarkingComponentsOnBinaryImageALL::InitLabelsAll(int /*unused*/) {} | |
| 312 | ✗ | void IvanovaPMarkingComponentsOnBinaryImageALL::MergeHorizontalPairsAll() {} | |
| 313 | ✗ | void IvanovaPMarkingComponentsOnBinaryImageALL::MergeVerticalPairsAll() {} | |
| 314 | ✗ | void IvanovaPMarkingComponentsOnBinaryImageALL::FinalizeRootsAll(int /*unused*/) {} | |
| 315 | ✗ | void IvanovaPMarkingComponentsOnBinaryImageALL::NormalizeLabelsAll(int /*unused*/) {} | |
| 316 | |||
| 317 | 28 | bool IvanovaPMarkingComponentsOnBinaryImageALL::RunImpl() { | |
| 318 | 28 | int total_pixels = width_ * height_; | |
| 319 |
1/2✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
|
28 | if (total_pixels <= 0) { |
| 320 | return false; | ||
| 321 | } | ||
| 322 | |||
| 323 | 28 | int rank = 0; | |
| 324 | 28 | int world_size = 1; | |
| 325 | 28 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); | |
| 326 | 28 | MPI_Comm_size(MPI_COMM_WORLD, &world_size); | |
| 327 | |||
| 328 | 28 | FirstPass(); | |
| 329 | |||
| 330 |
1/2✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
|
28 | if (current_label_ > 0) { |
| 331 | 28 | SecondPass(); | |
| 332 | } | ||
| 333 | |||
| 334 |
1/2✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
|
28 | if (world_size > 1) { |
| 335 | 28 | MPI_Barrier(MPI_COMM_WORLD); | |
| 336 | 28 | MPI_Bcast(¤t_label_, 1, MPI_INT, 0, MPI_COMM_WORLD); | |
| 337 | 28 | MPI_Bcast(labels_.data(), static_cast<int>(labels_.size()), MPI_INT, 0, MPI_COMM_WORLD); | |
| 338 | } | ||
| 339 | |||
| 340 | return true; | ||
| 341 | } | ||
| 342 | |||
| 343 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
|
28 | bool IvanovaPMarkingComponentsOnBinaryImageALL::PostProcessingImpl() { |
| 344 | OutType &output = GetOutput(); | ||
| 345 | output.clear(); | ||
| 346 | |||
| 347 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
|
28 | output.push_back(width_); |
| 348 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
|
28 | output.push_back(height_); |
| 349 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
|
28 | output.push_back(current_label_); |
| 350 | |||
| 351 |
4/4✓ Branch 0 taken 200012 times.
✓ Branch 1 taken 270 times.
✓ Branch 2 taken 200282 times.
✓ Branch 3 taken 28 times.
|
200310 | for (int label : labels_) { |
| 352 | output.push_back(label); | ||
| 353 | } | ||
| 354 | |||
| 355 | 28 | return true; | |
| 356 | } | ||
| 357 | |||
| 358 | } // namespace ivanova_p_marking_components_on_binary_image | ||
| 359 |