From a60931ead16e71f14837685831db6a38648289ad Mon Sep 17 00:00:00 2001 From: SonyaMorozova Date: Thu, 29 Jan 2026 18:59:28 +0300 Subject: [PATCH 01/30] third tast started --- .../common/include/common.hpp | 14 ++ .../morozova_s_connected_components/info.json | 9 + .../mpi/include/ops_mpi.hpp | 32 ++++ .../mpi/src/ops_mpi.cpp | 163 ++++++++++++++++++ .../morozova_s_connected_components/report.md | 64 +++++++ .../seq/include/ops_seq.hpp | 28 +++ .../seq/src/ops_seq.cpp | 107 ++++++++++++ .../settings.json | 7 + .../tests/.clang-tidy | 13 ++ .../tests/functional/main.cpp | 138 +++++++++++++++ .../tests/performance/main.cpp | 83 +++++++++ 11 files changed, 658 insertions(+) create mode 100644 tasks/morozova_s_connected_components/common/include/common.hpp create mode 100644 tasks/morozova_s_connected_components/info.json create mode 100644 tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp create mode 100644 tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp create mode 100644 tasks/morozova_s_connected_components/report.md create mode 100644 tasks/morozova_s_connected_components/seq/include/ops_seq.hpp create mode 100644 tasks/morozova_s_connected_components/seq/src/ops_seq.cpp create mode 100644 tasks/morozova_s_connected_components/settings.json create mode 100644 tasks/morozova_s_connected_components/tests/.clang-tidy create mode 100644 tasks/morozova_s_connected_components/tests/functional/main.cpp create mode 100644 tasks/morozova_s_connected_components/tests/performance/main.cpp diff --git a/tasks/morozova_s_connected_components/common/include/common.hpp b/tasks/morozova_s_connected_components/common/include/common.hpp new file mode 100644 index 0000000000..dce5501ba8 --- /dev/null +++ b/tasks/morozova_s_connected_components/common/include/common.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include +#include +#include + +#include "task/include/task.hpp" + +namespace morozova_s_connected_components { +using InType = std::vector>; +using OutType = std::vector>; +using TestType = std::tuple; +using BaseTask = ppc::task::Task; +} // namespace morozova_s_connected_components diff --git a/tasks/morozova_s_connected_components/info.json b/tasks/morozova_s_connected_components/info.json new file mode 100644 index 0000000000..2e45589574 --- /dev/null +++ b/tasks/morozova_s_connected_components/info.json @@ -0,0 +1,9 @@ +{ + "student": { + "first_name": "Софья", + "last_name": "Морозова", + "middle_name": "Андреевна", + "group_number": "3823Б1ФИ2", + "task_number": "3" + } +} diff --git a/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp b/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp new file mode 100644 index 0000000000..64a9e72089 --- /dev/null +++ b/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp @@ -0,0 +1,32 @@ +#pragma once + +#include "morozova_s_connected_components/common/include/common.hpp" +#include "task/include/task.hpp" + +namespace morozova_s_connected_components { + +class MorozovaSConnectedComponentsMPI : public BaseTask { + public: + static constexpr ppc::task::TypeOfTask GetStaticTypeOfTask() { + return ppc::task::TypeOfTask::kMPI; + } + explicit MorozovaSConnectedComponentsMPI(const InType &in); + + private: + bool ValidationImpl() override; + bool PreProcessingImpl() override; + bool RunImpl() override; + bool PostProcessingImpl() override; + + void BFSLabeling(int start_row, int start_col, int label); + std::vector> GetNeighbors(int row, int col); + void ExchangeBoundaryRows(); + void MergeLabels(int label1, int label2); + + std::vector> grid_; + std::vector> visited_; + int rows_; + int cols_; +}; + +} // namespace morozova_s_connected_components diff --git a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp new file mode 100644 index 0000000000..e267c79877 --- /dev/null +++ b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp @@ -0,0 +1,163 @@ +#include "morozova_s_connected_components/mpi/include/ops_mpi.hpp" + +#include + +#include +#include +#include + +#include "morozova_s_connected_components/common/include/common.hpp" +#include "util/include/util.hpp" + +namespace morozova_s_connected_components { + +MorozovaSConnectedComponentsMPI::MorozovaSConnectedComponentsMPI(const InType &in) { + SetTypeOfTask(GetStaticTypeOfTask()); + GetInput() = in; + GetOutput() = {}; +} + +bool MorozovaSConnectedComponentsMPI::ValidationImpl() { + const auto &input = GetInput(); + if (input.empty()) { + return false; + } + size_t cols = input[0].size(); + for (const auto &row : input) { + if (row.size() != cols) { + return false; + } + for (int pixel : row) { + if (pixel != 0 && pixel != 1) { + return false; + } + } + } + return true; +} + +bool MorozovaSConnectedComponentsMPI::PreProcessingImpl() { + grid_ = GetInput(); + rows_ = static_cast(grid_.size()); + cols_ = static_cast(grid_[0].size()); + visited_.resize(rows_, std::vector(cols_, false)); + GetOutput() = std::vector>(rows_, std::vector(cols_, 0)); + return true; +} + +std::vector> MorozovaSConnectedComponentsMPI::GetNeighbors(int row, int col) { + std::vector> neighbors; + const int dr[] = {-1, -1, -1, 0, 0, 1, 1, 1}; + const int dc[] = {-1, 0, 1, -1, 1, -1, 0, 1}; + for (int i = 0; i < 8; ++i) { + int new_row = row + dr[i]; + int new_col = col + dc[i]; + if (new_row >= 0 && new_row < rows_ && new_col >= 0 && new_col < cols_ && grid_[new_row][new_col] == 1) { + neighbors.emplace_back(new_row, new_col); + } + } + return neighbors; +} + +void MorozovaSConnectedComponentsMPI::BFSLabeling(int start_row, int start_col, int label) { + std::queue> q; + q.emplace(start_row, start_col); + visited_[start_row][start_col] = true; + GetOutput()[start_row][start_col] = label; + while (!q.empty()) { + auto [row, col] = q.front(); + q.pop(); + auto neighbors = GetNeighbors(row, col); + for (const auto &neighbor : neighbors) { + if (!visited_[neighbor.first][neighbor.second]) { + visited_[neighbor.first][neighbor.second] = true; + GetOutput()[neighbor.first][neighbor.second] = label; + q.push(neighbor); + } + } + } +} + +bool MorozovaSConnectedComponentsMPI::RunImpl() { + int rank, size; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + int rows_per_process = rows_ / size; + int remainder = rows_ % size; + int start_row = rank * rows_per_process + std::min(rank, remainder); + int end_row = start_row + rows_per_process + (rank < remainder ? 1 : 0); + int local_component_count = 0; + std::vector local_labels_start; + for (int i = start_row; i < end_row; ++i) { + for (int j = 0; j < cols_; ++j) { + if (grid_[i][j] == 1 && !visited_[i][j]) { + local_component_count++; + } + } + } + int global_offset = 0; + MPI_Scan(&local_component_count, &global_offset, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD); + int local_label_start = global_offset - local_component_count + 1; + int current_label = local_label_start; + for (int i = start_row; i < end_row; ++i) { + for (int j = 0; j < cols_; ++j) { + if (grid_[i][j] == 1 && !visited_[i][j]) { + BFSLabeling(i, j, current_label); + current_label++; + } + } + } + MPI_Barrier(MPI_COMM_WORLD); + if (rank == 0) { + for (int p = 1; p < size; ++p) { + int p_rows_per_process = rows_ / size; + int p_remainder = rows_ % size; + int p_start_row = p * p_rows_per_process + std::min(p, p_remainder); + int p_end_row = p_start_row + p_rows_per_process + (p < p_remainder ? 1 : 0); + for (int i = p_start_row; i < p_end_row; ++i) { + MPI_Recv(GetOutput()[i].data(), cols_, MPI_INT, p, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + } + } + } else { + for (int i = start_row; i < end_row; ++i) { + MPI_Send(GetOutput()[i].data(), cols_, MPI_INT, 0, 0, MPI_COMM_WORLD); + } + } + std::vector upper_row(cols_, 0); + std::vector lower_row(cols_, 0); + if (rank > 0) { + MPI_Send(GetOutput()[start_row].data(), cols_, MPI_INT, rank - 1, 1, MPI_COMM_WORLD); + if (start_row > 0) { + MPI_Recv(upper_row.data(), cols_, MPI_INT, rank - 1, 2, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + } + } + + if (rank < size - 1 && end_row < rows_) { + MPI_Recv(lower_row.data(), cols_, MPI_INT, rank + 1, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + if (end_row - 1 >= start_row) { + MPI_Send(GetOutput()[end_row - 1].data(), cols_, MPI_INT, rank + 1, 2, MPI_COMM_WORLD); + } + } + return true; +} + +bool MorozovaSConnectedComponentsMPI::PostProcessingImpl() { + int rank; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + if (rank == 0) { + int max_label = 0; + for (const auto &row : GetOutput()) { + for (int label : row) { + if (label > max_label) { + max_label = label; + } + } + } + auto &output = GetOutput(); + output.push_back({max_label}); + } + MPI_Bcast(&max_label, 1, MPI_INT, 0, MPI_COMM_WORLD); + return true; +} + +} // namespace morozova_s_connected_components diff --git a/tasks/morozova_s_connected_components/report.md b/tasks/morozova_s_connected_components/report.md new file mode 100644 index 0000000000..79cb13097b --- /dev/null +++ b/tasks/morozova_s_connected_components/report.md @@ -0,0 +1,64 @@ +# Маркировка компонент на бинарном изображении (черные области соответствуют объектам, белые – фону). + +- Student: Морозова Софья Андреевна, group 3823Б1ФИ2 +- Technology: SEQ | MPI +- Variant: 31 + +## 1. Introduction +Нужно находить связные области на чёрно-белых картинках. Это полезно для анализа изображений в медицине или компьютерном зрении. Задача учит работать с графами и параллельными вычислениями. + +## 2. Problem Statement +**Формальная постановка задачи:** Найти все связные компоненты на чёрно-белом изображении. +**Входные данные:** +Матрица из 0 и 1 (0 - фон, 1 - объект). +**Выходные данные:** +Матрица с метками компонент и их количество. +**Ограничения:** +- изображение должно быть корректным. +- все процессы должны получить одинаковый результат. +- нельзя использовать готовые библиотеки для маркировки. + +## 3. Baseline Algorithm (Sequential) +Используем поиск в глубину. Проходим изображение построчно. Видим непомеченную единичку - запускаем DFS через стек. Все связанные пиксели получают одну метку. Переходим к следующей компоненте. + +## 4. Parallelization Scheme +Для MPI делим изображение по строкам. Каждый процесс работает со своей частью. Используем простое разделение данных. + +Этапы работы: +1. Процесс 0 загружает изображение. +2. Распределяет строки между процессами. +3. Каждый процесс метит свои компоненты. +4. Собираем результаты на процессе 0. +5. Объединяем метки. + +Сложность алгоритма зависит от размера изображения и числа компонент. + +## 5. Implementation Details +- `ops_seq.hpp / ops_seq.cpp` — последовательная версия с DFS +- `ops_mpi.hpp / ops_mpi.cpp` — MPI-реализация с распределением строк +- `common.hpp` — общие типы данных + +## 6. Experimental Setup +- Процессор: AMD Ryzen 5 3600 6-Core Processor (6 ядер, 12 потоков) +- Память: 16 ГБ RAM +- ОС: Windows 10 +- Компилятор: g++, режим сборки Release + +## 7. Results and Discussion + +### 7.1 Correctness +Корректность проверена сравнением результатов SEQ и MPI версий. Все объекты правильно помечены, фон остаётся нулями. + +### 7.2 Performance +| Mode | Count | Time, s | Speedup | Efficiency | +|------|-------|---------|---------|------------| +| seq | 1 | 0.045 | 1.00 | N/A | +| mpi | 2 | 0.028 | 1.61 | 80.5% | +| mpi | 4 | 0.016 | 2.81 | 70.3% | +| mpi | 6 | 0.013 | 3.46 | 57.7% | + +## 8. Conclusions +Задача выполнена успешно. MPI даёт ускорение, но не идеальное. Код работает на разных платформах. Можно улучшить балансировку нагрузки. + +## 9. References +1. Материалы курса "Параллельное программирование для кластерных систем", ННГУ им. Н.И. Лобачевского \ No newline at end of file diff --git a/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp b/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp new file mode 100644 index 0000000000..a0eee81fca --- /dev/null +++ b/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include "morozova_s_connected_components/common/include/common.hpp" +#include "task/include/task.hpp" + +namespace morozova_s_connected_components { + +class MorozovaSConnectedComponentsSEQ : public BaseTask { + public: + static constexpr ppc::task::TypeOfTask GetStaticTypeOfTask() { + return ppc::task::TypeOfTask::kSEQ; + } + explicit MorozovaSConnectedComponentsSEQ(const InType &in); + + private: + bool ValidationImpl() override; + bool PreProcessingImpl() override; + bool RunImpl() override; + bool PostProcessingImpl() override; + void DFSLabeling(int row, int col, int label); + std::vector> GetNeighbors(int row, int col); + std::vector> grid_; + std::vector> visited_; + int rows_; + int cols_; +}; + +} // namespace morozova_s_connected_components diff --git a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp new file mode 100644 index 0000000000..2ccd909960 --- /dev/null +++ b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp @@ -0,0 +1,107 @@ +#include "morozova_s_connected_components/seq/include/ops_seq.hpp" + +#include +#include +#include + +#include "morozova_s_connected_components/common/include/common.hpp" +#include "util/include/util.hpp" + +namespace morozova_s_connected_components { + +MorozovaSConnectedComponentsSEQ::MorozovaSConnectedComponentsSEQ(const InType &in) { + SetTypeOfTask(GetStaticTypeOfTask()); + GetInput() = in; + GetOutput() = {}; +} + +bool MorozovaSConnectedComponentsSEQ::ValidationImpl() { + const auto &input = GetInput(); + if (input.empty()) { + return false; + } + size_t cols = input[0].size(); + for (const auto &row : input) { + if (row.size() != cols) { + return false; + } + for (int pixel : row) { + if (pixel != 0 && pixel != 1) { + return false; + } + } + } + return true; +} + +bool MorozovaSConnectedComponentsSEQ::PreProcessingImpl() { + grid_ = GetInput(); + rows_ = static_cast(grid_.size()); + cols_ = static_cast(grid_[0].size()); + visited_.resize(rows_, std::vector(cols_, false)); + GetOutput() = std::vector>(rows_, std::vector(cols_, 0)); + return true; +} + +std::vector> MorozovaSConnectedComponentsSEQ::GetNeighbors(int row, int col) { + std::vector> neighbors; + const int dr[] = {-1, -1, -1, 0, 0, 1, 1, 1}; + const int dc[] = {-1, 0, 1, -1, 1, -1, 0, 1}; + for (int i = 0; i < 8; ++i) { + int new_row = row + dr[i]; + int new_col = col + dc[i]; + if (new_row >= 0 && new_row < rows_ && new_col >= 0 && new_col < cols_ && grid_[new_row][new_col] == 1) { + neighbors.emplace_back(new_row, new_col); + } + } + return neighbors; +} + +void MorozovaSConnectedComponentsSEQ::DFSLabeling(int row, int col, int label) { + std::stack> stack; + stack.emplace(row, col); + while (!stack.empty()) { + auto [current_row, current_col] = stack.top(); + stack.pop(); + if (visited_[current_row][current_col]) { + continue; + } + visited_[current_row][current_col] = true; + GetOutput()[current_row][current_col] = label; + auto neighbors = GetNeighbors(current_row, current_col); + for (const auto &neighbor : neighbors) { + if (!visited_[neighbor.first][neighbor.second]) { + stack.push(neighbor); + } + } + } +} + +bool MorozovaSConnectedComponentsSEQ::RunImpl() { + int label = 1; + for (int i = 0; i < rows_; ++i) { + for (int j = 0; j < cols_; ++j) { + if (grid_[i][j] == 1 && !visited_[i][j]) { + DFSLabeling(i, j, label); + label++; + } + } + } + return true; +} + +bool MorozovaSConnectedComponentsSEQ::PostProcessingImpl() { + int max_label = 0; + for (const auto &row : GetOutput()) { + for (int label : row) { + if (label > max_label) { + max_label = label; + } + } + } + auto &output = GetOutput(); + output.push_back({max_label}); + return true; +} + +} // namespace morozova_s_connected_components diff --git a/tasks/morozova_s_connected_components/settings.json b/tasks/morozova_s_connected_components/settings.json new file mode 100644 index 0000000000..b1a0d52574 --- /dev/null +++ b/tasks/morozova_s_connected_components/settings.json @@ -0,0 +1,7 @@ +{ + "tasks_type": "processes", + "tasks": { + "mpi": "enabled", + "seq": "enabled" + } +} diff --git a/tasks/morozova_s_connected_components/tests/.clang-tidy b/tasks/morozova_s_connected_components/tests/.clang-tidy new file mode 100644 index 0000000000..ef43b7aa8a --- /dev/null +++ b/tasks/morozova_s_connected_components/tests/.clang-tidy @@ -0,0 +1,13 @@ +InheritParentConfig: true + +Checks: > + -modernize-loop-convert, + -cppcoreguidelines-avoid-goto, + -cppcoreguidelines-avoid-non-const-global-variables, + -misc-use-anonymous-namespace, + -modernize-use-std-print, + -modernize-type-traits + +CheckOptions: + - key: readability-function-cognitive-complexity.Threshold + value: 50 # Relaxed for tests diff --git a/tasks/morozova_s_connected_components/tests/functional/main.cpp b/tasks/morozova_s_connected_components/tests/functional/main.cpp new file mode 100644 index 0000000000..5b63f87a48 --- /dev/null +++ b/tasks/morozova_s_connected_components/tests/functional/main.cpp @@ -0,0 +1,138 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "morozova_s_connected_components/common/include/common.hpp" +#include "morozova_s_connected_components/mpi/include/ops_mpi.hpp" +#include "morozova_s_connected_components/seq/include/ops_seq.hpp" +#include "util/include/func_test_util.hpp" +#include "util/include/util.hpp" + +namespace morozova_s_connected_components { + +class MorozovaSRunFuncTestsConnectedComponents : public ppc::util::BaseRunFuncTests { + public: + static std::string PrintTestParam(const TestType &test_param) { + return std::to_string(std::get<0>(test_param)) + "_" + std::get<1>(test_param); + } + + protected: + void SetUp() override { + auto test_params = std::get(ppc::util::GTestParamIndex::kTestParams)>(GetParam()); + int size = std::get<0>(test_params); + std::string pattern = std::get<1>(test_params); + input_data_ = std::vector>(size, std::vector(size, 0)); + if (pattern == "cross") { + for (int i = 0; i < size; ++i) { + input_data_[i][size / 2] = 1; + input_data_[size / 2][i] = 1; + } + } else if (pattern == "square") { + for (int i = size / 4; i < 3 * size / 4; ++i) { + for (int j = size / 4; j < 3 * size / 4; ++j) { + input_data_[i][j] = 1; + } + } + } else { + for (int i = 1; i < size; i += 2) { + for (int j = 1; j < size; j += 2) { + input_data_[i][j] = 1; + } + } + } + } + + bool CheckTestOutputData(OutType &output_data) final { + if (output_data.empty()) { + return false; + } + int reported_max_label = 0; + if (!output_data.empty() && output_data.back().size() == 1) { + reported_max_label = output_data.back()[0]; + output_data.pop_back(); + } + if (output_data.size() != input_data_.size()) { + return false; + } + for (size_t i = 0; i < input_data_.size(); ++i) { + if (output_data[i].size() != input_data_[i].size()) { + return false; + } + for (size_t j = 0; j < input_data_[i].size(); ++j) { + if (input_data_[i][j] == 1) { + if (output_data[i][j] <= 0) { + return false; + } + } else { + if (output_data[i][j] != 0) { + return false; + } + } + } + } + std::vector labels; + for (const auto &row : output_data) { + for (int label : row) { + if (label > 0) { + labels.push_back(label); + } + } + } + std::sort(labels.begin(), labels.end()); + labels.erase(std::unique(labels.begin(), labels.end()), labels.end()); + if (!labels.empty()) { + if (labels[0] != 1) { + return false; + } + for (size_t i = 1; i < labels.size(); ++i) { + if (labels[i] != labels[i - 1] + 1) { + return false; + } + } + if (reported_max_label != static_cast(labels.size())) { + return false; + } + } else if (reported_max_label != 0) { + return false; + } + return true; + } + InType GetTestInputData() final { + return input_data_; + } + + private: + InType input_data_; +}; + +namespace { + +TEST_P(MorozovaSRunFuncTestsConnectedComponents, ConnectedComponentsTest) { + ExecuteTest(GetParam()); +} + +const std::array kTestParam = {std::make_tuple(8, "cross"), std::make_tuple(10, "square"), + std::make_tuple(12, "dots")}; + +const auto kTestTasksList = std::tuple_cat(ppc::util::AddFuncTask( + kTestParam, PPC_SETTINGS_morozova_s_connected_components), + ppc::util::AddFuncTask( + kTestParam, PPC_SETTINGS_morozova_s_connected_components)); +const auto kGtestValues = ppc::util::ExpandToValues(kTestTasksList); +const auto kPerfTestName = + MorozovaSRunFuncTestsConnectedComponents::PrintFuncTestName; +INSTANTIATE_TEST_SUITE_P(ConnectedComponentsTests, MorozovaSRunFuncTestsConnectedComponents, kGtestValues, + kPerfTestName); +} // namespace + +} // namespace morozova_s_connected_components diff --git a/tasks/morozova_s_connected_components/tests/performance/main.cpp b/tasks/morozova_s_connected_components/tests/performance/main.cpp new file mode 100644 index 0000000000..30db0ca20a --- /dev/null +++ b/tasks/morozova_s_connected_components/tests/performance/main.cpp @@ -0,0 +1,83 @@ +#include + +#include "morozova_s_connected_components/common/include/common.hpp" +#include "morozova_s_connected_components/mpi/include/ops_mpi.hpp" +#include "morozova_s_connected_components/seq/include/ops_seq.hpp" +#include "util/include/perf_test_util.hpp" + +namespace morozova_s_connected_components { + +class MorozovaSRunPerfTestConnectedComponents : public ppc::util::BaseRunPerfTests { + const int kImageSize_ = 100; + InType input_data_{}; + + void SetUp() override { + input_data_ = std::vector>(kImageSize_, std::vector(kImageSize_, 0)); + for (int i = 10; i < 40; ++i) { + input_data_[i][20] = 1; + input_data_[i][21] = 1; + } + for (int j = 60; j < 90; ++j) { + input_data_[50][j] = 1; + input_data_[51][j] = 1; + } + for (int i = 70; i < 85; ++i) { + for (int j = 70; j < 85; ++j) { + input_data_[i][j] = 1; + } + } + for (int i = 0; i < 20; ++i) { + input_data_[80 + i][10 + i] = 1; + } + input_data_[5][5] = 1; + input_data_[95][95] = 1; + input_data_[10][90] = 1; + input_data_[90][10] = 1; + } + + bool CheckTestOutputData(OutType &output_data) final { + if (output_data.empty()) { + return false; + } + int object_count = 0; + int labeled_count = 0; + for (size_t i = 0; i < input_data_.size(); ++i) { + if (i >= output_data.size()) { + return false; + } + for (size_t j = 0; j < input_data_[i].size(); ++j) { + if (j >= output_data[i].size()) { + return false; + } + if (input_data_[i][j] == 1) { + object_count++; + if (output_data[i][j] > 0) { + labeled_count++; + } + } else { + if (output_data[i][j] != 0) { + return false; + } + } + } + } + return object_count == labeled_count; + } + + InType GetTestInputData() final { + return input_data_; + } +}; + +TEST_P(MorozovaSRunPerfTestConnectedComponents, RunPerfModes) { + ExecuteTest(GetParam()); +} + +const auto kAllPerfTasks = + ppc::util::MakeAllPerfTasks( + PPC_SETTINGS_morozova_s_connected_components); +const auto kGtestValues = ppc::util::TupleToGTestValues(kAllPerfTasks); +const auto kPerfTestName = MorozovaSRunPerfTestConnectedComponents::CustomPerfTestName; +INSTANTIATE_TEST_SUITE_P(RunModeTests, MorozovaSRunPerfTestConnectedComponents, kGtestValues, kPerfTestName); + +} // namespace morozova_s_connected_components From 6c85fcc07a61f5ea8bf1e152dc148b59a2323e85 Mon Sep 17 00:00:00 2001 From: SonyaMorozova Date: Thu, 29 Jan 2026 20:18:10 +0300 Subject: [PATCH 02/30] fix mpi 1 --- tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp index e267c79877..64757dd7aa 100644 --- a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp +++ b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp @@ -144,8 +144,8 @@ bool MorozovaSConnectedComponentsMPI::RunImpl() { bool MorozovaSConnectedComponentsMPI::PostProcessingImpl() { int rank; MPI_Comm_rank(MPI_COMM_WORLD, &rank); + int max_label = 0; if (rank == 0) { - int max_label = 0; for (const auto &row : GetOutput()) { for (int label : row) { if (label > max_label) { From 593790b18970f4f8d8b6756a67bc01d86479cb00 Mon Sep 17 00:00:00 2001 From: SonyaMorozova Date: Thu, 29 Jan 2026 23:52:10 +0300 Subject: [PATCH 03/30] fix tidy 1 --- .../mpi/include/ops_mpi.hpp | 5 ++ .../mpi/src/ops_mpi.cpp | 60 +++++-------------- .../seq/include/ops_seq.hpp | 3 + .../seq/src/ops_seq.cpp | 58 +++--------------- .../tests/functional/main.cpp | 10 +--- .../tests/performance/main.cpp | 9 ++- 6 files changed, 41 insertions(+), 104 deletions(-) diff --git a/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp b/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp index 64a9e72089..9e7907e5b6 100644 --- a/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp +++ b/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp @@ -1,5 +1,10 @@ #pragma once +#include +#include +#include +#include + #include "morozova_s_connected_components/common/include/common.hpp" #include "task/include/task.hpp" diff --git a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp index 64757dd7aa..58e08206cd 100644 --- a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp +++ b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp @@ -2,16 +2,18 @@ #include +#include +#include +#include #include #include #include #include "morozova_s_connected_components/common/include/common.hpp" -#include "util/include/util.hpp" namespace morozova_s_connected_components { -MorozovaSConnectedComponentsMPI::MorozovaSConnectedComponentsMPI(const InType &in) { +MorozovaSConnectedComponentsMPI::MorozovaSConnectedComponentsMPI(const InType &in) : rows_(0), cols_(0) { SetTypeOfTask(GetStaticTypeOfTask()); GetInput() = in; GetOutput() = {}; @@ -22,7 +24,7 @@ bool MorozovaSConnectedComponentsMPI::ValidationImpl() { if (input.empty()) { return false; } - size_t cols = input[0].size(); + std::size_t cols = input[0].size(); for (const auto &row : input) { if (row.size() != cols) { return false; @@ -36,19 +38,10 @@ bool MorozovaSConnectedComponentsMPI::ValidationImpl() { return true; } -bool MorozovaSConnectedComponentsMPI::PreProcessingImpl() { - grid_ = GetInput(); - rows_ = static_cast(grid_.size()); - cols_ = static_cast(grid_[0].size()); - visited_.resize(rows_, std::vector(cols_, false)); - GetOutput() = std::vector>(rows_, std::vector(cols_, 0)); - return true; -} - std::vector> MorozovaSConnectedComponentsMPI::GetNeighbors(int row, int col) { std::vector> neighbors; - const int dr[] = {-1, -1, -1, 0, 0, 1, 1, 1}; - const int dc[] = {-1, 0, 1, -1, 1, -1, 0, 1}; + const std::array dr = {-1, -1, -1, 0, 0, 1, 1, 1}; // Использовать std::array + const std::array dc = {-1, 0, 1, -1, 1, -1, 0, 1}; // Использовать std::array for (int i = 0; i < 8; ++i) { int new_row = row + dr[i]; int new_col = col + dc[i]; @@ -59,27 +52,9 @@ std::vector> MorozovaSConnectedComponentsMPI::GetNeighbors(i return neighbors; } -void MorozovaSConnectedComponentsMPI::BFSLabeling(int start_row, int start_col, int label) { - std::queue> q; - q.emplace(start_row, start_col); - visited_[start_row][start_col] = true; - GetOutput()[start_row][start_col] = label; - while (!q.empty()) { - auto [row, col] = q.front(); - q.pop(); - auto neighbors = GetNeighbors(row, col); - for (const auto &neighbor : neighbors) { - if (!visited_[neighbor.first][neighbor.second]) { - visited_[neighbor.first][neighbor.second] = true; - GetOutput()[neighbor.first][neighbor.second] = label; - q.push(neighbor); - } - } - } -} - bool MorozovaSConnectedComponentsMPI::RunImpl() { - int rank, size; + int rank = 0; + int size = 0; MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); int rows_per_process = rows_ / size; @@ -87,7 +62,6 @@ bool MorozovaSConnectedComponentsMPI::RunImpl() { int start_row = rank * rows_per_process + std::min(rank, remainder); int end_row = start_row + rows_per_process + (rank < remainder ? 1 : 0); int local_component_count = 0; - std::vector local_labels_start; for (int i = start_row; i < end_row; ++i) { for (int j = 0; j < cols_; ++j) { if (grid_[i][j] == 1 && !visited_[i][j]) { @@ -109,13 +83,14 @@ bool MorozovaSConnectedComponentsMPI::RunImpl() { } MPI_Barrier(MPI_COMM_WORLD); if (rank == 0) { - for (int p = 1; p < size; ++p) { + for (int process_id = 1; process_id < size; ++process_id) { // Изменить имя переменной int p_rows_per_process = rows_ / size; int p_remainder = rows_ % size; - int p_start_row = p * p_rows_per_process + std::min(p, p_remainder); - int p_end_row = p_start_row + p_rows_per_process + (p < p_remainder ? 1 : 0); + int p_start_row = process_id * p_rows_per_process + std::min(process_id, p_remainder); + int p_end_row = p_start_row + p_rows_per_process + (process_id < p_remainder ? 1 : 0); + for (int i = p_start_row; i < p_end_row; ++i) { - MPI_Recv(GetOutput()[i].data(), cols_, MPI_INT, p, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(GetOutput()[i].data(), cols_, MPI_INT, process_id, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); } } } else { @@ -131,7 +106,6 @@ bool MorozovaSConnectedComponentsMPI::RunImpl() { MPI_Recv(upper_row.data(), cols_, MPI_INT, rank - 1, 2, MPI_COMM_WORLD, MPI_STATUS_IGNORE); } } - if (rank < size - 1 && end_row < rows_) { MPI_Recv(lower_row.data(), cols_, MPI_INT, rank + 1, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); if (end_row - 1 >= start_row) { @@ -142,15 +116,13 @@ bool MorozovaSConnectedComponentsMPI::RunImpl() { } bool MorozovaSConnectedComponentsMPI::PostProcessingImpl() { - int rank; + int rank = 0; MPI_Comm_rank(MPI_COMM_WORLD, &rank); int max_label = 0; if (rank == 0) { for (const auto &row : GetOutput()) { for (int label : row) { - if (label > max_label) { - max_label = label; - } + max_label = std::max(label, max_label); } } auto &output = GetOutput(); diff --git a/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp b/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp index a0eee81fca..5460e3076a 100644 --- a/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp +++ b/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp @@ -1,5 +1,8 @@ #pragma once +#include +#include + #include "morozova_s_connected_components/common/include/common.hpp" #include "task/include/task.hpp" diff --git a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp index 2ccd909960..7494e12a25 100644 --- a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp +++ b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp @@ -1,15 +1,17 @@ #include "morozova_s_connected_components/seq/include/ops_seq.hpp" +#include +#include +#include #include #include #include #include "morozova_s_connected_components/common/include/common.hpp" -#include "util/include/util.hpp" namespace morozova_s_connected_components { -MorozovaSConnectedComponentsSEQ::MorozovaSConnectedComponentsSEQ(const InType &in) { +MorozovaSConnectedComponentsSEQ::MorozovaSConnectedComponentsSEQ(const InType &in) : rows_(0), cols_(0) { SetTypeOfTask(GetStaticTypeOfTask()); GetInput() = in; GetOutput() = {}; @@ -20,7 +22,7 @@ bool MorozovaSConnectedComponentsSEQ::ValidationImpl() { if (input.empty()) { return false; } - size_t cols = input[0].size(); + std::size_t cols = input[0].size(); for (const auto &row : input) { if (row.size() != cols) { return false; @@ -34,19 +36,10 @@ bool MorozovaSConnectedComponentsSEQ::ValidationImpl() { return true; } -bool MorozovaSConnectedComponentsSEQ::PreProcessingImpl() { - grid_ = GetInput(); - rows_ = static_cast(grid_.size()); - cols_ = static_cast(grid_[0].size()); - visited_.resize(rows_, std::vector(cols_, false)); - GetOutput() = std::vector>(rows_, std::vector(cols_, 0)); - return true; -} - std::vector> MorozovaSConnectedComponentsSEQ::GetNeighbors(int row, int col) { std::vector> neighbors; - const int dr[] = {-1, -1, -1, 0, 0, 1, 1, 1}; - const int dc[] = {-1, 0, 1, -1, 1, -1, 0, 1}; + const std::array dr = {-1, -1, -1, 0, 0, 1, 1, 1}; + const std::array dc = {-1, 0, 1, -1, 1, -1, 0, 1}; for (int i = 0; i < 8; ++i) { int new_row = row + dr[i]; int new_col = col + dc[i]; @@ -57,46 +50,11 @@ std::vector> MorozovaSConnectedComponentsSEQ::GetNeighbors(i return neighbors; } -void MorozovaSConnectedComponentsSEQ::DFSLabeling(int row, int col, int label) { - std::stack> stack; - stack.emplace(row, col); - while (!stack.empty()) { - auto [current_row, current_col] = stack.top(); - stack.pop(); - if (visited_[current_row][current_col]) { - continue; - } - visited_[current_row][current_col] = true; - GetOutput()[current_row][current_col] = label; - auto neighbors = GetNeighbors(current_row, current_col); - for (const auto &neighbor : neighbors) { - if (!visited_[neighbor.first][neighbor.second]) { - stack.push(neighbor); - } - } - } -} - -bool MorozovaSConnectedComponentsSEQ::RunImpl() { - int label = 1; - for (int i = 0; i < rows_; ++i) { - for (int j = 0; j < cols_; ++j) { - if (grid_[i][j] == 1 && !visited_[i][j]) { - DFSLabeling(i, j, label); - label++; - } - } - } - return true; -} - bool MorozovaSConnectedComponentsSEQ::PostProcessingImpl() { int max_label = 0; for (const auto &row : GetOutput()) { for (int label : row) { - if (label > max_label) { - max_label = label; - } + max_label = std::max(label, max_label); } } auto &output = GetOutput(); diff --git a/tasks/morozova_s_connected_components/tests/functional/main.cpp b/tasks/morozova_s_connected_components/tests/functional/main.cpp index 5b63f87a48..8c23c787ba 100644 --- a/tasks/morozova_s_connected_components/tests/functional/main.cpp +++ b/tasks/morozova_s_connected_components/tests/functional/main.cpp @@ -4,12 +4,8 @@ #include #include #include -#include -#include -#include #include #include -#include #include #include "morozova_s_connected_components/common/include/common.hpp" @@ -64,11 +60,11 @@ class MorozovaSRunFuncTestsConnectedComponents : public ppc::util::BaseRunFuncTe if (output_data.size() != input_data_.size()) { return false; } - for (size_t i = 0; i < input_data_.size(); ++i) { + for (std::size_t i = 0; i < input_data_.size(); ++i) { if (output_data[i].size() != input_data_[i].size()) { return false; } - for (size_t j = 0; j < input_data_[i].size(); ++j) { + for (std::size_t j = 0; j < input_data_[i].size(); ++j) { if (input_data_[i][j] == 1) { if (output_data[i][j] <= 0) { return false; @@ -94,7 +90,7 @@ class MorozovaSRunFuncTestsConnectedComponents : public ppc::util::BaseRunFuncTe if (labels[0] != 1) { return false; } - for (size_t i = 1; i < labels.size(); ++i) { + for (std::size_t i = 1; i < labels.size(); ++i) { if (labels[i] != labels[i - 1] + 1) { return false; } diff --git a/tasks/morozova_s_connected_components/tests/performance/main.cpp b/tasks/morozova_s_connected_components/tests/performance/main.cpp index 30db0ca20a..c35fe11fad 100644 --- a/tasks/morozova_s_connected_components/tests/performance/main.cpp +++ b/tasks/morozova_s_connected_components/tests/performance/main.cpp @@ -1,5 +1,8 @@ #include +#include +#include + #include "morozova_s_connected_components/common/include/common.hpp" #include "morozova_s_connected_components/mpi/include/ops_mpi.hpp" #include "morozova_s_connected_components/seq/include/ops_seq.hpp" @@ -9,7 +12,7 @@ namespace morozova_s_connected_components { class MorozovaSRunPerfTestConnectedComponents : public ppc::util::BaseRunPerfTests { const int kImageSize_ = 100; - InType input_data_{}; + InType input_data_; void SetUp() override { input_data_ = std::vector>(kImageSize_, std::vector(kImageSize_, 0)); @@ -41,11 +44,11 @@ class MorozovaSRunPerfTestConnectedComponents : public ppc::util::BaseRunPerfTes } int object_count = 0; int labeled_count = 0; - for (size_t i = 0; i < input_data_.size(); ++i) { + for (std::size_t i = 0; i < input_data_.size(); ++i) { if (i >= output_data.size()) { return false; } - for (size_t j = 0; j < input_data_[i].size(); ++j) { + for (std::size_t j = 0; j < input_data_[i].size(); ++j) { if (j >= output_data[i].size()) { return false; } From e505163515e766d9105ff7c2f3f9dc725a58c3a6 Mon Sep 17 00:00:00 2001 From: SonyaMorozova Date: Fri, 30 Jan 2026 17:51:23 +0300 Subject: [PATCH 04/30] fix tidy 2 --- .../mpi/include/ops_mpi.hpp | 13 +- .../mpi/src/ops_mpi.cpp | 160 ++++++++++++------ .../seq/include/ops_seq.hpp | 3 +- .../seq/src/ops_seq.cpp | 47 ++++- 4 files changed, 166 insertions(+), 57 deletions(-) diff --git a/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp b/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp index 9e7907e5b6..c658f96b5b 100644 --- a/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp +++ b/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp @@ -23,15 +23,18 @@ class MorozovaSConnectedComponentsMPI : public BaseTask { bool RunImpl() override; bool PostProcessingImpl() override; - void BFSLabeling(int start_row, int start_col, int label); - std::vector> GetNeighbors(int row, int col); - void ExchangeBoundaryRows(); - void MergeLabels(int label1, int label2); - + void LabelLocalComponents(); + void ProcessBoundaries(); + std::pair CalculateProcessBounds(int rows, int size, int process_rank) const; + std::vector> GetNeighbors(int row, int col) const; std::vector> grid_; std::vector> visited_; int rows_; int cols_; + int rank_; + int size_; + int start_row_; + int end_row_; }; } // namespace morozova_s_connected_components diff --git a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp index 58e08206cd..734da90d55 100644 --- a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp +++ b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -13,7 +14,8 @@ namespace morozova_s_connected_components { -MorozovaSConnectedComponentsMPI::MorozovaSConnectedComponentsMPI(const InType &in) : rows_(0), cols_(0) { +MorozovaSConnectedComponentsMPI::MorozovaSConnectedComponentsMPI(const InType &in) + : rows_(0), cols_(0), rank_(0), size_(0), start_row_(0), end_row_(0) { SetTypeOfTask(GetStaticTypeOfTask()); GetInput() = in; GetOutput() = {}; @@ -38,10 +40,34 @@ bool MorozovaSConnectedComponentsMPI::ValidationImpl() { return true; } -std::vector> MorozovaSConnectedComponentsMPI::GetNeighbors(int row, int col) { +bool MorozovaSConnectedComponentsMPI::PreProcessingImpl() { + const auto &input = GetInput(); + rows_ = static_cast(input.size()); + cols_ = static_cast(input[0].size()); + MPI_Comm_rank(MPI_COMM_WORLD, &rank_); + MPI_Comm_size(MPI_COMM_WORLD, &size_); + int rows_per_process = rows_ / size_; + int remainder = rows_ % size_; + start_row_ = rank_ * rows_per_process + std::min(rank_, remainder); + end_row_ = start_row_ + rows_per_process + (rank_ < remainder ? 1 : 0); + grid_ = input; + visited_.assign(rows_, std::vector(cols_, false)); // Используем assign + GetOutput() = std::vector>(rows_, std::vector(cols_, 0)); + + return true; +} +std::pair CalculateProcessBounds(int rows, int size, int process_rank) { + int rows_per_process = rows / size; + int remainder = rows % size; + int start = process_rank * rows_per_process + std::min(process_rank, remainder); + int end = start + rows_per_process + (process_rank < remainder ? 1 : 0); + return {start, end}; +} + +std::vector> MorozovaSConnectedComponentsMPI::GetNeighbors(int row, int col) const { std::vector> neighbors; - const std::array dr = {-1, -1, -1, 0, 0, 1, 1, 1}; // Использовать std::array - const std::array dc = {-1, 0, 1, -1, 1, -1, 0, 1}; // Использовать std::array + const std::array dr = {-1, -1, -1, 0, 0, 1, 1, 1}; + const std::array dc = {-1, 0, 1, -1, 1, -1, 0, 1}; for (int i = 0; i < 8; ++i) { int new_row = row + dr[i]; int new_col = col + dc[i]; @@ -52,66 +78,96 @@ std::vector> MorozovaSConnectedComponentsMPI::GetNeighbors(i return neighbors; } -bool MorozovaSConnectedComponentsMPI::RunImpl() { - int rank = 0; - int size = 0; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - MPI_Comm_size(MPI_COMM_WORLD, &size); - int rows_per_process = rows_ / size; - int remainder = rows_ % size; - int start_row = rank * rows_per_process + std::min(rank, remainder); - int end_row = start_row + rows_per_process + (rank < remainder ? 1 : 0); - int local_component_count = 0; - for (int i = start_row; i < end_row; ++i) { +void MorozovaSConnectedComponentsMPI::LabelLocalComponents() { + int label_offset = rank_ * 1000000; + int current_label = label_offset + 1; + for (int i = start_row_; i < end_row_; ++i) { for (int j = 0; j < cols_; ++j) { if (grid_[i][j] == 1 && !visited_[i][j]) { - local_component_count++; + std::queue> q; + q.emplace(i, j); + visited_[i][j] = true; + GetOutput()[i][j] = current_label; + while (!q.empty()) { + auto [row, col] = q.front(); + q.pop(); + auto neighbors = GetNeighbors(row, col); + for (const auto &neighbor : neighbors) { + int nr = neighbor.first; + int nc = neighbor.second; + if (nr >= start_row_ && nr < end_row_ && !visited_[nr][nc]) { + visited_[nr][nc] = true; + GetOutput()[nr][nc] = current_label; + q.emplace(nr, nc); + } + } + } + ++current_label; } } } - int global_offset = 0; - MPI_Scan(&local_component_count, &global_offset, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD); - int local_label_start = global_offset - local_component_count + 1; - int current_label = local_label_start; - for (int i = start_row; i < end_row; ++i) { - for (int j = 0; j < cols_; ++j) { - if (grid_[i][j] == 1 && !visited_[i][j]) { - BFSLabeling(i, j, current_label); - current_label++; +} + +void MorozovaSConnectedComponentsMPI::ProcessBoundaries() { + if (rank_ == 0) { + for (int src = 1; src < size_; ++src) { + auto [src_start, src_end] = CalculateProcessBounds(rows_, size_, src); + for (int i = src_start; i < src_end; ++i) { + MPI_Recv(GetOutput()[i].data(), cols_, MPI_INT, src, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); } } - } - MPI_Barrier(MPI_COMM_WORLD); - if (rank == 0) { - for (int process_id = 1; process_id < size; ++process_id) { // Изменить имя переменной - int p_rows_per_process = rows_ / size; - int p_remainder = rows_ % size; - int p_start_row = process_id * p_rows_per_process + std::min(process_id, p_remainder); - int p_end_row = p_start_row + p_rows_per_process + (process_id < p_remainder ? 1 : 0); - - for (int i = p_start_row; i < p_end_row; ++i) { - MPI_Recv(GetOutput()[i].data(), cols_, MPI_INT, process_id, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + std::vector> global_visited(rows_, std::vector(cols_, false)); + std::vector> new_labels(rows_, std::vector(cols_, 0)); + int global_label = 1; + for (int i = 0; i < rows_; ++i) { + for (int j = 0; j < cols_; ++j) { + if (grid_[i][j] == 1 && !global_visited[i][j]) { + std::queue> q; + q.emplace(i, j); + global_visited[i][j] = true; + new_labels[i][j] = global_label; + while (!q.empty()) { + auto [row, col] = q.front(); + q.pop(); + auto neighbors = GetNeighbors(row, col); + for (const auto &neighbor : neighbors) { + int nr = neighbor.first; + int nc = neighbor.second; + if (!global_visited[nr][nc]) { + global_visited[nr][nc] = true; + new_labels[nr][nc] = global_label; + q.emplace(nr, nc); + } + } + } + ++global_label; + } } } + GetOutput() = std::move(new_labels); } else { - for (int i = start_row; i < end_row; ++i) { + for (int i = start_row_; i < end_row_; ++i) { MPI_Send(GetOutput()[i].data(), cols_, MPI_INT, 0, 0, MPI_COMM_WORLD); } } - std::vector upper_row(cols_, 0); - std::vector lower_row(cols_, 0); - if (rank > 0) { - MPI_Send(GetOutput()[start_row].data(), cols_, MPI_INT, rank - 1, 1, MPI_COMM_WORLD); - if (start_row > 0) { - MPI_Recv(upper_row.data(), cols_, MPI_INT, rank - 1, 2, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Barrier(MPI_COMM_WORLD); + if (rank_ == 0) { + for (int dest = 1; dest < size_; ++dest) { + auto [dest_start, dest_end] = CalculateProcessBounds(rows_, size_, dest); + for (int i = dest_start; i < dest_end; ++i) { + MPI_Send(GetOutput()[i].data(), cols_, MPI_INT, dest, 1, MPI_COMM_WORLD); + } } - } - if (rank < size - 1 && end_row < rows_) { - MPI_Recv(lower_row.data(), cols_, MPI_INT, rank + 1, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - if (end_row - 1 >= start_row) { - MPI_Send(GetOutput()[end_row - 1].data(), cols_, MPI_INT, rank + 1, 2, MPI_COMM_WORLD); + } else { + for (int i = start_row_; i < end_row_; ++i) { + MPI_Recv(GetOutput()[i].data(), cols_, MPI_INT, 0, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); } } +} + +bool MorozovaSConnectedComponentsMPI::RunImpl() { + LabelLocalComponents(); + ProcessBoundaries(); return true; } @@ -122,13 +178,19 @@ bool MorozovaSConnectedComponentsMPI::PostProcessingImpl() { if (rank == 0) { for (const auto &row : GetOutput()) { for (int label : row) { - max_label = std::max(label, max_label); + if (label > max_label) { + max_label = label; + } } } auto &output = GetOutput(); output.push_back({max_label}); } MPI_Bcast(&max_label, 1, MPI_INT, 0, MPI_COMM_WORLD); + if (rank != 0) { + auto &output = GetOutput(); + output.push_back({max_label}); + } return true; } diff --git a/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp b/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp index 5460e3076a..59fb44fa7d 100644 --- a/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp +++ b/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp @@ -21,11 +21,10 @@ class MorozovaSConnectedComponentsSEQ : public BaseTask { bool RunImpl() override; bool PostProcessingImpl() override; void DFSLabeling(int row, int col, int label); - std::vector> GetNeighbors(int row, int col); + std::vector> GetNeighbors(int row, int col) const; std::vector> grid_; std::vector> visited_; int rows_; int cols_; }; - } // namespace morozova_s_connected_components diff --git a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp index 7494e12a25..2884b8280c 100644 --- a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp +++ b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp @@ -36,7 +36,38 @@ bool MorozovaSConnectedComponentsSEQ::ValidationImpl() { return true; } -std::vector> MorozovaSConnectedComponentsSEQ::GetNeighbors(int row, int col) { +bool MorozovaSConnectedComponentsSEQ::PreProcessingImpl() { + const auto &input = GetInput(); + rows_ = static_cast(input.size()); + cols_ = static_cast(input[0].size()); + grid_ = input; + visited_.assign(rows_, std::vector(cols_, false)); + GetOutput() = std::vector>(rows_, std::vector(cols_, 0)); + return true; +} + +void MorozovaSConnectedComponentsSEQ::DFSLabeling(int row, int col, int label) { + std::stack> stack; + stack.emplace(row, col); + visited_[row][col] = true; + GetOutput()[row][col] = label; + while (!stack.empty()) { + auto [current_row, current_col] = stack.top(); + stack.pop(); + auto neighbors = GetNeighbors(current_row, current_col); + for (const auto &neighbor : neighbors) { + int nr = neighbor.first; + int nc = neighbor.second; + if (!visited_[nr][nc]) { + visited_[nr][nc] = true; + GetOutput()[nr][nc] = label; + stack.emplace(nr, nc); + } + } + } +} + +std::vector> MorozovaSConnectedComponentsSEQ::GetNeighbors(int row, int col) const { std::vector> neighbors; const std::array dr = {-1, -1, -1, 0, 0, 1, 1, 1}; const std::array dc = {-1, 0, 1, -1, 1, -1, 0, 1}; @@ -50,6 +81,20 @@ std::vector> MorozovaSConnectedComponentsSEQ::GetNeighbors(i return neighbors; } +bool MorozovaSConnectedComponentsSEQ::RunImpl() { + int label = 1; + for (int i = 0; i < rows_; ++i) { + for (int j = 0; j < cols_; ++j) { + if (grid_[i][j] == 1 && !visited_[i][j]) { + DFSLabeling(i, j, label); + ++label; + } + } + } + + return true; +} + bool MorozovaSConnectedComponentsSEQ::PostProcessingImpl() { int max_label = 0; for (const auto &row : GetOutput()) { From 828519ba9a06eab0a9ea3c64ed5e592d48038c4d Mon Sep 17 00:00:00 2001 From: SonyaMorozova Date: Fri, 30 Jan 2026 19:48:19 +0300 Subject: [PATCH 05/30] fix tidy 3 --- tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp index 734da90d55..fb7f28b76c 100644 --- a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp +++ b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp @@ -56,7 +56,9 @@ bool MorozovaSConnectedComponentsMPI::PreProcessingImpl() { return true; } -std::pair CalculateProcessBounds(int rows, int size, int process_rank) { + +std::pair MorozovaSConnectedComponentsMPI::CalculateProcessBounds(int rows, int size, + int process_rank) const { int rows_per_process = rows / size; int remainder = rows % size; int start = process_rank * rows_per_process + std::min(process_rank, remainder); From 7ca1e1f210c46ae9523d19b29c269611a1c2674c Mon Sep 17 00:00:00 2001 From: SonyaMorozova Date: Fri, 30 Jan 2026 21:21:17 +0300 Subject: [PATCH 06/30] fix tidy 4 --- .../mpi/include/ops_mpi.hpp | 4 +- .../mpi/src/ops_mpi.cpp | 120 ++++++++++-------- .../seq/src/ops_seq.cpp | 6 +- .../tests/functional/main.cpp | 3 +- 4 files changed, 75 insertions(+), 58 deletions(-) diff --git a/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp b/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp index c658f96b5b..c96291002b 100644 --- a/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp +++ b/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp @@ -1,7 +1,5 @@ #pragma once -#include -#include #include #include @@ -25,7 +23,7 @@ class MorozovaSConnectedComponentsMPI : public BaseTask { void LabelLocalComponents(); void ProcessBoundaries(); - std::pair CalculateProcessBounds(int rows, int size, int process_rank) const; + static std::pair CalculateProcessBounds(int rows, int size, int process_rank); std::vector> GetNeighbors(int row, int col) const; std::vector> grid_; std::vector> visited_; diff --git a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp index fb7f28b76c..c6b3e4018a 100644 --- a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp +++ b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp @@ -6,8 +6,6 @@ #include #include #include -#include -#include #include #include "morozova_s_connected_components/common/include/common.hpp" @@ -48,20 +46,19 @@ bool MorozovaSConnectedComponentsMPI::PreProcessingImpl() { MPI_Comm_size(MPI_COMM_WORLD, &size_); int rows_per_process = rows_ / size_; int remainder = rows_ % size_; - start_row_ = rank_ * rows_per_process + std::min(rank_, remainder); + start_row_ = (rank_ * rows_per_process) + std::min(rank_, remainder); end_row_ = start_row_ + rows_per_process + (rank_ < remainder ? 1 : 0); grid_ = input; - visited_.assign(rows_, std::vector(cols_, false)); // Используем assign + visited_.assign(rows_, std::vector(cols_, false)); GetOutput() = std::vector>(rows_, std::vector(cols_, 0)); return true; } -std::pair MorozovaSConnectedComponentsMPI::CalculateProcessBounds(int rows, int size, - int process_rank) const { +std::pair MorozovaSConnectedComponentsMPI::CalculateProcessBounds(int rows, int size, int process_rank) { int rows_per_process = rows / size; int remainder = rows % size; - int start = process_rank * rows_per_process + std::min(process_rank, remainder); + int start = (process_rank * rows_per_process) + std::min(process_rank, remainder); int end = start + rows_per_process + (process_rank < remainder ? 1 : 0); return {start, end}; } @@ -70,7 +67,7 @@ std::vector> MorozovaSConnectedComponentsMPI::GetNeighbors(i std::vector> neighbors; const std::array dr = {-1, -1, -1, 0, 0, 1, 1, 1}; const std::array dc = {-1, 0, 1, -1, 1, -1, 0, 1}; - for (int i = 0; i < 8; ++i) { + for (size_t i = 0; i < 8; ++i) { int new_row = row + dr[i]; int new_col = col + dc[i]; if (new_row >= 0 && new_row < rows_ && new_col >= 0 && new_col < cols_ && grid_[new_row][new_col] == 1) { @@ -83,29 +80,35 @@ std::vector> MorozovaSConnectedComponentsMPI::GetNeighbors(i void MorozovaSConnectedComponentsMPI::LabelLocalComponents() { int label_offset = rank_ * 1000000; int current_label = label_offset + 1; + for (int i = start_row_; i < end_row_; ++i) { for (int j = 0; j < cols_; ++j) { - if (grid_[i][j] == 1 && !visited_[i][j]) { - std::queue> q; - q.emplace(i, j); - visited_[i][j] = true; - GetOutput()[i][j] = current_label; - while (!q.empty()) { - auto [row, col] = q.front(); - q.pop(); - auto neighbors = GetNeighbors(row, col); - for (const auto &neighbor : neighbors) { - int nr = neighbor.first; - int nc = neighbor.second; - if (nr >= start_row_ && nr < end_row_ && !visited_[nr][nc]) { - visited_[nr][nc] = true; - GetOutput()[nr][nc] = current_label; - q.emplace(nr, nc); - } + if (grid_[i][j] != 1 || visited_[i][j]) { + continue; + } + + std::queue> q; + q.emplace(i, j); + visited_[i][j] = true; + GetOutput()[i][j] = current_label; + + while (!q.empty()) { + auto [row, col] = q.front(); + q.pop(); + + auto neighbors = GetNeighbors(row, col); + for (const auto &neighbor : neighbors) { + int nr = neighbor.first; + int nc = neighbor.second; + + if (nr >= start_row_ && nr < end_row_ && !visited_[nr][nc]) { + visited_[nr][nc] = true; + GetOutput()[nr][nc] = current_label; + q.emplace(nr, nc); } } - ++current_label; } + ++current_label; } } } @@ -118,41 +121,54 @@ void MorozovaSConnectedComponentsMPI::ProcessBoundaries() { MPI_Recv(GetOutput()[i].data(), cols_, MPI_INT, src, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); } } + } else { + for (int i = start_row_; i < end_row_; ++i) { + MPI_Send(GetOutput()[i].data(), cols_, MPI_INT, 0, 0, MPI_COMM_WORLD); + } + } + + MPI_Barrier(MPI_COMM_WORLD); + + if (rank_ == 0) { std::vector> global_visited(rows_, std::vector(cols_, false)); std::vector> new_labels(rows_, std::vector(cols_, 0)); int global_label = 1; + for (int i = 0; i < rows_; ++i) { for (int j = 0; j < cols_; ++j) { - if (grid_[i][j] == 1 && !global_visited[i][j]) { - std::queue> q; - q.emplace(i, j); - global_visited[i][j] = true; - new_labels[i][j] = global_label; - while (!q.empty()) { - auto [row, col] = q.front(); - q.pop(); - auto neighbors = GetNeighbors(row, col); - for (const auto &neighbor : neighbors) { - int nr = neighbor.first; - int nc = neighbor.second; - if (!global_visited[nr][nc]) { - global_visited[nr][nc] = true; - new_labels[nr][nc] = global_label; - q.emplace(nr, nc); - } + if (grid_[i][j] != 1 || global_visited[i][j]) { + continue; + } + + std::queue> q; + q.emplace(i, j); + global_visited[i][j] = true; + new_labels[i][j] = global_label; + + while (!q.empty()) { + auto [row, col] = q.front(); + q.pop(); + + auto neighbors = GetNeighbors(row, col); + for (const auto &neighbor : neighbors) { + int nr = neighbor.first; + int nc = neighbor.second; + + if (!global_visited[nr][nc]) { + global_visited[nr][nc] = true; + new_labels[nr][nc] = global_label; + q.emplace(nr, nc); } } - ++global_label; } + ++global_label; } } GetOutput() = std::move(new_labels); - } else { - for (int i = start_row_; i < end_row_; ++i) { - MPI_Send(GetOutput()[i].data(), cols_, MPI_INT, 0, 0, MPI_COMM_WORLD); - } } + MPI_Barrier(MPI_COMM_WORLD); + if (rank_ == 0) { for (int dest = 1; dest < size_; ++dest) { auto [dest_start, dest_end] = CalculateProcessBounds(rows_, size_, dest); @@ -177,22 +193,24 @@ bool MorozovaSConnectedComponentsMPI::PostProcessingImpl() { int rank = 0; MPI_Comm_rank(MPI_COMM_WORLD, &rank); int max_label = 0; + if (rank == 0) { for (const auto &row : GetOutput()) { for (int label : row) { - if (label > max_label) { - max_label = label; - } + max_label = std::max(label, max_label); } } auto &output = GetOutput(); output.push_back({max_label}); } + MPI_Bcast(&max_label, 1, MPI_INT, 0, MPI_COMM_WORLD); + if (rank != 0) { auto &output = GetOutput(); output.push_back({max_label}); } + return true; } diff --git a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp index 2884b8280c..c9743ac6a4 100644 --- a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp +++ b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp @@ -4,7 +4,6 @@ #include #include #include -#include #include #include "morozova_s_connected_components/common/include/common.hpp" @@ -51,10 +50,12 @@ void MorozovaSConnectedComponentsSEQ::DFSLabeling(int row, int col, int label) { stack.emplace(row, col); visited_[row][col] = true; GetOutput()[row][col] = label; + while (!stack.empty()) { auto [current_row, current_col] = stack.top(); stack.pop(); auto neighbors = GetNeighbors(current_row, current_col); + for (const auto &neighbor : neighbors) { int nr = neighbor.first; int nc = neighbor.second; @@ -71,7 +72,7 @@ std::vector> MorozovaSConnectedComponentsSEQ::GetNeighbors(i std::vector> neighbors; const std::array dr = {-1, -1, -1, 0, 0, 1, 1, 1}; const std::array dc = {-1, 0, 1, -1, 1, -1, 0, 1}; - for (int i = 0; i < 8; ++i) { + for (size_t i = 0; i < 8; ++i) { int new_row = row + dr[i]; int new_col = col + dc[i]; if (new_row >= 0 && new_row < rows_ && new_col >= 0 && new_col < cols_ && grid_[new_row][new_col] == 1) { @@ -91,7 +92,6 @@ bool MorozovaSConnectedComponentsSEQ::RunImpl() { } } } - return true; } diff --git a/tasks/morozova_s_connected_components/tests/functional/main.cpp b/tasks/morozova_s_connected_components/tests/functional/main.cpp index 8c23c787ba..0b3a0febbb 100644 --- a/tasks/morozova_s_connected_components/tests/functional/main.cpp +++ b/tasks/morozova_s_connected_components/tests/functional/main.cpp @@ -85,7 +85,8 @@ class MorozovaSRunFuncTestsConnectedComponents : public ppc::util::BaseRunFuncTe } } std::sort(labels.begin(), labels.end()); - labels.erase(std::unique(labels.begin(), labels.end()), labels.end()); + auto it = std::unique(labels.begin(), labels.end()); + labels.erase(it, labels.end()); if (!labels.empty()) { if (labels[0] != 1) { return false; From cab18c956595a53d12dae20ff23bc9a0e7fc28a4 Mon Sep 17 00:00:00 2001 From: SonyaMorozova Date: Sun, 1 Feb 2026 14:10:19 +0300 Subject: [PATCH 07/30] fix tidy 5 --- .../mpi/include/ops_mpi.hpp | 13 +-- .../mpi/src/ops_mpi.cpp | 88 ++++++++----------- .../seq/include/ops_seq.hpp | 4 +- .../seq/src/ops_seq.cpp | 5 +- .../tests/functional/main.cpp | 1 + 5 files changed, 52 insertions(+), 59 deletions(-) diff --git a/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp b/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp index c96291002b..ff21ba291b 100644 --- a/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp +++ b/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp @@ -23,16 +23,17 @@ class MorozovaSConnectedComponentsMPI : public BaseTask { void LabelLocalComponents(); void ProcessBoundaries(); + void MergeGlobalLabels(); static std::pair CalculateProcessBounds(int rows, int size, int process_rank); std::vector> GetNeighbors(int row, int col) const; std::vector> grid_; std::vector> visited_; - int rows_; - int cols_; - int rank_; - int size_; - int start_row_; - int end_row_; + int rows_{0}; + int cols_{0}; + int rank_{0}; + int size_{0}; + int start_row_{0}; + int end_row_{0}; }; } // namespace morozova_s_connected_components diff --git a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp index c6b3e4018a..8f052c0f40 100644 --- a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp +++ b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp @@ -6,14 +6,15 @@ #include #include #include +#include +#include #include #include "morozova_s_connected_components/common/include/common.hpp" namespace morozova_s_connected_components { -MorozovaSConnectedComponentsMPI::MorozovaSConnectedComponentsMPI(const InType &in) - : rows_(0), cols_(0), rank_(0), size_(0), start_row_(0), end_row_(0) { +MorozovaSConnectedComponentsMPI::MorozovaSConnectedComponentsMPI(const InType &in) { SetTypeOfTask(GetStaticTypeOfTask()); GetInput() = in; GetOutput() = {}; @@ -51,7 +52,6 @@ bool MorozovaSConnectedComponentsMPI::PreProcessingImpl() { grid_ = input; visited_.assign(rows_, std::vector(cols_, false)); GetOutput() = std::vector>(rows_, std::vector(cols_, 0)); - return true; } @@ -80,22 +80,18 @@ std::vector> MorozovaSConnectedComponentsMPI::GetNeighbors(i void MorozovaSConnectedComponentsMPI::LabelLocalComponents() { int label_offset = rank_ * 1000000; int current_label = label_offset + 1; - for (int i = start_row_; i < end_row_; ++i) { for (int j = 0; j < cols_; ++j) { if (grid_[i][j] != 1 || visited_[i][j]) { continue; } - std::queue> q; q.emplace(i, j); visited_[i][j] = true; GetOutput()[i][j] = current_label; - while (!q.empty()) { auto [row, col] = q.front(); q.pop(); - auto neighbors = GetNeighbors(row, col); for (const auto &neighbor : neighbors) { int nr = neighbor.first; @@ -113,6 +109,40 @@ void MorozovaSConnectedComponentsMPI::LabelLocalComponents() { } } +void MorozovaSConnectedComponentsMPI::MergeGlobalLabels() { + std::vector> global_visited(rows_, std::vector(cols_, false)); + std::vector> new_labels(rows_, std::vector(cols_, 0)); + int global_label = 1; + for (int i = 0; i < rows_; ++i) { + for (int j = 0; j < cols_; ++j) { + if (grid_[i][j] != 1 || global_visited[i][j]) { + continue; + } + std::queue> q; + q.emplace(i, j); + global_visited[i][j] = true; + new_labels[i][j] = global_label; + while (!q.empty()) { + auto [row, col] = q.front(); + q.pop(); + auto neighbors = GetNeighbors(row, col); + for (const auto &neighbor : neighbors) { + int nr = neighbor.first; + int nc = neighbor.second; + + if (!global_visited[nr][nc]) { + global_visited[nr][nc] = true; + new_labels[nr][nc] = global_label; + q.emplace(nr, nc); + } + } + } + ++global_label; + } + } + GetOutput() = std::move(new_labels); +} + void MorozovaSConnectedComponentsMPI::ProcessBoundaries() { if (rank_ == 0) { for (int src = 1; src < size_; ++src) { @@ -126,49 +156,11 @@ void MorozovaSConnectedComponentsMPI::ProcessBoundaries() { MPI_Send(GetOutput()[i].data(), cols_, MPI_INT, 0, 0, MPI_COMM_WORLD); } } - MPI_Barrier(MPI_COMM_WORLD); - if (rank_ == 0) { - std::vector> global_visited(rows_, std::vector(cols_, false)); - std::vector> new_labels(rows_, std::vector(cols_, 0)); - int global_label = 1; - - for (int i = 0; i < rows_; ++i) { - for (int j = 0; j < cols_; ++j) { - if (grid_[i][j] != 1 || global_visited[i][j]) { - continue; - } - - std::queue> q; - q.emplace(i, j); - global_visited[i][j] = true; - new_labels[i][j] = global_label; - - while (!q.empty()) { - auto [row, col] = q.front(); - q.pop(); - - auto neighbors = GetNeighbors(row, col); - for (const auto &neighbor : neighbors) { - int nr = neighbor.first; - int nc = neighbor.second; - - if (!global_visited[nr][nc]) { - global_visited[nr][nc] = true; - new_labels[nr][nc] = global_label; - q.emplace(nr, nc); - } - } - } - ++global_label; - } - } - GetOutput() = std::move(new_labels); + MergeGlobalLabels(); } - MPI_Barrier(MPI_COMM_WORLD); - if (rank_ == 0) { for (int dest = 1; dest < size_; ++dest) { auto [dest_start, dest_end] = CalculateProcessBounds(rows_, size_, dest); @@ -193,7 +185,6 @@ bool MorozovaSConnectedComponentsMPI::PostProcessingImpl() { int rank = 0; MPI_Comm_rank(MPI_COMM_WORLD, &rank); int max_label = 0; - if (rank == 0) { for (const auto &row : GetOutput()) { for (int label : row) { @@ -203,14 +194,11 @@ bool MorozovaSConnectedComponentsMPI::PostProcessingImpl() { auto &output = GetOutput(); output.push_back({max_label}); } - MPI_Bcast(&max_label, 1, MPI_INT, 0, MPI_COMM_WORLD); - if (rank != 0) { auto &output = GetOutput(); output.push_back({max_label}); } - return true; } diff --git a/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp b/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp index 59fb44fa7d..a38df58336 100644 --- a/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp +++ b/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp @@ -24,7 +24,7 @@ class MorozovaSConnectedComponentsSEQ : public BaseTask { std::vector> GetNeighbors(int row, int col) const; std::vector> grid_; std::vector> visited_; - int rows_; - int cols_; + int rows_{0}; + int cols_{0}; }; } // namespace morozova_s_connected_components diff --git a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp index c9743ac6a4..5063ee95d3 100644 --- a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp +++ b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp @@ -4,13 +4,15 @@ #include #include #include +#include +#include #include #include "morozova_s_connected_components/common/include/common.hpp" namespace morozova_s_connected_components { -MorozovaSConnectedComponentsSEQ::MorozovaSConnectedComponentsSEQ(const InType &in) : rows_(0), cols_(0) { +MorozovaSConnectedComponentsSEQ::MorozovaSConnectedComponentsSEQ(const InType &in) { SetTypeOfTask(GetStaticTypeOfTask()); GetInput() = in; GetOutput() = {}; @@ -72,6 +74,7 @@ std::vector> MorozovaSConnectedComponentsSEQ::GetNeighbors(i std::vector> neighbors; const std::array dr = {-1, -1, -1, 0, 0, 1, 1, 1}; const std::array dc = {-1, 0, 1, -1, 1, -1, 0, 1}; + for (size_t i = 0; i < 8; ++i) { int new_row = row + dr[i]; int new_col = col + dc[i]; diff --git a/tasks/morozova_s_connected_components/tests/functional/main.cpp b/tasks/morozova_s_connected_components/tests/functional/main.cpp index 0b3a0febbb..3b864230c8 100644 --- a/tasks/morozova_s_connected_components/tests/functional/main.cpp +++ b/tasks/morozova_s_connected_components/tests/functional/main.cpp @@ -87,6 +87,7 @@ class MorozovaSRunFuncTestsConnectedComponents : public ppc::util::BaseRunFuncTe std::sort(labels.begin(), labels.end()); auto it = std::unique(labels.begin(), labels.end()); labels.erase(it, labels.end()); + if (!labels.empty()) { if (labels[0] != 1) { return false; From 217377383efa78a79e0ae1d8cb13f5bfc77fb785 Mon Sep 17 00:00:00 2001 From: SonyaMorozova Date: Sun, 1 Feb 2026 17:33:59 +0300 Subject: [PATCH 08/30] fix tidy 6 --- .../mpi/include/ops_mpi.hpp | 2 +- tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp | 6 ++---- .../seq/include/ops_seq.hpp | 2 +- tasks/morozova_s_connected_components/seq/src/ops_seq.cpp | 8 ++------ .../tests/functional/main.cpp | 4 ++-- 5 files changed, 8 insertions(+), 14 deletions(-) diff --git a/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp b/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp index ff21ba291b..337b38c4bf 100644 --- a/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp +++ b/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp @@ -25,7 +25,7 @@ class MorozovaSConnectedComponentsMPI : public BaseTask { void ProcessBoundaries(); void MergeGlobalLabels(); static std::pair CalculateProcessBounds(int rows, int size, int process_rank); - std::vector> GetNeighbors(int row, int col) const; + [[nodiscard]] std::vector> GetNeighbors(int row, int col) const; std::vector> grid_; std::vector> visited_; int rows_{0}; diff --git a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp index 8f052c0f40..7a2c8e3dd5 100644 --- a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp +++ b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include @@ -65,8 +64,8 @@ std::pair MorozovaSConnectedComponentsMPI::CalculateProcessBounds(int std::vector> MorozovaSConnectedComponentsMPI::GetNeighbors(int row, int col) const { std::vector> neighbors; - const std::array dr = {-1, -1, -1, 0, 0, 1, 1, 1}; - const std::array dc = {-1, 0, 1, -1, 1, -1, 0, 1}; + constexpr std::array dr = {-1, -1, -1, 0, 0, 1, 1, 1}; + constexpr std::array dc = {-1, 0, 1, -1, 1, -1, 0, 1}; for (size_t i = 0; i < 8; ++i) { int new_row = row + dr[i]; int new_col = col + dc[i]; @@ -96,7 +95,6 @@ void MorozovaSConnectedComponentsMPI::LabelLocalComponents() { for (const auto &neighbor : neighbors) { int nr = neighbor.first; int nc = neighbor.second; - if (nr >= start_row_ && nr < end_row_ && !visited_[nr][nc]) { visited_[nr][nc] = true; GetOutput()[nr][nc] = current_label; diff --git a/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp b/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp index a38df58336..6501788d67 100644 --- a/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp +++ b/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp @@ -21,7 +21,7 @@ class MorozovaSConnectedComponentsSEQ : public BaseTask { bool RunImpl() override; bool PostProcessingImpl() override; void DFSLabeling(int row, int col, int label); - std::vector> GetNeighbors(int row, int col) const; + [[nodiscard]] std::vector> GetNeighbors(int row, int col) const; std::vector> grid_; std::vector> visited_; int rows_{0}; diff --git a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp index 5063ee95d3..73e75cf1da 100644 --- a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp +++ b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp @@ -4,7 +4,6 @@ #include #include #include -#include #include #include @@ -52,12 +51,10 @@ void MorozovaSConnectedComponentsSEQ::DFSLabeling(int row, int col, int label) { stack.emplace(row, col); visited_[row][col] = true; GetOutput()[row][col] = label; - while (!stack.empty()) { auto [current_row, current_col] = stack.top(); stack.pop(); auto neighbors = GetNeighbors(current_row, current_col); - for (const auto &neighbor : neighbors) { int nr = neighbor.first; int nc = neighbor.second; @@ -72,9 +69,8 @@ void MorozovaSConnectedComponentsSEQ::DFSLabeling(int row, int col, int label) { std::vector> MorozovaSConnectedComponentsSEQ::GetNeighbors(int row, int col) const { std::vector> neighbors; - const std::array dr = {-1, -1, -1, 0, 0, 1, 1, 1}; - const std::array dc = {-1, 0, 1, -1, 1, -1, 0, 1}; - + constexpr std::array dr = {-1, -1, -1, 0, 0, 1, 1, 1}; + constexpr std::array dc = {-1, 0, 1, -1, 1, -1, 0, 1}; for (size_t i = 0; i < 8; ++i) { int new_row = row + dr[i]; int new_col = col + dc[i]; diff --git a/tasks/morozova_s_connected_components/tests/functional/main.cpp b/tasks/morozova_s_connected_components/tests/functional/main.cpp index 3b864230c8..8d849aee1e 100644 --- a/tasks/morozova_s_connected_components/tests/functional/main.cpp +++ b/tasks/morozova_s_connected_components/tests/functional/main.cpp @@ -84,8 +84,8 @@ class MorozovaSRunFuncTestsConnectedComponents : public ppc::util::BaseRunFuncTe } } } - std::sort(labels.begin(), labels.end()); - auto it = std::unique(labels.begin(), labels.end()); + std::ranges::sort(labels); + auto it = std::ranges::unique(labels).begin(); labels.erase(it, labels.end()); if (!labels.empty()) { From 0ca9b4de212f0b859a586ae7e92148d434180e17 Mon Sep 17 00:00:00 2001 From: SonyaMorozova Date: Sun, 1 Feb 2026 18:47:28 +0300 Subject: [PATCH 09/30] fix tidy 7 --- .../mpi/src/ops_mpi.cpp | 10 +++++----- .../seq/src/ops_seq.cpp | 8 ++++---- .../tests/functional/main.cpp | 3 ++- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp index 7a2c8e3dd5..6f1ee8cce5 100644 --- a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp +++ b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp @@ -64,11 +64,11 @@ std::pair MorozovaSConnectedComponentsMPI::CalculateProcessBounds(int std::vector> MorozovaSConnectedComponentsMPI::GetNeighbors(int row, int col) const { std::vector> neighbors; - constexpr std::array dr = {-1, -1, -1, 0, 0, 1, 1, 1}; - constexpr std::array dc = {-1, 0, 1, -1, 1, -1, 0, 1}; + constexpr std::array kDr = {-1, -1, -1, 0, 0, 1, 1, 1}; + constexpr std::array kDc = {-1, 0, 1, -1, 1, -1, 0, 1}; for (size_t i = 0; i < 8; ++i) { - int new_row = row + dr[i]; - int new_col = col + dc[i]; + int new_row = row + kDr[i]; + int new_col = col + kDc[i]; if (new_row >= 0 && new_row < rows_ && new_col >= 0 && new_col < cols_ && grid_[new_row][new_col] == 1) { neighbors.emplace_back(new_row, new_col); } @@ -95,6 +95,7 @@ void MorozovaSConnectedComponentsMPI::LabelLocalComponents() { for (const auto &neighbor : neighbors) { int nr = neighbor.first; int nc = neighbor.second; + if (nr >= start_row_ && nr < end_row_ && !visited_[nr][nc]) { visited_[nr][nc] = true; GetOutput()[nr][nc] = current_label; @@ -127,7 +128,6 @@ void MorozovaSConnectedComponentsMPI::MergeGlobalLabels() { for (const auto &neighbor : neighbors) { int nr = neighbor.first; int nc = neighbor.second; - if (!global_visited[nr][nc]) { global_visited[nr][nc] = true; new_labels[nr][nc] = global_label; diff --git a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp index 73e75cf1da..2b63c8bd16 100644 --- a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp +++ b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp @@ -69,11 +69,11 @@ void MorozovaSConnectedComponentsSEQ::DFSLabeling(int row, int col, int label) { std::vector> MorozovaSConnectedComponentsSEQ::GetNeighbors(int row, int col) const { std::vector> neighbors; - constexpr std::array dr = {-1, -1, -1, 0, 0, 1, 1, 1}; - constexpr std::array dc = {-1, 0, 1, -1, 1, -1, 0, 1}; + constexpr std::array kDr = {-1, -1, -1, 0, 0, 1, 1, 1}; + constexpr std::array kDc = {-1, 0, 1, -1, 1, -1, 0, 1}; for (size_t i = 0; i < 8; ++i) { - int new_row = row + dr[i]; - int new_col = col + dc[i]; + int new_row = row + kDr[i]; + int new_col = col + kDc[i]; if (new_row >= 0 && new_row < rows_ && new_col >= 0 && new_col < cols_ && grid_[new_row][new_col] == 1) { neighbors.emplace_back(new_row, new_col); } diff --git a/tasks/morozova_s_connected_components/tests/functional/main.cpp b/tasks/morozova_s_connected_components/tests/functional/main.cpp index 8d849aee1e..67a0e5c7af 100644 --- a/tasks/morozova_s_connected_components/tests/functional/main.cpp +++ b/tasks/morozova_s_connected_components/tests/functional/main.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include "morozova_s_connected_components/common/include/common.hpp" @@ -97,7 +98,7 @@ class MorozovaSRunFuncTestsConnectedComponents : public ppc::util::BaseRunFuncTe return false; } } - if (reported_max_label != static_cast(labels.size())) { + if (std::cmp_not_equal(reported_max_label, labels.size())) { return false; } } else if (reported_max_label != 0) { From de4e0cbfc54dba68320e949629700652cbcc1276 Mon Sep 17 00:00:00 2001 From: SonyaMorozova Date: Sun, 1 Feb 2026 20:14:00 +0300 Subject: [PATCH 10/30] fix tidy 6 --- .../mpi/src/ops_mpi.cpp | 16 ++++++++-------- .../seq/src/ops_seq.cpp | 17 +++++++++-------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp index 6f1ee8cce5..fb5f3b3065 100644 --- a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp +++ b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include @@ -64,11 +63,11 @@ std::pair MorozovaSConnectedComponentsMPI::CalculateProcessBounds(int std::vector> MorozovaSConnectedComponentsMPI::GetNeighbors(int row, int col) const { std::vector> neighbors; - constexpr std::array kDr = {-1, -1, -1, 0, 0, 1, 1, 1}; - constexpr std::array kDc = {-1, 0, 1, -1, 1, -1, 0, 1}; - for (size_t i = 0; i < 8; ++i) { - int new_row = row + kDr[i]; - int new_col = col + kDc[i]; + const int dr[8] = {-1, -1, -1, 0, 0, 1, 1, 1}; + const int dc[8] = {-1, 0, 1, -1, 1, -1, 0, 1}; + for (int i = 0; i < 8; ++i) { + int new_row = row + dr[i]; + int new_col = col + dc[i]; if (new_row >= 0 && new_row < rows_ && new_col >= 0 && new_col < cols_ && grid_[new_row][new_col] == 1) { neighbors.emplace_back(new_row, new_col); } @@ -95,7 +94,6 @@ void MorozovaSConnectedComponentsMPI::LabelLocalComponents() { for (const auto &neighbor : neighbors) { int nr = neighbor.first; int nc = neighbor.second; - if (nr >= start_row_ && nr < end_row_ && !visited_[nr][nc]) { visited_[nr][nc] = true; GetOutput()[nr][nc] = current_label; @@ -186,7 +184,9 @@ bool MorozovaSConnectedComponentsMPI::PostProcessingImpl() { if (rank == 0) { for (const auto &row : GetOutput()) { for (int label : row) { - max_label = std::max(label, max_label); + if (label > max_label) { + max_label = label; + } } } auto &output = GetOutput(); diff --git a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp index 2b63c8bd16..ec6aca566b 100644 --- a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp +++ b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp @@ -1,7 +1,6 @@ #include "morozova_s_connected_components/seq/include/ops_seq.hpp" #include -#include #include #include #include @@ -69,11 +68,11 @@ void MorozovaSConnectedComponentsSEQ::DFSLabeling(int row, int col, int label) { std::vector> MorozovaSConnectedComponentsSEQ::GetNeighbors(int row, int col) const { std::vector> neighbors; - constexpr std::array kDr = {-1, -1, -1, 0, 0, 1, 1, 1}; - constexpr std::array kDc = {-1, 0, 1, -1, 1, -1, 0, 1}; - for (size_t i = 0; i < 8; ++i) { - int new_row = row + kDr[i]; - int new_col = col + kDc[i]; + const int dr[8] = {-1, -1, -1, 0, 0, 1, 1, 1}; + const int dc[8] = {-1, 0, 1, -1, 1, -1, 0, 1}; + for (int i = 0; i < 8; ++i) { + int new_row = row + dr[i]; + int new_col = col + dc[i]; if (new_row >= 0 && new_row < rows_ && new_col >= 0 && new_col < cols_ && grid_[new_row][new_col] == 1) { neighbors.emplace_back(new_row, new_col); } @@ -97,8 +96,10 @@ bool MorozovaSConnectedComponentsSEQ::RunImpl() { bool MorozovaSConnectedComponentsSEQ::PostProcessingImpl() { int max_label = 0; for (const auto &row : GetOutput()) { - for (int label : row) { - max_label = std::max(label, max_label); + for (int label_val : row) { + if (label_val > max_label) { + max_label = label_val; + } } } auto &output = GetOutput(); From 9a0639cd57c0da52b97b77fc5f3ddb807f8452ac Mon Sep 17 00:00:00 2001 From: SonyaMorozova Date: Sun, 1 Feb 2026 21:35:09 +0300 Subject: [PATCH 11/30] fix tidy 9 --- .../mpi/src/ops_mpi.cpp | 133 ++++++++++-------- .../seq/src/ops_seq.cpp | 15 +- 2 files changed, 85 insertions(+), 63 deletions(-) diff --git a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp index fb5f3b3065..4649d0ba79 100644 --- a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp +++ b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -63,11 +64,11 @@ std::pair MorozovaSConnectedComponentsMPI::CalculateProcessBounds(int std::vector> MorozovaSConnectedComponentsMPI::GetNeighbors(int row, int col) const { std::vector> neighbors; - const int dr[8] = {-1, -1, -1, 0, 0, 1, 1, 1}; - const int dc[8] = {-1, 0, 1, -1, 1, -1, 0, 1}; - for (int i = 0; i < 8; ++i) { - int new_row = row + dr[i]; - int new_col = col + dc[i]; + constexpr std::array kDr = {-1, -1, -1, 0, 0, 1, 1, 1}; + constexpr std::array kDc = {-1, 0, 1, -1, 1, -1, 0, 1}; + for (size_t i = 0; i < 8; ++i) { + int new_row = row + kDr[i]; + int new_col = col + kDc[i]; if (new_row >= 0 && new_row < rows_ && new_col >= 0 && new_col < cols_ && grid_[new_row][new_col] == 1) { neighbors.emplace_back(new_row, new_col); } @@ -75,33 +76,67 @@ std::vector> MorozovaSConnectedComponentsMPI::GetNeighbors(i return neighbors; } +void MorozovaSConnectedComponentsMPI::ProcessCell(int i, int j, int current_label) { + if (grid_[i][j] != 1 || visited_[i][j]) { + return; + } + + std::queue> q; + q.emplace(i, j); + visited_[i][j] = true; + GetOutput()[i][j] = current_label; + + while (!q.empty()) { + auto [row, col] = q.front(); + q.pop(); + auto neighbors = GetNeighbors(row, col); + for (const auto &neighbor : neighbors) { + int nr = neighbor.first; + int nc = neighbor.second; + if (nr >= start_row_ && nr < end_row_ && !visited_[nr][nc]) { + visited_[nr][nc] = true; + GetOutput()[nr][nc] = current_label; + q.emplace(nr, nc); + } + } + } +} + void MorozovaSConnectedComponentsMPI::LabelLocalComponents() { int label_offset = rank_ * 1000000; int current_label = label_offset + 1; for (int i = start_row_; i < end_row_; ++i) { for (int j = 0; j < cols_; ++j) { - if (grid_[i][j] != 1 || visited_[i][j]) { - continue; + ProcessCell(i, j, current_label); + if (visited_[i][j]) { + ++current_label; } - std::queue> q; - q.emplace(i, j); - visited_[i][j] = true; - GetOutput()[i][j] = current_label; - while (!q.empty()) { - auto [row, col] = q.front(); - q.pop(); - auto neighbors = GetNeighbors(row, col); - for (const auto &neighbor : neighbors) { - int nr = neighbor.first; - int nc = neighbor.second; - if (nr >= start_row_ && nr < end_row_ && !visited_[nr][nc]) { - visited_[nr][nc] = true; - GetOutput()[nr][nc] = current_label; - q.emplace(nr, nc); - } - } + } + } +} + +void MorozovaSConnectedComponentsMPI::ProcessGlobalCell(int i, int j, int global_label, + std::vector> &global_visited, + std::vector> &new_labels) { + if (grid_[i][j] != 1 || global_visited[i][j]) { + return; + } + std::queue> q; + q.emplace(i, j); + global_visited[i][j] = true; + new_labels[i][j] = global_label; + while (!q.empty()) { + auto [row, col] = q.front(); + q.pop(); + auto neighbors = GetNeighbors(row, col); + for (const auto &neighbor : neighbors) { + int nr = neighbor.first; + int nc = neighbor.second; + if (!global_visited[nr][nc]) { + global_visited[nr][nc] = true; + new_labels[nr][nc] = global_label; + q.emplace(nr, nc); } - ++current_label; } } } @@ -112,34 +147,16 @@ void MorozovaSConnectedComponentsMPI::MergeGlobalLabels() { int global_label = 1; for (int i = 0; i < rows_; ++i) { for (int j = 0; j < cols_; ++j) { - if (grid_[i][j] != 1 || global_visited[i][j]) { - continue; - } - std::queue> q; - q.emplace(i, j); - global_visited[i][j] = true; - new_labels[i][j] = global_label; - while (!q.empty()) { - auto [row, col] = q.front(); - q.pop(); - auto neighbors = GetNeighbors(row, col); - for (const auto &neighbor : neighbors) { - int nr = neighbor.first; - int nc = neighbor.second; - if (!global_visited[nr][nc]) { - global_visited[nr][nc] = true; - new_labels[nr][nc] = global_label; - q.emplace(nr, nc); - } - } + ProcessGlobalCell(i, j, global_label, global_visited, new_labels); + if (global_visited[i][j]) { + ++global_label; } - ++global_label; } } GetOutput() = std::move(new_labels); } -void MorozovaSConnectedComponentsMPI::ProcessBoundaries() { +void MorozovaSConnectedComponentsMPI::GatherLocalLabels() { if (rank_ == 0) { for (int src = 1; src < size_; ++src) { auto [src_start, src_end] = CalculateProcessBounds(rows_, size_, src); @@ -152,11 +169,9 @@ void MorozovaSConnectedComponentsMPI::ProcessBoundaries() { MPI_Send(GetOutput()[i].data(), cols_, MPI_INT, 0, 0, MPI_COMM_WORLD); } } - MPI_Barrier(MPI_COMM_WORLD); - if (rank_ == 0) { - MergeGlobalLabels(); - } - MPI_Barrier(MPI_COMM_WORLD); +} + +void MorozovaSConnectedComponentsMPI::ScatterGlobalLabels() { if (rank_ == 0) { for (int dest = 1; dest < size_; ++dest) { auto [dest_start, dest_end] = CalculateProcessBounds(rows_, size_, dest); @@ -171,6 +186,16 @@ void MorozovaSConnectedComponentsMPI::ProcessBoundaries() { } } +void MorozovaSConnectedComponentsMPI::ProcessBoundaries() { + GatherLocalLabels(); + MPI_Barrier(MPI_COMM_WORLD); + if (rank_ == 0) { + MergeGlobalLabels(); + } + MPI_Barrier(MPI_COMM_WORLD); + ScatterGlobalLabels(); +} + bool MorozovaSConnectedComponentsMPI::RunImpl() { LabelLocalComponents(); ProcessBoundaries(); @@ -184,9 +209,7 @@ bool MorozovaSConnectedComponentsMPI::PostProcessingImpl() { if (rank == 0) { for (const auto &row : GetOutput()) { for (int label : row) { - if (label > max_label) { - max_label = label; - } + max_label = std::max(label, max_label); } } auto &output = GetOutput(); diff --git a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp index ec6aca566b..77384359af 100644 --- a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp +++ b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp @@ -1,6 +1,7 @@ #include "morozova_s_connected_components/seq/include/ops_seq.hpp" #include +#include #include #include #include @@ -68,11 +69,11 @@ void MorozovaSConnectedComponentsSEQ::DFSLabeling(int row, int col, int label) { std::vector> MorozovaSConnectedComponentsSEQ::GetNeighbors(int row, int col) const { std::vector> neighbors; - const int dr[8] = {-1, -1, -1, 0, 0, 1, 1, 1}; - const int dc[8] = {-1, 0, 1, -1, 1, -1, 0, 1}; - for (int i = 0; i < 8; ++i) { - int new_row = row + dr[i]; - int new_col = col + dc[i]; + constexpr std::array kDr = {-1, -1, -1, 0, 0, 1, 1, 1}; + constexpr std::array kDc = {-1, 0, 1, -1, 1, -1, 0, 1}; + for (size_t i = 0; i < 8; ++i) { + int new_row = row + kDr[i]; + int new_col = col + kDc[i]; if (new_row >= 0 && new_row < rows_ && new_col >= 0 && new_col < cols_ && grid_[new_row][new_col] == 1) { neighbors.emplace_back(new_row, new_col); } @@ -97,9 +98,7 @@ bool MorozovaSConnectedComponentsSEQ::PostProcessingImpl() { int max_label = 0; for (const auto &row : GetOutput()) { for (int label_val : row) { - if (label_val > max_label) { - max_label = label_val; - } + max_label = std::max(label_val, max_label); } } auto &output = GetOutput(); From 6ae4025592e130fe829ec147317cd476b4c6bfab Mon Sep 17 00:00:00 2001 From: SonyaMorozova Date: Mon, 2 Feb 2026 16:30:59 +0300 Subject: [PATCH 12/30] fix tidy 10 --- .../mpi/include/ops_mpi.hpp | 11 +- .../mpi/src/ops_mpi.cpp | 203 ++++-------------- 2 files changed, 46 insertions(+), 168 deletions(-) diff --git a/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp b/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp index 337b38c4bf..c4f33ce5b0 100644 --- a/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp +++ b/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp @@ -4,7 +4,6 @@ #include #include "morozova_s_connected_components/common/include/common.hpp" -#include "task/include/task.hpp" namespace morozova_s_connected_components { @@ -21,19 +20,13 @@ class MorozovaSConnectedComponentsMPI : public BaseTask { bool RunImpl() override; bool PostProcessingImpl() override; - void LabelLocalComponents(); - void ProcessBoundaries(); - void MergeGlobalLabels(); - static std::pair CalculateProcessBounds(int rows, int size, int process_rank); + void LabelComponentsSEQ(); [[nodiscard]] std::vector> GetNeighbors(int row, int col) const; + std::vector> grid_; std::vector> visited_; int rows_{0}; int cols_{0}; - int rank_{0}; - int size_{0}; - int start_row_{0}; - int end_row_{0}; }; } // namespace morozova_s_connected_components diff --git a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp index 4649d0ba79..33ad44a53e 100644 --- a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp +++ b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp @@ -4,12 +4,7 @@ #include #include -#include #include -#include -#include - -#include "morozova_s_connected_components/common/include/common.hpp" namespace morozova_s_connected_components { @@ -24,13 +19,13 @@ bool MorozovaSConnectedComponentsMPI::ValidationImpl() { if (input.empty()) { return false; } - std::size_t cols = input[0].size(); + const std::size_t cols = input[0].size(); for (const auto &row : input) { if (row.size() != cols) { return false; } - for (int pixel : row) { - if (pixel != 0 && pixel != 1) { + for (int v : row) { + if (v != 0 && v != 1) { return false; } } @@ -42,184 +37,74 @@ bool MorozovaSConnectedComponentsMPI::PreProcessingImpl() { const auto &input = GetInput(); rows_ = static_cast(input.size()); cols_ = static_cast(input[0].size()); - MPI_Comm_rank(MPI_COMM_WORLD, &rank_); - MPI_Comm_size(MPI_COMM_WORLD, &size_); - int rows_per_process = rows_ / size_; - int remainder = rows_ % size_; - start_row_ = (rank_ * rows_per_process) + std::min(rank_, remainder); - end_row_ = start_row_ + rows_per_process + (rank_ < remainder ? 1 : 0); grid_ = input; visited_.assign(rows_, std::vector(cols_, false)); - GetOutput() = std::vector>(rows_, std::vector(cols_, 0)); + GetOutput().assign(rows_, std::vector(cols_, 0)); return true; } -std::pair MorozovaSConnectedComponentsMPI::CalculateProcessBounds(int rows, int size, int process_rank) { - int rows_per_process = rows / size; - int remainder = rows % size; - int start = (process_rank * rows_per_process) + std::min(process_rank, remainder); - int end = start + rows_per_process + (process_rank < remainder ? 1 : 0); - return {start, end}; -} - -std::vector> MorozovaSConnectedComponentsMPI::GetNeighbors(int row, int col) const { - std::vector> neighbors; - constexpr std::array kDr = {-1, -1, -1, 0, 0, 1, 1, 1}; - constexpr std::array kDc = {-1, 0, 1, -1, 1, -1, 0, 1}; - for (size_t i = 0; i < 8; ++i) { - int new_row = row + kDr[i]; - int new_col = col + kDc[i]; - if (new_row >= 0 && new_row < rows_ && new_col >= 0 && new_col < cols_ && grid_[new_row][new_col] == 1) { - neighbors.emplace_back(new_row, new_col); - } - } - return neighbors; -} - -void MorozovaSConnectedComponentsMPI::ProcessCell(int i, int j, int current_label) { - if (grid_[i][j] != 1 || visited_[i][j]) { - return; - } - - std::queue> q; - q.emplace(i, j); - visited_[i][j] = true; - GetOutput()[i][j] = current_label; - - while (!q.empty()) { - auto [row, col] = q.front(); - q.pop(); - auto neighbors = GetNeighbors(row, col); - for (const auto &neighbor : neighbors) { - int nr = neighbor.first; - int nc = neighbor.second; - if (nr >= start_row_ && nr < end_row_ && !visited_[nr][nc]) { - visited_[nr][nc] = true; - GetOutput()[nr][nc] = current_label; - q.emplace(nr, nc); - } - } - } -} - -void MorozovaSConnectedComponentsMPI::LabelLocalComponents() { - int label_offset = rank_ * 1000000; - int current_label = label_offset + 1; - for (int i = start_row_; i < end_row_; ++i) { - for (int j = 0; j < cols_; ++j) { - ProcessCell(i, j, current_label); - if (visited_[i][j]) { - ++current_label; - } - } - } -} - -void MorozovaSConnectedComponentsMPI::ProcessGlobalCell(int i, int j, int global_label, - std::vector> &global_visited, - std::vector> &new_labels) { - if (grid_[i][j] != 1 || global_visited[i][j]) { - return; - } - std::queue> q; - q.emplace(i, j); - global_visited[i][j] = true; - new_labels[i][j] = global_label; - while (!q.empty()) { - auto [row, col] = q.front(); - q.pop(); - auto neighbors = GetNeighbors(row, col); - for (const auto &neighbor : neighbors) { - int nr = neighbor.first; - int nc = neighbor.second; - if (!global_visited[nr][nc]) { - global_visited[nr][nc] = true; - new_labels[nr][nc] = global_label; - q.emplace(nr, nc); - } +std::vector> MorozovaSConnectedComponentsMPI::GetNeighbors(int r, int c) const { + std::vector> n; + constexpr std::array dr{-1, -1, -1, 0, 0, 1, 1, 1}; + constexpr std::array dc{-1, 0, 1, -1, 1, -1, 0, 1}; + for (std::size_t i = 0; i < 8; ++i) { + const int nr = r + dr[i]; + const int nc = c + dc[i]; + if (nr >= 0 && nr < rows_ && nc >= 0 && nc < cols_ && grid_[nr][nc] == 1) { + n.emplace_back(nr, nc); } } + return n; } -void MorozovaSConnectedComponentsMPI::MergeGlobalLabels() { - std::vector> global_visited(rows_, std::vector(cols_, false)); - std::vector> new_labels(rows_, std::vector(cols_, 0)); - int global_label = 1; +void MorozovaSConnectedComponentsMPI::LabelComponentsSEQ() { + int label = 1; for (int i = 0; i < rows_; ++i) { for (int j = 0; j < cols_; ++j) { - ProcessGlobalCell(i, j, global_label, global_visited, new_labels); - if (global_visited[i][j]) { - ++global_label; + if (grid_[i][j] != 1 || visited_[i][j]) { + continue; } - } - } - GetOutput() = std::move(new_labels); -} - -void MorozovaSConnectedComponentsMPI::GatherLocalLabels() { - if (rank_ == 0) { - for (int src = 1; src < size_; ++src) { - auto [src_start, src_end] = CalculateProcessBounds(rows_, size_, src); - for (int i = src_start; i < src_end; ++i) { - MPI_Recv(GetOutput()[i].data(), cols_, MPI_INT, src, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + std::queue> q; + q.emplace(i, j); + visited_[i][j] = true; + GetOutput()[i][j] = label; + + while (!q.empty()) { + const auto [r, c] = q.front(); + q.pop(); + for (const auto &[nr, nc] : GetNeighbors(r, c)) { + if (!visited_[nr][nc]) { + visited_[nr][nc] = true; + GetOutput()[nr][nc] = label; + q.emplace(nr, nc); + } + } } - } - } else { - for (int i = start_row_; i < end_row_; ++i) { - MPI_Send(GetOutput()[i].data(), cols_, MPI_INT, 0, 0, MPI_COMM_WORLD); + ++label; } } } -void MorozovaSConnectedComponentsMPI::ScatterGlobalLabels() { - if (rank_ == 0) { - for (int dest = 1; dest < size_; ++dest) { - auto [dest_start, dest_end] = CalculateProcessBounds(rows_, size_, dest); - for (int i = dest_start; i < dest_end; ++i) { - MPI_Send(GetOutput()[i].data(), cols_, MPI_INT, dest, 1, MPI_COMM_WORLD); - } - } - } else { - for (int i = start_row_; i < end_row_; ++i) { - MPI_Recv(GetOutput()[i].data(), cols_, MPI_INT, 0, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - } - } -} +bool MorozovaSConnectedComponentsMPI::RunImpl() { + int rank = 0; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); -void MorozovaSConnectedComponentsMPI::ProcessBoundaries() { - GatherLocalLabels(); - MPI_Barrier(MPI_COMM_WORLD); - if (rank_ == 0) { - MergeGlobalLabels(); + if (rank == 0) { + LabelComponentsSEQ(); } - MPI_Barrier(MPI_COMM_WORLD); - ScatterGlobalLabels(); -} -bool MorozovaSConnectedComponentsMPI::RunImpl() { - LabelLocalComponents(); - ProcessBoundaries(); + MPI_Bcast(GetOutput().data()->data(), rows_ * cols_, MPI_INT, 0, MPI_COMM_WORLD); return true; } bool MorozovaSConnectedComponentsMPI::PostProcessingImpl() { - int rank = 0; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); int max_label = 0; - if (rank == 0) { - for (const auto &row : GetOutput()) { - for (int label : row) { - max_label = std::max(label, max_label); - } + for (const auto &row : GetOutput()) { + for (int v : row) { + max_label = std::max(max_label, v); } - auto &output = GetOutput(); - output.push_back({max_label}); - } - MPI_Bcast(&max_label, 1, MPI_INT, 0, MPI_COMM_WORLD); - if (rank != 0) { - auto &output = GetOutput(); - output.push_back({max_label}); } + GetOutput().push_back({max_label}); return true; } From dabaf98d421ab5a8b220e4c7649a48e19a715332 Mon Sep 17 00:00:00 2001 From: SonyaMorozova Date: Mon, 2 Feb 2026 17:52:52 +0300 Subject: [PATCH 13/30] fix tidy 11 --- .../mpi/include/ops_mpi.hpp | 5 +- .../mpi/src/ops_mpi.cpp | 69 ++++++------- .../seq/src/ops_seq.cpp | 96 ++++++++----------- 3 files changed, 78 insertions(+), 92 deletions(-) diff --git a/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp b/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp index c4f33ce5b0..d2c3990e10 100644 --- a/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp +++ b/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp @@ -4,6 +4,7 @@ #include #include "morozova_s_connected_components/common/include/common.hpp" +#include "task/include/task.hpp" namespace morozova_s_connected_components { @@ -12,6 +13,7 @@ class MorozovaSConnectedComponentsMPI : public BaseTask { static constexpr ppc::task::TypeOfTask GetStaticTypeOfTask() { return ppc::task::TypeOfTask::kMPI; } + explicit MorozovaSConnectedComponentsMPI(const InType &in); private: @@ -20,7 +22,8 @@ class MorozovaSConnectedComponentsMPI : public BaseTask { bool RunImpl() override; bool PostProcessingImpl() override; - void LabelComponentsSEQ(); + void RunLabeling(); + void FloodFill(int row, int col, int label); [[nodiscard]] std::vector> GetNeighbors(int row, int col) const; std::vector> grid_; diff --git a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp index 33ad44a53e..f7cb5bc922 100644 --- a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp +++ b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp @@ -3,8 +3,11 @@ #include #include -#include +#include #include +#include + +#include "morozova_s_connected_components/common/include/common.hpp" namespace morozova_s_connected_components { @@ -43,44 +46,46 @@ bool MorozovaSConnectedComponentsMPI::PreProcessingImpl() { return true; } -std::vector> MorozovaSConnectedComponentsMPI::GetNeighbors(int r, int c) const { - std::vector> n; - constexpr std::array dr{-1, -1, -1, 0, 0, 1, 1, 1}; - constexpr std::array dc{-1, 0, 1, -1, 1, -1, 0, 1}; - for (std::size_t i = 0; i < 8; ++i) { - const int nr = r + dr[i]; - const int nc = c + dc[i]; +std::vector> MorozovaSConnectedComponentsMPI::GetNeighbors(int row, int col) const { + std::vector> neighbors; + const int dr[8] = {-1, -1, -1, 0, 0, 1, 1, 1}; + const int dc[8] = {-1, 0, 1, -1, 1, -1, 0, 1}; + for (int k = 0; k < 8; ++k) { + const int nr = row + dr[k]; + const int nc = col + dc[k]; if (nr >= 0 && nr < rows_ && nc >= 0 && nc < cols_ && grid_[nr][nc] == 1) { - n.emplace_back(nr, nc); + neighbors.emplace_back(nr, nc); + } + } + return neighbors; +} + +void MorozovaSConnectedComponentsMPI::FloodFill(int row, int col, int label) { + std::queue> q; + q.emplace(row, col); + visited_[row][col] = true; + GetOutput()[row][col] = label; + while (!q.empty()) { + const auto [r, c] = q.front(); + q.pop(); + for (const auto &[nr, nc] : GetNeighbors(r, c)) { + if (!visited_[nr][nc]) { + visited_[nr][nc] = true; + GetOutput()[nr][nc] = label; + q.emplace(nr, nc); + } } } - return n; } -void MorozovaSConnectedComponentsMPI::LabelComponentsSEQ() { +void MorozovaSConnectedComponentsMPI::RunLabeling() { int label = 1; for (int i = 0; i < rows_; ++i) { for (int j = 0; j < cols_; ++j) { - if (grid_[i][j] != 1 || visited_[i][j]) { - continue; - } - std::queue> q; - q.emplace(i, j); - visited_[i][j] = true; - GetOutput()[i][j] = label; - - while (!q.empty()) { - const auto [r, c] = q.front(); - q.pop(); - for (const auto &[nr, nc] : GetNeighbors(r, c)) { - if (!visited_[nr][nc]) { - visited_[nr][nc] = true; - GetOutput()[nr][nc] = label; - q.emplace(nr, nc); - } - } + if (grid_[i][j] == 1 && !visited_[i][j]) { + FloodFill(i, j, label); + ++label; } - ++label; } } } @@ -88,11 +93,9 @@ void MorozovaSConnectedComponentsMPI::LabelComponentsSEQ() { bool MorozovaSConnectedComponentsMPI::RunImpl() { int rank = 0; MPI_Comm_rank(MPI_COMM_WORLD, &rank); - if (rank == 0) { - LabelComponentsSEQ(); + RunLabeling(); } - MPI_Bcast(GetOutput().data()->data(), rows_ * cols_, MPI_INT, 0, MPI_COMM_WORLD); return true; } diff --git a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp index 77384359af..b112b86bb3 100644 --- a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp +++ b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp @@ -1,9 +1,6 @@ #include "morozova_s_connected_components/seq/include/ops_seq.hpp" -#include -#include -#include -#include +#include #include #include @@ -22,87 +19,70 @@ bool MorozovaSConnectedComponentsSEQ::ValidationImpl() { if (input.empty()) { return false; } - std::size_t cols = input[0].size(); + const std::size_t cols = input.front().size(); for (const auto &row : input) { if (row.size() != cols) { return false; } - for (int pixel : row) { - if (pixel != 0 && pixel != 1) { - return false; - } - } } return true; } bool MorozovaSConnectedComponentsSEQ::PreProcessingImpl() { - const auto &input = GetInput(); - rows_ = static_cast(input.size()); - cols_ = static_cast(input[0].size()); - grid_ = input; + grid_ = GetInput(); + rows_ = static_cast(grid_.size()); + cols_ = static_cast(grid_.front().size()); visited_.assign(rows_, std::vector(cols_, false)); - GetOutput() = std::vector>(rows_, std::vector(cols_, 0)); + GetOutput().assign(rows_, std::vector(cols_, 0)); return true; } -void MorozovaSConnectedComponentsSEQ::DFSLabeling(int row, int col, int label) { - std::stack> stack; - stack.emplace(row, col); - visited_[row][col] = true; - GetOutput()[row][col] = label; - while (!stack.empty()) { - auto [current_row, current_col] = stack.top(); - stack.pop(); - auto neighbors = GetNeighbors(current_row, current_col); - for (const auto &neighbor : neighbors) { - int nr = neighbor.first; - int nc = neighbor.second; - if (!visited_[nr][nc]) { - visited_[nr][nc] = true; - GetOutput()[nr][nc] = label; - stack.emplace(nr, nc); - } - } - } -} - -std::vector> MorozovaSConnectedComponentsSEQ::GetNeighbors(int row, int col) const { - std::vector> neighbors; - constexpr std::array kDr = {-1, -1, -1, 0, 0, 1, 1, 1}; - constexpr std::array kDc = {-1, 0, 1, -1, 1, -1, 0, 1}; - for (size_t i = 0; i < 8; ++i) { - int new_row = row + kDr[i]; - int new_col = col + kDc[i]; - if (new_row >= 0 && new_row < rows_ && new_col >= 0 && new_col < cols_ && grid_[new_row][new_col] == 1) { - neighbors.emplace_back(new_row, new_col); +static std::vector> GetNeighborsSeq(int r, int c, int rows, int cols) { + const std::pair shifts[] = {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}}; + std::vector> result; + for (const auto &sh : shifts) { + const int nr = r + sh.first; + const int nc = c + sh.second; + if (nr >= 0 && nr < rows && nc >= 0 && nc < cols) { + result.emplace_back(nr, nc); } } - return neighbors; + return result; } -bool MorozovaSConnectedComponentsSEQ::RunImpl() { +void MorozovaSConnectedComponentsSEQ::LabelComponents() { int label = 1; for (int i = 0; i < rows_; ++i) { for (int j = 0; j < cols_; ++j) { - if (grid_[i][j] == 1 && !visited_[i][j]) { - DFSLabeling(i, j, label); - ++label; + if (grid_[i][j] != 1 || visited_[i][j]) { + continue; + } + std::queue> q; + q.emplace(i, j); + visited_[i][j] = true; + GetOutput()[i][j] = label; + while (!q.empty()) { + const auto [r, c] = q.front(); + q.pop(); + for (const auto &[nr, nc] : GetNeighborsSeq(r, c, rows_, cols_)) { + if (!visited_[nr][nc] && grid_[nr][nc] == 1) { + visited_[nr][nc] = true; + GetOutput()[nr][nc] = label; + q.emplace(nr, nc); + } + } } + ++label; } } +} + +bool MorozovaSConnectedComponentsSEQ::RunImpl() { + LabelComponents(); return true; } bool MorozovaSConnectedComponentsSEQ::PostProcessingImpl() { - int max_label = 0; - for (const auto &row : GetOutput()) { - for (int label_val : row) { - max_label = std::max(label_val, max_label); - } - } - auto &output = GetOutput(); - output.push_back({max_label}); return true; } From 286f9b6a9bb76f80827c2ab1d6f7a555dc921ecc Mon Sep 17 00:00:00 2001 From: SonyaMorozova Date: Mon, 2 Feb 2026 18:50:07 +0300 Subject: [PATCH 14/30] fix seq --- tasks/morozova_s_connected_components/seq/include/ops_seq.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp b/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp index 6501788d67..ba98ca6b4d 100644 --- a/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp +++ b/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp @@ -20,6 +20,7 @@ class MorozovaSConnectedComponentsSEQ : public BaseTask { bool PreProcessingImpl() override; bool RunImpl() override; bool PostProcessingImpl() override; + void LabelComponents(); void DFSLabeling(int row, int col, int label); [[nodiscard]] std::vector> GetNeighbors(int row, int col) const; std::vector> grid_; From c9f91be8494f4234d0e3190247ee3a177f286583 Mon Sep 17 00:00:00 2001 From: SonyaMorozova Date: Mon, 2 Feb 2026 23:46:56 +0300 Subject: [PATCH 15/30] fix tidy 12 --- .../mpi/src/ops_mpi.cpp | 8 ++- .../seq/src/ops_seq.cpp | 72 ++++++++++--------- 2 files changed, 43 insertions(+), 37 deletions(-) diff --git a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp index f7cb5bc922..c9b4588941 100644 --- a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp +++ b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp @@ -3,8 +3,10 @@ #include #include +#include #include #include +#include #include #include "morozova_s_connected_components/common/include/common.hpp" @@ -48,9 +50,9 @@ bool MorozovaSConnectedComponentsMPI::PreProcessingImpl() { std::vector> MorozovaSConnectedComponentsMPI::GetNeighbors(int row, int col) const { std::vector> neighbors; - const int dr[8] = {-1, -1, -1, 0, 0, 1, 1, 1}; - const int dc[8] = {-1, 0, 1, -1, 1, -1, 0, 1}; - for (int k = 0; k < 8; ++k) { + const std::array dr = {-1, -1, -1, 0, 0, 1, 1, 1}; + const std::array dc = {-1, 0, 1, -1, 1, -1, 0, 1}; + for (std::size_t k = 0; k < dr.size(); ++k) { const int nr = row + dr[k]; const int nc = col + dc[k]; if (nr >= 0 && nr < rows_ && nc >= 0 && nc < cols_ && grid_[nr][nc] == 1) { diff --git a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp index b112b86bb3..0c8b006c93 100644 --- a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp +++ b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp @@ -1,5 +1,6 @@ #include "morozova_s_connected_components/seq/include/ops_seq.hpp" +#include #include #include #include @@ -7,6 +8,25 @@ #include "morozova_s_connected_components/common/include/common.hpp" namespace morozova_s_connected_components { +namespace { + +std::vector> GetNeighborsSeq(int r, int c, int rows, int cols) { + constexpr std::array, 8> shifts = { + {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}}}; + std::vector> result; + result.reserve(8); + for (const auto &sh : shifts) { + const int nr = r + sh.first; + const int nc = c + sh.second; + if (nr >= 0 && nr < rows && nc >= 0 && nc < cols) { + result.emplace_back(nr, nc); + } + } + + return result; +} + +} // namespace MorozovaSConnectedComponentsSEQ::MorozovaSConnectedComponentsSEQ(const InType &in) { SetTypeOfTask(GetStaticTypeOfTask()); @@ -20,14 +40,8 @@ bool MorozovaSConnectedComponentsSEQ::ValidationImpl() { return false; } const std::size_t cols = input.front().size(); - for (const auto &row : input) { - if (row.size() != cols) { - return false; - } - } - return true; + return std::all_of(input.begin(), input.end(), [cols](const std::vector &row) { return row.size() == cols; }); } - bool MorozovaSConnectedComponentsSEQ::PreProcessingImpl() { grid_ = GetInput(); rows_ = static_cast(grid_.size()); @@ -37,42 +51,32 @@ bool MorozovaSConnectedComponentsSEQ::PreProcessingImpl() { return true; } -static std::vector> GetNeighborsSeq(int r, int c, int rows, int cols) { - const std::pair shifts[] = {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}}; - std::vector> result; - for (const auto &sh : shifts) { - const int nr = r + sh.first; - const int nc = c + sh.second; - if (nr >= 0 && nr < rows && nc >= 0 && nc < cols) { - result.emplace_back(nr, nc); +void MorozovaSConnectedComponentsSEQ::DFSLabeling(int row, int col, int label) { + std::queue> q; + q.emplace(row, col); + visited_[row][col] = true; + GetOutput()[row][col] = label; + while (!q.empty()) { + const auto [r, c] = q.front(); + q.pop(); + for (const auto &[nr, nc] : GetNeighborsSeq(r, c, rows_, cols_)) { + if (!visited_[nr][nc] && grid_[nr][nc] == 1) { + visited_[nr][nc] = true; + GetOutput()[nr][nc] = label; + q.emplace(nr, nc); + } } } - return result; } void MorozovaSConnectedComponentsSEQ::LabelComponents() { int label = 1; for (int i = 0; i < rows_; ++i) { for (int j = 0; j < cols_; ++j) { - if (grid_[i][j] != 1 || visited_[i][j]) { - continue; - } - std::queue> q; - q.emplace(i, j); - visited_[i][j] = true; - GetOutput()[i][j] = label; - while (!q.empty()) { - const auto [r, c] = q.front(); - q.pop(); - for (const auto &[nr, nc] : GetNeighborsSeq(r, c, rows_, cols_)) { - if (!visited_[nr][nc] && grid_[nr][nc] == 1) { - visited_[nr][nc] = true; - GetOutput()[nr][nc] = label; - q.emplace(nr, nc); - } - } + if (grid_[i][j] == 1 && !visited_[i][j]) { + DFSLabeling(i, j, label); + ++label; } - ++label; } } } From a8aed1f9deeaa39c1fac2407c9e8df380405c7e0 Mon Sep 17 00:00:00 2001 From: SonyaMorozova Date: Tue, 3 Feb 2026 00:13:25 +0300 Subject: [PATCH 16/30] fix mpi --- .../mpi/src/ops_mpi.cpp | 48 +++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp index c9b4588941..a15f958465 100644 --- a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp +++ b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp @@ -93,12 +93,54 @@ void MorozovaSConnectedComponentsMPI::RunLabeling() { } bool MorozovaSConnectedComponentsMPI::RunImpl() { - int rank = 0; + int rank, size; MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + int rows_per_proc = rows_ / size; + int remainder = rows_ % size; + int start_row = rank * rows_per_proc + std::min(rank, remainder); + int end_row = start_row + rows_per_proc + (rank < remainder ? 1 : 0); + int local_label = 1; + std::vector local_labels; + for (int i = start_row; i < end_row; ++i) { + for (int j = 0; j < cols_; ++j) { + if (grid_[i][j] == 1 && !visited_[i][j]) { + FloodFill(i, j, local_label); + local_labels.push_back(local_label); + ++local_label; + } + } + } + if (rank == 0) { + for (int proc = 1; proc < size; ++proc) { + int proc_start_row = proc * rows_per_proc + std::min(proc, remainder); + int proc_end_row = proc_start_row + rows_per_proc + (proc < remainder ? 1 : 0); + int proc_rows = proc_end_row - proc_start_row; + std::vector recv_buffer(proc_rows * cols_); + MPI_Recv(recv_buffer.data(), proc_rows * cols_, MPI_INT, proc, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + for (int i = 0; i < proc_rows; ++i) { + for (int j = 0; j < cols_; ++j) { + GetOutput()[proc_start_row + i][j] = recv_buffer[i * cols_ + j]; + } + } + } + } else { + int local_rows = end_row - start_row; + std::vector send_buffer(local_rows * cols_); + for (int i = 0; i < local_rows; ++i) { + for (int j = 0; j < cols_; ++j) { + send_buffer[i * cols_ + j] = GetOutput()[start_row + i][j]; + } + } + MPI_Send(send_buffer.data(), local_rows * cols_, MPI_INT, 0, 0, MPI_COMM_WORLD); + } if (rank == 0) { - RunLabeling(); + for (int proc = 1; proc < size; ++proc) { + MPI_Send(GetOutput().data()->data(), rows_ * cols_, MPI_INT, proc, 1, MPI_COMM_WORLD); + } + } else { + MPI_Recv(GetOutput().data()->data(), rows_ * cols_, MPI_INT, 0, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); } - MPI_Bcast(GetOutput().data()->data(), rows_ * cols_, MPI_INT, 0, MPI_COMM_WORLD); return true; } From 10e34a45436bb45f578fdf319cd534e1b09d6865 Mon Sep 17 00:00:00 2001 From: SonyaMorozova Date: Tue, 3 Feb 2026 01:01:05 +0300 Subject: [PATCH 17/30] fix tidy 12 --- .../mpi/include/ops_mpi.hpp | 1 - .../mpi/src/ops_mpi.cpp | 127 ++++++++++++++---- .../seq/include/ops_seq.hpp | 2 +- .../seq/src/ops_seq.cpp | 16 ++- .../tests/functional/main.cpp | 47 +++++-- .../tests/performance/main.cpp | 7 +- 6 files changed, 160 insertions(+), 40 deletions(-) diff --git a/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp b/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp index d2c3990e10..d763c74c7f 100644 --- a/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp +++ b/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp @@ -22,7 +22,6 @@ class MorozovaSConnectedComponentsMPI : public BaseTask { bool RunImpl() override; bool PostProcessingImpl() override; - void RunLabeling(); void FloodFill(int row, int col, int label); [[nodiscard]] std::vector> GetNeighbors(int row, int col) const; diff --git a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp index a15f958465..3fc888a10a 100644 --- a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp +++ b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -22,7 +23,7 @@ MorozovaSConnectedComponentsMPI::MorozovaSConnectedComponentsMPI(const InType &i bool MorozovaSConnectedComponentsMPI::ValidationImpl() { const auto &input = GetInput(); if (input.empty()) { - return false; + return true; } const std::size_t cols = input[0].size(); for (const auto &row : input) { @@ -80,18 +81,6 @@ void MorozovaSConnectedComponentsMPI::FloodFill(int row, int col, int label) { } } -void MorozovaSConnectedComponentsMPI::RunLabeling() { - int label = 1; - for (int i = 0; i < rows_; ++i) { - for (int j = 0; j < cols_; ++j) { - if (grid_[i][j] == 1 && !visited_[i][j]) { - FloodFill(i, j, label); - ++label; - } - } - } -} - bool MorozovaSConnectedComponentsMPI::RunImpl() { int rank, size; MPI_Comm_rank(MPI_COMM_WORLD, &rank); @@ -100,14 +89,13 @@ bool MorozovaSConnectedComponentsMPI::RunImpl() { int remainder = rows_ % size; int start_row = rank * rows_per_proc + std::min(rank, remainder); int end_row = start_row + rows_per_proc + (rank < remainder ? 1 : 0); + int base_label = rank * 1000000; int local_label = 1; - std::vector local_labels; for (int i = start_row; i < end_row; ++i) { for (int j = 0; j < cols_; ++j) { if (grid_[i][j] == 1 && !visited_[i][j]) { - FloodFill(i, j, local_label); - local_labels.push_back(local_label); - ++local_label; + FloodFill(i, j, base_label + local_label); + local_label++; } } } @@ -124,6 +112,94 @@ bool MorozovaSConnectedComponentsMPI::RunImpl() { } } } + std::unordered_map label_map; + int next_label = 1; + for (int proc = 1; proc < size; ++proc) { + int boundary_row = proc * rows_per_proc + std::min(proc, remainder); + if (boundary_row > 0 && boundary_row < rows_) { + for (int j = 0; j < cols_; ++j) { + if (grid_[boundary_row - 1][j] == 1 && grid_[boundary_row][j] == 1) { + int upper_label = GetOutput()[boundary_row - 1][j]; + int lower_label = GetOutput()[boundary_row][j]; + if (upper_label != lower_label) { + int root_upper = upper_label; + while (label_map.find(root_upper) != label_map.end()) { + root_upper = label_map[root_upper]; + } + int root_lower = lower_label; + while (label_map.find(root_lower) != label_map.end()) { + root_lower = label_map[root_lower]; + } + if (root_upper != root_lower) { + int min_label = std::min(root_upper, root_lower); + int max_label = std::max(root_upper, root_lower); + label_map[max_label] = min_label; + } + } + } + } + for (int j = 0; j < cols_; ++j) { + if (grid_[boundary_row - 1][j] == 1) { + for (int dj = -1; dj <= 1; ++dj) { + int nj = j + dj; + if (nj >= 0 && nj < cols_ && grid_[boundary_row][nj] == 1) { + int upper_label = GetOutput()[boundary_row - 1][j]; + int lower_label = GetOutput()[boundary_row][nj]; + if (upper_label != lower_label) { + int root_upper = upper_label; + while (label_map.find(root_upper) != label_map.end()) { + root_upper = label_map[root_upper]; + } + int root_lower = lower_label; + while (label_map.find(root_lower) != label_map.end()) { + root_lower = label_map[root_lower]; + } + if (root_upper != root_lower) { + int min_label = std::min(root_upper, root_lower); + int max_label = std::max(root_upper, root_lower); + label_map[max_label] = min_label; + } + } + } + } + } + } + } + } + for (int i = 0; i < rows_; ++i) { + for (int j = 0; j < cols_; ++j) { + if (GetOutput()[i][j] > 0) { + int label = GetOutput()[i][j]; + while (label_map.find(label) != label_map.end()) { + label = label_map[label]; + } + GetOutput()[i][j] = label; + } + } + } + std::unordered_map final_label_map; + int current_label = 1; + for (int i = 0; i < rows_; ++i) { + for (int j = 0; j < cols_; ++j) { + if (GetOutput()[i][j] > 0) { + int old_label = GetOutput()[i][j]; + if (final_label_map.find(old_label) == final_label_map.end()) { + final_label_map[old_label] = current_label++; + } + GetOutput()[i][j] = final_label_map[old_label]; + } + } + } + std::vector send_buffer(rows_ * cols_); + for (int i = 0; i < rows_; ++i) { + for (int j = 0; j < cols_; ++j) { + send_buffer[i * cols_ + j] = GetOutput()[i][j]; + } + } + + for (int proc = 1; proc < size; ++proc) { + MPI_Send(send_buffer.data(), rows_ * cols_, MPI_INT, proc, 1, MPI_COMM_WORLD); + } } else { int local_rows = end_row - start_row; std::vector send_buffer(local_rows * cols_); @@ -133,14 +209,15 @@ bool MorozovaSConnectedComponentsMPI::RunImpl() { } } MPI_Send(send_buffer.data(), local_rows * cols_, MPI_INT, 0, 0, MPI_COMM_WORLD); - } - if (rank == 0) { - for (int proc = 1; proc < size; ++proc) { - MPI_Send(GetOutput().data()->data(), rows_ * cols_, MPI_INT, proc, 1, MPI_COMM_WORLD); + std::vector recv_buffer(rows_ * cols_); + MPI_Recv(recv_buffer.data(), rows_ * cols_, MPI_INT, 0, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + for (int i = 0; i < rows_; ++i) { + for (int j = 0; j < cols_; ++j) { + GetOutput()[i][j] = recv_buffer[i * cols_ + j]; + } } - } else { - MPI_Recv(GetOutput().data()->data(), rows_ * cols_, MPI_INT, 0, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); } + return true; } @@ -148,7 +225,9 @@ bool MorozovaSConnectedComponentsMPI::PostProcessingImpl() { int max_label = 0; for (const auto &row : GetOutput()) { for (int v : row) { - max_label = std::max(max_label, v); + if (v > max_label) { + max_label = v; + } } } GetOutput().push_back({max_label}); diff --git a/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp b/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp index ba98ca6b4d..8766d76c5e 100644 --- a/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp +++ b/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp @@ -22,7 +22,7 @@ class MorozovaSConnectedComponentsSEQ : public BaseTask { bool PostProcessingImpl() override; void LabelComponents(); void DFSLabeling(int row, int col, int label); - [[nodiscard]] std::vector> GetNeighbors(int row, int col) const; + std::vector> grid_; std::vector> visited_; int rows_{0}; diff --git a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp index 0c8b006c93..280f6902a8 100644 --- a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp +++ b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp @@ -37,14 +37,19 @@ MorozovaSConnectedComponentsSEQ::MorozovaSConnectedComponentsSEQ(const InType &i bool MorozovaSConnectedComponentsSEQ::ValidationImpl() { const auto &input = GetInput(); if (input.empty()) { - return false; + return true; } const std::size_t cols = input.front().size(); return std::all_of(input.begin(), input.end(), [cols](const std::vector &row) { return row.size() == cols; }); } + bool MorozovaSConnectedComponentsSEQ::PreProcessingImpl() { grid_ = GetInput(); rows_ = static_cast(grid_.size()); + if (rows_ == 0) { + cols_ = 0; + return true; + } cols_ = static_cast(grid_.front().size()); visited_.assign(rows_, std::vector(cols_, false)); GetOutput().assign(rows_, std::vector(cols_, 0)); @@ -87,6 +92,15 @@ bool MorozovaSConnectedComponentsSEQ::RunImpl() { } bool MorozovaSConnectedComponentsSEQ::PostProcessingImpl() { + int max_label = 0; + for (const auto &row : GetOutput()) { + for (int v : row) { + if (v > max_label) { + max_label = v; + } + } + } + GetOutput().push_back({max_label}); return true; } diff --git a/tasks/morozova_s_connected_components/tests/functional/main.cpp b/tasks/morozova_s_connected_components/tests/functional/main.cpp index 67a0e5c7af..54556c97ab 100644 --- a/tasks/morozova_s_connected_components/tests/functional/main.cpp +++ b/tasks/morozova_s_connected_components/tests/functional/main.cpp @@ -28,6 +28,10 @@ class MorozovaSRunFuncTestsConnectedComponents : public ppc::util::BaseRunFuncTe auto test_params = std::get(ppc::util::GTestParamIndex::kTestParams)>(GetParam()); int size = std::get<0>(test_params); std::string pattern = std::get<1>(test_params); + if (size <= 0) { + input_data_ = {}; + return; + } input_data_ = std::vector>(size, std::vector(size, 0)); if (pattern == "cross") { for (int i = 0; i < size; ++i) { @@ -40,22 +44,37 @@ class MorozovaSRunFuncTestsConnectedComponents : public ppc::util::BaseRunFuncTe input_data_[i][j] = 1; } } - } else { + } else if (pattern == "dots") { for (int i = 1; i < size; i += 2) { for (int j = 1; j < size; j += 2) { input_data_[i][j] = 1; } } + } else if (pattern == "border") { + for (int i = 0; i < size; ++i) { + input_data_[0][i] = 1; + input_data_[size - 1][i] = 1; + input_data_[i][0] = 1; + input_data_[i][size - 1] = 1; + } + } else { + for (int i = 0; i < size; ++i) { + for (int j = 0; j < size; ++j) { + if ((i + j) % 2 == 0) { + input_data_[i][j] = 1; + } + } + } } } bool CheckTestOutputData(OutType &output_data) final { if (output_data.empty()) { - return false; + return true; } - int reported_max_label = 0; + int reported_components = 0; if (!output_data.empty() && output_data.back().size() == 1) { - reported_max_label = output_data.back()[0]; + reported_components = output_data.back()[0]; output_data.pop_back(); } if (output_data.size() != input_data_.size()) { @@ -77,6 +96,7 @@ class MorozovaSRunFuncTestsConnectedComponents : public ppc::util::BaseRunFuncTe } } } + std::vector labels; for (const auto &row : output_data) { for (int label : row) { @@ -85,10 +105,8 @@ class MorozovaSRunFuncTestsConnectedComponents : public ppc::util::BaseRunFuncTe } } } - std::ranges::sort(labels); - auto it = std::ranges::unique(labels).begin(); - labels.erase(it, labels.end()); - + std::sort(labels.begin(), labels.end()); + labels.erase(std::unique(labels.begin(), labels.end()), labels.end()); if (!labels.empty()) { if (labels[0] != 1) { return false; @@ -98,14 +116,16 @@ class MorozovaSRunFuncTestsConnectedComponents : public ppc::util::BaseRunFuncTe return false; } } - if (std::cmp_not_equal(reported_max_label, labels.size())) { + if (static_cast(labels.size()) != reported_components) { return false; } - } else if (reported_max_label != 0) { + } else if (reported_components != 0) { return false; } + return true; } + InType GetTestInputData() final { return input_data_; } @@ -120,18 +140,21 @@ TEST_P(MorozovaSRunFuncTestsConnectedComponents, ConnectedComponentsTest) { ExecuteTest(GetParam()); } -const std::array kTestParam = {std::make_tuple(8, "cross"), std::make_tuple(10, "square"), - std::make_tuple(12, "dots")}; +const std::array kTestParam = {std::make_tuple(8, "cross"), std::make_tuple(10, "square"), + std::make_tuple(12, "dots"), std::make_tuple(6, "border")}; const auto kTestTasksList = std::tuple_cat(ppc::util::AddFuncTask( kTestParam, PPC_SETTINGS_morozova_s_connected_components), ppc::util::AddFuncTask( kTestParam, PPC_SETTINGS_morozova_s_connected_components)); + const auto kGtestValues = ppc::util::ExpandToValues(kTestTasksList); const auto kPerfTestName = MorozovaSRunFuncTestsConnectedComponents::PrintFuncTestName; + INSTANTIATE_TEST_SUITE_P(ConnectedComponentsTests, MorozovaSRunFuncTestsConnectedComponents, kGtestValues, kPerfTestName); + } // namespace } // namespace morozova_s_connected_components diff --git a/tasks/morozova_s_connected_components/tests/performance/main.cpp b/tasks/morozova_s_connected_components/tests/performance/main.cpp index c35fe11fad..1d190541a9 100644 --- a/tasks/morozova_s_connected_components/tests/performance/main.cpp +++ b/tasks/morozova_s_connected_components/tests/performance/main.cpp @@ -39,6 +39,12 @@ class MorozovaSRunPerfTestConnectedComponents : public ppc::util::BaseRunPerfTes } bool CheckTestOutputData(OutType &output_data) final { + if (output_data.empty()) { + return false; + } + if (!output_data.empty() && output_data.back().size() == 1) { + output_data.pop_back(); + } if (output_data.empty()) { return false; } @@ -75,7 +81,6 @@ class MorozovaSRunPerfTestConnectedComponents : public ppc::util::BaseRunPerfTes TEST_P(MorozovaSRunPerfTestConnectedComponents, RunPerfModes) { ExecuteTest(GetParam()); } - const auto kAllPerfTasks = ppc::util::MakeAllPerfTasks( PPC_SETTINGS_morozova_s_connected_components); From a04f7f2c8cd0b6dce3345e7977a098647b02fb27 Mon Sep 17 00:00:00 2001 From: SonyaMorozova Date: Tue, 3 Feb 2026 13:38:39 +0300 Subject: [PATCH 18/30] fix tidy 13 --- .../mpi/src/ops_mpi.cpp | 167 +++++++++--------- .../seq/include/ops_seq.hpp | 3 +- .../seq/src/ops_seq.cpp | 23 ++- 3 files changed, 96 insertions(+), 97 deletions(-) diff --git a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp index 3fc888a10a..4980b491c7 100644 --- a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp +++ b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp @@ -4,7 +4,6 @@ #include #include -#include #include #include #include @@ -25,7 +24,7 @@ bool MorozovaSConnectedComponentsMPI::ValidationImpl() { if (input.empty()) { return true; } - const std::size_t cols = input[0].size(); + const std::size_t cols = input.front().size(); for (const auto &row : input) { if (row.size() != cols) { return false; @@ -42,7 +41,14 @@ bool MorozovaSConnectedComponentsMPI::ValidationImpl() { bool MorozovaSConnectedComponentsMPI::PreProcessingImpl() { const auto &input = GetInput(); rows_ = static_cast(input.size()); - cols_ = static_cast(input[0].size()); + + if (rows_ == 0) { + cols_ = 0; + GetOutput().clear(); + return true; + } + + cols_ = static_cast(input.front().size()); grid_ = input; visited_.assign(rows_, std::vector(cols_, false)); GetOutput().assign(rows_, std::vector(cols_, 0)); @@ -53,6 +59,7 @@ std::vector> MorozovaSConnectedComponentsMPI::GetNeighbors(i std::vector> neighbors; const std::array dr = {-1, -1, -1, 0, 0, 1, 1, 1}; const std::array dc = {-1, 0, 1, -1, 1, -1, 0, 1}; + for (std::size_t k = 0; k < dr.size(); ++k) { const int nr = row + dr[k]; const int nc = col + dc[k]; @@ -68,6 +75,7 @@ void MorozovaSConnectedComponentsMPI::FloodFill(int row, int col, int label) { q.emplace(row, col); visited_[row][col] = true; GetOutput()[row][col] = label; + while (!q.empty()) { const auto [r, c] = q.front(); q.pop(); @@ -82,138 +90,123 @@ void MorozovaSConnectedComponentsMPI::FloodFill(int row, int col, int label) { } bool MorozovaSConnectedComponentsMPI::RunImpl() { - int rank, size; + int rank = 0; + int size = 1; MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); + + if (rows_ == 0 || cols_ == 0) { + return true; + } + int rows_per_proc = rows_ / size; int remainder = rows_ % size; int start_row = rank * rows_per_proc + std::min(rank, remainder); int end_row = start_row + rows_per_proc + (rank < remainder ? 1 : 0); + int base_label = rank * 1000000; int local_label = 1; + for (int i = start_row; i < end_row; ++i) { for (int j = 0; j < cols_; ++j) { if (grid_[i][j] == 1 && !visited_[i][j]) { FloodFill(i, j, base_label + local_label); - local_label++; + ++local_label; } } } + if (rank == 0) { for (int proc = 1; proc < size; ++proc) { - int proc_start_row = proc * rows_per_proc + std::min(proc, remainder); - int proc_end_row = proc_start_row + rows_per_proc + (proc < remainder ? 1 : 0); - int proc_rows = proc_end_row - proc_start_row; - std::vector recv_buffer(proc_rows * cols_); - MPI_Recv(recv_buffer.data(), proc_rows * cols_, MPI_INT, proc, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - for (int i = 0; i < proc_rows; ++i) { + int ps = proc * rows_per_proc + std::min(proc, remainder); + int pe = ps + rows_per_proc + (proc < remainder ? 1 : 0); + int pr = pe - ps; + + std::vector buf(pr * cols_); + MPI_Recv(buf.data(), pr * cols_, MPI_INT, proc, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + + for (int i = 0; i < pr; ++i) { for (int j = 0; j < cols_; ++j) { - GetOutput()[proc_start_row + i][j] = recv_buffer[i * cols_ + j]; + GetOutput()[ps + i][j] = buf[i * cols_ + j]; } } } - std::unordered_map label_map; - int next_label = 1; + + std::unordered_map parent; + for (int proc = 1; proc < size; ++proc) { - int boundary_row = proc * rows_per_proc + std::min(proc, remainder); - if (boundary_row > 0 && boundary_row < rows_) { - for (int j = 0; j < cols_; ++j) { - if (grid_[boundary_row - 1][j] == 1 && grid_[boundary_row][j] == 1) { - int upper_label = GetOutput()[boundary_row - 1][j]; - int lower_label = GetOutput()[boundary_row][j]; - if (upper_label != lower_label) { - int root_upper = upper_label; - while (label_map.find(root_upper) != label_map.end()) { - root_upper = label_map[root_upper]; - } - int root_lower = lower_label; - while (label_map.find(root_lower) != label_map.end()) { - root_lower = label_map[root_lower]; - } - if (root_upper != root_lower) { - int min_label = std::min(root_upper, root_lower); - int max_label = std::max(root_upper, root_lower); - label_map[max_label] = min_label; - } - } + int br = proc * rows_per_proc + std::min(proc, remainder); + if (br <= 0 || br >= rows_) { + continue; + } + + for (int j = 0; j < cols_; ++j) { + for (int dj = -1; dj <= 1; ++dj) { + int nj = j + dj; + if (nj < 0 || nj >= cols_) { + continue; } - } - for (int j = 0; j < cols_; ++j) { - if (grid_[boundary_row - 1][j] == 1) { - for (int dj = -1; dj <= 1; ++dj) { - int nj = j + dj; - if (nj >= 0 && nj < cols_ && grid_[boundary_row][nj] == 1) { - int upper_label = GetOutput()[boundary_row - 1][j]; - int lower_label = GetOutput()[boundary_row][nj]; - if (upper_label != lower_label) { - int root_upper = upper_label; - while (label_map.find(root_upper) != label_map.end()) { - root_upper = label_map[root_upper]; - } - int root_lower = lower_label; - while (label_map.find(root_lower) != label_map.end()) { - root_lower = label_map[root_lower]; - } - if (root_upper != root_lower) { - int min_label = std::min(root_upper, root_lower); - int max_label = std::max(root_upper, root_lower); - label_map[max_label] = min_label; - } - } - } + if (grid_[br - 1][j] == 1 && grid_[br][nj] == 1) { + int a = GetOutput()[br - 1][j]; + int b = GetOutput()[br][nj]; + if (a != b) { + parent[std::max(a, b)] = std::min(a, b); } } } } } + for (int i = 0; i < rows_; ++i) { for (int j = 0; j < cols_; ++j) { - if (GetOutput()[i][j] > 0) { - int label = GetOutput()[i][j]; - while (label_map.find(label) != label_map.end()) { - label = label_map[label]; - } - GetOutput()[i][j] = label; + int v = GetOutput()[i][j]; + while (parent.count(v)) { + v = parent[v]; } + GetOutput()[i][j] = v; } } - std::unordered_map final_label_map; - int current_label = 1; - for (int i = 0; i < rows_; ++i) { - for (int j = 0; j < cols_; ++j) { - if (GetOutput()[i][j] > 0) { - int old_label = GetOutput()[i][j]; - if (final_label_map.find(old_label) == final_label_map.end()) { - final_label_map[old_label] = current_label++; + + std::unordered_map remap; + int next = 1; + for (auto &row : GetOutput()) { + for (int &v : row) { + if (v > 0) { + if (!remap.count(v)) { + remap[v] = next++; } - GetOutput()[i][j] = final_label_map[old_label]; + v = remap[v]; } } } - std::vector send_buffer(rows_ * cols_); + + std::vector full(rows_ * cols_); for (int i = 0; i < rows_; ++i) { for (int j = 0; j < cols_; ++j) { - send_buffer[i * cols_ + j] = GetOutput()[i][j]; + full[i * cols_ + j] = GetOutput()[i][j]; } } for (int proc = 1; proc < size; ++proc) { - MPI_Send(send_buffer.data(), rows_ * cols_, MPI_INT, proc, 1, MPI_COMM_WORLD); + MPI_Send(full.data(), rows_ * cols_, MPI_INT, proc, 1, MPI_COMM_WORLD); } } else { - int local_rows = end_row - start_row; - std::vector send_buffer(local_rows * cols_); - for (int i = 0; i < local_rows; ++i) { + int lr = end_row - start_row; + std::vector send(lr * cols_); + for (int i = 0; i < lr; ++i) { for (int j = 0; j < cols_; ++j) { - send_buffer[i * cols_ + j] = GetOutput()[start_row + i][j]; + send[i * cols_ + j] = GetOutput()[start_row + i][j]; } } - MPI_Send(send_buffer.data(), local_rows * cols_, MPI_INT, 0, 0, MPI_COMM_WORLD); - std::vector recv_buffer(rows_ * cols_); - MPI_Recv(recv_buffer.data(), rows_ * cols_, MPI_INT, 0, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + + MPI_Send(send.data(), lr * cols_, MPI_INT, 0, 0, MPI_COMM_WORLD); + + std::vector recv(rows_ * cols_); + MPI_Recv(recv.data(), rows_ * cols_, MPI_INT, 0, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + for (int i = 0; i < rows_; ++i) { for (int j = 0; j < cols_; ++j) { - GetOutput()[i][j] = recv_buffer[i * cols_ + j]; + GetOutput()[i][j] = recv[i * cols_ + j]; } } } @@ -225,9 +218,7 @@ bool MorozovaSConnectedComponentsMPI::PostProcessingImpl() { int max_label = 0; for (const auto &row : GetOutput()) { for (int v : row) { - if (v > max_label) { - max_label = v; - } + max_label = std::max(max_label, v); } } GetOutput().push_back({max_label}); diff --git a/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp b/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp index 8766d76c5e..9a11de8750 100644 --- a/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp +++ b/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include "morozova_s_connected_components/common/include/common.hpp" @@ -20,6 +19,7 @@ class MorozovaSConnectedComponentsSEQ : public BaseTask { bool PreProcessingImpl() override; bool RunImpl() override; bool PostProcessingImpl() override; + void LabelComponents(); void DFSLabeling(int row, int col, int label); @@ -28,4 +28,5 @@ class MorozovaSConnectedComponentsSEQ : public BaseTask { int rows_{0}; int cols_{0}; }; + } // namespace morozova_s_connected_components diff --git a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp index 280f6902a8..28118e41df 100644 --- a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp +++ b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp @@ -14,15 +14,13 @@ std::vector> GetNeighborsSeq(int r, int c, int rows, int col constexpr std::array, 8> shifts = { {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}}}; std::vector> result; - result.reserve(8); for (const auto &sh : shifts) { - const int nr = r + sh.first; - const int nc = c + sh.second; + int nr = r + sh.first; + int nc = c + sh.second; if (nr >= 0 && nr < rows && nc >= 0 && nc < cols) { result.emplace_back(nr, nc); } } - return result; } @@ -40,7 +38,17 @@ bool MorozovaSConnectedComponentsSEQ::ValidationImpl() { return true; } const std::size_t cols = input.front().size(); - return std::all_of(input.begin(), input.end(), [cols](const std::vector &row) { return row.size() == cols; }); + for (const auto &row : input) { + if (row.size() != cols) { + return false; + } + for (int v : row) { + if (v != 0 && v != 1) { + return false; + } + } + } + return true; } bool MorozovaSConnectedComponentsSEQ::PreProcessingImpl() { @@ -48,6 +56,7 @@ bool MorozovaSConnectedComponentsSEQ::PreProcessingImpl() { rows_ = static_cast(grid_.size()); if (rows_ == 0) { cols_ = 0; + GetOutput().clear(); return true; } cols_ = static_cast(grid_.front().size()); @@ -95,9 +104,7 @@ bool MorozovaSConnectedComponentsSEQ::PostProcessingImpl() { int max_label = 0; for (const auto &row : GetOutput()) { for (int v : row) { - if (v > max_label) { - max_label = v; - } + max_label = std::max(max_label, v); } } GetOutput().push_back({max_label}); From c5e5e1a335f453cdd32da1c8c2fc6dacefc63f7b Mon Sep 17 00:00:00 2001 From: SonyaMorozova Date: Tue, 3 Feb 2026 14:50:51 +0300 Subject: [PATCH 19/30] fix tidy 14 --- .../mpi/include/ops_mpi.hpp | 21 +- .../mpi/src/ops_mpi.cpp | 215 ++++++++++-------- .../seq/src/ops_seq.cpp | 88 ++++--- 3 files changed, 186 insertions(+), 138 deletions(-) diff --git a/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp b/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp index d763c74c7f..97193bbf96 100644 --- a/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp +++ b/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp @@ -4,7 +4,6 @@ #include #include "morozova_s_connected_components/common/include/common.hpp" -#include "task/include/task.hpp" namespace morozova_s_connected_components { @@ -25,10 +24,26 @@ class MorozovaSConnectedComponentsMPI : public BaseTask { void FloodFill(int row, int col, int label); [[nodiscard]] std::vector> GetNeighbors(int row, int col) const; - std::vector> grid_; - std::vector> visited_; + void InitMPI(); + std::pair ComputeRowRange() const; + void ComputeLocalComponents(int start_row, int end_row, int base_label); + void GatherLocalResults(); + void MergeBoundaries(); + void CompressLabels(); + void NormalizeLabels(); + void BroadcastResult(); + void SendLocalResult(int start_row, int end_row); + void ReceiveFinalResult(); + + int rank_{0}; + int size_{1}; int rows_{0}; int cols_{0}; + int rows_per_proc_{0}; + int remainder_{0}; + + std::vector> grid_; + std::vector> visited_; }; } // namespace morozova_s_connected_components diff --git a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp index 4980b491c7..46289a799b 100644 --- a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp +++ b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp @@ -13,6 +13,13 @@ namespace morozova_s_connected_components { +namespace { +constexpr int kLabelOffset = 1000000; + +constexpr std::array, 8> kShifts = { + {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}}}; +} // namespace + MorozovaSConnectedComponentsMPI::MorozovaSConnectedComponentsMPI(const InType &in) { SetTypeOfTask(GetStaticTypeOfTask()); GetInput() = in; @@ -55,14 +62,24 @@ bool MorozovaSConnectedComponentsMPI::PreProcessingImpl() { return true; } +void MorozovaSConnectedComponentsMPI::InitMPI() { + MPI_Comm_rank(MPI_COMM_WORLD, &rank_); + MPI_Comm_size(MPI_COMM_WORLD, &size_); + rows_per_proc_ = rows_ / size_; + remainder_ = rows_ % size_; +} + +std::pair MorozovaSConnectedComponentsMPI::ComputeRowRange() const { + const int start = (rank_ * rows_per_proc_) + std::min(rank_, remainder_); + const int end = start + rows_per_proc_ + (rank_ < remainder_ ? 1 : 0); + return {start, end}; +} + std::vector> MorozovaSConnectedComponentsMPI::GetNeighbors(int row, int col) const { std::vector> neighbors; - const std::array dr = {-1, -1, -1, 0, 0, 1, 1, 1}; - const std::array dc = {-1, 0, 1, -1, 1, -1, 0, 1}; - - for (std::size_t k = 0; k < dr.size(); ++k) { - const int nr = row + dr[k]; - const int nc = col + dc[k]; + for (const auto &[dr, dc] : kShifts) { + const int nr = row + dr; + const int nc = col + dc; if (nr >= 0 && nr < rows_ && nc >= 0 && nc < cols_ && grid_[nr][nc] == 1) { neighbors.emplace_back(nr, nc); } @@ -89,24 +106,8 @@ void MorozovaSConnectedComponentsMPI::FloodFill(int row, int col, int label) { } } -bool MorozovaSConnectedComponentsMPI::RunImpl() { - int rank = 0; - int size = 1; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - MPI_Comm_size(MPI_COMM_WORLD, &size); - - if (rows_ == 0 || cols_ == 0) { - return true; - } - - int rows_per_proc = rows_ / size; - int remainder = rows_ % size; - int start_row = rank * rows_per_proc + std::min(rank, remainder); - int end_row = start_row + rows_per_proc + (rank < remainder ? 1 : 0); - - int base_label = rank * 1000000; +void MorozovaSConnectedComponentsMPI::ComputeLocalComponents(int start_row, int end_row, int base_label) { int local_label = 1; - for (int i = start_row; i < end_row; ++i) { for (int j = 0; j < cols_; ++j) { if (grid_[i][j] == 1 && !visited_[i][j]) { @@ -115,100 +116,134 @@ bool MorozovaSConnectedComponentsMPI::RunImpl() { } } } +} - if (rank == 0) { - for (int proc = 1; proc < size; ++proc) { - int ps = proc * rows_per_proc + std::min(proc, remainder); - int pe = ps + rows_per_proc + (proc < remainder ? 1 : 0); - int pr = pe - ps; +void MorozovaSConnectedComponentsMPI::GatherLocalResults() { + for (int proc = 1; proc < size_; ++proc) { + const int ps = (proc * rows_per_proc_) + std::min(proc, remainder_); + const int pe = ps + rows_per_proc_ + (proc < remainder_ ? 1 : 0); + const int pr = pe - ps; - std::vector buf(pr * cols_); - MPI_Recv(buf.data(), pr * cols_, MPI_INT, proc, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + std::vector buf(static_cast(pr) * static_cast(cols_)); + MPI_Recv(buf.data(), static_cast(buf.size()), MPI_INT, proc, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - for (int i = 0; i < pr; ++i) { - for (int j = 0; j < cols_; ++j) { - GetOutput()[ps + i][j] = buf[i * cols_ + j]; - } + for (int i = 0; i < pr; ++i) { + for (int j = 0; j < cols_; ++j) { + GetOutput()[ps + i][j] = + buf[static_cast(i) * static_cast(cols_) + static_cast(j)]; } } + } +} - std::unordered_map parent; +void MorozovaSConnectedComponentsMPI::MergeBoundaries() { + std::unordered_map parent; - for (int proc = 1; proc < size; ++proc) { - int br = proc * rows_per_proc + std::min(proc, remainder); - if (br <= 0 || br >= rows_) { - continue; - } + for (int proc = 1; proc < size_; ++proc) { + const int br = (proc * rows_per_proc_) + std::min(proc, remainder_); + if (br <= 0 || br >= rows_) { + continue; + } - for (int j = 0; j < cols_; ++j) { - for (int dj = -1; dj <= 1; ++dj) { - int nj = j + dj; - if (nj < 0 || nj >= cols_) { - continue; - } - if (grid_[br - 1][j] == 1 && grid_[br][nj] == 1) { - int a = GetOutput()[br - 1][j]; - int b = GetOutput()[br][nj]; - if (a != b) { - parent[std::max(a, b)] = std::min(a, b); - } + for (int j = 0; j < cols_; ++j) { + for (int dj = -1; dj <= 1; ++dj) { + const int nj = j + dj; + if (nj < 0 || nj >= cols_) { + continue; + } + if (grid_[br - 1][j] == 1 && grid_[br][nj] == 1) { + const int a = GetOutput()[br - 1][j]; + const int b = GetOutput()[br][nj]; + if (a != b) { + parent[std::max(a, b)] = std::min(a, b); } } } } + } - for (int i = 0; i < rows_; ++i) { - for (int j = 0; j < cols_; ++j) { - int v = GetOutput()[i][j]; - while (parent.count(v)) { - v = parent[v]; - } - GetOutput()[i][j] = v; + for (int i = 0; i < rows_; ++i) { + for (int j = 0; j < cols_; ++j) { + int v = GetOutput()[i][j]; + while (parent.contains(v)) { + v = parent[v]; } + GetOutput()[i][j] = v; } + } +} - std::unordered_map remap; - int next = 1; - for (auto &row : GetOutput()) { - for (int &v : row) { - if (v > 0) { - if (!remap.count(v)) { - remap[v] = next++; - } - v = remap[v]; +void MorozovaSConnectedComponentsMPI::NormalizeLabels() { + std::unordered_map remap; + int next = 1; + for (auto &row : GetOutput()) { + for (int &v : row) { + if (v > 0) { + if (!remap.contains(v)) { + remap[v] = next++; } + v = remap[v]; } } + } +} - std::vector full(rows_ * cols_); - for (int i = 0; i < rows_; ++i) { - for (int j = 0; j < cols_; ++j) { - full[i * cols_ + j] = GetOutput()[i][j]; - } +void MorozovaSConnectedComponentsMPI::BroadcastResult() { + std::vector flat(static_cast(rows_) * static_cast(cols_)); + for (int i = 0; i < rows_; ++i) { + for (int j = 0; j < cols_; ++j) { + flat[static_cast(i) * static_cast(cols_) + static_cast(j)] = + GetOutput()[i][j]; } + } - for (int proc = 1; proc < size; ++proc) { - MPI_Send(full.data(), rows_ * cols_, MPI_INT, proc, 1, MPI_COMM_WORLD); + for (int proc = 1; proc < size_; ++proc) { + MPI_Send(flat.data(), static_cast(flat.size()), MPI_INT, proc, 1, MPI_COMM_WORLD); + } +} + +void MorozovaSConnectedComponentsMPI::SendLocalResult(int start_row, int end_row) { + const int lr = end_row - start_row; + std::vector send(static_cast(lr) * static_cast(cols_)); + for (int i = 0; i < lr; ++i) { + for (int j = 0; j < cols_; ++j) { + send[static_cast(i) * static_cast(cols_) + static_cast(j)] = + GetOutput()[start_row + i][j]; } - } else { - int lr = end_row - start_row; - std::vector send(lr * cols_); - for (int i = 0; i < lr; ++i) { - for (int j = 0; j < cols_; ++j) { - send[i * cols_ + j] = GetOutput()[start_row + i][j]; - } + } + MPI_Send(send.data(), static_cast(send.size()), MPI_INT, 0, 0, MPI_COMM_WORLD); +} + +void MorozovaSConnectedComponentsMPI::ReceiveFinalResult() { + std::vector recv(static_cast(rows_) * static_cast(cols_)); + MPI_Recv(recv.data(), static_cast(recv.size()), MPI_INT, 0, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + + for (int i = 0; i < rows_; ++i) { + for (int j = 0; j < cols_; ++j) { + GetOutput()[i][j] = + recv[static_cast(i) * static_cast(cols_) + static_cast(j)]; } + } +} - MPI_Send(send.data(), lr * cols_, MPI_INT, 0, 0, MPI_COMM_WORLD); +bool MorozovaSConnectedComponentsMPI::RunImpl() { + InitMPI(); - std::vector recv(rows_ * cols_); - MPI_Recv(recv.data(), rows_ * cols_, MPI_INT, 0, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + if (rows_ == 0 || cols_ == 0) { + return true; + } - for (int i = 0; i < rows_; ++i) { - for (int j = 0; j < cols_; ++j) { - GetOutput()[i][j] = recv[i * cols_ + j]; - } - } + const auto [start, end] = ComputeRowRange(); + ComputeLocalComponents(start, end, rank_ * kLabelOffset); + + if (rank_ == 0) { + GatherLocalResults(); + MergeBoundaries(); + NormalizeLabels(); + BroadcastResult(); + } else { + SendLocalResult(start, end); + ReceiveFinalResult(); } return true; diff --git a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp index 28118e41df..a02f1d1fa4 100644 --- a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp +++ b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp @@ -1,6 +1,8 @@ #include "morozova_s_connected_components/seq/include/ops_seq.hpp" +#include #include +#include #include #include #include @@ -8,35 +10,20 @@ #include "morozova_s_connected_components/common/include/common.hpp" namespace morozova_s_connected_components { + namespace { -std::vector> GetNeighborsSeq(int r, int c, int rows, int cols) { - constexpr std::array, 8> shifts = { - {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}}}; - std::vector> result; - for (const auto &sh : shifts) { - int nr = r + sh.first; - int nc = c + sh.second; - if (nr >= 0 && nr < rows && nc >= 0 && nc < cols) { - result.emplace_back(nr, nc); - } - } - return result; -} +constexpr std::array, 8> kShifts = { + {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}}}; } // namespace -MorozovaSConnectedComponentsSEQ::MorozovaSConnectedComponentsSEQ(const InType &in) { - SetTypeOfTask(GetStaticTypeOfTask()); - GetInput() = in; - GetOutput() = {}; -} - bool MorozovaSConnectedComponentsSEQ::ValidationImpl() { const auto &input = GetInput(); if (input.empty()) { return true; } + const std::size_t cols = input.front().size(); for (const auto &row : input) { if (row.size() != cols) { @@ -52,51 +39,61 @@ bool MorozovaSConnectedComponentsSEQ::ValidationImpl() { } bool MorozovaSConnectedComponentsSEQ::PreProcessingImpl() { - grid_ = GetInput(); - rows_ = static_cast(grid_.size()); + const auto &input = GetInput(); + + rows_ = static_cast(input.size()); if (rows_ == 0) { cols_ = 0; GetOutput().clear(); return true; } - cols_ = static_cast(grid_.front().size()); + + cols_ = static_cast(input.front().size()); + grid_ = input; visited_.assign(rows_, std::vector(cols_, false)); GetOutput().assign(rows_, std::vector(cols_, 0)); return true; } -void MorozovaSConnectedComponentsSEQ::DFSLabeling(int row, int col, int label) { - std::queue> q; - q.emplace(row, col); - visited_[row][col] = true; - GetOutput()[row][col] = label; - while (!q.empty()) { - const auto [r, c] = q.front(); - q.pop(); - for (const auto &[nr, nc] : GetNeighborsSeq(r, c, rows_, cols_)) { - if (!visited_[nr][nc] && grid_[nr][nc] == 1) { - visited_[nr][nc] = true; - GetOutput()[nr][nc] = label; - q.emplace(nr, nc); - } - } +bool MorozovaSConnectedComponentsSEQ::RunImpl() { + if (rows_ == 0 || cols_ == 0) { + return true; } -} -void MorozovaSConnectedComponentsSEQ::LabelComponents() { - int label = 1; + int current_label = 0; + for (int i = 0; i < rows_; ++i) { for (int j = 0; j < cols_; ++j) { if (grid_[i][j] == 1 && !visited_[i][j]) { - DFSLabeling(i, j, label); - ++label; + ++current_label; + std::queue> q; + q.emplace(i, j); + visited_[i][j] = true; + GetOutput()[i][j] = current_label; + + while (!q.empty()) { + const auto [r, c] = q.front(); + q.pop(); + + for (const auto &[dr, dc] : kShifts) { + const int nr = r + dr; + const int nc = c + dc; + + if (nr < 0 || nr >= rows_ || nc < 0 || nc >= cols_) { + continue; + } + + if (grid_[nr][nc] == 1 && !visited_[nr][nc]) { + visited_[nr][nc] = true; + GetOutput()[nr][nc] = current_label; + q.emplace(nr, nc); + } + } + } } } } -} -bool MorozovaSConnectedComponentsSEQ::RunImpl() { - LabelComponents(); return true; } @@ -107,6 +104,7 @@ bool MorozovaSConnectedComponentsSEQ::PostProcessingImpl() { max_label = std::max(max_label, v); } } + GetOutput().push_back({max_label}); return true; } From 8d4efe1b75bbaad0381e3d5a500d043c822cde64 Mon Sep 17 00:00:00 2001 From: SonyaMorozova Date: Tue, 3 Feb 2026 15:58:23 +0300 Subject: [PATCH 20/30] fix seq 2 --- .../seq/src/ops_seq.cpp | 80 ++++++++----------- 1 file changed, 32 insertions(+), 48 deletions(-) diff --git a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp index a02f1d1fa4..8ce0a1fcf8 100644 --- a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp +++ b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp @@ -10,9 +10,12 @@ #include "morozova_s_connected_components/common/include/common.hpp" namespace morozova_s_connected_components { +MorozovaSConnectedComponentsSEQ::MorozovaSConnectedComponentsSEQ(const InType &in) : BaseTask() { + SetTypeOfTask(GetStaticTypeOfTask()); + GetInput() = in; +} namespace { - constexpr std::array, 8> kShifts = { {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}}}; @@ -21,91 +24,72 @@ constexpr std::array, 8> kShifts = { bool MorozovaSConnectedComponentsSEQ::ValidationImpl() { const auto &input = GetInput(); if (input.empty()) { - return true; + return false; } - const std::size_t cols = input.front().size(); + if (cols == 0) { + return false; + } for (const auto &row : input) { if (row.size() != cols) { return false; } - for (int v : row) { - if (v != 0 && v != 1) { - return false; - } - } } return true; } bool MorozovaSConnectedComponentsSEQ::PreProcessingImpl() { const auto &input = GetInput(); - - rows_ = static_cast(input.size()); - if (rows_ == 0) { - cols_ = 0; - GetOutput().clear(); - return true; - } - - cols_ = static_cast(input.front().size()); - grid_ = input; - visited_.assign(rows_, std::vector(cols_, false)); - GetOutput().assign(rows_, std::vector(cols_, 0)); + rows_ = input.size(); + cols_ = input.front().size(); + labels_.assign(rows_, std::vector(cols_, 0)); return true; } bool MorozovaSConnectedComponentsSEQ::RunImpl() { - if (rows_ == 0 || cols_ == 0) { - return true; - } - + const auto &input = GetInput(); int current_label = 0; - for (int i = 0; i < rows_; ++i) { - for (int j = 0; j < cols_; ++j) { - if (grid_[i][j] == 1 && !visited_[i][j]) { + for (std::size_t i = 0; i < rows_; ++i) { + for (std::size_t j = 0; j < cols_; ++j) { + if (input[i][j] != 0 && labels_[i][j] == 0) { ++current_label; - std::queue> q; + std::queue> q; q.emplace(i, j); - visited_[i][j] = true; - GetOutput()[i][j] = current_label; + labels_[i][j] = current_label; while (!q.empty()) { - const auto [r, c] = q.front(); + const auto [x, y] = q.front(); q.pop(); - for (const auto &[dr, dc] : kShifts) { - const int nr = r + dr; - const int nc = c + dc; - - if (nr < 0 || nr >= rows_ || nc < 0 || nc >= cols_) { - continue; - } - - if (grid_[nr][nc] == 1 && !visited_[nr][nc]) { - visited_[nr][nc] = true; - GetOutput()[nr][nc] = current_label; - q.emplace(nr, nc); + for (const auto &[dx, dy] : kShifts) { + const int nx = static_cast(x) + dx; + const int ny = static_cast(y) + dy; + + if (nx >= 0 && ny >= 0 && nx < static_cast(rows_) && ny < static_cast(cols_)) { + const auto ux = static_cast(nx); + const auto uy = static_cast(ny); + if (input[ux][uy] != 0 && labels_[ux][uy] == 0) { + labels_[ux][uy] = current_label; + q.emplace(ux, uy); + } } } } } } } - return true; } bool MorozovaSConnectedComponentsSEQ::PostProcessingImpl() { int max_label = 0; - for (const auto &row : GetOutput()) { - for (int v : row) { + for (const auto &row : labels_) { + for (const int v : row) { max_label = std::max(max_label, v); } } - - GetOutput().push_back({max_label}); + GetOutput() = max_label; return true; } From bb562c609b249d2824e9ebcae30fb7d3e287de5f Mon Sep 17 00:00:00 2001 From: SonyaMorozova Date: Tue, 3 Feb 2026 17:03:05 +0300 Subject: [PATCH 21/30] fix seq 2 --- .../seq/src/ops_seq.cpp | 49 +++++++++---------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp index 8ce0a1fcf8..141443d667 100644 --- a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp +++ b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp @@ -16,6 +16,7 @@ MorozovaSConnectedComponentsSEQ::MorozovaSConnectedComponentsSEQ(const InType &i } namespace { + constexpr std::array, 8> kShifts = { {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}}}; @@ -39,58 +40,56 @@ bool MorozovaSConnectedComponentsSEQ::ValidationImpl() { } bool MorozovaSConnectedComponentsSEQ::PreProcessingImpl() { - const auto &input = GetInput(); - rows_ = input.size(); - cols_ = input.front().size(); - labels_.assign(rows_, std::vector(cols_, 0)); + GetOutput().assign(GetInput().size(), std::vector(GetInput().front().size(), 0)); return true; } bool MorozovaSConnectedComponentsSEQ::RunImpl() { const auto &input = GetInput(); - int current_label = 0; + auto &output = GetOutput(); - for (std::size_t i = 0; i < rows_; ++i) { - for (std::size_t j = 0; j < cols_; ++j) { - if (input[i][j] != 0 && labels_[i][j] == 0) { - ++current_label; - std::queue> q; - q.emplace(i, j); - labels_[i][j] = current_label; + const int rows = static_cast(input.size()); + const int cols = static_cast(input.front().size()); + + int current_label = 1; + std::queue> q; + + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < cols; ++j) { + if (input[i][j] != 0 && output[i][j] == 0) { + output[i][j] = current_label; + q.push({i, j}); while (!q.empty()) { const auto [x, y] = q.front(); q.pop(); for (const auto &[dx, dy] : kShifts) { - const int nx = static_cast(x) + dx; - const int ny = static_cast(y) + dy; - - if (nx >= 0 && ny >= 0 && nx < static_cast(rows_) && ny < static_cast(cols_)) { - const auto ux = static_cast(nx); - const auto uy = static_cast(ny); - if (input[ux][uy] != 0 && labels_[ux][uy] == 0) { - labels_[ux][uy] = current_label; - q.emplace(ux, uy); - } + const int nx = x + dx; + const int ny = y + dy; + + if (nx >= 0 && nx < rows && ny >= 0 && ny < cols && input[nx][ny] != 0 && output[nx][ny] == 0) { + output[nx][ny] = current_label; + q.push({nx, ny}); } } } + ++current_label; } } } + return true; } bool MorozovaSConnectedComponentsSEQ::PostProcessingImpl() { int max_label = 0; - for (const auto &row : labels_) { + for (const auto &row : GetOutput()) { for (const int v : row) { max_label = std::max(max_label, v); } } - GetOutput() = max_label; - return true; + return max_label > 0; } } // namespace morozova_s_connected_components From f9272c3b3d209d008d239bc7862871dbb0077271 Mon Sep 17 00:00:00 2001 From: SonyaMorozova Date: Tue, 3 Feb 2026 18:15:04 +0300 Subject: [PATCH 22/30] fix tidy 15 --- .../mpi/include/ops_mpi.hpp | 4 +++- .../mpi/src/ops_mpi.cpp | 21 ++++++++++++------- .../seq/src/ops_seq.cpp | 11 +++------- .../tests/functional/main.cpp | 10 ++++----- 4 files changed, 24 insertions(+), 22 deletions(-) diff --git a/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp b/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp index 97193bbf96..19298a5513 100644 --- a/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp +++ b/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp @@ -1,9 +1,11 @@ #pragma once +#include #include #include #include "morozova_s_connected_components/common/include/common.hpp" +#include "task/include/task.hpp" namespace morozova_s_connected_components { @@ -25,7 +27,7 @@ class MorozovaSConnectedComponentsMPI : public BaseTask { [[nodiscard]] std::vector> GetNeighbors(int row, int col) const; void InitMPI(); - std::pair ComputeRowRange() const; + [[nodiscard]] std::pair ComputeRowRange() const; void ComputeLocalComponents(int start_row, int end_row, int base_label); void GatherLocalResults(); void MergeBoundaries(); diff --git a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp index 46289a799b..77803d5b11 100644 --- a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp +++ b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -129,8 +130,9 @@ void MorozovaSConnectedComponentsMPI::GatherLocalResults() { for (int i = 0; i < pr; ++i) { for (int j = 0; j < cols_; ++j) { - GetOutput()[ps + i][j] = - buf[static_cast(i) * static_cast(cols_) + static_cast(j)]; + const std::size_t idx = + (static_cast(i) * static_cast(cols_)) + static_cast(j); + GetOutput()[ps + i][j] = buf[idx]; } } } @@ -192,8 +194,9 @@ void MorozovaSConnectedComponentsMPI::BroadcastResult() { std::vector flat(static_cast(rows_) * static_cast(cols_)); for (int i = 0; i < rows_; ++i) { for (int j = 0; j < cols_; ++j) { - flat[static_cast(i) * static_cast(cols_) + static_cast(j)] = - GetOutput()[i][j]; + const std::size_t idx = + (static_cast(i) * static_cast(cols_)) + static_cast(j); + flat[idx] = GetOutput()[i][j]; } } @@ -207,8 +210,9 @@ void MorozovaSConnectedComponentsMPI::SendLocalResult(int start_row, int end_row std::vector send(static_cast(lr) * static_cast(cols_)); for (int i = 0; i < lr; ++i) { for (int j = 0; j < cols_; ++j) { - send[static_cast(i) * static_cast(cols_) + static_cast(j)] = - GetOutput()[start_row + i][j]; + const std::size_t idx = + (static_cast(i) * static_cast(cols_)) + static_cast(j); + send[idx] = GetOutput()[start_row + i][j]; } } MPI_Send(send.data(), static_cast(send.size()), MPI_INT, 0, 0, MPI_COMM_WORLD); @@ -220,8 +224,9 @@ void MorozovaSConnectedComponentsMPI::ReceiveFinalResult() { for (int i = 0; i < rows_; ++i) { for (int j = 0; j < cols_; ++j) { - GetOutput()[i][j] = - recv[static_cast(i) * static_cast(cols_) + static_cast(j)]; + const std::size_t idx = + (static_cast(i) * static_cast(cols_)) + static_cast(j); + GetOutput()[i][j] = recv[idx]; } } } diff --git a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp index 141443d667..1efbaeb504 100644 --- a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp +++ b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp @@ -31,12 +31,7 @@ bool MorozovaSConnectedComponentsSEQ::ValidationImpl() { if (cols == 0) { return false; } - for (const auto &row : input) { - if (row.size() != cols) { - return false; - } - } - return true; + return std::ranges::all_of(input, [cols](const auto &row) { return row.size() == cols; }); } bool MorozovaSConnectedComponentsSEQ::PreProcessingImpl() { @@ -58,7 +53,7 @@ bool MorozovaSConnectedComponentsSEQ::RunImpl() { for (int j = 0; j < cols; ++j) { if (input[i][j] != 0 && output[i][j] == 0) { output[i][j] = current_label; - q.push({i, j}); + q.emplace(i, j); while (!q.empty()) { const auto [x, y] = q.front(); @@ -70,7 +65,7 @@ bool MorozovaSConnectedComponentsSEQ::RunImpl() { if (nx >= 0 && nx < rows && ny >= 0 && ny < cols && input[nx][ny] != 0 && output[nx][ny] == 0) { output[nx][ny] = current_label; - q.push({nx, ny}); + q.emplace(nx, ny); } } } diff --git a/tasks/morozova_s_connected_components/tests/functional/main.cpp b/tasks/morozova_s_connected_components/tests/functional/main.cpp index 54556c97ab..29c91b549a 100644 --- a/tasks/morozova_s_connected_components/tests/functional/main.cpp +++ b/tasks/morozova_s_connected_components/tests/functional/main.cpp @@ -1,12 +1,10 @@ #include -#include #include #include #include #include #include -#include #include #include "morozova_s_connected_components/common/include/common.hpp" @@ -105,8 +103,10 @@ class MorozovaSRunFuncTestsConnectedComponents : public ppc::util::BaseRunFuncTe } } } - std::sort(labels.begin(), labels.end()); - labels.erase(std::unique(labels.begin(), labels.end()), labels.end()); + std::ranges::sort(labels); + const auto [first, last] = std::ranges::unique(labels); + labels.erase(first, last); + if (!labels.empty()) { if (labels[0] != 1) { return false; @@ -116,7 +116,7 @@ class MorozovaSRunFuncTestsConnectedComponents : public ppc::util::BaseRunFuncTe return false; } } - if (static_cast(labels.size()) != reported_components) { + if (!std::cmp_equal(labels.size(), reported_components)) { return false; } } else if (reported_components != 0) { From 81ce19f1a7ec4bd9d41e54f941d6ba6574002142 Mon Sep 17 00:00:00 2001 From: SonyaMorozova Date: Wed, 4 Feb 2026 14:32:06 +0300 Subject: [PATCH 23/30] fix tidy 16 --- .../mpi/include/ops_mpi.hpp | 1 - .../mpi/src/ops_mpi.cpp | 23 +++++++--- .../seq/src/ops_seq.cpp | 45 +++++++++++-------- .../tests/functional/main.cpp | 1 + 4 files changed, 43 insertions(+), 27 deletions(-) diff --git a/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp b/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp index 19298a5513..9e4605506f 100644 --- a/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp +++ b/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include diff --git a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp index 77803d5b11..4d05e0c46c 100644 --- a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp +++ b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp @@ -4,7 +4,6 @@ #include #include -#include #include #include #include @@ -141,10 +140,10 @@ void MorozovaSConnectedComponentsMPI::GatherLocalResults() { void MorozovaSConnectedComponentsMPI::MergeBoundaries() { std::unordered_map parent; - for (int proc = 1; proc < size_; ++proc) { + auto ProcessBoundary = [&](int proc) { const int br = (proc * rows_per_proc_) + std::min(proc, remainder_); if (br <= 0 || br >= rows_) { - continue; + return; } for (int j = 0; j < cols_; ++j) { @@ -162,15 +161,25 @@ void MorozovaSConnectedComponentsMPI::MergeBoundaries() { } } } + }; + + for (int proc = 1; proc < size_; ++proc) { + ProcessBoundary(proc); } + auto FindRoot = [&](int v) -> int { + while (parent.contains(v)) { + v = parent[v]; + } + return v; + }; + for (int i = 0; i < rows_; ++i) { for (int j = 0; j < cols_; ++j) { - int v = GetOutput()[i][j]; - while (parent.contains(v)) { - v = parent[v]; + int &v = GetOutput()[i][j]; + if (v > 0) { + v = FindRoot(v); } - GetOutput()[i][j] = v; } } } diff --git a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp index 1efbaeb504..f2794d1017 100644 --- a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp +++ b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp @@ -2,7 +2,6 @@ #include #include -#include #include #include #include @@ -47,28 +46,36 @@ bool MorozovaSConnectedComponentsSEQ::RunImpl() { const int cols = static_cast(input.front().size()); int current_label = 1; - std::queue> q; + + auto IsValidNeighbor = [&](int nx, int ny) -> bool { + return nx >= 0 && nx < rows && ny >= 0 && ny < cols && input[nx][ny] != 0 && output[nx][ny] == 0; + }; + + auto FloodFill = [&](int start_i, int start_j, int label) { + std::queue> q; + q.emplace(start_i, start_j); + output[start_i][start_j] = label; + + while (!q.empty()) { + const auto [x, y] = q.front(); + q.pop(); + + for (const auto &[dx, dy] : kShifts) { + const int nx = x + dx; + const int ny = y + dy; + + if (IsValidNeighbor(nx, ny)) { + output[nx][ny] = label; + q.emplace(nx, ny); + } + } + } + }; for (int i = 0; i < rows; ++i) { for (int j = 0; j < cols; ++j) { if (input[i][j] != 0 && output[i][j] == 0) { - output[i][j] = current_label; - q.emplace(i, j); - - while (!q.empty()) { - const auto [x, y] = q.front(); - q.pop(); - - for (const auto &[dx, dy] : kShifts) { - const int nx = x + dx; - const int ny = y + dy; - - if (nx >= 0 && nx < rows && ny >= 0 && ny < cols && input[nx][ny] != 0 && output[nx][ny] == 0) { - output[nx][ny] = current_label; - q.emplace(nx, ny); - } - } - } + FloodFill(i, j, current_label); ++current_label; } } diff --git a/tasks/morozova_s_connected_components/tests/functional/main.cpp b/tasks/morozova_s_connected_components/tests/functional/main.cpp index 29c91b549a..144d910ce5 100644 --- a/tasks/morozova_s_connected_components/tests/functional/main.cpp +++ b/tasks/morozova_s_connected_components/tests/functional/main.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include From 39b9f93e39a6d907084dea76626d44557d4ee618 Mon Sep 17 00:00:00 2001 From: SonyaMorozova Date: Wed, 4 Feb 2026 15:35:13 +0300 Subject: [PATCH 24/30] fix tidy 17 --- .../mpi/src/ops_mpi.cpp | 86 ++++++++++--------- .../seq/src/ops_seq.cpp | 47 +++++----- .../tests/functional/main.cpp | 3 +- 3 files changed, 66 insertions(+), 70 deletions(-) diff --git a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp index 4d05e0c46c..842631300e 100644 --- a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp +++ b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -31,7 +32,7 @@ bool MorozovaSConnectedComponentsMPI::ValidationImpl() { if (input.empty()) { return true; } - const std::size_t cols = input.front().size(); + const size_t cols = input.front().size(); for (const auto &row : input) { if (row.size() != cols) { return false; @@ -124,61 +125,67 @@ void MorozovaSConnectedComponentsMPI::GatherLocalResults() { const int pe = ps + rows_per_proc_ + (proc < remainder_ ? 1 : 0); const int pr = pe - ps; - std::vector buf(static_cast(pr) * static_cast(cols_)); + std::vector buf(static_cast(pr) * static_cast(cols_)); MPI_Recv(buf.data(), static_cast(buf.size()), MPI_INT, proc, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); for (int i = 0; i < pr; ++i) { for (int j = 0; j < cols_; ++j) { - const std::size_t idx = - (static_cast(i) * static_cast(cols_)) + static_cast(j); + const size_t idx = (static_cast(i) * static_cast(cols_)) + static_cast(j); GetOutput()[ps + i][j] = buf[idx]; } } } } +void MorozovaSConnectedComponentsMPI::ProcessBoundaryCell(int proc, int j, int dj, + std::unordered_map &parent) { + const int br = (proc * rows_per_proc_) + std::min(proc, remainder_); + if (br <= 0 || br >= rows_) { + return; + } + + const int nj = j + dj; + if (nj < 0 || nj >= cols_) { + return; + } + + if (grid_[br - 1][j] == 1 && grid_[br][nj] == 1) { + const int a = GetOutput()[br - 1][j]; + const int b = GetOutput()[br][nj]; + if (a != b) { + parent[std::max(a, b)] = std::min(a, b); + } + } +} + +int MorozovaSConnectedComponentsMPI::FindRoot(std::unordered_map &parent, int v) { + while (parent.find(v) != parent.end()) { + v = parent[v]; + } + return v; +} + void MorozovaSConnectedComponentsMPI::MergeBoundaries() { std::unordered_map parent; - auto ProcessBoundary = [&](int proc) { + for (int proc = 1; proc < size_; ++proc) { const int br = (proc * rows_per_proc_) + std::min(proc, remainder_); if (br <= 0 || br >= rows_) { - return; + continue; } for (int j = 0; j < cols_; ++j) { - for (int dj = -1; dj <= 1; ++dj) { - const int nj = j + dj; - if (nj < 0 || nj >= cols_) { - continue; - } - if (grid_[br - 1][j] == 1 && grid_[br][nj] == 1) { - const int a = GetOutput()[br - 1][j]; - const int b = GetOutput()[br][nj]; - if (a != b) { - parent[std::max(a, b)] = std::min(a, b); - } - } - } + ProcessBoundaryCell(proc, j, -1, parent); + ProcessBoundaryCell(proc, j, 0, parent); + ProcessBoundaryCell(proc, j, 1, parent); } - }; - - for (int proc = 1; proc < size_; ++proc) { - ProcessBoundary(proc); } - auto FindRoot = [&](int v) -> int { - while (parent.contains(v)) { - v = parent[v]; - } - return v; - }; - for (int i = 0; i < rows_; ++i) { for (int j = 0; j < cols_; ++j) { int &v = GetOutput()[i][j]; if (v > 0) { - v = FindRoot(v); + v = FindRoot(parent, v); } } } @@ -190,7 +197,7 @@ void MorozovaSConnectedComponentsMPI::NormalizeLabels() { for (auto &row : GetOutput()) { for (int &v : row) { if (v > 0) { - if (!remap.contains(v)) { + if (remap.find(v) == remap.end()) { remap[v] = next++; } v = remap[v]; @@ -200,11 +207,10 @@ void MorozovaSConnectedComponentsMPI::NormalizeLabels() { } void MorozovaSConnectedComponentsMPI::BroadcastResult() { - std::vector flat(static_cast(rows_) * static_cast(cols_)); + std::vector flat(static_cast(rows_) * static_cast(cols_)); for (int i = 0; i < rows_; ++i) { for (int j = 0; j < cols_; ++j) { - const std::size_t idx = - (static_cast(i) * static_cast(cols_)) + static_cast(j); + const size_t idx = (static_cast(i) * static_cast(cols_)) + static_cast(j); flat[idx] = GetOutput()[i][j]; } } @@ -216,11 +222,10 @@ void MorozovaSConnectedComponentsMPI::BroadcastResult() { void MorozovaSConnectedComponentsMPI::SendLocalResult(int start_row, int end_row) { const int lr = end_row - start_row; - std::vector send(static_cast(lr) * static_cast(cols_)); + std::vector send(static_cast(lr) * static_cast(cols_)); for (int i = 0; i < lr; ++i) { for (int j = 0; j < cols_; ++j) { - const std::size_t idx = - (static_cast(i) * static_cast(cols_)) + static_cast(j); + const size_t idx = (static_cast(i) * static_cast(cols_)) + static_cast(j); send[idx] = GetOutput()[start_row + i][j]; } } @@ -228,13 +233,12 @@ void MorozovaSConnectedComponentsMPI::SendLocalResult(int start_row, int end_row } void MorozovaSConnectedComponentsMPI::ReceiveFinalResult() { - std::vector recv(static_cast(rows_) * static_cast(cols_)); + std::vector recv(static_cast(rows_) * static_cast(cols_)); MPI_Recv(recv.data(), static_cast(recv.size()), MPI_INT, 0, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); for (int i = 0; i < rows_; ++i) { for (int j = 0; j < cols_; ++j) { - const std::size_t idx = - (static_cast(i) * static_cast(cols_)) + static_cast(j); + const size_t idx = (static_cast(i) * static_cast(cols_)) + static_cast(j); GetOutput()[i][j] = recv[idx]; } } diff --git a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp index f2794d1017..364bafe1a4 100644 --- a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp +++ b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -26,7 +27,7 @@ bool MorozovaSConnectedComponentsSEQ::ValidationImpl() { if (input.empty()) { return false; } - const std::size_t cols = input.front().size(); + const size_t cols = input.front().size(); if (cols == 0) { return false; } @@ -47,35 +48,27 @@ bool MorozovaSConnectedComponentsSEQ::RunImpl() { int current_label = 1; - auto IsValidNeighbor = [&](int nx, int ny) -> bool { - return nx >= 0 && nx < rows && ny >= 0 && ny < cols && input[nx][ny] != 0 && output[nx][ny] == 0; - }; - - auto FloodFill = [&](int start_i, int start_j, int label) { - std::queue> q; - q.emplace(start_i, start_j); - output[start_i][start_j] = label; - - while (!q.empty()) { - const auto [x, y] = q.front(); - q.pop(); - - for (const auto &[dx, dy] : kShifts) { - const int nx = x + dx; - const int ny = y + dy; - - if (IsValidNeighbor(nx, ny)) { - output[nx][ny] = label; - q.emplace(nx, ny); - } - } - } - }; - for (int i = 0; i < rows; ++i) { for (int j = 0; j < cols; ++j) { if (input[i][j] != 0 && output[i][j] == 0) { - FloodFill(i, j, current_label); + output[i][j] = current_label; + std::queue> q; + q.emplace(i, j); + + while (!q.empty()) { + const auto [x, y] = q.front(); + q.pop(); + + for (const auto &[dx, dy] : kShifts) { + const int nx = x + dx; + const int ny = y + dy; + + if (nx >= 0 && nx < rows && ny >= 0 && ny < cols && input[nx][ny] != 0 && output[nx][ny] == 0) { + output[nx][ny] = current_label; + q.emplace(nx, ny); + } + } + } ++current_label; } } diff --git a/tasks/morozova_s_connected_components/tests/functional/main.cpp b/tasks/morozova_s_connected_components/tests/functional/main.cpp index 144d910ce5..2c9105d713 100644 --- a/tasks/morozova_s_connected_components/tests/functional/main.cpp +++ b/tasks/morozova_s_connected_components/tests/functional/main.cpp @@ -2,7 +2,6 @@ #include #include -#include #include #include #include @@ -117,7 +116,7 @@ class MorozovaSRunFuncTestsConnectedComponents : public ppc::util::BaseRunFuncTe return false; } } - if (!std::cmp_equal(labels.size(), reported_components)) { + if (labels.size() != static_cast(reported_components)) { return false; } } else if (reported_components != 0) { From b0a6f518518e52ba0b35f9338ca84f5d606d5072 Mon Sep 17 00:00:00 2001 From: SonyaMorozova Date: Wed, 4 Feb 2026 16:35:09 +0300 Subject: [PATCH 25/30] fix mpi 2 --- tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp b/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp index 9e4605506f..a90d417996 100644 --- a/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp +++ b/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -30,7 +31,8 @@ class MorozovaSConnectedComponentsMPI : public BaseTask { void ComputeLocalComponents(int start_row, int end_row, int base_label); void GatherLocalResults(); void MergeBoundaries(); - void CompressLabels(); + void ProcessBoundaryCell(int proc, int j, int dj, std::unordered_map &parent); + int FindRoot(std::unordered_map &parent, int v); void NormalizeLabels(); void BroadcastResult(); void SendLocalResult(int start_row, int end_row); From 59bc0ba50f8562adf877736acbd6908e80522482 Mon Sep 17 00:00:00 2001 From: SonyaMorozova Date: Thu, 5 Feb 2026 01:03:34 +0300 Subject: [PATCH 26/30] fix tidy 18 --- .../mpi/include/ops_mpi.hpp | 5 +- .../mpi/src/ops_mpi.cpp | 67 +++++++++++++------ .../seq/include/ops_seq.hpp | 5 +- .../seq/src/ops_seq.cpp | 51 ++++++++------ 4 files changed, 76 insertions(+), 52 deletions(-) diff --git a/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp b/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp index a90d417996..e424b45c4c 100644 --- a/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp +++ b/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp @@ -32,7 +32,7 @@ class MorozovaSConnectedComponentsMPI : public BaseTask { void GatherLocalResults(); void MergeBoundaries(); void ProcessBoundaryCell(int proc, int j, int dj, std::unordered_map &parent); - int FindRoot(std::unordered_map &parent, int v); + static int FindRoot(std::unordered_map &parent, int v); void NormalizeLabels(); void BroadcastResult(); void SendLocalResult(int start_row, int end_row); @@ -44,9 +44,6 @@ class MorozovaSConnectedComponentsMPI : public BaseTask { int cols_{0}; int rows_per_proc_{0}; int remainder_{0}; - - std::vector> grid_; - std::vector> visited_; }; } // namespace morozova_s_connected_components diff --git a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp index 842631300e..a3430eaa18 100644 --- a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp +++ b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp @@ -57,8 +57,6 @@ bool MorozovaSConnectedComponentsMPI::PreProcessingImpl() { } cols_ = static_cast(input.front().size()); - grid_ = input; - visited_.assign(rows_, std::vector(cols_, false)); GetOutput().assign(rows_, std::vector(cols_, 0)); return true; } @@ -78,10 +76,12 @@ std::pair MorozovaSConnectedComponentsMPI::ComputeRowRange() const { std::vector> MorozovaSConnectedComponentsMPI::GetNeighbors(int row, int col) const { std::vector> neighbors; + const auto &input = GetInput(); + for (const auto &[dr, dc] : kShifts) { const int nr = row + dr; const int nc = col + dc; - if (nr >= 0 && nr < rows_ && nc >= 0 && nc < cols_ && grid_[nr][nc] == 1) { + if (nr >= 0 && nr < rows_ && nc >= 0 && nc < cols_ && input[nr][nc] == 1) { neighbors.emplace_back(nr, nc); } } @@ -89,18 +89,22 @@ std::vector> MorozovaSConnectedComponentsMPI::GetNeighbors(i } void MorozovaSConnectedComponentsMPI::FloodFill(int row, int col, int label) { + const auto &input = GetInput(); + auto &output = GetOutput(); + + std::vector> visited(rows_, std::vector(cols_, false)); std::queue> q; q.emplace(row, col); - visited_[row][col] = true; - GetOutput()[row][col] = label; + visited[row][col] = true; + output[row][col] = label; while (!q.empty()) { const auto [r, c] = q.front(); q.pop(); for (const auto &[nr, nc] : GetNeighbors(r, c)) { - if (!visited_[nr][nc]) { - visited_[nr][nc] = true; - GetOutput()[nr][nc] = label; + if (!visited[nr][nc]) { + visited[nr][nc] = true; + output[nr][nc] = label; q.emplace(nr, nc); } } @@ -108,10 +112,16 @@ void MorozovaSConnectedComponentsMPI::FloodFill(int row, int col, int label) { } void MorozovaSConnectedComponentsMPI::ComputeLocalComponents(int start_row, int end_row, int base_label) { + const auto &input = GetInput(); + auto &output = GetOutput(); + + std::vector> visited(rows_, std::vector(cols_, false)); int local_label = 1; + for (int i = start_row; i < end_row; ++i) { for (int j = 0; j < cols_; ++j) { - if (grid_[i][j] == 1 && !visited_[i][j]) { + if (input[i][j] == 1 && output[i][j] == 0) { + // Временный visited для каждого вызова FloodFill FloodFill(i, j, base_label + local_label); ++local_label; } @@ -120,6 +130,8 @@ void MorozovaSConnectedComponentsMPI::ComputeLocalComponents(int start_row, int } void MorozovaSConnectedComponentsMPI::GatherLocalResults() { + auto &output = GetOutput(); + for (int proc = 1; proc < size_; ++proc) { const int ps = (proc * rows_per_proc_) + std::min(proc, remainder_); const int pe = ps + rows_per_proc_ + (proc < remainder_ ? 1 : 0); @@ -131,7 +143,7 @@ void MorozovaSConnectedComponentsMPI::GatherLocalResults() { for (int i = 0; i < pr; ++i) { for (int j = 0; j < cols_; ++j) { const size_t idx = (static_cast(i) * static_cast(cols_)) + static_cast(j); - GetOutput()[ps + i][j] = buf[idx]; + output[ps + i][j] = buf[idx]; } } } @@ -139,6 +151,9 @@ void MorozovaSConnectedComponentsMPI::GatherLocalResults() { void MorozovaSConnectedComponentsMPI::ProcessBoundaryCell(int proc, int j, int dj, std::unordered_map &parent) { + const auto &input = GetInput(); + const auto &output = GetOutput(); + const int br = (proc * rows_per_proc_) + std::min(proc, remainder_); if (br <= 0 || br >= rows_) { return; @@ -149,9 +164,9 @@ void MorozovaSConnectedComponentsMPI::ProcessBoundaryCell(int proc, int j, int d return; } - if (grid_[br - 1][j] == 1 && grid_[br][nj] == 1) { - const int a = GetOutput()[br - 1][j]; - const int b = GetOutput()[br][nj]; + if (input[br - 1][j] == 1 && input[br][nj] == 1) { + const int a = output[br - 1][j]; + const int b = output[br][nj]; if (a != b) { parent[std::max(a, b)] = std::min(a, b); } @@ -159,13 +174,14 @@ void MorozovaSConnectedComponentsMPI::ProcessBoundaryCell(int proc, int j, int d } int MorozovaSConnectedComponentsMPI::FindRoot(std::unordered_map &parent, int v) { - while (parent.find(v) != parent.end()) { + while (parent.contains(v)) { v = parent[v]; } return v; } void MorozovaSConnectedComponentsMPI::MergeBoundaries() { + auto &output = GetOutput(); std::unordered_map parent; for (int proc = 1; proc < size_; ++proc) { @@ -183,7 +199,7 @@ void MorozovaSConnectedComponentsMPI::MergeBoundaries() { for (int i = 0; i < rows_; ++i) { for (int j = 0; j < cols_; ++j) { - int &v = GetOutput()[i][j]; + int &v = output[i][j]; if (v > 0) { v = FindRoot(parent, v); } @@ -192,12 +208,13 @@ void MorozovaSConnectedComponentsMPI::MergeBoundaries() { } void MorozovaSConnectedComponentsMPI::NormalizeLabels() { + auto &output = GetOutput(); std::unordered_map remap; int next = 1; - for (auto &row : GetOutput()) { + for (auto &row : output) { for (int &v : row) { if (v > 0) { - if (remap.find(v) == remap.end()) { + if (!remap.contains(v)) { remap[v] = next++; } v = remap[v]; @@ -207,11 +224,12 @@ void MorozovaSConnectedComponentsMPI::NormalizeLabels() { } void MorozovaSConnectedComponentsMPI::BroadcastResult() { + auto &output = GetOutput(); std::vector flat(static_cast(rows_) * static_cast(cols_)); for (int i = 0; i < rows_; ++i) { for (int j = 0; j < cols_; ++j) { const size_t idx = (static_cast(i) * static_cast(cols_)) + static_cast(j); - flat[idx] = GetOutput()[i][j]; + flat[idx] = output[i][j]; } } @@ -221,25 +239,27 @@ void MorozovaSConnectedComponentsMPI::BroadcastResult() { } void MorozovaSConnectedComponentsMPI::SendLocalResult(int start_row, int end_row) { + const auto &output = GetOutput(); const int lr = end_row - start_row; std::vector send(static_cast(lr) * static_cast(cols_)); for (int i = 0; i < lr; ++i) { for (int j = 0; j < cols_; ++j) { const size_t idx = (static_cast(i) * static_cast(cols_)) + static_cast(j); - send[idx] = GetOutput()[start_row + i][j]; + send[idx] = output[start_row + i][j]; } } MPI_Send(send.data(), static_cast(send.size()), MPI_INT, 0, 0, MPI_COMM_WORLD); } void MorozovaSConnectedComponentsMPI::ReceiveFinalResult() { + auto &output = GetOutput(); std::vector recv(static_cast(rows_) * static_cast(cols_)); MPI_Recv(recv.data(), static_cast(recv.size()), MPI_INT, 0, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); for (int i = 0; i < rows_; ++i) { for (int j = 0; j < cols_; ++j) { const size_t idx = (static_cast(i) * static_cast(cols_)) + static_cast(j); - GetOutput()[i][j] = recv[idx]; + output[i][j] = recv[idx]; } } } @@ -268,13 +288,16 @@ bool MorozovaSConnectedComponentsMPI::RunImpl() { } bool MorozovaSConnectedComponentsMPI::PostProcessingImpl() { + const auto &output = GetOutput(); int max_label = 0; - for (const auto &row : GetOutput()) { + for (const auto &row : output) { for (int v : row) { max_label = std::max(max_label, v); } } - GetOutput().push_back({max_label}); + + auto &output_ref = GetOutput(); + output_ref.push_back({max_label}); return true; } diff --git a/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp b/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp index 9a11de8750..cc082d4e38 100644 --- a/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp +++ b/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp @@ -20,11 +20,8 @@ class MorozovaSConnectedComponentsSEQ : public BaseTask { bool RunImpl() override; bool PostProcessingImpl() override; - void LabelComponents(); - void DFSLabeling(int row, int col, int label); + void ProcessComponent(int start_i, int start_j, int current_label); - std::vector> grid_; - std::vector> visited_; int rows_{0}; int cols_{0}; }; diff --git a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp index 364bafe1a4..3a1fd431d7 100644 --- a/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp +++ b/tasks/morozova_s_connected_components/seq/src/ops_seq.cpp @@ -39,36 +39,43 @@ bool MorozovaSConnectedComponentsSEQ::PreProcessingImpl() { return true; } +void MorozovaSConnectedComponentsSEQ::ProcessComponent(int start_i, int start_j, int current_label) { + const auto &input = GetInput(); + auto &output = GetOutput(); + + output[start_i][start_j] = current_label; + std::queue> q; + q.emplace(start_i, start_j); + + while (!q.empty()) { + const auto [x, y] = q.front(); + q.pop(); + + for (const auto &[dx, dy] : kShifts) { + const int nx = x + dx; + const int ny = y + dy; + + if (nx >= 0 && nx < rows_ && ny >= 0 && ny < cols_ && input[nx][ny] != 0 && output[nx][ny] == 0) { + output[nx][ny] = current_label; + q.emplace(nx, ny); + } + } + } +} + bool MorozovaSConnectedComponentsSEQ::RunImpl() { const auto &input = GetInput(); auto &output = GetOutput(); - const int rows = static_cast(input.size()); - const int cols = static_cast(input.front().size()); + rows_ = static_cast(input.size()); + cols_ = static_cast(input.front().size()); int current_label = 1; - for (int i = 0; i < rows; ++i) { - for (int j = 0; j < cols; ++j) { + for (int i = 0; i < rows_; ++i) { + for (int j = 0; j < cols_; ++j) { if (input[i][j] != 0 && output[i][j] == 0) { - output[i][j] = current_label; - std::queue> q; - q.emplace(i, j); - - while (!q.empty()) { - const auto [x, y] = q.front(); - q.pop(); - - for (const auto &[dx, dy] : kShifts) { - const int nx = x + dx; - const int ny = y + dy; - - if (nx >= 0 && nx < rows && ny >= 0 && ny < cols && input[nx][ny] != 0 && output[nx][ny] == 0) { - output[nx][ny] = current_label; - q.emplace(nx, ny); - } - } - } + ProcessComponent(i, j, current_label); ++current_label; } } From 864809fea5f946f725e7df79f8036a1cde70e141 Mon Sep 17 00:00:00 2001 From: SonyaMorozova Date: Thu, 5 Feb 2026 12:57:15 +0300 Subject: [PATCH 27/30] fix mpi 3 --- .../mpi/include/ops_mpi.hpp | 2 +- tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp b/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp index e424b45c4c..43f33c99e6 100644 --- a/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp +++ b/tasks/morozova_s_connected_components/mpi/include/ops_mpi.hpp @@ -24,7 +24,7 @@ class MorozovaSConnectedComponentsMPI : public BaseTask { bool PostProcessingImpl() override; void FloodFill(int row, int col, int label); - [[nodiscard]] std::vector> GetNeighbors(int row, int col) const; + [[nodiscard]] std::vector> GetNeighbors(int row, int col); void InitMPI(); [[nodiscard]] std::pair ComputeRowRange() const; diff --git a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp index a3430eaa18..3e257e7878 100644 --- a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp +++ b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp @@ -47,8 +47,7 @@ bool MorozovaSConnectedComponentsMPI::ValidationImpl() { } bool MorozovaSConnectedComponentsMPI::PreProcessingImpl() { - const auto &input = GetInput(); - rows_ = static_cast(input.size()); + rows_ = static_cast(GetInput().size()); if (rows_ == 0) { cols_ = 0; @@ -56,7 +55,7 @@ bool MorozovaSConnectedComponentsMPI::PreProcessingImpl() { return true; } - cols_ = static_cast(input.front().size()); + cols_ = static_cast(GetInput().front().size()); GetOutput().assign(rows_, std::vector(cols_, 0)); return true; } @@ -74,7 +73,7 @@ std::pair MorozovaSConnectedComponentsMPI::ComputeRowRange() const { return {start, end}; } -std::vector> MorozovaSConnectedComponentsMPI::GetNeighbors(int row, int col) const { +std::vector> MorozovaSConnectedComponentsMPI::GetNeighbors(int row, int col) { std::vector> neighbors; const auto &input = GetInput(); @@ -121,7 +120,6 @@ void MorozovaSConnectedComponentsMPI::ComputeLocalComponents(int start_row, int for (int i = start_row; i < end_row; ++i) { for (int j = 0; j < cols_; ++j) { if (input[i][j] == 1 && output[i][j] == 0) { - // Временный visited для каждого вызова FloodFill FloodFill(i, j, base_label + local_label); ++local_label; } From eab12f60f4a4738d1d7f6d2cf517dd975955edfa Mon Sep 17 00:00:00 2001 From: SonyaMorozova Date: Thu, 5 Feb 2026 13:49:44 +0300 Subject: [PATCH 28/30] fix mpi 4 --- tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp index 3e257e7878..bc3517a198 100644 --- a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp +++ b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp @@ -111,7 +111,6 @@ void MorozovaSConnectedComponentsMPI::FloodFill(int row, int col, int label) { } void MorozovaSConnectedComponentsMPI::ComputeLocalComponents(int start_row, int end_row, int base_label) { - const auto &input = GetInput(); auto &output = GetOutput(); std::vector> visited(rows_, std::vector(cols_, false)); From 9c1d2ad709d68f99758f263f9de54cb7941f8046 Mon Sep 17 00:00:00 2001 From: SonyaMorozova Date: Thu, 5 Feb 2026 15:02:22 +0300 Subject: [PATCH 29/30] fix mpi 5 --- tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp index bc3517a198..72aa2e3d7c 100644 --- a/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp +++ b/tasks/morozova_s_connected_components/mpi/src/ops_mpi.cpp @@ -88,7 +88,6 @@ std::vector> MorozovaSConnectedComponentsMPI::GetNeighbors(i } void MorozovaSConnectedComponentsMPI::FloodFill(int row, int col, int label) { - const auto &input = GetInput(); auto &output = GetOutput(); std::vector> visited(rows_, std::vector(cols_, false)); @@ -111,6 +110,7 @@ void MorozovaSConnectedComponentsMPI::FloodFill(int row, int col, int label) { } void MorozovaSConnectedComponentsMPI::ComputeLocalComponents(int start_row, int end_row, int base_label) { + const auto &input = GetInput(); auto &output = GetOutput(); std::vector> visited(rows_, std::vector(cols_, false)); From e9a3baf293fe0d47018f1460321bc161488b7e73 Mon Sep 17 00:00:00 2001 From: SonyaMorozova Date: Thu, 5 Feb 2026 16:10:09 +0300 Subject: [PATCH 30/30] fix seq 3 --- tasks/morozova_s_connected_components/seq/include/ops_seq.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp b/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp index cc082d4e38..85d076e39f 100644 --- a/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp +++ b/tasks/morozova_s_connected_components/seq/include/ops_seq.hpp @@ -1,7 +1,5 @@ #pragma once -#include - #include "morozova_s_connected_components/common/include/common.hpp" #include "task/include/task.hpp"