From 31c4626c0444660f1a7b3b3dd549868cf406a42f Mon Sep 17 00:00:00 2001 From: root Date: Wed, 19 Nov 2025 16:16:12 +0000 Subject: [PATCH 1/5] rebranch --- .../common/include/common.hpp | 16 +++ tasks/kutergin_a_closest_pair/info.json | 9 ++ .../mpi/include/ops_mpi.hpp | 22 ++++ .../mpi/src/ops_mpi.cpp | 101 ++++++++++++++++++ tasks/kutergin_a_closest_pair/report.md | 51 +++++++++ .../seq/include/ops_seq.hpp | 25 +++++ .../seq/src/ops_seq.cpp | 53 +++++++++ tasks/kutergin_a_closest_pair/settings.json | 7 ++ .../kutergin_a_closest_pair/tests/.clang-tidy | 13 +++ .../tests/functional/main.cpp | 93 ++++++++++++++++ .../tests/performance/main.cpp | 49 +++++++++ 11 files changed, 439 insertions(+) create mode 100644 tasks/kutergin_a_closest_pair/common/include/common.hpp create mode 100644 tasks/kutergin_a_closest_pair/info.json create mode 100644 tasks/kutergin_a_closest_pair/mpi/include/ops_mpi.hpp create mode 100644 tasks/kutergin_a_closest_pair/mpi/src/ops_mpi.cpp create mode 100644 tasks/kutergin_a_closest_pair/report.md create mode 100644 tasks/kutergin_a_closest_pair/seq/include/ops_seq.hpp create mode 100644 tasks/kutergin_a_closest_pair/seq/src/ops_seq.cpp create mode 100644 tasks/kutergin_a_closest_pair/settings.json create mode 100644 tasks/kutergin_a_closest_pair/tests/.clang-tidy create mode 100644 tasks/kutergin_a_closest_pair/tests/functional/main.cpp create mode 100644 tasks/kutergin_a_closest_pair/tests/performance/main.cpp diff --git a/tasks/kutergin_a_closest_pair/common/include/common.hpp b/tasks/kutergin_a_closest_pair/common/include/common.hpp new file mode 100644 index 0000000000..0a4657be7f --- /dev/null +++ b/tasks/kutergin_a_closest_pair/common/include/common.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include +#include +#include + +#include "task/include/task.hpp" + +namespace kutergin_a_closest_pair { + +using InType = std::vector;; +using OutType = int; +using TestType = std::tuple, std::string>; +using BaseTask = ppc::task::Task; + +} // namespace kutergin_a_closest_pair \ No newline at end of file diff --git a/tasks/kutergin_a_closest_pair/info.json b/tasks/kutergin_a_closest_pair/info.json new file mode 100644 index 0000000000..1d40028d8a --- /dev/null +++ b/tasks/kutergin_a_closest_pair/info.json @@ -0,0 +1,9 @@ +{ + "student": { + "first_name": "Антон", + "last_name": "Кутергин", + "middle_name": "Андреевич", + "group_number": "3823Б1ФИ1", + "task_number": "7" + } +} diff --git a/tasks/kutergin_a_closest_pair/mpi/include/ops_mpi.hpp b/tasks/kutergin_a_closest_pair/mpi/include/ops_mpi.hpp new file mode 100644 index 0000000000..099ad9843f --- /dev/null +++ b/tasks/kutergin_a_closest_pair/mpi/include/ops_mpi.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include "kutergin_a_closest_pair/common/include/common.hpp" +#include "task/include/task.hpp" + +namespace kutergin_a_closest_pair { + +class KuterginAClosestPairMPI : public BaseTask { + public: + static constexpr ppc::task::TypeOfTask GetStaticTypeOfTask() { + return ppc::task::TypeOfTask::kMPI; + } + explicit KuterginAClosestPairMPI(const InType &in); + + private: + bool ValidationImpl() override; + bool PreProcessingImpl() override; + bool RunImpl() override; + bool PostProcessingImpl() override; +}; + +} // namespace kutergin_a_closest_pair diff --git a/tasks/kutergin_a_closest_pair/mpi/src/ops_mpi.cpp b/tasks/kutergin_a_closest_pair/mpi/src/ops_mpi.cpp new file mode 100644 index 0000000000..50f50538f9 --- /dev/null +++ b/tasks/kutergin_a_closest_pair/mpi/src/ops_mpi.cpp @@ -0,0 +1,101 @@ +#include "kutergin_a_closest_pair/mpi/include/ops_mpi.hpp" + +#include + +#include +#include +#include +#include + +#include "kutergin_a_closest_pair/common/include/common.hpp" +#include "util/include/util.hpp" + +namespace kutergin_a_closest_pair { + +KuterginAClosestPairMPI::KuterginAClosestPairMPI(const InType &in) { + SetTypeOfTask(GetStaticTypeOfTask()); + GetInput() = in; + GetOutput() = -1; +} + +bool KuterginAClosestPairMPI::ValidationImpl() { + return true; +} + +bool KuterginAClosestPairMPI::PreProcessingImpl() { + return true; +} + +bool KuterginAClosestPairMPI::RunImpl() { + int rank, size; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + const auto& v = GetInput(); + int n = v.size(); + + MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD); + + if (n < 2) { + GetOutput() = -1; + return true; + } + int local_size = n / size; + int remainder = n % size; + + int start = rank * local_size + std::min(rank, remainder); + int end = start + local_size + (rank < remainder ? 1 : 0); + + if (rank == size - 1) { + end = n; + } + + std::vector local_data(end - start); + if (rank == 0) { + std::copy(v.begin() + start, v.begin() + end, local_data.begin()); + + for (int i = 1; i < size; ++i) { + int other_start = i * local_size + std::min(i, remainder); + int other_end = other_start + local_size + (i < remainder ? 1 : 0); + if (i == size - 1) other_end = n; + + MPI_Send(v.data() + other_start, other_end - other_start, + MPI_INT, i, 0, MPI_COMM_WORLD); + } + } else { + MPI_Recv(local_data.data(), local_data.size(), + MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + } + + + int local_min = std::numeric_limits::max(); + int local_idx = -1; + + for (int i = 0; i < static_cast(local_data.size()) - 1; ++i) { + int diff = std::abs(local_data[i + 1] - local_data[i]); + if (diff < local_min) { + local_min = diff; + local_idx = start + i; + } + } + + if (rank < size - 1 && end < n) { + int boundary_diff = std::abs(v[end] - local_data.back()); + if (boundary_diff < local_min) { + local_min = boundary_diff; + local_idx = end - 1; + } + } + + struct { int val; int idx; } local{local_min, local_idx}, global; + MPI_Allreduce(&local, &global, 1, MPI_2INT, MPI_MINLOC, MPI_COMM_WORLD); + + GetOutput() = global.idx; + return true; +} + +bool KuterginAClosestPairMPI::PostProcessingImpl() { + return true; +} + +} // namespace kutergin_a_closest_pair diff --git a/tasks/kutergin_a_closest_pair/report.md b/tasks/kutergin_a_closest_pair/report.md new file mode 100644 index 0000000000..2497c38975 --- /dev/null +++ b/tasks/kutergin_a_closest_pair/report.md @@ -0,0 +1,51 @@ +# Нахождение наиболее близких соседних элементов вектора + +- Student: Кутергин Антон Андреевич, group 3823Б1ФИ1 +- Technology: SEQ | MPI +- Variant: 7 + +## 1 Введение + +Нужно было реализовать параллельный и последовательный алгоритм для поиска наиболее близких соседних элементов вектора + +## 2 Постановка задачи + +На вход подается вектор v, нужно найти такой индекс i, что велечина |v[i] - v[i+1]| минимальна среди всех пар элемента + +## 3. Baseline Algorithm (Sequential) + +Последовательно просматривает пары v[i], v[i+1], сравнивает разности и возвращает индекс максимума + +## 4. Parallelization Scheme + +Вектор разбивается на MPI процессы, корректно обрабатывая границы между процессами, чтобы последнему числу этого процесса и первому следующего процесса также образуют пару. Каждый ищет свой локальный минимум среди всех своих соседних пар. Возвращаем глобальный индекс пары с помощью MPI_Reduce + +## 6. Experimental Setup + +-HARDWARE/OS: CPU - Intel Core i5-8300H, cores/threads - 4/8, RAM - 12gb, OS - Ubuntu 24.04 (DevContainer / WSL 2) +TOOLCHAIN: g++ 13.3.0, build type - Release + + +## 7. Results and Discussion + +### 7.1 Correctness + +Функциональные тесты: вектор может принимать как положительные, так и отрицательные значения или содержать и положительные и отрицательные значения, так же обрабатывается случай, когда вектор пуст или у него одно значение и пару ему не найти. +MPI версия запускалась на 4 ядрах - эталонное ускорение в 4 раза. +Тест на производительность: генерация n чисел и запуск алгоритмов, чтобы узнать время выполнения. + +### 7.2 Performance + +| Размер данных | MPI версия (сек) | SEQ версия (сек) | Ускорение | +|---------------|------------------------|-------------------------|-----------| +| 10,000,000 | 0.0269160954 | 0.0310927963 | 1.22x | +| 100,000,000 | 0.411453807 | 0.5857917309 | 1.39x | + + +## 8. Conclusions + +Алгоритм нахождения наиболее близких соседних элементов вектора работает как последовательно, так и параллельно. Чем больше данных, тем быстрее работает MPI версия алгоритма, но не сильно, т.к. в задаче мы просто проходим по вектору и находим разницу и накладные расходы MPI не особо много выигрывают. + +## 9. References +1. Лекции по параллельному программированию +2. Практические занятия по параллельному программированию \ No newline at end of file diff --git a/tasks/kutergin_a_closest_pair/seq/include/ops_seq.hpp b/tasks/kutergin_a_closest_pair/seq/include/ops_seq.hpp new file mode 100644 index 0000000000..c14b0b7f07 --- /dev/null +++ b/tasks/kutergin_a_closest_pair/seq/include/ops_seq.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include + +#include "kutergin_a_closest_pair/common/include/common.hpp" +#include "task/include/task.hpp" + +namespace kutergin_a_closest_pair { + +class KuterginAClosestPairSEQ : public BaseTask { + public: + static constexpr ppc::task::TypeOfTask GetStaticTypeOfTask() { + return ppc::task::TypeOfTask::kSEQ; + } + explicit KuterginAClosestPairSEQ(const InType &in); + + private: + std::vector _data; + bool ValidationImpl() override; + bool PreProcessingImpl() override; + bool RunImpl() override; + bool PostProcessingImpl() override; +}; + +} // namespace kutergin_a_closest_pair \ No newline at end of file diff --git a/tasks/kutergin_a_closest_pair/seq/src/ops_seq.cpp b/tasks/kutergin_a_closest_pair/seq/src/ops_seq.cpp new file mode 100644 index 0000000000..15bfdb63a4 --- /dev/null +++ b/tasks/kutergin_a_closest_pair/seq/src/ops_seq.cpp @@ -0,0 +1,53 @@ +#include "kutergin_a_closest_pair/seq/include/ops_seq.hpp" + +#include +#include +#include +#include + +#include "kutergin_a_closest_pair/common/include/common.hpp" +#include "util/include/util.hpp" + +namespace kutergin_a_closest_pair { + +KuterginAClosestPairSEQ::KuterginAClosestPairSEQ(const InType &in) { + SetTypeOfTask(GetStaticTypeOfTask()); + GetInput() = in; + GetOutput() = -1; +} + +bool KuterginAClosestPairSEQ::ValidationImpl() { + return true; +} + +bool KuterginAClosestPairSEQ::PreProcessingImpl() { + return true; +} + +bool KuterginAClosestPairSEQ::RunImpl() { + const auto &v = GetInput(); + if (v.size() < 2) { + GetOutput() = -1; + return true; +} + + int best_idx = 0; + int min_diff = std::abs(v[1] - v[0]); + + for (size_t i = 1; i < v.size() - 1; ++i) { + int diff = std::abs(v[i + 1] - v[i]); + if (diff < min_diff) { + min_diff = diff; + best_idx = i; + } + } + + GetOutput() = best_idx; + return true; +} + +bool KuterginAClosestPairSEQ::PostProcessingImpl() { + return true; +} + +} // namespace kutergin_a_closest_pair diff --git a/tasks/kutergin_a_closest_pair/settings.json b/tasks/kutergin_a_closest_pair/settings.json new file mode 100644 index 0000000000..b1a0d52574 --- /dev/null +++ b/tasks/kutergin_a_closest_pair/settings.json @@ -0,0 +1,7 @@ +{ + "tasks_type": "processes", + "tasks": { + "mpi": "enabled", + "seq": "enabled" + } +} diff --git a/tasks/kutergin_a_closest_pair/tests/.clang-tidy b/tasks/kutergin_a_closest_pair/tests/.clang-tidy new file mode 100644 index 0000000000..ef43b7aa8a --- /dev/null +++ b/tasks/kutergin_a_closest_pair/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/kutergin_a_closest_pair/tests/functional/main.cpp b/tasks/kutergin_a_closest_pair/tests/functional/main.cpp new file mode 100644 index 0000000000..ac122ab34c --- /dev/null +++ b/tasks/kutergin_a_closest_pair/tests/functional/main.cpp @@ -0,0 +1,93 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kutergin_a_closest_pair/common/include/common.hpp" +#include "kutergin_a_closest_pair/mpi/include/ops_mpi.hpp" +#include "kutergin_a_closest_pair/seq/include/ops_seq.hpp" +#include "util/include/func_test_util.hpp" +#include "util/include/util.hpp" + +namespace kutergin_a_closest_pair { + +class KuterginAClosestPairFuncTests : public ppc::util::BaseRunFuncTests { + public: + static std::string PrintTestParam(const TestType &test_param) { + return std::get<1>(test_param); + } + + protected: + void SetUp() override { + TestType params = std::get(ppc::util::GTestParamIndex::kTestParams)>(GetParam()); + input_data_ = std::get<0>(std::get<0>(params)); + expected_ = std::get<1>(std::get<0>(params)); + std::cout << "Test: " << std::get<1>(params) << "\nInput: "; + for (auto v : input_data_) std::cout << v << ' '; + std::cout << "\nExpected index: " << expected_ << "\n"; + } + + bool CheckTestOutputData(OutType &output_data) final { + return output_data == expected_; + } + + InType GetTestInputData() final { + return input_data_; + } + + private: + InType input_data_; + OutType expected_; +}; + +namespace { + std::vector v1{1,3,5,6,9}; // closest pair 5-6 => index 2 +std::vector v2{10,11,30,40}; // 10-11 => index 0 +std::vector v3{5,2,3,10}; // 2-3 => index 1 +std::vector v4{100,99,101,200}; // 100-99 => index 0 +std::vector v5{1}; // no pair => -1 +std::vector v6{}; // no pair => -1 +std::vector v7{4,4,4,4}; // 4-4 => index 0 +std::vector v8{-10,-5,-7,0}; // closest pair -5,-7 => index 1 +std::vector v9{-1,-2,-8,-10,-11}; // closest pair -1,-2 => index 0 +std::vector v10{-100,50,-50,0}; // closest pair 50,-50 => index 1 + +const std::array kTestParam = { + std::make_tuple(std::make_tuple(v1,2), "test1"), + std::make_tuple(std::make_tuple(v2,0), "test2"), + std::make_tuple(std::make_tuple(v3,1), "test3"), + std::make_tuple(std::make_tuple(v4,0), "test4"), + std::make_tuple(std::make_tuple(v5,-1), "test5"), + std::make_tuple(std::make_tuple(v6,-1), "test6"), + std::make_tuple(std::make_tuple(v7,0), "test7"), + std::make_tuple(std::make_tuple(v8,1), "test8"), + std::make_tuple(std::make_tuple(v9,0), "test9"), + std::make_tuple(std::make_tuple(v10,2), "test10") +}; + + const auto kTestTasksList = std::tuple_cat(ppc::util::AddFuncTask(kTestParam, PPC_SETTINGS_kutergin_a_closest_pair), + ppc::util::AddFuncTask( + kTestParam, PPC_SETTINGS_kutergin_a_closest_pair)); + + const auto kGTestValues = ppc::util::ExpandToValues(kTestTasksList); + + const auto kNameGen = + KuterginAClosestPairFuncTests::PrintFuncTestName; + + INSTANTIATE_TEST_SUITE_P(ClosestPairTests,KuterginAClosestPairFuncTests,kGTestValues,kNameGen); + + TEST_P(KuterginAClosestPairFuncTests, ClosestPairTest) { + ExecuteTest(GetParam()); + } +} // namespace + +} // namespace kutergin_a_closest_pair diff --git a/tasks/kutergin_a_closest_pair/tests/performance/main.cpp b/tasks/kutergin_a_closest_pair/tests/performance/main.cpp new file mode 100644 index 0000000000..c089f316be --- /dev/null +++ b/tasks/kutergin_a_closest_pair/tests/performance/main.cpp @@ -0,0 +1,49 @@ +#include + +#include + +#include "kutergin_a_closest_pair/common/include/common.hpp" +#include "kutergin_a_closest_pair/mpi/include/ops_mpi.hpp" +#include "kutergin_a_closest_pair/seq/include/ops_seq.hpp" +#include "util/include/perf_test_util.hpp" + +namespace kutergin_a_closest_pair { + +class KuterginAClosestPairPerfTests : public ppc::util::BaseRunPerfTests { + public: + void SetUp() override { + const size_t vector_size = 100000000; + std::vector vector(vector_size); + + for (size_t i = 0; i < vector_size; i++) { + vector[i] = static_cast(i % 1000) + ((i & 1) == 0 ? 1 : -1); + } + input_data_ = std::move(vector); +} + + bool CheckTestOutputData(OutType &output_data) final { + return output_data == 0; + } + + InType GetTestInputData() final { + return input_data_; + } + + private: + InType input_data_; +}; + +TEST_P(KuterginAClosestPairPerfTests, RunPerfModes) { + ExecuteTest(GetParam()); +} + +const auto kAllPerfTasks = + ppc::util::MakeAllPerfTasks(PPC_SETTINGS_kutergin_a_closest_pair); + +const auto kGtestValues = ppc::util::TupleToGTestValues(kAllPerfTasks); + +const auto kPerfTestName = KuterginAClosestPairPerfTests::CustomPerfTestName; + +INSTANTIATE_TEST_SUITE_P(RunModeTests, KuterginAClosestPairPerfTests, kGtestValues, kPerfTestName); + +} // namespace kutergin_a_closest_pair From a883737f3571f7d6f1ba9e4db2cb1f205d49bc79 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 19 Nov 2025 16:44:00 +0000 Subject: [PATCH 2/5] clang format --- .../common/include/common.hpp | 5 +- .../mpi/src/ops_mpi.cpp | 118 +++++++++--------- .../seq/include/ops_seq.hpp | 2 +- .../seq/src/ops_seq.cpp | 6 +- .../tests/functional/main.cpp | 63 +++++----- .../tests/performance/main.cpp | 18 +-- 6 files changed, 105 insertions(+), 107 deletions(-) diff --git a/tasks/kutergin_a_closest_pair/common/include/common.hpp b/tasks/kutergin_a_closest_pair/common/include/common.hpp index 0a4657be7f..d3dfb131d2 100644 --- a/tasks/kutergin_a_closest_pair/common/include/common.hpp +++ b/tasks/kutergin_a_closest_pair/common/include/common.hpp @@ -8,9 +8,10 @@ namespace kutergin_a_closest_pair { -using InType = std::vector;; +using InType = std::vector; +; using OutType = int; using TestType = std::tuple, std::string>; using BaseTask = ppc::task::Task; -} // namespace kutergin_a_closest_pair \ No newline at end of file +} // namespace kutergin_a_closest_pair diff --git a/tasks/kutergin_a_closest_pair/mpi/src/ops_mpi.cpp b/tasks/kutergin_a_closest_pair/mpi/src/ops_mpi.cpp index 50f50538f9..17606709bf 100644 --- a/tasks/kutergin_a_closest_pair/mpi/src/ops_mpi.cpp +++ b/tasks/kutergin_a_closest_pair/mpi/src/ops_mpi.cpp @@ -27,71 +27,73 @@ bool KuterginAClosestPairMPI::PreProcessingImpl() { } bool KuterginAClosestPairMPI::RunImpl() { - int rank, size; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - MPI_Comm_size(MPI_COMM_WORLD, &size); - - const auto& v = GetInput(); - int n = v.size(); - - MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD); - - if (n < 2) { - GetOutput() = -1; - return true; - } - int local_size = n / size; - int remainder = n % size; - - int start = rank * local_size + std::min(rank, remainder); - int end = start + local_size + (rank < remainder ? 1 : 0); - - if (rank == size - 1) { - end = n; - } - - std::vector local_data(end - start); - if (rank == 0) { - std::copy(v.begin() + start, v.begin() + end, local_data.begin()); - - for (int i = 1; i < size; ++i) { - int other_start = i * local_size + std::min(i, remainder); - int other_end = other_start + local_size + (i < remainder ? 1 : 0); - if (i == size - 1) other_end = n; - - MPI_Send(v.data() + other_start, other_end - other_start, - MPI_INT, i, 0, MPI_COMM_WORLD); - } - } else { - MPI_Recv(local_data.data(), local_data.size(), - MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - } + int rank, size; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + const auto &v = GetInput(); + int n = v.size(); + + MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD); + + if (n < 2) { + GetOutput() = -1; + return true; + } + int local_size = n / size; + int remainder = n % size; + int start = rank * local_size + std::min(rank, remainder); + int end = start + local_size + (rank < remainder ? 1 : 0); - int local_min = std::numeric_limits::max(); - int local_idx = -1; + if (rank == size - 1) { + end = n; + } - for (int i = 0; i < static_cast(local_data.size()) - 1; ++i) { - int diff = std::abs(local_data[i + 1] - local_data[i]); - if (diff < local_min) { - local_min = diff; - local_idx = start + i; - } + std::vector local_data(end - start); + if (rank == 0) { + std::copy(v.begin() + start, v.begin() + end, local_data.begin()); + + for (int i = 1; i < size; ++i) { + int other_start = i * local_size + std::min(i, remainder); + int other_end = other_start + local_size + (i < remainder ? 1 : 0); + if (i == size - 1) { + other_end = n; + } + + MPI_Send(v.data() + other_start, other_end - other_start, MPI_INT, i, 0, MPI_COMM_WORLD); + } + } else { + MPI_Recv(local_data.data(), local_data.size(), MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + } + + int local_min = std::numeric_limits::max(); + int local_idx = -1; + + for (int i = 0; i < static_cast(local_data.size()) - 1; ++i) { + int diff = std::abs(local_data[i + 1] - local_data[i]); + if (diff < local_min) { + local_min = diff; + local_idx = start + i; } + } - if (rank < size - 1 && end < n) { - int boundary_diff = std::abs(v[end] - local_data.back()); - if (boundary_diff < local_min) { - local_min = boundary_diff; - local_idx = end - 1; - } + if (rank < size - 1 && end < n) { + int boundary_diff = std::abs(v[end] - local_data.back()); + if (boundary_diff < local_min) { + local_min = boundary_diff; + local_idx = end - 1; } + } - struct { int val; int idx; } local{local_min, local_idx}, global; - MPI_Allreduce(&local, &global, 1, MPI_2INT, MPI_MINLOC, MPI_COMM_WORLD); - - GetOutput() = global.idx; - return true; + struct { + int val; + int idx; + } local{local_min, local_idx}, global; + MPI_Allreduce(&local, &global, 1, MPI_2INT, MPI_MINLOC, MPI_COMM_WORLD); + + GetOutput() = global.idx; + return true; } bool KuterginAClosestPairMPI::PostProcessingImpl() { diff --git a/tasks/kutergin_a_closest_pair/seq/include/ops_seq.hpp b/tasks/kutergin_a_closest_pair/seq/include/ops_seq.hpp index c14b0b7f07..045ed3700b 100644 --- a/tasks/kutergin_a_closest_pair/seq/include/ops_seq.hpp +++ b/tasks/kutergin_a_closest_pair/seq/include/ops_seq.hpp @@ -22,4 +22,4 @@ class KuterginAClosestPairSEQ : public BaseTask { bool PostProcessingImpl() override; }; -} // namespace kutergin_a_closest_pair \ No newline at end of file +} // namespace kutergin_a_closest_pair diff --git a/tasks/kutergin_a_closest_pair/seq/src/ops_seq.cpp b/tasks/kutergin_a_closest_pair/seq/src/ops_seq.cpp index 15bfdb63a4..4cf3c917b7 100644 --- a/tasks/kutergin_a_closest_pair/seq/src/ops_seq.cpp +++ b/tasks/kutergin_a_closest_pair/seq/src/ops_seq.cpp @@ -17,11 +17,11 @@ KuterginAClosestPairSEQ::KuterginAClosestPairSEQ(const InType &in) { } bool KuterginAClosestPairSEQ::ValidationImpl() { - return true; + return true; } bool KuterginAClosestPairSEQ::PreProcessingImpl() { - return true; + return true; } bool KuterginAClosestPairSEQ::RunImpl() { @@ -29,7 +29,7 @@ bool KuterginAClosestPairSEQ::RunImpl() { if (v.size() < 2) { GetOutput() = -1; return true; -} + } int best_idx = 0; int min_diff = std::abs(v[1] - v[0]); diff --git a/tasks/kutergin_a_closest_pair/tests/functional/main.cpp b/tasks/kutergin_a_closest_pair/tests/functional/main.cpp index ac122ab34c..89b35beceb 100644 --- a/tasks/kutergin_a_closest_pair/tests/functional/main.cpp +++ b/tasks/kutergin_a_closest_pair/tests/functional/main.cpp @@ -23,16 +23,18 @@ namespace kutergin_a_closest_pair { class KuterginAClosestPairFuncTests : public ppc::util::BaseRunFuncTests { public: static std::string PrintTestParam(const TestType &test_param) { - return std::get<1>(test_param); + return std::get<1>(test_param); } protected: void SetUp() override { TestType params = std::get(ppc::util::GTestParamIndex::kTestParams)>(GetParam()); input_data_ = std::get<0>(std::get<0>(params)); - expected_ = std::get<1>(std::get<0>(params)); + expected_ = std::get<1>(std::get<0>(params)); std::cout << "Test: " << std::get<1>(params) << "\nInput: "; - for (auto v : input_data_) std::cout << v << ' '; + for (auto v : input_data_) { + std::cout << v << ' '; + } std::cout << "\nExpected index: " << expected_ << "\n"; } @@ -50,44 +52,37 @@ class KuterginAClosestPairFuncTests : public ppc::util::BaseRunFuncTests v1{1,3,5,6,9}; // closest pair 5-6 => index 2 -std::vector v2{10,11,30,40}; // 10-11 => index 0 -std::vector v3{5,2,3,10}; // 2-3 => index 1 -std::vector v4{100,99,101,200}; // 100-99 => index 0 -std::vector v5{1}; // no pair => -1 -std::vector v6{}; // no pair => -1 -std::vector v7{4,4,4,4}; // 4-4 => index 0 -std::vector v8{-10,-5,-7,0}; // closest pair -5,-7 => index 1 -std::vector v9{-1,-2,-8,-10,-11}; // closest pair -1,-2 => index 0 -std::vector v10{-100,50,-50,0}; // closest pair 50,-50 => index 1 +std::vector v1{1, 3, 5, 6, 9}; // closest pair 5-6 => index 2 +std::vector v2{10, 11, 30, 40}; // 10-11 => index 0 +std::vector v3{5, 2, 3, 10}; // 2-3 => index 1 +std::vector v4{100, 99, 101, 200}; // 100-99 => index 0 +std::vector v5{1}; // no pair => -1 +std::vector v6{}; // no pair => -1 +std::vector v7{4, 4, 4, 4}; // 4-4 => index 0 +std::vector v8{-10, -5, -7, 0}; // closest pair -5,-7 => index 1 +std::vector v9{-1, -2, -8, -10, -11}; // closest pair -1,-2 => index 0 +std::vector v10{-100, 50, -50, 0}; // closest pair 50,-50 => index 1 const std::array kTestParam = { - std::make_tuple(std::make_tuple(v1,2), "test1"), - std::make_tuple(std::make_tuple(v2,0), "test2"), - std::make_tuple(std::make_tuple(v3,1), "test3"), - std::make_tuple(std::make_tuple(v4,0), "test4"), - std::make_tuple(std::make_tuple(v5,-1), "test5"), - std::make_tuple(std::make_tuple(v6,-1), "test6"), - std::make_tuple(std::make_tuple(v7,0), "test7"), - std::make_tuple(std::make_tuple(v8,1), "test8"), - std::make_tuple(std::make_tuple(v9,0), "test9"), - std::make_tuple(std::make_tuple(v10,2), "test10") -}; + std::make_tuple(std::make_tuple(v1, 2), "test1"), std::make_tuple(std::make_tuple(v2, 0), "test2"), + std::make_tuple(std::make_tuple(v3, 1), "test3"), std::make_tuple(std::make_tuple(v4, 0), "test4"), + std::make_tuple(std::make_tuple(v5, -1), "test5"), std::make_tuple(std::make_tuple(v6, -1), "test6"), + std::make_tuple(std::make_tuple(v7, 0), "test7"), std::make_tuple(std::make_tuple(v8, 1), "test8"), + std::make_tuple(std::make_tuple(v9, 0), "test9"), std::make_tuple(std::make_tuple(v10, 2), "test10")}; - const auto kTestTasksList = std::tuple_cat(ppc::util::AddFuncTask(kTestParam, PPC_SETTINGS_kutergin_a_closest_pair), - ppc::util::AddFuncTask( - kTestParam, PPC_SETTINGS_kutergin_a_closest_pair)); +const auto kTestTasksList = std::tuple_cat( + ppc::util::AddFuncTask(kTestParam, PPC_SETTINGS_kutergin_a_closest_pair), + ppc::util::AddFuncTask(kTestParam, PPC_SETTINGS_kutergin_a_closest_pair)); - const auto kGTestValues = ppc::util::ExpandToValues(kTestTasksList); +const auto kGTestValues = ppc::util::ExpandToValues(kTestTasksList); - const auto kNameGen = - KuterginAClosestPairFuncTests::PrintFuncTestName; +const auto kNameGen = KuterginAClosestPairFuncTests::PrintFuncTestName; - INSTANTIATE_TEST_SUITE_P(ClosestPairTests,KuterginAClosestPairFuncTests,kGTestValues,kNameGen); +INSTANTIATE_TEST_SUITE_P(ClosestPairTests, KuterginAClosestPairFuncTests, kGTestValues, kNameGen); - TEST_P(KuterginAClosestPairFuncTests, ClosestPairTest) { - ExecuteTest(GetParam()); - } +TEST_P(KuterginAClosestPairFuncTests, ClosestPairTest) { + ExecuteTest(GetParam()); +} } // namespace } // namespace kutergin_a_closest_pair diff --git a/tasks/kutergin_a_closest_pair/tests/performance/main.cpp b/tasks/kutergin_a_closest_pair/tests/performance/main.cpp index c089f316be..76328e51d9 100644 --- a/tasks/kutergin_a_closest_pair/tests/performance/main.cpp +++ b/tasks/kutergin_a_closest_pair/tests/performance/main.cpp @@ -10,26 +10,26 @@ namespace kutergin_a_closest_pair { class KuterginAClosestPairPerfTests : public ppc::util::BaseRunPerfTests { - public: + public: void SetUp() override { const size_t vector_size = 100000000; std::vector vector(vector_size); - + for (size_t i = 0; i < vector_size; i++) { - vector[i] = static_cast(i % 1000) + ((i & 1) == 0 ? 1 : -1); + vector[i] = static_cast(i % 1000) + ((i & 1) == 0 ? 1 : -1); } - input_data_ = std::move(vector); -} + input_data_ = std::move(vector); + } bool CheckTestOutputData(OutType &output_data) final { - return output_data == 0; + return output_data == 0; } InType GetTestInputData() final { return input_data_; } - private: + private: InType input_data_; }; @@ -37,8 +37,8 @@ TEST_P(KuterginAClosestPairPerfTests, RunPerfModes) { ExecuteTest(GetParam()); } -const auto kAllPerfTasks = - ppc::util::MakeAllPerfTasks(PPC_SETTINGS_kutergin_a_closest_pair); +const auto kAllPerfTasks = ppc::util::MakeAllPerfTasks( + PPC_SETTINGS_kutergin_a_closest_pair); const auto kGtestValues = ppc::util::TupleToGTestValues(kAllPerfTasks); From f5dd08ca88225fdd175d56bb85698b7c35d82125 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 19 Nov 2025 19:46:28 +0000 Subject: [PATCH 3/5] clang-tidy --- .../mpi/include/ops_mpi.hpp | 2 +- .../mpi/src/ops_mpi.cpp | 180 ++++++++++++------ .../seq/include/ops_seq.hpp | 4 +- .../seq/src/ops_seq.cpp | 17 +- .../tests/functional/main.cpp | 3 + 5 files changed, 136 insertions(+), 70 deletions(-) diff --git a/tasks/kutergin_a_closest_pair/mpi/include/ops_mpi.hpp b/tasks/kutergin_a_closest_pair/mpi/include/ops_mpi.hpp index 099ad9843f..ae452aa1c7 100644 --- a/tasks/kutergin_a_closest_pair/mpi/include/ops_mpi.hpp +++ b/tasks/kutergin_a_closest_pair/mpi/include/ops_mpi.hpp @@ -19,4 +19,4 @@ class KuterginAClosestPairMPI : public BaseTask { bool PostProcessingImpl() override; }; -} // namespace kutergin_a_closest_pair +} // namespace kutergin_a_closest_pair \ No newline at end of file diff --git a/tasks/kutergin_a_closest_pair/mpi/src/ops_mpi.cpp b/tasks/kutergin_a_closest_pair/mpi/src/ops_mpi.cpp index 17606709bf..a058579d68 100644 --- a/tasks/kutergin_a_closest_pair/mpi/src/ops_mpi.cpp +++ b/tasks/kutergin_a_closest_pair/mpi/src/ops_mpi.cpp @@ -26,78 +26,140 @@ bool KuterginAClosestPairMPI::PreProcessingImpl() { return true; } -bool KuterginAClosestPairMPI::RunImpl() { - int rank, size; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - MPI_Comm_size(MPI_COMM_WORLD, &size); - - const auto &v = GetInput(); - int n = v.size(); - - MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD); +// Вспомогательные функции (не методы класса) +namespace { + +std::vector DistributeData(int rank, int size, int n, const std::vector& v) { + int local_size = n / size; + int remainder = n % size; + + int start = rank * local_size + std::min(rank, remainder); + int end = start + local_size + (rank < remainder ? 1 : 0); + + if (rank == size - 1) { + end = n; + } + + std::vector local_data(end - start); + if (rank == 0) { + std::copy(v.begin() + start, v.begin() + end, local_data.begin()); + + for (int i = 1; i < size; ++i) { + int other_start = i * local_size + std::min(i, remainder); + int other_end = other_start + local_size + (i < remainder ? 1 : 0); + if (i == size - 1) { + other_end = n; + } + + MPI_Send(v.data() + other_start, other_end - other_start, + MPI_INT, i, 0, MPI_COMM_WORLD); + } + } else { + MPI_Recv(local_data.data(), static_cast(local_data.size()), + MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + } + + return local_data; +} - if (n < 2) { - GetOutput() = -1; - return true; - } - int local_size = n / size; - int remainder = n % size; +int FindLocalMin(const std::vector& local_data, int start_idx, int& found_idx) { + int local_min = std::numeric_limits::max(); + found_idx = -1; + + for (int i = 0; i < static_cast(local_data.size()) - 1; ++i) { + int diff = std::abs(local_data[i + 1] - local_data[i]); + if (diff < local_min) { + local_min = diff; + found_idx = start_idx + i; + } + } + + return local_min; +} - int start = rank * local_size + std::min(rank, remainder); - int end = start + local_size + (rank < remainder ? 1 : 0); +int CalculateStartIndex(int rank, int size, int n) { + int local_size = n / size; + int remainder = n % size; + return rank * local_size + std::min(rank, remainder); +} - if (rank == size - 1) { - end = n; - } +int CalculateEndIndex(int rank, int size, int n) { + int local_size = n / size; + int remainder = n % size; + int end = CalculateStartIndex(rank, size, n) + local_size + (rank < remainder ? 1 : 0); + if (rank == size - 1) { + end = n; + } + return end; +} - std::vector local_data(end - start); - if (rank == 0) { - std::copy(v.begin() + start, v.begin() + end, local_data.begin()); +int CheckBoundary(int rank, int size, int end, int n, + const std::vector& v, const std::vector& local_data, + int current_min, int& current_idx) { + if (rank < size - 1 && end < n) { + int boundary_diff = std::abs(v[end] - local_data.back()); + if (boundary_diff < current_min) { + current_min = boundary_diff; + current_idx = end - 1; + } + } + return current_min; +} - for (int i = 1; i < size; ++i) { - int other_start = i * local_size + std::min(i, remainder); - int other_end = other_start + local_size + (i < remainder ? 1 : 0); - if (i == size - 1) { - other_end = n; - } +} // namespace - MPI_Send(v.data() + other_start, other_end - other_start, MPI_INT, i, 0, MPI_COMM_WORLD); - } - } else { - MPI_Recv(local_data.data(), local_data.size(), MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - } - - int local_min = std::numeric_limits::max(); - int local_idx = -1; - - for (int i = 0; i < static_cast(local_data.size()) - 1; ++i) { - int diff = std::abs(local_data[i + 1] - local_data[i]); - if (diff < local_min) { - local_min = diff; - local_idx = start + i; +bool KuterginAClosestPairMPI::RunImpl() { + int rank = 0; + int size = 0; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + const auto& v = GetInput(); + int n = static_cast(v.size()); + + MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD); + + if (n < 2) { + GetOutput() = -1; + return true; } - } - if (rank < size - 1 && end < n) { - int boundary_diff = std::abs(v[end] - local_data.back()); - if (boundary_diff < local_min) { - local_min = boundary_diff; - local_idx = end - 1; + // Распределение данных + auto local_data = DistributeData(rank, size, n, v); + if (local_data.empty()) { + GetOutput() = -1; + return true; } - } - - struct { - int val; - int idx; - } local{local_min, local_idx}, global; - MPI_Allreduce(&local, &global, 1, MPI_2INT, MPI_MINLOC, MPI_COMM_WORLD); - GetOutput() = global.idx; - return true; + // Локальный поиск + int start_idx = CalculateStartIndex(rank, size, n); + int local_idx = -1; + int local_min = FindLocalMin(local_data, start_idx, local_idx); + + // Проверка границ + int end = CalculateEndIndex(rank, size, n); + local_min = CheckBoundary(rank, size, end, n, v, local_data, local_min, local_idx); + + // Глобальная редукция + struct MinIndex { + int val = 0; + int idx = -1; + }; + + MinIndex local_result; + local_result.val = local_min; + local_result.idx = local_idx; + + MinIndex global_result; + + MPI_Allreduce(&local_result, &global_result, 1, MPI_2INT, MPI_MINLOC, MPI_COMM_WORLD); + + GetOutput() = global_result.idx; + return true; } bool KuterginAClosestPairMPI::PostProcessingImpl() { return true; } -} // namespace kutergin_a_closest_pair +} // namespace kutergin_a_closest_pair \ No newline at end of file diff --git a/tasks/kutergin_a_closest_pair/seq/include/ops_seq.hpp b/tasks/kutergin_a_closest_pair/seq/include/ops_seq.hpp index 045ed3700b..30f1875a23 100644 --- a/tasks/kutergin_a_closest_pair/seq/include/ops_seq.hpp +++ b/tasks/kutergin_a_closest_pair/seq/include/ops_seq.hpp @@ -1,7 +1,5 @@ #pragma once -#include - #include "kutergin_a_closest_pair/common/include/common.hpp" #include "task/include/task.hpp" @@ -15,7 +13,7 @@ class KuterginAClosestPairSEQ : public BaseTask { explicit KuterginAClosestPairSEQ(const InType &in); private: - std::vector _data; + std::vector data_; bool ValidationImpl() override; bool PreProcessingImpl() override; bool RunImpl() override; diff --git a/tasks/kutergin_a_closest_pair/seq/src/ops_seq.cpp b/tasks/kutergin_a_closest_pair/seq/src/ops_seq.cpp index 4cf3c917b7..0ae6422357 100644 --- a/tasks/kutergin_a_closest_pair/seq/src/ops_seq.cpp +++ b/tasks/kutergin_a_closest_pair/seq/src/ops_seq.cpp @@ -10,10 +10,11 @@ namespace kutergin_a_closest_pair { -KuterginAClosestPairSEQ::KuterginAClosestPairSEQ(const InType &in) { +KuterginAClosestPairSEQ::KuterginAClosestPairSEQ(const InType &in) : data_() { SetTypeOfTask(GetStaticTypeOfTask()); GetInput() = in; GetOutput() = -1; + data_ = in; } bool KuterginAClosestPairSEQ::ValidationImpl() { @@ -25,16 +26,18 @@ bool KuterginAClosestPairSEQ::PreProcessingImpl() { } bool KuterginAClosestPairSEQ::RunImpl() { - const auto &v = GetInput(); - if (v.size() < 2) { + const auto& v = GetInput(); + int n = static_cast(v.size()); + + if (n < 2) { GetOutput() = -1; return true; } - int best_idx = 0; - int min_diff = std::abs(v[1] - v[0]); + int min_diff = std::numeric_limits::max(); + int best_idx = -1; - for (size_t i = 1; i < v.size() - 1; ++i) { + for (int i = 0; i < n - 1; ++i) { int diff = std::abs(v[i + 1] - v[i]); if (diff < min_diff) { min_diff = diff; @@ -50,4 +53,4 @@ bool KuterginAClosestPairSEQ::PostProcessingImpl() { return true; } -} // namespace kutergin_a_closest_pair +} // namespace kutergin_a_closest_pair \ No newline at end of file diff --git a/tasks/kutergin_a_closest_pair/tests/functional/main.cpp b/tasks/kutergin_a_closest_pair/tests/functional/main.cpp index 89b35beceb..6a29dd05d9 100644 --- a/tasks/kutergin_a_closest_pair/tests/functional/main.cpp +++ b/tasks/kutergin_a_closest_pair/tests/functional/main.cpp @@ -22,6 +22,9 @@ namespace kutergin_a_closest_pair { class KuterginAClosestPairFuncTests : public ppc::util::BaseRunFuncTests { public: + + KuterginAClosestPairFuncTests() : input_data_(), expected_(0) {} + static std::string PrintTestParam(const TestType &test_param) { return std::get<1>(test_param); } From fa442e159cd24aa2bf57583daf3cae05a4a2e72d Mon Sep 17 00:00:00 2001 From: root Date: Wed, 19 Nov 2025 19:53:18 +0000 Subject: [PATCH 4/5] clang t and f --- .../mpi/include/ops_mpi.hpp | 2 +- .../mpi/src/ops_mpi.cpp | 213 +++++++++--------- .../seq/src/ops_seq.cpp | 8 +- .../tests/functional/main.cpp | 1 - 4 files changed, 110 insertions(+), 114 deletions(-) diff --git a/tasks/kutergin_a_closest_pair/mpi/include/ops_mpi.hpp b/tasks/kutergin_a_closest_pair/mpi/include/ops_mpi.hpp index ae452aa1c7..099ad9843f 100644 --- a/tasks/kutergin_a_closest_pair/mpi/include/ops_mpi.hpp +++ b/tasks/kutergin_a_closest_pair/mpi/include/ops_mpi.hpp @@ -19,4 +19,4 @@ class KuterginAClosestPairMPI : public BaseTask { bool PostProcessingImpl() override; }; -} // namespace kutergin_a_closest_pair \ No newline at end of file +} // namespace kutergin_a_closest_pair diff --git a/tasks/kutergin_a_closest_pair/mpi/src/ops_mpi.cpp b/tasks/kutergin_a_closest_pair/mpi/src/ops_mpi.cpp index a058579d68..b3bf2dccde 100644 --- a/tasks/kutergin_a_closest_pair/mpi/src/ops_mpi.cpp +++ b/tasks/kutergin_a_closest_pair/mpi/src/ops_mpi.cpp @@ -29,137 +29,134 @@ bool KuterginAClosestPairMPI::PreProcessingImpl() { // Вспомогательные функции (не методы класса) namespace { -std::vector DistributeData(int rank, int size, int n, const std::vector& v) { - int local_size = n / size; - int remainder = n % size; - - int start = rank * local_size + std::min(rank, remainder); - int end = start + local_size + (rank < remainder ? 1 : 0); - - if (rank == size - 1) { - end = n; - } - - std::vector local_data(end - start); - if (rank == 0) { - std::copy(v.begin() + start, v.begin() + end, local_data.begin()); - - for (int i = 1; i < size; ++i) { - int other_start = i * local_size + std::min(i, remainder); - int other_end = other_start + local_size + (i < remainder ? 1 : 0); - if (i == size - 1) { - other_end = n; - } - - MPI_Send(v.data() + other_start, other_end - other_start, - MPI_INT, i, 0, MPI_COMM_WORLD); - } - } else { - MPI_Recv(local_data.data(), static_cast(local_data.size()), - MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); +std::vector DistributeData(int rank, int size, int n, const std::vector &v) { + int local_size = n / size; + int remainder = n % size; + + int start = rank * local_size + std::min(rank, remainder); + int end = start + local_size + (rank < remainder ? 1 : 0); + + if (rank == size - 1) { + end = n; + } + + std::vector local_data(end - start); + if (rank == 0) { + std::copy(v.begin() + start, v.begin() + end, local_data.begin()); + + for (int i = 1; i < size; ++i) { + int other_start = i * local_size + std::min(i, remainder); + int other_end = other_start + local_size + (i < remainder ? 1 : 0); + if (i == size - 1) { + other_end = n; + } + + MPI_Send(v.data() + other_start, other_end - other_start, MPI_INT, i, 0, MPI_COMM_WORLD); } - - return local_data; + } else { + MPI_Recv(local_data.data(), static_cast(local_data.size()), MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + } + + return local_data; } -int FindLocalMin(const std::vector& local_data, int start_idx, int& found_idx) { - int local_min = std::numeric_limits::max(); - found_idx = -1; - - for (int i = 0; i < static_cast(local_data.size()) - 1; ++i) { - int diff = std::abs(local_data[i + 1] - local_data[i]); - if (diff < local_min) { - local_min = diff; - found_idx = start_idx + i; - } +int FindLocalMin(const std::vector &local_data, int start_idx, int &found_idx) { + int local_min = std::numeric_limits::max(); + found_idx = -1; + + for (int i = 0; i < static_cast(local_data.size()) - 1; ++i) { + int diff = std::abs(local_data[i + 1] - local_data[i]); + if (diff < local_min) { + local_min = diff; + found_idx = start_idx + i; } - - return local_min; + } + + return local_min; } int CalculateStartIndex(int rank, int size, int n) { - int local_size = n / size; - int remainder = n % size; - return rank * local_size + std::min(rank, remainder); + int local_size = n / size; + int remainder = n % size; + return rank * local_size + std::min(rank, remainder); } int CalculateEndIndex(int rank, int size, int n) { - int local_size = n / size; - int remainder = n % size; - int end = CalculateStartIndex(rank, size, n) + local_size + (rank < remainder ? 1 : 0); - if (rank == size - 1) { - end = n; - } - return end; + int local_size = n / size; + int remainder = n % size; + int end = CalculateStartIndex(rank, size, n) + local_size + (rank < remainder ? 1 : 0); + if (rank == size - 1) { + end = n; + } + return end; } -int CheckBoundary(int rank, int size, int end, int n, - const std::vector& v, const std::vector& local_data, - int current_min, int& current_idx) { - if (rank < size - 1 && end < n) { - int boundary_diff = std::abs(v[end] - local_data.back()); - if (boundary_diff < current_min) { - current_min = boundary_diff; - current_idx = end - 1; - } +int CheckBoundary(int rank, int size, int end, int n, const std::vector &v, const std::vector &local_data, + int current_min, int ¤t_idx) { + if (rank < size - 1 && end < n) { + int boundary_diff = std::abs(v[end] - local_data.back()); + if (boundary_diff < current_min) { + current_min = boundary_diff; + current_idx = end - 1; } - return current_min; + } + return current_min; } -} // namespace +} // namespace bool KuterginAClosestPairMPI::RunImpl() { - int rank = 0; - int size = 0; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - MPI_Comm_size(MPI_COMM_WORLD, &size); - - const auto& v = GetInput(); - int n = static_cast(v.size()); - - MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD); - - if (n < 2) { - GetOutput() = -1; - return true; - } + int rank = 0; + int size = 0; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); - // Распределение данных - auto local_data = DistributeData(rank, size, n, v); - if (local_data.empty()) { - GetOutput() = -1; - return true; - } + const auto &v = GetInput(); + int n = static_cast(v.size()); - // Локальный поиск - int start_idx = CalculateStartIndex(rank, size, n); - int local_idx = -1; - int local_min = FindLocalMin(local_data, start_idx, local_idx); - - // Проверка границ - int end = CalculateEndIndex(rank, size, n); - local_min = CheckBoundary(rank, size, end, n, v, local_data, local_min, local_idx); - - // Глобальная редукция - struct MinIndex { - int val = 0; - int idx = -1; - }; - - MinIndex local_result; - local_result.val = local_min; - local_result.idx = local_idx; - - MinIndex global_result; - - MPI_Allreduce(&local_result, &global_result, 1, MPI_2INT, MPI_MINLOC, MPI_COMM_WORLD); - - GetOutput() = global_result.idx; + MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD); + + if (n < 2) { + GetOutput() = -1; + return true; + } + + // Распределение данных + auto local_data = DistributeData(rank, size, n, v); + if (local_data.empty()) { + GetOutput() = -1; return true; + } + + // Локальный поиск + int start_idx = CalculateStartIndex(rank, size, n); + int local_idx = -1; + int local_min = FindLocalMin(local_data, start_idx, local_idx); + + // Проверка границ + int end = CalculateEndIndex(rank, size, n); + local_min = CheckBoundary(rank, size, end, n, v, local_data, local_min, local_idx); + + // Глобальная редукция + struct MinIndex { + int val = 0; + int idx = -1; + }; + + MinIndex local_result; + local_result.val = local_min; + local_result.idx = local_idx; + + MinIndex global_result; + + MPI_Allreduce(&local_result, &global_result, 1, MPI_2INT, MPI_MINLOC, MPI_COMM_WORLD); + + GetOutput() = global_result.idx; + return true; } bool KuterginAClosestPairMPI::PostProcessingImpl() { return true; } -} // namespace kutergin_a_closest_pair \ No newline at end of file +} // namespace kutergin_a_closest_pair diff --git a/tasks/kutergin_a_closest_pair/seq/src/ops_seq.cpp b/tasks/kutergin_a_closest_pair/seq/src/ops_seq.cpp index 0ae6422357..b122bd63a7 100644 --- a/tasks/kutergin_a_closest_pair/seq/src/ops_seq.cpp +++ b/tasks/kutergin_a_closest_pair/seq/src/ops_seq.cpp @@ -14,7 +14,7 @@ KuterginAClosestPairSEQ::KuterginAClosestPairSEQ(const InType &in) : data_() { SetTypeOfTask(GetStaticTypeOfTask()); GetInput() = in; GetOutput() = -1; - data_ = in; + data_ = in; } bool KuterginAClosestPairSEQ::ValidationImpl() { @@ -26,9 +26,9 @@ bool KuterginAClosestPairSEQ::PreProcessingImpl() { } bool KuterginAClosestPairSEQ::RunImpl() { - const auto& v = GetInput(); + const auto &v = GetInput(); int n = static_cast(v.size()); - + if (n < 2) { GetOutput() = -1; return true; @@ -53,4 +53,4 @@ bool KuterginAClosestPairSEQ::PostProcessingImpl() { return true; } -} // namespace kutergin_a_closest_pair \ No newline at end of file +} // namespace kutergin_a_closest_pair diff --git a/tasks/kutergin_a_closest_pair/tests/functional/main.cpp b/tasks/kutergin_a_closest_pair/tests/functional/main.cpp index 6a29dd05d9..b1668621eb 100644 --- a/tasks/kutergin_a_closest_pair/tests/functional/main.cpp +++ b/tasks/kutergin_a_closest_pair/tests/functional/main.cpp @@ -22,7 +22,6 @@ namespace kutergin_a_closest_pair { class KuterginAClosestPairFuncTests : public ppc::util::BaseRunFuncTests { public: - KuterginAClosestPairFuncTests() : input_data_(), expected_(0) {} static std::string PrintTestParam(const TestType &test_param) { From ee6e0e4a9483689abe99543d2176a673c999097b Mon Sep 17 00:00:00 2001 From: root Date: Wed, 19 Nov 2025 20:43:41 +0000 Subject: [PATCH 5/5] clang-tidy format --- tasks/kutergin_a_closest_pair/seq/src/ops_seq.cpp | 3 +-- .../tests/functional/main.cpp | 15 +++++---------- .../tests/performance/main.cpp | 2 ++ 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/tasks/kutergin_a_closest_pair/seq/src/ops_seq.cpp b/tasks/kutergin_a_closest_pair/seq/src/ops_seq.cpp index b122bd63a7..4ed1efa8e8 100644 --- a/tasks/kutergin_a_closest_pair/seq/src/ops_seq.cpp +++ b/tasks/kutergin_a_closest_pair/seq/src/ops_seq.cpp @@ -1,8 +1,7 @@ #include "kutergin_a_closest_pair/seq/include/ops_seq.hpp" -#include +#include #include -#include #include #include "kutergin_a_closest_pair/common/include/common.hpp" diff --git a/tasks/kutergin_a_closest_pair/tests/functional/main.cpp b/tasks/kutergin_a_closest_pair/tests/functional/main.cpp index b1668621eb..f52887587c 100644 --- a/tasks/kutergin_a_closest_pair/tests/functional/main.cpp +++ b/tasks/kutergin_a_closest_pair/tests/functional/main.cpp @@ -1,12 +1,8 @@ #include -#include -#include #include #include -#include -#include -#include +#include #include #include #include @@ -16,13 +12,12 @@ #include "kutergin_a_closest_pair/mpi/include/ops_mpi.hpp" #include "kutergin_a_closest_pair/seq/include/ops_seq.hpp" #include "util/include/func_test_util.hpp" -#include "util/include/util.hpp" namespace kutergin_a_closest_pair { class KuterginAClosestPairFuncTests : public ppc::util::BaseRunFuncTests { public: - KuterginAClosestPairFuncTests() : input_data_(), expected_(0) {} + KuterginAClosestPairFuncTests() : expected_(0) {} static std::string PrintTestParam(const TestType &test_param) { return std::get<1>(test_param); @@ -34,17 +29,17 @@ class KuterginAClosestPairFuncTests : public ppc::util::BaseRunFuncTests(std::get<0>(params)); expected_ = std::get<1>(std::get<0>(params)); std::cout << "Test: " << std::get<1>(params) << "\nInput: "; - for (auto v : input_data_) { + for (const auto &v : input_data_) { std::cout << v << ' '; } std::cout << "\nExpected index: " << expected_ << "\n"; } - bool CheckTestOutputData(OutType &output_data) final { + bool CheckTestOutputData(OutType &output_data) override { return output_data == expected_; } - InType GetTestInputData() final { + InType GetTestInputData() override { return input_data_; } diff --git a/tasks/kutergin_a_closest_pair/tests/performance/main.cpp b/tasks/kutergin_a_closest_pair/tests/performance/main.cpp index 76328e51d9..73e5af7526 100644 --- a/tasks/kutergin_a_closest_pair/tests/performance/main.cpp +++ b/tasks/kutergin_a_closest_pair/tests/performance/main.cpp @@ -1,5 +1,7 @@ #include +#include +#include #include #include "kutergin_a_closest_pair/common/include/common.hpp"