From d07d4580f2b223bee171498cd75ee70767d5515c Mon Sep 17 00:00:00 2001 From: Leonova Anna Date: Mon, 17 Nov 2025 17:29:05 +0300 Subject: [PATCH 01/16] init --- .../common/include/common.hpp | 15 +++ .../data/pic.jpg | Bin 0 -> 23 bytes .../info.json | 9 ++ .../mpi/include/ops_mpi.hpp | 22 +++++ .../mpi/src/ops_mpi.cpp | 70 ++++++++++++++ .../report.md | 0 .../seq/include/ops_seq.hpp | 22 +++++ .../seq/src/ops_seq.cpp | 55 +++++++++++ .../settings.json | 7 ++ .../tests/.clang-tidy | 13 +++ .../tests/functional/main.cpp | 88 ++++++++++++++++++ .../tests/performance/main.cpp | 40 ++++++++ 12 files changed, 341 insertions(+) create mode 100644 tasks/leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp create mode 100644 tasks/leonova_a_most_diff_neigh_vec_elems/data/pic.jpg create mode 100644 tasks/leonova_a_most_diff_neigh_vec_elems/info.json create mode 100644 tasks/leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp create mode 100644 tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp create mode 100644 tasks/leonova_a_most_diff_neigh_vec_elems/report.md create mode 100644 tasks/leonova_a_most_diff_neigh_vec_elems/seq/include/ops_seq.hpp create mode 100644 tasks/leonova_a_most_diff_neigh_vec_elems/seq/src/ops_seq.cpp create mode 100644 tasks/leonova_a_most_diff_neigh_vec_elems/settings.json create mode 100644 tasks/leonova_a_most_diff_neigh_vec_elems/tests/.clang-tidy create mode 100644 tasks/leonova_a_most_diff_neigh_vec_elems/tests/functional/main.cpp create mode 100644 tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp b/tasks/leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp new file mode 100644 index 0000000000..97844364fe --- /dev/null +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include +#include + +#include "task/include/task.hpp" + +namespace leonova_a_most_diff_neigh_vec_elems { + +using InType = std::vector; +using OutType = std::tuple; +using TestType = std::tuple, std::vector>; +using BaseTask = ppc::task::Task; + +} // namespace leonova_a_most_diff_neigh_vec_elems diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/data/pic.jpg b/tasks/leonova_a_most_diff_neigh_vec_elems/data/pic.jpg new file mode 100644 index 0000000000000000000000000000000000000000..637624238c89d914613ed301968bffbf462bc110 GIT binary patch literal 23 bcmWGA<1$h(;xaNd<@(RSzyQYo|NjR7KDY + +#include +#include + +#include "leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp" +#include "util/include/util.hpp" + +namespace leonova_a_most_diff_neigh_vec_elems { + +LeonovaAMostDiffNeighVecElemsMPI::LeonovaAMostDiffNeighVecElemsMPI(const InType &in) { + SetTypeOfTask(GetStaticTypeOfTask()); + GetInput() = in; + GetOutput() = std::tuple(0, 0); +} + +bool LeonovaAMostDiffNeighVecElemsMPI::ValidationImpl() { + return true; +} + +bool LeonovaAMostDiffNeighVecElemsMPI::PreProcessingImpl() { + return true; +} + +bool LeonovaAMostDiffNeighVecElemsMPI::RunImpl() { + // auto input = GetInput(); + // if (input == 0) { + // return false; + // } + + // for (InType i = 0; i < GetInput(); i++) { + // for (InType j = 0; j < GetInput(); j++) { + // for (InType k = 0; k < GetInput(); k++) { + // std::vector tmp(i + j + k, 1); + // GetOutput() += std::accumulate(tmp.begin(), tmp.end(), 0); + // GetOutput() -= i + j + k; + // } + // } + // } + + // const int num_threads = ppc::util::GetNumThreads(); + // GetOutput() *= num_threads; + + // int rank = 0; + // MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + // if (rank == 0) { + // GetOutput() /= num_threads; + // } else { + // int counter = 0; + // for (int i = 0; i < num_threads; i++) { + // counter++; + // } + + // if (counter != 0) { + // GetOutput() /= counter; + // } + // } + + // MPI_Barrier(MPI_COMM_WORLD); + return true; +} + +bool LeonovaAMostDiffNeighVecElemsMPI::PostProcessingImpl() { + return true; +} + +} // namespace leonova_a_most_diff_neigh_vec_elems diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/report.md b/tasks/leonova_a_most_diff_neigh_vec_elems/report.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/seq/include/ops_seq.hpp b/tasks/leonova_a_most_diff_neigh_vec_elems/seq/include/ops_seq.hpp new file mode 100644 index 0000000000..69052d4de2 --- /dev/null +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/seq/include/ops_seq.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include "leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp" +#include "task/include/task.hpp" + +namespace leonova_a_most_diff_neigh_vec_elems { + +class LeonovaAMostDiffNeighVecElemsSEQ : public BaseTask { + public: + static constexpr ppc::task::TypeOfTask GetStaticTypeOfTask() { + return ppc::task::TypeOfTask::kSEQ; + } + explicit LeonovaAMostDiffNeighVecElemsSEQ(const InType &in); + + private: + bool ValidationImpl() override; + bool PreProcessingImpl() override; + bool RunImpl() override; + bool PostProcessingImpl() override; +}; + +} // namespace leonova_a_most_diff_neigh_vec_elems diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/seq/src/ops_seq.cpp b/tasks/leonova_a_most_diff_neigh_vec_elems/seq/src/ops_seq.cpp new file mode 100644 index 0000000000..2a5c4397a9 --- /dev/null +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/seq/src/ops_seq.cpp @@ -0,0 +1,55 @@ +#include "leonova_a_most_diff_neigh_vec_elems/seq/include/ops_seq.hpp" + +#include +#include +#include + +#include "leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp" +#include "util/include/util.hpp" + +namespace leonova_a_most_diff_neigh_vec_elems { + +LeonovaAMostDiffNeighVecElemsSEQ::LeonovaAMostDiffNeighVecElemsSEQ(const InType &in) { + SetTypeOfTask(GetStaticTypeOfTask()); + GetInput() = in; + GetOutput() = std::tuple(0,0); +} + +bool LeonovaAMostDiffNeighVecElemsSEQ::ValidationImpl() { + return true; +}//проверка что данные валидны - у меня нечего валидировать + +bool LeonovaAMostDiffNeighVecElemsSEQ::PreProcessingImpl() { + return true; +}//предобработка данных - мне не нужно + +bool LeonovaAMostDiffNeighVecElemsSEQ::RunImpl() { + if (GetInput().empty()) { + return false;//на вход ничего не пришло - ошибка! + } + if(GetInput().size() == 1)//в векторе всего один элемент => я хочу чтобы вывелся сам элемент в паре с собой - это не ошибка - самая большая разница это 0 + { + std::get<0>(GetOutput()) = GetInput()[0]; + std::get<1>(GetOutput()) = GetInput()[0]; + return true; + } + +int max_diff = -1;//фиктивная разница + for (std::vector::size_type i = 0; i < GetInput().size() - 1; i++) { + std::tuple curr_elems(GetInput()[i], GetInput()[i + 1]);//текущая пара елементов + int curr_diff = abs(std::get<0>(curr_elems) - std::get<1>(curr_elems));//разница очевидно считается по модулю + if(curr_diff > max_diff)//берем первую пару с наибольшей разницей в значениях + { + max_diff = curr_diff; + GetOutput() = curr_elems; + } + } + + return true; +}//основной код + +bool LeonovaAMostDiffNeighVecElemsSEQ::PostProcessingImpl() { + return true; +}//постобработка данных - не нужна + +} // namespace leonova_a_most_diff_neigh_vec_elems diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/settings.json b/tasks/leonova_a_most_diff_neigh_vec_elems/settings.json new file mode 100644 index 0000000000..b1a0d52574 --- /dev/null +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/settings.json @@ -0,0 +1,7 @@ +{ + "tasks_type": "processes", + "tasks": { + "mpi": "enabled", + "seq": "enabled" + } +} diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/tests/.clang-tidy b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/.clang-tidy new file mode 100644 index 0000000000..ef43b7aa8a --- /dev/null +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/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/leonova_a_most_diff_neigh_vec_elems/tests/functional/main.cpp b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/functional/main.cpp new file mode 100644 index 0000000000..4f2c87414b --- /dev/null +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/functional/main.cpp @@ -0,0 +1,88 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp" +#include "leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp" +#include "leonova_a_most_diff_neigh_vec_elems/seq/include/ops_seq.hpp" +#include "util/include/func_test_util.hpp" +#include "util/include/util.hpp" + +namespace leonova_a_most_diff_neigh_vec_elems { + +class MostDiffNeighVecElemsRunFuncTestsProcesses : 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); + return ""; + } + + protected: + void SetUp() override { + // int width = -1; + // int height = -1; + // int channels = -1; + // std::vector img; + // // Read image in RGB to ensure consistent channel count + // { + // std::string abs_path = ppc::util::GetAbsoluteTaskPath(PPC_ID_leonova_a_most_diff_neigh_vec_elems, "pic.jpg"); + // auto *data = stbi_load(abs_path.c_str(), &width, &height, &channels, STBI_rgb); + // if (data == nullptr) { + // throw std::runtime_error("Failed to load image: " + std::string(stbi_failure_reason())); + // } + // channels = STBI_rgb; + // img = std::vector(data, data + (static_cast(width * height * channels))); + // stbi_image_free(data); + // if (std::cmp_not_equal(width, height)) { + // throw std::runtime_error("width != height: "); + // } + // } + + // TestType params = std::get(ppc::util::GTestParamIndex::kTestParams)>(GetParam()); + // input_data_ = width - height + std::min(std::accumulate(img.begin(), img.end(), 0), channels); + } + + bool CheckTestOutputData(OutType &output_data) final { + //return (input_data_ == output_data); + return true; + } + + InType GetTestInputData() final { + return input_data_; + } + + private: + InType input_data_ = std::vector(); +}; + +namespace { + +TEST_P(MostDiffNeighVecElemsRunFuncTestsProcesses, MatmulFromPic) { + ExecuteTest(GetParam()); +} + +const std::array kTestParam = {std::make_tuple(3, "3"), std::make_tuple(5, "5"), std::make_tuple(7, "7")}; + +const auto kTestTasksList = + std::tuple_cat(ppc::util::AddFuncTask(kTestParam, PPC_SETTINGS_leonova_a_most_diff_neigh_vec_elems), + ppc::util::AddFuncTask(kTestParam, PPC_SETTINGS_leonova_a_most_diff_neigh_vec_elems)); + +const auto kGtestValues = ppc::util::ExpandToValues(kTestTasksList); + +const auto kPerfTestName = MostDiffNeighVecElemsRunFuncTestsProcesses::PrintFuncTestName; + +INSTANTIATE_TEST_SUITE_P(VecTests, MostDiffNeighVecElemsRunFuncTestsProcesses, kGtestValues, kPerfTestName);//kPerfTestName + +} // namespace + +} // namespace leonova_a_most_diff_neigh_vec_elems diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp new file mode 100644 index 0000000000..dbda9fcf36 --- /dev/null +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp @@ -0,0 +1,40 @@ +#include + +#include "leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp" +#include "leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp" +#include "leonova_a_most_diff_neigh_vec_elems/seq/include/ops_seq.hpp" +#include "util/include/perf_test_util.hpp" + +namespace leonova_a_most_diff_neigh_vec_elems { + +class MostDiffNeighVecElemsRunPerfTestsProcesses : public ppc::util::BaseRunPerfTests { + const int kCount_ = 100; + InType input_data_{}; + + void SetUp() override { + input_data_ = kCount_; + } + + bool CheckTestOutputData(OutType &output_data) final { + return input_data_ == output_data; + } + + InType GetTestInputData() final { + return input_data_; + } +}; + +TEST_P(MostDiffNeighVecElemsRunPerfTestsProcesses, RunPerfModes) { + ExecuteTest(GetParam()); +} + +const auto kAllPerfTasks = + ppc::util::MakeAllPerfTasks(PPC_SETTINGS_leonova_a_most_diff_neigh_vec_elems); + +const auto kGtestValues = ppc::util::TupleToGTestValues(kAllPerfTasks); + +const auto kPerfTestName = MostDiffNeighVecElemsRunPerfTestsProcesses::CustomPerfTestName; + +INSTANTIATE_TEST_SUITE_P(RunModeTests, MostDiffNeighVecElemsRunPerfTestsProcesses, kGtestValues, kPerfTestName); + +} // namespace leonova_a_most_diff_neigh_vec_elems From d04ff9cc2b161e9717fd42b58e9a7d34190ef9ad Mon Sep 17 00:00:00 2001 From: Leonova Anna Date: Mon, 17 Nov 2025 20:13:40 +0300 Subject: [PATCH 02/16] 1 --- .pre-commit-config.yaml | 104 +++++------ .../common/include/common.hpp | 2 +- .../info.json | 18 +- .../mpi/src/ops_mpi.cpp | 110 +++++++---- .../seq/src/ops_seq.cpp | 28 ++- .../settings.json | 14 +- .../tests/.clang-tidy | 26 +-- .../tests/functional/main.cpp | 176 ++++++++++++++---- .../tests/performance/main.cpp | 149 ++++++++++++++- 9 files changed, 453 insertions(+), 174 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b70f3d31c9..eeb9844077 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,52 +1,52 @@ -# Pre-commit hooks for automated formatting and linting -# See https://pre-commit.com for more information -# See https://pre-commit.com/hooks.html for more hooks - -repos: - # C++ formatting with clang-format - - repo: https://github.com/pre-commit/mirrors-clang-format - rev: v21.1.2 - hooks: - - id: clang-format - files: \.(cpp|hpp|c|h)$ - exclude: ^(3rdparty/|build.*/|install/) - args: [--style=file] - - # CMake formatting - - repo: https://github.com/cheshirekow/cmake-format-precommit - rev: v0.6.13 - hooks: - - id: cmake-format - files: \.(cmake|CMakeLists\.txt)$ - exclude: ^(3rdparty/|build.*/|install/) - - # Ruff Python linter - - repo: https://github.com/charliermarsh/ruff-pre-commit - rev: v0.14.0 - hooks: - - id: ruff - args: [--fix] - - id: ruff-format - - # Flake8 Python style/lint checker (supplemental to Ruff) - - repo: https://github.com/pycqa/flake8 - rev: 7.3.0 - hooks: - - id: flake8 - - # YAML linting - - repo: https://github.com/adrienverge/yamllint.git - rev: v1.37.1 - hooks: - - id: yamllint - - # Shell script linting with shellcheck - - repo: https://github.com/koalaman/shellcheck-precommit - rev: v0.11.0 - hooks: - - id: shellcheck - files: \.sh$ - -# Configuration -default_stages: [pre-commit] -fail_fast: false +# Pre-commit hooks for automated formatting and linting +# See https://pre-commit.com for more information +# See https://pre-commit.com/hooks.html for more hooks + +repos: + # C++ formatting with clang-format + - repo: https://github.com/pre-commit/mirrors-clang-format + rev: v21.1.2 + hooks: + - id: clang-format + files: \.(cpp|hpp|c|h)$ + exclude: ^(3rdparty/|build.*/|install/) + args: [--style=file] + + # CMake formatting + - repo: https://github.com/cheshirekow/cmake-format-precommit + rev: v0.6.13 + hooks: + - id: cmake-format + files: \.(cmake|CMakeLists\.txt)$ + exclude: ^(3rdparty/|build.*/|install/) + + # Ruff Python linter + - repo: https://github.com/charliermarsh/ruff-pre-commit + rev: v0.14.0 + hooks: + - id: ruff + args: [--fix] + - id: ruff-format + + # Flake8 Python style/lint checker (supplemental to Ruff) + - repo: https://github.com/pycqa/flake8 + rev: 7.3.0 + hooks: + - id: flake8 + + # YAML linting + - repo: https://github.com/adrienverge/yamllint.git + rev: v1.37.1 + hooks: + - id: yamllint + + # Shell script linting with shellcheck + - repo: https://github.com/koalaman/shellcheck-precommit + rev: v0.11.0 + hooks: + - id: shellcheck + files: \.sh$ + +# Configuration +default_stages: [pre-commit] +fail_fast: false diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp b/tasks/leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp index 97844364fe..ab3509fea2 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp @@ -1,7 +1,7 @@ #pragma once -#include #include +#include #include "task/include/task.hpp" diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/info.json b/tasks/leonova_a_most_diff_neigh_vec_elems/info.json index 1ec6eb1dc9..674ed3e6c2 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/info.json +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/info.json @@ -1,9 +1,9 @@ -{ - "student": { - "first_name": "Анна", - "last_name": "Леонова", - "middle_name": "Сергеевна", - "group_number": "3823Б1ФИ1", - "task_number": "1" - } -} +{ + "student": { + "first_name": "Анна", + "last_name": "Леонова", + "middle_name": "Сергеевна", + "group_number": "3823Б1ФИ1", + "task_number": "1" + } +} diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp b/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp index f3b895ff51..b26dd4b898 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp @@ -1,9 +1,10 @@ #include "leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp" #include - -#include #include +#include +#include +#include #include "leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp" #include "util/include/util.hpp" @@ -17,7 +18,7 @@ LeonovaAMostDiffNeighVecElemsMPI::LeonovaAMostDiffNeighVecElemsMPI(const InType } bool LeonovaAMostDiffNeighVecElemsMPI::ValidationImpl() { - return true; + return !GetInput().empty(); } bool LeonovaAMostDiffNeighVecElemsMPI::PreProcessingImpl() { @@ -25,41 +26,72 @@ bool LeonovaAMostDiffNeighVecElemsMPI::PreProcessingImpl() { } bool LeonovaAMostDiffNeighVecElemsMPI::RunImpl() { - // auto input = GetInput(); - // if (input == 0) { - // return false; - // } - - // for (InType i = 0; i < GetInput(); i++) { - // for (InType j = 0; j < GetInput(); j++) { - // for (InType k = 0; k < GetInput(); k++) { - // std::vector tmp(i + j + k, 1); - // GetOutput() += std::accumulate(tmp.begin(), tmp.end(), 0); - // GetOutput() -= i + j + k; - // } - // } - // } - - // const int num_threads = ppc::util::GetNumThreads(); - // GetOutput() *= num_threads; - - // int rank = 0; - // MPI_Comm_rank(MPI_COMM_WORLD, &rank); - - // if (rank == 0) { - // GetOutput() /= num_threads; - // } else { - // int counter = 0; - // for (int i = 0; i < num_threads; i++) { - // counter++; - // } - - // if (counter != 0) { - // GetOutput() /= counter; - // } - // } - - // MPI_Barrier(MPI_COMM_WORLD); + const auto& input_vec = GetInput(); + + // Обработка особых случаев + if (input_vec.empty()) { + GetOutput() = std::make_tuple(0, 0); + return true; + } + + if (input_vec.size() == 1) { + GetOutput() = std::make_tuple(input_vec[0], input_vec[0]); + return true; + } + + int rank, size; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + // Для простоты, если процессов больше 1, пусть процесс 0 обработает все данные + // Это временное решение чтобы избежать deadlock'ов + if (size > 1) { + if (rank == 0) { + // Процесс 0 обрабатывает все данные + int max_diff = -1; + std::tuple best_pair(0, 0); + + for (size_t i = 0; i < input_vec.size() - 1; ++i) { + int diff = std::abs(input_vec[i] - input_vec[i + 1]); + if (diff > max_diff) { + max_diff = diff; + best_pair = std::make_tuple(input_vec[i], input_vec[i + 1]); + } + } + + GetOutput() = best_pair; + + // Рассылаем результат всем процессам + int result_first = std::get<0>(best_pair); + int result_second = std::get<1>(best_pair); + for (int dest = 1; dest < size; ++dest) { + MPI_Send(&result_first, 1, MPI_INT, dest, 0, MPI_COMM_WORLD); + MPI_Send(&result_second, 1, MPI_INT, dest, 1, MPI_COMM_WORLD); + } + } else { + // Остальные процессы получают результат + int result_first, result_second; + MPI_Recv(&result_first, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(&result_second, 1, MPI_INT, 0, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + GetOutput() = std::make_tuple(result_first, result_second); + } + } else { + // Только один процесс - обрабатываем последовательно + int max_diff = -1; + std::tuple best_pair(0, 0); + + for (size_t i = 0; i < input_vec.size() - 1; ++i) { + int diff = std::abs(input_vec[i] - input_vec[i + 1]); + if (diff > max_diff) { + max_diff = diff; + best_pair = std::make_tuple(input_vec[i], input_vec[i + 1]); + } + } + + GetOutput() = best_pair; + } + + MPI_Barrier(MPI_COMM_WORLD); return true; } @@ -67,4 +99,4 @@ bool LeonovaAMostDiffNeighVecElemsMPI::PostProcessingImpl() { return true; } -} // namespace leonova_a_most_diff_neigh_vec_elems +} // namespace leonova_a_most_diff_neigh_vec_elems \ No newline at end of file diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/seq/src/ops_seq.cpp b/tasks/leonova_a_most_diff_neigh_vec_elems/seq/src/ops_seq.cpp index 2a5c4397a9..bea3d3285c 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/seq/src/ops_seq.cpp +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/seq/src/ops_seq.cpp @@ -1,7 +1,7 @@ #include "leonova_a_most_diff_neigh_vec_elems/seq/include/ops_seq.hpp" -#include #include +#include #include #include "leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp" @@ -12,33 +12,31 @@ namespace leonova_a_most_diff_neigh_vec_elems { LeonovaAMostDiffNeighVecElemsSEQ::LeonovaAMostDiffNeighVecElemsSEQ(const InType &in) { SetTypeOfTask(GetStaticTypeOfTask()); GetInput() = in; - GetOutput() = std::tuple(0,0); + GetOutput() = std::tuple(0, 0); } bool LeonovaAMostDiffNeighVecElemsSEQ::ValidationImpl() { - return true; -}//проверка что данные валидны - у меня нечего валидировать + return !GetInput().empty(); +} // проверка что данные валидны bool LeonovaAMostDiffNeighVecElemsSEQ::PreProcessingImpl() { return true; -}//предобработка данных - мне не нужно +} // предобработка данных - мне не нужно bool LeonovaAMostDiffNeighVecElemsSEQ::RunImpl() { - if (GetInput().empty()) { - return false;//на вход ничего не пришло - ошибка! - } - if(GetInput().size() == 1)//в векторе всего один элемент => я хочу чтобы вывелся сам элемент в паре с собой - это не ошибка - самая большая разница это 0 + if (GetInput().size() == 1) // в векторе всего один элемент => я хочу чтобы вывелся сам элемент в паре с собой - это + // не ошибка - самая большая разница это 0 { std::get<0>(GetOutput()) = GetInput()[0]; std::get<1>(GetOutput()) = GetInput()[0]; return true; } -int max_diff = -1;//фиктивная разница + int max_diff = -1; // фиктивная разница for (std::vector::size_type i = 0; i < GetInput().size() - 1; i++) { - std::tuple curr_elems(GetInput()[i], GetInput()[i + 1]);//текущая пара елементов - int curr_diff = abs(std::get<0>(curr_elems) - std::get<1>(curr_elems));//разница очевидно считается по модулю - if(curr_diff > max_diff)//берем первую пару с наибольшей разницей в значениях + std::tuple curr_elems(GetInput()[i], GetInput()[i + 1]); // текущая пара елементов + int curr_diff = abs(std::get<0>(curr_elems) - std::get<1>(curr_elems)); // разница очевидно считается по модулю + if (curr_diff > max_diff) // берем первую пару с наибольшей разницей в значениях { max_diff = curr_diff; GetOutput() = curr_elems; @@ -46,10 +44,10 @@ int max_diff = -1;//фиктивная разница } return true; -}//основной код +} // основной код bool LeonovaAMostDiffNeighVecElemsSEQ::PostProcessingImpl() { return true; -}//постобработка данных - не нужна +} // постобработка данных - не нужна } // namespace leonova_a_most_diff_neigh_vec_elems diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/settings.json b/tasks/leonova_a_most_diff_neigh_vec_elems/settings.json index b1a0d52574..7d2c35b298 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/settings.json +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/settings.json @@ -1,7 +1,7 @@ -{ - "tasks_type": "processes", - "tasks": { - "mpi": "enabled", - "seq": "enabled" - } -} +{ + "tasks_type": "processes", + "tasks": { + "mpi": "enabled", + "seq": "enabled" + } +} diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/tests/.clang-tidy b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/.clang-tidy index ef43b7aa8a..d68523c24e 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/tests/.clang-tidy +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/.clang-tidy @@ -1,13 +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 +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/leonova_a_most_diff_neigh_vec_elems/tests/functional/main.cpp b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/functional/main.cpp index 4f2c87414b..36cb2e28db 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/tests/functional/main.cpp +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/functional/main.cpp @@ -1,5 +1,99 @@ +// #include +// #include + +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include + +// #include "leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp" +// #include "leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp" +// #include "leonova_a_most_diff_neigh_vec_elems/seq/include/ops_seq.hpp" +// #include "util/include/func_test_util.hpp" +// #include "util/include/util.hpp" + +// namespace leonova_a_most_diff_neigh_vec_elems { + +// class MostDiffNeighVecElemsRunFuncTestsProcesses : 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); +// return ""; +// } + +// protected: +// void SetUp() override {//дает данные для теста +// // int width = -1; +// // int height = -1; +// // int channels = -1; +// // std::vector img; +// // // Read image in RGB to ensure consistent channel count +// // { +// // std::string abs_path = ppc::util::GetAbsoluteTaskPath(PPC_ID_leonova_a_most_diff_neigh_vec_elems, +// "pic.jpg"); +// // auto *data = stbi_load(abs_path.c_str(), &width, &height, &channels, STBI_rgb); +// // if (data == nullptr) { +// // throw std::runtime_error("Failed to load image: " + std::string(stbi_failure_reason())); +// // } +// // channels = STBI_rgb; +// // img = std::vector(data, data + (static_cast(width * height * channels))); +// // stbi_image_free(data); +// // if (std::cmp_not_equal(width, height)) { +// // throw std::runtime_error("width != height: "); +// // } +// // } + +// // TestType params = std::get(ppc::util::GTestParamIndex::kTestParams)>(GetParam()); +// // input_data_ = width - height + std::min(std::accumulate(img.begin(), img.end(), 0), channels); +// } + +// bool CheckTestOutputData(OutType &output_data) final {//проверяетвыход +// //return (input_data_ == output_data); +// return true; +// } + +// InType GetTestInputData() final { +// return input_data_; +// } + +// private: +// InType input_data_ = std::vector(); +// }; + +// namespace { + +// TEST_P(MostDiffNeighVecElemsRunFuncTestsProcesses, VecElemsDiff) { +// ExecuteTest(GetParam()); +// } + +// const std::array kTestParam = {};//{std::make_tuple(3, "3"), std::make_tuple(5, "5"), std::make_tuple(7, +// "7")}; + +// const auto kTestTasksList = +// std::tuple_cat(ppc::util::AddFuncTask(kTestParam, +// PPC_SETTINGS_leonova_a_most_diff_neigh_vec_elems), +// ppc::util::AddFuncTask(kTestParam, +// PPC_SETTINGS_leonova_a_most_diff_neigh_vec_elems)); + +// const auto kGtestValues = ppc::util::ExpandToValues(kTestTasksList); + +// const auto kPerfTestName = +// MostDiffNeighVecElemsRunFuncTestsProcesses::PrintFuncTestName; + +// INSTANTIATE_TEST_SUITE_P(VecTests, MostDiffNeighVecElemsRunFuncTestsProcesses, kGtestValues, +// kPerfTestName);//kPerfTestName + +// } // namespace + +// } // namespace leonova_a_most_diff_neigh_vec_elems + #include -#include #include #include @@ -22,39 +116,44 @@ namespace leonova_a_most_diff_neigh_vec_elems { class MostDiffNeighVecElemsRunFuncTestsProcesses : 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); - return ""; + // static std::string PrintTestParam(const TestType &test_param) { + // // Возвращаем строковое представление тестового параметра + // auto expected_pair = std::get<0>(test_param); + // return "expected_" + std::to_string(std::get<0>(expected_pair)) + "_" + + // std::to_string(std::get<1>(expected_pair)); + // } + // static std::string PrintTestParam(const TestType &test_param) { + // auto expected_pair = std::get<0>(test_param); + // // Используем только буквы, цифры и подчеркивания + // return "expected_" + std::to_string(std::get<0>(expected_pair)) + "_" + + // std::to_string(std::get<1>(expected_pair)); + // } + static std::string PrintTestParam(const TestType &test_param) { + auto expected_pair = std::get<0>(test_param); + int first = std::get<0>(expected_pair); + int second = std::get<1>(expected_pair); + + std::string first_str = (first < 0) ? "neg" + std::to_string(-first) : std::to_string(first); + std::string second_str = (second < 0) ? "neg" + std::to_string(-second) : std::to_string(second); + + return "expected_" + first_str + "_" + second_str; } protected: void SetUp() override { - // int width = -1; - // int height = -1; - // int channels = -1; - // std::vector img; - // // Read image in RGB to ensure consistent channel count - // { - // std::string abs_path = ppc::util::GetAbsoluteTaskPath(PPC_ID_leonova_a_most_diff_neigh_vec_elems, "pic.jpg"); - // auto *data = stbi_load(abs_path.c_str(), &width, &height, &channels, STBI_rgb); - // if (data == nullptr) { - // throw std::runtime_error("Failed to load image: " + std::string(stbi_failure_reason())); - // } - // channels = STBI_rgb; - // img = std::vector(data, data + (static_cast(width * height * channels))); - // stbi_image_free(data); - // if (std::cmp_not_equal(width, height)) { - // throw std::runtime_error("width != height: "); - // } - // } - - // TestType params = std::get(ppc::util::GTestParamIndex::kTestParams)>(GetParam()); - // input_data_ = width - height + std::min(std::accumulate(img.begin(), img.end(), 0), channels); + // Получаем параметры теста + TestType params = std::get(ppc::util::GTestParamIndex::kTestParams)>(GetParam()); + + // input_data_ - это вектор для обработки + input_data_ = std::get<1>(params); + + // expected_output_ - ожидаемая пара элементов + expected_output_ = std::get<0>(params); } bool CheckTestOutputData(OutType &output_data) final { - //return (input_data_ == output_data); - return true; + // Проверяем, что выходные данные соответствуют ожидаемым + return (expected_output_ == output_data); } InType GetTestInputData() final { @@ -63,25 +162,34 @@ class MostDiffNeighVecElemsRunFuncTestsProcesses : public ppc::util::BaseRunFunc private: InType input_data_ = std::vector(); + OutType expected_output_ = std::tuple(0, 0); }; namespace { -TEST_P(MostDiffNeighVecElemsRunFuncTestsProcesses, MatmulFromPic) { +TEST_P(MostDiffNeighVecElemsRunFuncTestsProcesses, VecElemsDiff) { ExecuteTest(GetParam()); } -const std::array kTestParam = {std::make_tuple(3, "3"), std::make_tuple(5, "5"), std::make_tuple(7, "7")}; +// Определяем тестовые случаи +const std::array kTestParam = { + std::make_tuple(std::make_tuple(1, 10), std::vector{1, 10, 3, 10, 5}), // Максимальная разница между 1 и 10 + std::make_tuple(std::make_tuple(5, 20), std::vector{5, 20, 15, 10}), // Максимальная разница между 5 и 20 + std::make_tuple(std::make_tuple(7, 7), std::vector{7}), // Один элемент + std::make_tuple(std::make_tuple(0, 100), std::vector{0, 100, 100, 25}), // Максимальная разница между 0 и 100 + std::make_tuple(std::make_tuple(-10, -5), std::vector{-10, -5, -1, 3, 0, 0})}; -const auto kTestTasksList = - std::tuple_cat(ppc::util::AddFuncTask(kTestParam, PPC_SETTINGS_leonova_a_most_diff_neigh_vec_elems), - ppc::util::AddFuncTask(kTestParam, PPC_SETTINGS_leonova_a_most_diff_neigh_vec_elems)); +const auto kTestTasksList = std::tuple_cat(ppc::util::AddFuncTask( + kTestParam, PPC_SETTINGS_leonova_a_most_diff_neigh_vec_elems), + ppc::util::AddFuncTask( + kTestParam, PPC_SETTINGS_leonova_a_most_diff_neigh_vec_elems)); const auto kGtestValues = ppc::util::ExpandToValues(kTestTasksList); -const auto kPerfTestName = MostDiffNeighVecElemsRunFuncTestsProcesses::PrintFuncTestName; +const auto kPerfTestName = + MostDiffNeighVecElemsRunFuncTestsProcesses::PrintFuncTestName; -INSTANTIATE_TEST_SUITE_P(VecTests, MostDiffNeighVecElemsRunFuncTestsProcesses, kGtestValues, kPerfTestName);//kPerfTestName +INSTANTIATE_TEST_SUITE_P(VecTests, MostDiffNeighVecElemsRunFuncTestsProcesses, kGtestValues, kPerfTestName); } // namespace diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp index dbda9fcf36..718cebe7be 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp @@ -1,5 +1,117 @@ +// #include + +// #include "leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp" +// #include "leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp" +// #include "leonova_a_most_diff_neigh_vec_elems/seq/include/ops_seq.hpp" +// #include "util/include/perf_test_util.hpp" + +// namespace leonova_a_most_diff_neigh_vec_elems { + +// class MostDiffNeighVecElemsRunPerfTestsProcesses : public ppc::util::BaseRunPerfTests { +// const int kCount_ = 100; +// InType input_data_{}; + +// void SetUp() override { +// //input_data_ = kCount_; +// } + +// bool CheckTestOutputData(OutType &output_data) final { +// //return input_data_ == output_data; +// return true; +// } + +// InType GetTestInputData() final { +// return input_data_; +// } +// }; + +// TEST_P(MostDiffNeighVecElemsRunPerfTestsProcesses, RunPerfModes) { +// ExecuteTest(GetParam()); +// } + +// const auto kAllPerfTasks = +// ppc::util::MakeAllPerfTasks(PPC_SETTINGS_leonova_a_most_diff_neigh_vec_elems); + +// const auto kGtestValues = ppc::util::TupleToGTestValues(kAllPerfTasks); + +// const auto kPerfTestName = MostDiffNeighVecElemsRunPerfTestsProcesses::CustomPerfTestName; + +// INSTANTIATE_TEST_SUITE_P(RunModeTests, MostDiffNeighVecElemsRunPerfTestsProcesses, kGtestValues, kPerfTestName); + +// } // namespace leonova_a_most_diff_neigh_vec_elems + +// #include +// #include +// #include + +// #include "leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp" +// #include "leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp" +// #include "leonova_a_most_diff_neigh_vec_elems/seq/include/ops_seq.hpp" +// #include "util/include/perf_test_util.hpp" + +// namespace leonova_a_most_diff_neigh_vec_elems { + +// class MostDiffNeighVecElemsRunPerfTestsProcesses : public ppc::util::BaseRunPerfTests { +// const size_t kVectorSize_ = 1000000; // Большой вектор для performance тестов +// InType input_data_{}; + +// void SetUp() override { +// // Генерируем большой вектор для performance тестирования +// input_data_.resize(kVectorSize_); + +// // Заполняем вектор данными, создавая сценарий где максимальная разница +// // будет в определенном месте для проверки корректности +// std::random_device rd; +// std::mt19937 gen(rd()); +// std::uniform_int_distribution dist(1, 1000); + +// for (size_t i = 0; i < kVectorSize_; ++i) { +// input_data_[i] = dist(gen); +// } + +// // Создаем гарантированную максимальную разницу в середине вектора +// // для проверки что алгоритм работает корректно +// if (kVectorSize_ > 100) { +// input_data_[kVectorSize_ / 2] = 1; +// input_data_[kVectorSize_ / 2 + 1] = 10000; // Большая разница +// } +// } + +// bool CheckTestOutputData(OutType &output_data) final { +// // Проверяем что результат логически корректен +// // В performance тестах полная проверка может быть не нужна, +// // но базовая валидация важна +// int diff = std::abs(std::get<0>(output_data) - std::get<1>(output_data)); +// return diff >= 0; // Разница должна быть неотрицательной +// } + +// InType GetTestInputData() final { +// return input_data_; +// } +// }; + +// TEST_P(MostDiffNeighVecElemsRunPerfTestsProcesses, RunPerfModes) { +// ExecuteTest(GetParam()); +// } + +// const auto kAllPerfTasks = +// ppc::util::MakeAllPerfTasks(PPC_SETTINGS_leonova_a_most_diff_neigh_vec_elems); + +// const auto kGtestValues = ppc::util::TupleToGTestValues(kAllPerfTasks); + +// const auto kPerfTestName = MostDiffNeighVecElemsRunPerfTestsProcesses::CustomPerfTestName; + +// INSTANTIATE_TEST_SUITE_P(RunModeTests, MostDiffNeighVecElemsRunPerfTestsProcesses, kGtestValues, kPerfTestName); + +// } // namespace leonova_a_most_diff_neigh_vec_elems + #include +#include +#include + #include "leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp" #include "leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp" #include "leonova_a_most_diff_neigh_vec_elems/seq/include/ops_seq.hpp" @@ -8,15 +120,43 @@ namespace leonova_a_most_diff_neigh_vec_elems { class MostDiffNeighVecElemsRunPerfTestsProcesses : public ppc::util::BaseRunPerfTests { - const int kCount_ = 100; + const size_t kVectorSize_ = 1000000; InType input_data_{}; + OutType expected_output_{}; void SetUp() override { - input_data_ = kCount_; + input_data_.resize(kVectorSize_); + + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution dist(1, 1000); + + // Заполняем вектор случайными числами + for (size_t i = 0; i < kVectorSize_; ++i) { + input_data_[i] = dist(gen); + } + + // Создаем гарантированную МАКСИМАЛЬНУЮ РАЗНИЦУ МЕЖДУ СОСЕДНИМИ ЭЛЕМЕНТАМИ + // в определенной позиции + size_t max_diff_position = kVectorSize_ / 2; + if (max_diff_position + 1 < kVectorSize_) { + input_data_[max_diff_position] = 1; + input_data_[max_diff_position + 1] = 10000; // Большая разница между соседями + expected_output_ = std::make_tuple(1, 10000); + } + + // Добавляем еще одну большую разницу в другом месте (но меньшую) + size_t second_diff_position = kVectorSize_ / 4; + if (second_diff_position + 1 < kVectorSize_) { + input_data_[second_diff_position] = 100; + input_data_[second_diff_position + 1] = 5000; // Меньшая разница + } } bool CheckTestOutputData(OutType &output_data) final { - return input_data_ == output_data; + // Проверяем, что алгоритм нашел именно пару с максимальной разницей + // между СОСЕДНИМИ элементами + return (output_data == expected_output_) || (std::abs(std::get<0>(output_data) - std::get<1>(output_data)) == 9999); } InType GetTestInputData() final { @@ -29,7 +169,8 @@ TEST_P(MostDiffNeighVecElemsRunPerfTestsProcesses, RunPerfModes) { } const auto kAllPerfTasks = - ppc::util::MakeAllPerfTasks(PPC_SETTINGS_leonova_a_most_diff_neigh_vec_elems); + ppc::util::MakeAllPerfTasks( + PPC_SETTINGS_leonova_a_most_diff_neigh_vec_elems); const auto kGtestValues = ppc::util::TupleToGTestValues(kAllPerfTasks); From c7c023f0ce8040830bb7fd41717d54f6741e40d8 Mon Sep 17 00:00:00 2001 From: Leonova Anna Date: Mon, 17 Nov 2025 20:37:13 +0300 Subject: [PATCH 03/16] 2 --- .pre-commit-config.yaml | 104 +++++++++--------- .../mpi/src/ops_mpi.cpp | 23 ++-- .../seq/src/ops_seq.cpp | 2 +- .../tests/.clang-tidy | 26 ++--- 4 files changed, 78 insertions(+), 77 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index eeb9844077..b70f3d31c9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,52 +1,52 @@ -# Pre-commit hooks for automated formatting and linting -# See https://pre-commit.com for more information -# See https://pre-commit.com/hooks.html for more hooks - -repos: - # C++ formatting with clang-format - - repo: https://github.com/pre-commit/mirrors-clang-format - rev: v21.1.2 - hooks: - - id: clang-format - files: \.(cpp|hpp|c|h)$ - exclude: ^(3rdparty/|build.*/|install/) - args: [--style=file] - - # CMake formatting - - repo: https://github.com/cheshirekow/cmake-format-precommit - rev: v0.6.13 - hooks: - - id: cmake-format - files: \.(cmake|CMakeLists\.txt)$ - exclude: ^(3rdparty/|build.*/|install/) - - # Ruff Python linter - - repo: https://github.com/charliermarsh/ruff-pre-commit - rev: v0.14.0 - hooks: - - id: ruff - args: [--fix] - - id: ruff-format - - # Flake8 Python style/lint checker (supplemental to Ruff) - - repo: https://github.com/pycqa/flake8 - rev: 7.3.0 - hooks: - - id: flake8 - - # YAML linting - - repo: https://github.com/adrienverge/yamllint.git - rev: v1.37.1 - hooks: - - id: yamllint - - # Shell script linting with shellcheck - - repo: https://github.com/koalaman/shellcheck-precommit - rev: v0.11.0 - hooks: - - id: shellcheck - files: \.sh$ - -# Configuration -default_stages: [pre-commit] -fail_fast: false +# Pre-commit hooks for automated formatting and linting +# See https://pre-commit.com for more information +# See https://pre-commit.com/hooks.html for more hooks + +repos: + # C++ formatting with clang-format + - repo: https://github.com/pre-commit/mirrors-clang-format + rev: v21.1.2 + hooks: + - id: clang-format + files: \.(cpp|hpp|c|h)$ + exclude: ^(3rdparty/|build.*/|install/) + args: [--style=file] + + # CMake formatting + - repo: https://github.com/cheshirekow/cmake-format-precommit + rev: v0.6.13 + hooks: + - id: cmake-format + files: \.(cmake|CMakeLists\.txt)$ + exclude: ^(3rdparty/|build.*/|install/) + + # Ruff Python linter + - repo: https://github.com/charliermarsh/ruff-pre-commit + rev: v0.14.0 + hooks: + - id: ruff + args: [--fix] + - id: ruff-format + + # Flake8 Python style/lint checker (supplemental to Ruff) + - repo: https://github.com/pycqa/flake8 + rev: 7.3.0 + hooks: + - id: flake8 + + # YAML linting + - repo: https://github.com/adrienverge/yamllint.git + rev: v1.37.1 + hooks: + - id: yamllint + + # Shell script linting with shellcheck + - repo: https://github.com/koalaman/shellcheck-precommit + rev: v0.11.0 + hooks: + - id: shellcheck + files: \.sh$ + +# Configuration +default_stages: [pre-commit] +fail_fast: false diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp b/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp index b26dd4b898..8fe142b9c2 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp @@ -1,10 +1,11 @@ #include "leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp" #include -#include -#include + #include #include +#include +#include #include "leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp" #include "util/include/util.hpp" @@ -26,14 +27,14 @@ bool LeonovaAMostDiffNeighVecElemsMPI::PreProcessingImpl() { } bool LeonovaAMostDiffNeighVecElemsMPI::RunImpl() { - const auto& input_vec = GetInput(); - + const auto &input_vec = GetInput(); + // Обработка особых случаев if (input_vec.empty()) { GetOutput() = std::make_tuple(0, 0); return true; } - + if (input_vec.size() == 1) { GetOutput() = std::make_tuple(input_vec[0], input_vec[0]); return true; @@ -50,7 +51,7 @@ bool LeonovaAMostDiffNeighVecElemsMPI::RunImpl() { // Процесс 0 обрабатывает все данные int max_diff = -1; std::tuple best_pair(0, 0); - + for (size_t i = 0; i < input_vec.size() - 1; ++i) { int diff = std::abs(input_vec[i] - input_vec[i + 1]); if (diff > max_diff) { @@ -58,9 +59,9 @@ bool LeonovaAMostDiffNeighVecElemsMPI::RunImpl() { best_pair = std::make_tuple(input_vec[i], input_vec[i + 1]); } } - + GetOutput() = best_pair; - + // Рассылаем результат всем процессам int result_first = std::get<0>(best_pair); int result_second = std::get<1>(best_pair); @@ -79,7 +80,7 @@ bool LeonovaAMostDiffNeighVecElemsMPI::RunImpl() { // Только один процесс - обрабатываем последовательно int max_diff = -1; std::tuple best_pair(0, 0); - + for (size_t i = 0; i < input_vec.size() - 1; ++i) { int diff = std::abs(input_vec[i] - input_vec[i + 1]); if (diff > max_diff) { @@ -87,7 +88,7 @@ bool LeonovaAMostDiffNeighVecElemsMPI::RunImpl() { best_pair = std::make_tuple(input_vec[i], input_vec[i + 1]); } } - + GetOutput() = best_pair; } @@ -99,4 +100,4 @@ bool LeonovaAMostDiffNeighVecElemsMPI::PostProcessingImpl() { return true; } -} // namespace leonova_a_most_diff_neigh_vec_elems \ No newline at end of file +} // namespace leonova_a_most_diff_neigh_vec_elems diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/seq/src/ops_seq.cpp b/tasks/leonova_a_most_diff_neigh_vec_elems/seq/src/ops_seq.cpp index bea3d3285c..a69420eed1 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/seq/src/ops_seq.cpp +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/seq/src/ops_seq.cpp @@ -34,7 +34,7 @@ bool LeonovaAMostDiffNeighVecElemsSEQ::RunImpl() { int max_diff = -1; // фиктивная разница for (std::vector::size_type i = 0; i < GetInput().size() - 1; i++) { - std::tuple curr_elems(GetInput()[i], GetInput()[i + 1]); // текущая пара елементов + std::tuple curr_elems(GetInput()[i], GetInput()[i + 1]); // текущая пара елементов int curr_diff = abs(std::get<0>(curr_elems) - std::get<1>(curr_elems)); // разница очевидно считается по модулю if (curr_diff > max_diff) // берем первую пару с наибольшей разницей в значениях { diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/tests/.clang-tidy b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/.clang-tidy index d68523c24e..ef43b7aa8a 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/tests/.clang-tidy +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/.clang-tidy @@ -1,13 +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 +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 From ee76b43ab83ebf3a7b9d17754069bcfc8da60703 Mon Sep 17 00:00:00 2001 From: Leonova Anna Date: Mon, 17 Nov 2025 21:16:08 +0000 Subject: [PATCH 04/16] perf tests fix --- .../tests/performance/main.cpp | 122 +++++++++++++++--- 1 file changed, 105 insertions(+), 17 deletions(-) diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp index 718cebe7be..a13d5094e8 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp @@ -107,6 +107,80 @@ // } // namespace leonova_a_most_diff_neigh_vec_elems +// #include + +// #include +// #include + +// #include "leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp" +// #include "leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp" +// #include "leonova_a_most_diff_neigh_vec_elems/seq/include/ops_seq.hpp" +// #include "util/include/perf_test_util.hpp" + +// namespace leonova_a_most_diff_neigh_vec_elems { + +// class MostDiffNeighVecElemsRunPerfTestsProcesses : public ppc::util::BaseRunPerfTests { +// const size_t kVectorSize_ = 1000000; +// InType input_data_{}; +// OutType expected_output_{}; + +// void SetUp() override { +// input_data_.resize(kVectorSize_); + +// std::random_device rd; +// std::mt19937 gen(rd()); +// std::uniform_int_distribution dist(1, 1000); + +// // Заполняем вектор случайными числами +// for (size_t i = 0; i < kVectorSize_; ++i) { +// input_data_[i] = dist(gen); +// } + +// // Создаем гарантированную МАКСИМАЛЬНУЮ РАЗНИЦУ МЕЖДУ СОСЕДНИМИ ЭЛЕМЕНТАМИ +// // в определенной позиции +// size_t max_diff_position = kVectorSize_ / 2; +// if (max_diff_position + 1 < kVectorSize_) { +// input_data_[max_diff_position] = 1; +// input_data_[max_diff_position + 1] = 10000; // Большая разница между соседями +// expected_output_ = std::make_tuple(1, 10000); +// } + +// // Добавляем еще одну большую разницу в другом месте (но меньшую) +// size_t second_diff_position = kVectorSize_ / 4; +// if (second_diff_position + 1 < kVectorSize_) { +// input_data_[second_diff_position] = 100; +// input_data_[second_diff_position + 1] = 5000; // Меньшая разница +// } +// } + +// bool CheckTestOutputData(OutType &output_data) final { +// // Проверяем, что алгоритм нашел именно пару с максимальной разницей +// // между СОСЕДНИМИ элементами +// return (output_data == expected_output_) || (std::abs(std::get<0>(output_data) - std::get<1>(output_data)) == +// 9999); +// } + +// InType GetTestInputData() final { +// return input_data_; +// } +// }; + +// TEST_P(MostDiffNeighVecElemsRunPerfTestsProcesses, RunPerfModes) { +// ExecuteTest(GetParam()); +// } + +// const auto kAllPerfTasks = +// ppc::util::MakeAllPerfTasks( +// PPC_SETTINGS_leonova_a_most_diff_neigh_vec_elems); + +// const auto kGtestValues = ppc::util::TupleToGTestValues(kAllPerfTasks); + +// const auto kPerfTestName = MostDiffNeighVecElemsRunPerfTestsProcesses::CustomPerfTestName; + +// INSTANTIATE_TEST_SUITE_P(RunModeTests, MostDiffNeighVecElemsRunPerfTestsProcesses, kGtestValues, kPerfTestName); + +// } // namespace leonova_a_most_diff_neigh_vec_elems + #include #include @@ -120,7 +194,8 @@ namespace leonova_a_most_diff_neigh_vec_elems { class MostDiffNeighVecElemsRunPerfTestsProcesses : public ppc::util::BaseRunPerfTests { - const size_t kVectorSize_ = 1000000; + const size_t kVectorSize_ = 10000000; // Увеличили в 10 раз + const int kNumIterations_ = 100; // Добавили итерации для увеличения времени InType input_data_{}; OutType expected_output_{}; @@ -129,34 +204,47 @@ class MostDiffNeighVecElemsRunPerfTestsProcesses : public ppc::util::BaseRunPerf std::random_device rd; std::mt19937 gen(rd()); - std::uniform_int_distribution dist(1, 1000); + std::uniform_int_distribution dist(1, 10000); // Увеличили диапазон // Заполняем вектор случайными числами for (size_t i = 0; i < kVectorSize_; ++i) { input_data_[i] = dist(gen); } - // Создаем гарантированную МАКСИМАЛЬНУЮ РАЗНИЦУ МЕЖДУ СОСЕДНИМИ ЭЛЕМЕНТАМИ - // в определенной позиции - size_t max_diff_position = kVectorSize_ / 2; - if (max_diff_position + 1 < kVectorSize_) { - input_data_[max_diff_position] = 1; - input_data_[max_diff_position + 1] = 10000; // Большая разница между соседями - expected_output_ = std::make_tuple(1, 10000); + // Создаем несколько гарантированных максимальных разниц в разных местах + size_t max_diff_position1 = kVectorSize_ / 4; + size_t max_diff_position2 = kVectorSize_ / 2; + size_t max_diff_position3 = 3 * kVectorSize_ / 4; + + if (max_diff_position1 + 1 < kVectorSize_) { + input_data_[max_diff_position1] = 1; + input_data_[max_diff_position1 + 1] = 50000; // Большая разница + } + + if (max_diff_position2 + 1 < kVectorSize_) { + input_data_[max_diff_position2] = 100; + input_data_[max_diff_position2 + 1] = 60000; // Самая большая разница + expected_output_ = std::make_tuple(100, 60000); + } + + if (max_diff_position3 + 1 < kVectorSize_) { + input_data_[max_diff_position3] = 500; + input_data_[max_diff_position3 + 1] = 45000; // Большая разница } - // Добавляем еще одну большую разницу в другом месте (но меньшую) - size_t second_diff_position = kVectorSize_ / 4; - if (second_diff_position + 1 < kVectorSize_) { - input_data_[second_diff_position] = 100; - input_data_[second_diff_position + 1] = 5000; // Меньшая разница + // Добавляем паттерны для усложнения вычислений + for (size_t i = 0; i < kVectorSize_ / 100; i += 10) { + if (i + 1 < kVectorSize_) { + input_data_[i] = i % 1000; + input_data_[i + 1] = (i + 500) % 1000; + } } } bool CheckTestOutputData(OutType &output_data) final { - // Проверяем, что алгоритм нашел именно пару с максимальной разницей - // между СОСЕДНИМИ элементами - return (output_data == expected_output_) || (std::abs(std::get<0>(output_data) - std::get<1>(output_data)) == 9999); + // Проверяем, что алгоритм нашел пару с достаточно большой разницей + int diff = std::abs(std::get<0>(output_data) - std::get<1>(output_data)); + return diff >= 50000; // Ожидаем разницу не менее 50000 } InType GetTestInputData() final { From 4e53ecbc167ea42d3426f362e1d69b1adde4e0a3 Mon Sep 17 00:00:00 2001 From: Leonova Anna Date: Mon, 17 Nov 2025 21:27:05 +0000 Subject: [PATCH 05/16] perf tests clang --- .../tests/performance/main.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp index a13d5094e8..eb61998e80 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp @@ -195,7 +195,6 @@ namespace leonova_a_most_diff_neigh_vec_elems { class MostDiffNeighVecElemsRunPerfTestsProcesses : public ppc::util::BaseRunPerfTests { const size_t kVectorSize_ = 10000000; // Увеличили в 10 раз - const int kNumIterations_ = 100; // Добавили итерации для увеличения времени InType input_data_{}; OutType expected_output_{}; From da35df833722687880145e93edf960ff45125ef6 Mon Sep 17 00:00:00 2001 From: Leonova Anna Date: Mon, 17 Nov 2025 23:23:19 +0000 Subject: [PATCH 06/16] redo --- .../mpi/src/ops_mpi.cpp | 99 ++++--- .../seq/src/ops_seq.cpp | 19 +- .../tests/functional/main.cpp | 137 +--------- .../tests/performance/main.cpp | 243 ++---------------- 4 files changed, 119 insertions(+), 379 deletions(-) diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp b/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp index 8fe142b9c2..5549201ac8 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp @@ -1,7 +1,6 @@ #include "leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp" #include - #include #include #include @@ -29,10 +28,8 @@ bool LeonovaAMostDiffNeighVecElemsMPI::PreProcessingImpl() { bool LeonovaAMostDiffNeighVecElemsMPI::RunImpl() { const auto &input_vec = GetInput(); - // Обработка особых случаев - if (input_vec.empty()) { - GetOutput() = std::make_tuple(0, 0); - return true; + if (!ValidationImpl()) { + return false; } if (input_vec.size() == 1) { @@ -44,38 +41,80 @@ bool LeonovaAMostDiffNeighVecElemsMPI::RunImpl() { MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); - // Для простоты, если процессов больше 1, пусть процесс 0 обработает все данные - // Это временное решение чтобы избежать deadlock'ов + // Для простоты, если процессов больше 1, используем упрощенный подход + // чтобы избежать deadlock'ов с граничными элементами if (size > 1) { + // Рассылаем все данные всем процессам через MPI_Bcast + int total_size = static_cast(input_vec.size()); + MPI_Bcast(&total_size, 1, MPI_INT, 0, MPI_COMM_WORLD); + + std::vector all_data(total_size); if (rank == 0) { - // Процесс 0 обрабатывает все данные - int max_diff = -1; - std::tuple best_pair(0, 0); - - for (size_t i = 0; i < input_vec.size() - 1; ++i) { - int diff = std::abs(input_vec[i] - input_vec[i + 1]); - if (diff > max_diff) { - max_diff = diff; - best_pair = std::make_tuple(input_vec[i], input_vec[i + 1]); - } + all_data = input_vec; + } + MPI_Bcast(all_data.data(), total_size, MPI_INT, 0, MPI_COMM_WORLD); + + // Каждый процесс обрабатывает свою часть + int local_size = total_size / size; + int remainder = total_size % size; + + int start = rank * local_size + std::min(rank, remainder); + int end = start + local_size + (rank < remainder ? 1 : 0); + + // Убедимся что end не превышает total_size - 1 + if (end > total_size - 1) { + end = total_size - 1; + } + + // Локальный поиск в своей части + int local_max_diff = -1; + int local_first = 0; + int local_second = 0; + + for (int i = start; i < end; ++i) { + int diff = std::abs(all_data[i] - all_data[i + 1]); + if (diff > local_max_diff) { + local_max_diff = diff; + local_first = all_data[i]; + local_second = all_data[i + 1]; } + } - GetOutput() = best_pair; + // Собираем результаты + std::vector all_diffs(size); + std::vector all_firsts(size); + std::vector all_seconds(size); - // Рассылаем результат всем процессам - int result_first = std::get<0>(best_pair); - int result_second = std::get<1>(best_pair); - for (int dest = 1; dest < size; ++dest) { - MPI_Send(&result_first, 1, MPI_INT, dest, 0, MPI_COMM_WORLD); - MPI_Send(&result_second, 1, MPI_INT, dest, 1, MPI_COMM_WORLD); + MPI_Gather(&local_max_diff, 1, MPI_INT, all_diffs.data(), 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Gather(&local_first, 1, MPI_INT, all_firsts.data(), 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Gather(&local_second, 1, MPI_INT, all_seconds.data(), 1, MPI_INT, 0, MPI_COMM_WORLD); + + // Процесс 0 находит глобальный максимум + if (rank == 0) { + int global_max_diff = -1; + int global_first = 0; + int global_second = 0; + + for (int i = 0; i < size; ++i) { + if (all_diffs[i] > global_max_diff) { + global_max_diff = all_diffs[i]; + global_first = all_firsts[i]; + global_second = all_seconds[i]; + } } - } else { - // Остальные процессы получают результат - int result_first, result_second; - MPI_Recv(&result_first, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - MPI_Recv(&result_second, 1, MPI_INT, 0, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + GetOutput() = std::make_tuple(global_first, global_second); + } + + // Рассылаем результат + int result_first = std::get<0>(GetOutput()); + int result_second = std::get<1>(GetOutput()); + MPI_Bcast(&result_first, 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Bcast(&result_second, 1, MPI_INT, 0, MPI_COMM_WORLD); + + if (rank != 0) { GetOutput() = std::make_tuple(result_first, result_second); } + } else { // Только один процесс - обрабатываем последовательно int max_diff = -1; @@ -100,4 +139,4 @@ bool LeonovaAMostDiffNeighVecElemsMPI::PostProcessingImpl() { return true; } -} // namespace leonova_a_most_diff_neigh_vec_elems +} // namespace leonova_a_most_diff_neigh_vec_elems \ No newline at end of file diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/seq/src/ops_seq.cpp b/tasks/leonova_a_most_diff_neigh_vec_elems/seq/src/ops_seq.cpp index a69420eed1..0711a3ee4a 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/seq/src/ops_seq.cpp +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/seq/src/ops_seq.cpp @@ -17,26 +17,25 @@ LeonovaAMostDiffNeighVecElemsSEQ::LeonovaAMostDiffNeighVecElemsSEQ(const InType bool LeonovaAMostDiffNeighVecElemsSEQ::ValidationImpl() { return !GetInput().empty(); -} // проверка что данные валидны +} bool LeonovaAMostDiffNeighVecElemsSEQ::PreProcessingImpl() { return true; -} // предобработка данных - мне не нужно +} bool LeonovaAMostDiffNeighVecElemsSEQ::RunImpl() { - if (GetInput().size() == 1) // в векторе всего один элемент => я хочу чтобы вывелся сам элемент в паре с собой - это - // не ошибка - самая большая разница это 0 + if (GetInput().size() == 1) { std::get<0>(GetOutput()) = GetInput()[0]; std::get<1>(GetOutput()) = GetInput()[0]; return true; } - int max_diff = -1; // фиктивная разница + int max_diff = -1; for (std::vector::size_type i = 0; i < GetInput().size() - 1; i++) { - std::tuple curr_elems(GetInput()[i], GetInput()[i + 1]); // текущая пара елементов - int curr_diff = abs(std::get<0>(curr_elems) - std::get<1>(curr_elems)); // разница очевидно считается по модулю - if (curr_diff > max_diff) // берем первую пару с наибольшей разницей в значениях + std::tuple curr_elems(GetInput()[i], GetInput()[i + 1]); + int curr_diff = abs(std::get<0>(curr_elems) - std::get<1>(curr_elems)); + if (curr_diff > max_diff) { max_diff = curr_diff; GetOutput() = curr_elems; @@ -44,10 +43,10 @@ bool LeonovaAMostDiffNeighVecElemsSEQ::RunImpl() { } return true; -} // основной код +} bool LeonovaAMostDiffNeighVecElemsSEQ::PostProcessingImpl() { return true; -} // постобработка данных - не нужна +} } // namespace leonova_a_most_diff_neigh_vec_elems diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/tests/functional/main.cpp b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/functional/main.cpp index 36cb2e28db..27196350d5 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/tests/functional/main.cpp +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/functional/main.cpp @@ -1,98 +1,3 @@ -// #include -// #include - -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// #include - -// #include "leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp" -// #include "leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp" -// #include "leonova_a_most_diff_neigh_vec_elems/seq/include/ops_seq.hpp" -// #include "util/include/func_test_util.hpp" -// #include "util/include/util.hpp" - -// namespace leonova_a_most_diff_neigh_vec_elems { - -// class MostDiffNeighVecElemsRunFuncTestsProcesses : 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); -// return ""; -// } - -// protected: -// void SetUp() override {//дает данные для теста -// // int width = -1; -// // int height = -1; -// // int channels = -1; -// // std::vector img; -// // // Read image in RGB to ensure consistent channel count -// // { -// // std::string abs_path = ppc::util::GetAbsoluteTaskPath(PPC_ID_leonova_a_most_diff_neigh_vec_elems, -// "pic.jpg"); -// // auto *data = stbi_load(abs_path.c_str(), &width, &height, &channels, STBI_rgb); -// // if (data == nullptr) { -// // throw std::runtime_error("Failed to load image: " + std::string(stbi_failure_reason())); -// // } -// // channels = STBI_rgb; -// // img = std::vector(data, data + (static_cast(width * height * channels))); -// // stbi_image_free(data); -// // if (std::cmp_not_equal(width, height)) { -// // throw std::runtime_error("width != height: "); -// // } -// // } - -// // TestType params = std::get(ppc::util::GTestParamIndex::kTestParams)>(GetParam()); -// // input_data_ = width - height + std::min(std::accumulate(img.begin(), img.end(), 0), channels); -// } - -// bool CheckTestOutputData(OutType &output_data) final {//проверяетвыход -// //return (input_data_ == output_data); -// return true; -// } - -// InType GetTestInputData() final { -// return input_data_; -// } - -// private: -// InType input_data_ = std::vector(); -// }; - -// namespace { - -// TEST_P(MostDiffNeighVecElemsRunFuncTestsProcesses, VecElemsDiff) { -// ExecuteTest(GetParam()); -// } - -// const std::array kTestParam = {};//{std::make_tuple(3, "3"), std::make_tuple(5, "5"), std::make_tuple(7, -// "7")}; - -// const auto kTestTasksList = -// std::tuple_cat(ppc::util::AddFuncTask(kTestParam, -// PPC_SETTINGS_leonova_a_most_diff_neigh_vec_elems), -// ppc::util::AddFuncTask(kTestParam, -// PPC_SETTINGS_leonova_a_most_diff_neigh_vec_elems)); - -// const auto kGtestValues = ppc::util::ExpandToValues(kTestTasksList); - -// const auto kPerfTestName = -// MostDiffNeighVecElemsRunFuncTestsProcesses::PrintFuncTestName; - -// INSTANTIATE_TEST_SUITE_P(VecTests, MostDiffNeighVecElemsRunFuncTestsProcesses, kGtestValues, -// kPerfTestName);//kPerfTestName - -// } // namespace - -// } // namespace leonova_a_most_diff_neigh_vec_elems - #include #include @@ -116,18 +21,6 @@ namespace leonova_a_most_diff_neigh_vec_elems { class MostDiffNeighVecElemsRunFuncTestsProcesses : public ppc::util::BaseRunFuncTests { public: - // static std::string PrintTestParam(const TestType &test_param) { - // // Возвращаем строковое представление тестового параметра - // auto expected_pair = std::get<0>(test_param); - // return "expected_" + std::to_string(std::get<0>(expected_pair)) + "_" + - // std::to_string(std::get<1>(expected_pair)); - // } - // static std::string PrintTestParam(const TestType &test_param) { - // auto expected_pair = std::get<0>(test_param); - // // Используем только буквы, цифры и подчеркивания - // return "expected_" + std::to_string(std::get<0>(expected_pair)) + "_" + - // std::to_string(std::get<1>(expected_pair)); - // } static std::string PrintTestParam(const TestType &test_param) { auto expected_pair = std::get<0>(test_param); int first = std::get<0>(expected_pair); @@ -141,42 +34,38 @@ class MostDiffNeighVecElemsRunFuncTestsProcesses : public ppc::util::BaseRunFunc protected: void SetUp() override { - // Получаем параметры теста + TestType params = std::get(ppc::util::GTestParamIndex::kTestParams)>(GetParam()); - // input_data_ - это вектор для обработки - input_data_ = std::get<1>(params); + input_data = std::get<1>(params); - // expected_output_ - ожидаемая пара элементов - expected_output_ = std::get<0>(params); + expected_output = std::get<0>(params); } bool CheckTestOutputData(OutType &output_data) final { - // Проверяем, что выходные данные соответствуют ожидаемым - return (expected_output_ == output_data); + return (expected_output == output_data); } InType GetTestInputData() final { - return input_data_; + return input_data; } private: - InType input_data_ = std::vector(); - OutType expected_output_ = std::tuple(0, 0); + InType input_data = std::vector(); + OutType expected_output = std::tuple(0, 0); }; namespace { -TEST_P(MostDiffNeighVecElemsRunFuncTestsProcesses, VecElemsDiff) { +TEST_P(MostDiffNeighVecElemsRunFuncTestsProcesses, RunFuncTests) { ExecuteTest(GetParam()); } -// Определяем тестовые случаи const std::array kTestParam = { - std::make_tuple(std::make_tuple(1, 10), std::vector{1, 10, 3, 10, 5}), // Максимальная разница между 1 и 10 - std::make_tuple(std::make_tuple(5, 20), std::vector{5, 20, 15, 10}), // Максимальная разница между 5 и 20 - std::make_tuple(std::make_tuple(7, 7), std::vector{7}), // Один элемент - std::make_tuple(std::make_tuple(0, 100), std::vector{0, 100, 100, 25}), // Максимальная разница между 0 и 100 + std::make_tuple(std::make_tuple(1, 10), std::vector{1, 10, 3, 10, 5}), + std::make_tuple(std::make_tuple(5, 20), std::vector{5, 20, 15, 10}), + std::make_tuple(std::make_tuple(7, 7), std::vector{7}), + std::make_tuple(std::make_tuple(0, 100), std::vector{0, 100, 100, 25}), std::make_tuple(std::make_tuple(-10, -5), std::vector{-10, -5, -1, 3, 0, 0})}; const auto kTestTasksList = std::tuple_cat(ppc::util::AddFuncTask( @@ -189,7 +78,7 @@ const auto kGtestValues = ppc::util::ExpandToValues(kTestTasksList); const auto kPerfTestName = MostDiffNeighVecElemsRunFuncTestsProcesses::PrintFuncTestName; -INSTANTIATE_TEST_SUITE_P(VecTests, MostDiffNeighVecElemsRunFuncTestsProcesses, kGtestValues, kPerfTestName); +INSTANTIATE_TEST_SUITE_P(RunVecFunc, MostDiffNeighVecElemsRunFuncTestsProcesses, kGtestValues, kPerfTestName); } // namespace diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp index eb61998e80..cb767298c0 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp @@ -1,186 +1,3 @@ -// #include - -// #include "leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp" -// #include "leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp" -// #include "leonova_a_most_diff_neigh_vec_elems/seq/include/ops_seq.hpp" -// #include "util/include/perf_test_util.hpp" - -// namespace leonova_a_most_diff_neigh_vec_elems { - -// class MostDiffNeighVecElemsRunPerfTestsProcesses : public ppc::util::BaseRunPerfTests { -// const int kCount_ = 100; -// InType input_data_{}; - -// void SetUp() override { -// //input_data_ = kCount_; -// } - -// bool CheckTestOutputData(OutType &output_data) final { -// //return input_data_ == output_data; -// return true; -// } - -// InType GetTestInputData() final { -// return input_data_; -// } -// }; - -// TEST_P(MostDiffNeighVecElemsRunPerfTestsProcesses, RunPerfModes) { -// ExecuteTest(GetParam()); -// } - -// const auto kAllPerfTasks = -// ppc::util::MakeAllPerfTasks(PPC_SETTINGS_leonova_a_most_diff_neigh_vec_elems); - -// const auto kGtestValues = ppc::util::TupleToGTestValues(kAllPerfTasks); - -// const auto kPerfTestName = MostDiffNeighVecElemsRunPerfTestsProcesses::CustomPerfTestName; - -// INSTANTIATE_TEST_SUITE_P(RunModeTests, MostDiffNeighVecElemsRunPerfTestsProcesses, kGtestValues, kPerfTestName); - -// } // namespace leonova_a_most_diff_neigh_vec_elems - -// #include -// #include -// #include - -// #include "leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp" -// #include "leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp" -// #include "leonova_a_most_diff_neigh_vec_elems/seq/include/ops_seq.hpp" -// #include "util/include/perf_test_util.hpp" - -// namespace leonova_a_most_diff_neigh_vec_elems { - -// class MostDiffNeighVecElemsRunPerfTestsProcesses : public ppc::util::BaseRunPerfTests { -// const size_t kVectorSize_ = 1000000; // Большой вектор для performance тестов -// InType input_data_{}; - -// void SetUp() override { -// // Генерируем большой вектор для performance тестирования -// input_data_.resize(kVectorSize_); - -// // Заполняем вектор данными, создавая сценарий где максимальная разница -// // будет в определенном месте для проверки корректности -// std::random_device rd; -// std::mt19937 gen(rd()); -// std::uniform_int_distribution dist(1, 1000); - -// for (size_t i = 0; i < kVectorSize_; ++i) { -// input_data_[i] = dist(gen); -// } - -// // Создаем гарантированную максимальную разницу в середине вектора -// // для проверки что алгоритм работает корректно -// if (kVectorSize_ > 100) { -// input_data_[kVectorSize_ / 2] = 1; -// input_data_[kVectorSize_ / 2 + 1] = 10000; // Большая разница -// } -// } - -// bool CheckTestOutputData(OutType &output_data) final { -// // Проверяем что результат логически корректен -// // В performance тестах полная проверка может быть не нужна, -// // но базовая валидация важна -// int diff = std::abs(std::get<0>(output_data) - std::get<1>(output_data)); -// return diff >= 0; // Разница должна быть неотрицательной -// } - -// InType GetTestInputData() final { -// return input_data_; -// } -// }; - -// TEST_P(MostDiffNeighVecElemsRunPerfTestsProcesses, RunPerfModes) { -// ExecuteTest(GetParam()); -// } - -// const auto kAllPerfTasks = -// ppc::util::MakeAllPerfTasks(PPC_SETTINGS_leonova_a_most_diff_neigh_vec_elems); - -// const auto kGtestValues = ppc::util::TupleToGTestValues(kAllPerfTasks); - -// const auto kPerfTestName = MostDiffNeighVecElemsRunPerfTestsProcesses::CustomPerfTestName; - -// INSTANTIATE_TEST_SUITE_P(RunModeTests, MostDiffNeighVecElemsRunPerfTestsProcesses, kGtestValues, kPerfTestName); - -// } // namespace leonova_a_most_diff_neigh_vec_elems - -// #include - -// #include -// #include - -// #include "leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp" -// #include "leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp" -// #include "leonova_a_most_diff_neigh_vec_elems/seq/include/ops_seq.hpp" -// #include "util/include/perf_test_util.hpp" - -// namespace leonova_a_most_diff_neigh_vec_elems { - -// class MostDiffNeighVecElemsRunPerfTestsProcesses : public ppc::util::BaseRunPerfTests { -// const size_t kVectorSize_ = 1000000; -// InType input_data_{}; -// OutType expected_output_{}; - -// void SetUp() override { -// input_data_.resize(kVectorSize_); - -// std::random_device rd; -// std::mt19937 gen(rd()); -// std::uniform_int_distribution dist(1, 1000); - -// // Заполняем вектор случайными числами -// for (size_t i = 0; i < kVectorSize_; ++i) { -// input_data_[i] = dist(gen); -// } - -// // Создаем гарантированную МАКСИМАЛЬНУЮ РАЗНИЦУ МЕЖДУ СОСЕДНИМИ ЭЛЕМЕНТАМИ -// // в определенной позиции -// size_t max_diff_position = kVectorSize_ / 2; -// if (max_diff_position + 1 < kVectorSize_) { -// input_data_[max_diff_position] = 1; -// input_data_[max_diff_position + 1] = 10000; // Большая разница между соседями -// expected_output_ = std::make_tuple(1, 10000); -// } - -// // Добавляем еще одну большую разницу в другом месте (но меньшую) -// size_t second_diff_position = kVectorSize_ / 4; -// if (second_diff_position + 1 < kVectorSize_) { -// input_data_[second_diff_position] = 100; -// input_data_[second_diff_position + 1] = 5000; // Меньшая разница -// } -// } - -// bool CheckTestOutputData(OutType &output_data) final { -// // Проверяем, что алгоритм нашел именно пару с максимальной разницей -// // между СОСЕДНИМИ элементами -// return (output_data == expected_output_) || (std::abs(std::get<0>(output_data) - std::get<1>(output_data)) == -// 9999); -// } - -// InType GetTestInputData() final { -// return input_data_; -// } -// }; - -// TEST_P(MostDiffNeighVecElemsRunPerfTestsProcesses, RunPerfModes) { -// ExecuteTest(GetParam()); -// } - -// const auto kAllPerfTasks = -// ppc::util::MakeAllPerfTasks( -// PPC_SETTINGS_leonova_a_most_diff_neigh_vec_elems); - -// const auto kGtestValues = ppc::util::TupleToGTestValues(kAllPerfTasks); - -// const auto kPerfTestName = MostDiffNeighVecElemsRunPerfTestsProcesses::CustomPerfTestName; - -// INSTANTIATE_TEST_SUITE_P(RunModeTests, MostDiffNeighVecElemsRunPerfTestsProcesses, kGtestValues, kPerfTestName); - -// } // namespace leonova_a_most_diff_neigh_vec_elems - #include #include @@ -194,64 +11,60 @@ namespace leonova_a_most_diff_neigh_vec_elems { class MostDiffNeighVecElemsRunPerfTestsProcesses : public ppc::util::BaseRunPerfTests { - const size_t kVectorSize_ = 10000000; // Увеличили в 10 раз - InType input_data_{}; - OutType expected_output_{}; + const size_t n = 30000000; + InType input_data{}; + OutType expected_output{}; void SetUp() override { - input_data_.resize(kVectorSize_); + input_data.resize(n); std::random_device rd; std::mt19937 gen(rd()); - std::uniform_int_distribution dist(1, 10000); // Увеличили диапазон + std::uniform_int_distribution dist(-100000, 100000); - // Заполняем вектор случайными числами - for (size_t i = 0; i < kVectorSize_; ++i) { - input_data_[i] = dist(gen); + for (size_t i = 0; i < n; ++i) { + input_data[i] = dist(gen); } - // Создаем несколько гарантированных максимальных разниц в разных местах - size_t max_diff_position1 = kVectorSize_ / 4; - size_t max_diff_position2 = kVectorSize_ / 2; - size_t max_diff_position3 = 3 * kVectorSize_ / 4; + size_t max_diff_position1 = n / 4; + size_t max_diff_position2 = n / 2; + size_t max_diff_position3 = 3 * n / 4; - if (max_diff_position1 + 1 < kVectorSize_) { - input_data_[max_diff_position1] = 1; - input_data_[max_diff_position1 + 1] = 50000; // Большая разница + if (max_diff_position1 + 1 < n) { + input_data[max_diff_position1] = 1; + input_data[max_diff_position1 + 1] = 50000; } - if (max_diff_position2 + 1 < kVectorSize_) { - input_data_[max_diff_position2] = 100; - input_data_[max_diff_position2 + 1] = 60000; // Самая большая разница - expected_output_ = std::make_tuple(100, 60000); + if (max_diff_position2 + 1 < n) { + input_data[max_diff_position2] = 100; + input_data[max_diff_position2 + 1] = 60000; + expected_output = std::make_tuple(100, 60000); } - if (max_diff_position3 + 1 < kVectorSize_) { - input_data_[max_diff_position3] = 500; - input_data_[max_diff_position3 + 1] = 45000; // Большая разница + if (max_diff_position3 + 1 < n) { + input_data[max_diff_position3] = 500; + input_data[max_diff_position3 + 1] = 45000; } - // Добавляем паттерны для усложнения вычислений - for (size_t i = 0; i < kVectorSize_ / 100; i += 10) { - if (i + 1 < kVectorSize_) { - input_data_[i] = i % 1000; - input_data_[i + 1] = (i + 500) % 1000; + for (size_t i = 0; i < n / 100; i += 10) { + if (i + 1 < n) { + input_data[i] = i % 1000; + input_data[i + 1] = (i + 500) % 1000; } } } bool CheckTestOutputData(OutType &output_data) final { - // Проверяем, что алгоритм нашел пару с достаточно большой разницей int diff = std::abs(std::get<0>(output_data) - std::get<1>(output_data)); - return diff >= 50000; // Ожидаем разницу не менее 50000 + return diff >= 50000; } InType GetTestInputData() final { - return input_data_; + return input_data; } }; -TEST_P(MostDiffNeighVecElemsRunPerfTestsProcesses, RunPerfModes) { +TEST_P(MostDiffNeighVecElemsRunPerfTestsProcesses, RunPerfTests) { ExecuteTest(GetParam()); } @@ -263,6 +76,6 @@ const auto kGtestValues = ppc::util::TupleToGTestValues(kAllPerfTasks); const auto kPerfTestName = MostDiffNeighVecElemsRunPerfTestsProcesses::CustomPerfTestName; -INSTANTIATE_TEST_SUITE_P(RunModeTests, MostDiffNeighVecElemsRunPerfTestsProcesses, kGtestValues, kPerfTestName); +INSTANTIATE_TEST_SUITE_P(RunVecPerf, MostDiffNeighVecElemsRunPerfTestsProcesses, kGtestValues, kPerfTestName); } // namespace leonova_a_most_diff_neigh_vec_elems From 3477380c86c9e01aaa9b3694d95271f9b74a5b9e Mon Sep 17 00:00:00 2001 From: Leonova Anna Date: Mon, 17 Nov 2025 23:26:32 +0000 Subject: [PATCH 07/16] redo clang --- .../mpi/src/ops_mpi.cpp | 9 +++++---- .../seq/src/ops_seq.cpp | 6 ++---- .../tests/functional/main.cpp | 9 ++++----- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp b/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp index 5549201ac8..3f546cd8f9 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp @@ -1,6 +1,7 @@ #include "leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp" #include + #include #include #include @@ -47,7 +48,7 @@ bool LeonovaAMostDiffNeighVecElemsMPI::RunImpl() { // Рассылаем все данные всем процессам через MPI_Bcast int total_size = static_cast(input_vec.size()); MPI_Bcast(&total_size, 1, MPI_INT, 0, MPI_COMM_WORLD); - + std::vector all_data(total_size); if (rank == 0) { all_data = input_vec; @@ -57,10 +58,10 @@ bool LeonovaAMostDiffNeighVecElemsMPI::RunImpl() { // Каждый процесс обрабатывает свою часть int local_size = total_size / size; int remainder = total_size % size; - + int start = rank * local_size + std::min(rank, remainder); int end = start + local_size + (rank < remainder ? 1 : 0); - + // Убедимся что end не превышает total_size - 1 if (end > total_size - 1) { end = total_size - 1; @@ -139,4 +140,4 @@ bool LeonovaAMostDiffNeighVecElemsMPI::PostProcessingImpl() { return true; } -} // namespace leonova_a_most_diff_neigh_vec_elems \ No newline at end of file +} // namespace leonova_a_most_diff_neigh_vec_elems diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/seq/src/ops_seq.cpp b/tasks/leonova_a_most_diff_neigh_vec_elems/seq/src/ops_seq.cpp index 0711a3ee4a..b0c5cd6c55 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/seq/src/ops_seq.cpp +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/seq/src/ops_seq.cpp @@ -24,8 +24,7 @@ bool LeonovaAMostDiffNeighVecElemsSEQ::PreProcessingImpl() { } bool LeonovaAMostDiffNeighVecElemsSEQ::RunImpl() { - if (GetInput().size() == 1) - { + if (GetInput().size() == 1) { std::get<0>(GetOutput()) = GetInput()[0]; std::get<1>(GetOutput()) = GetInput()[0]; return true; @@ -35,8 +34,7 @@ bool LeonovaAMostDiffNeighVecElemsSEQ::RunImpl() { for (std::vector::size_type i = 0; i < GetInput().size() - 1; i++) { std::tuple curr_elems(GetInput()[i], GetInput()[i + 1]); int curr_diff = abs(std::get<0>(curr_elems) - std::get<1>(curr_elems)); - if (curr_diff > max_diff) - { + if (curr_diff > max_diff) { max_diff = curr_diff; GetOutput() = curr_elems; } diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/tests/functional/main.cpp b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/functional/main.cpp index 27196350d5..2c4ccbc3c9 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/tests/functional/main.cpp +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/functional/main.cpp @@ -34,7 +34,6 @@ class MostDiffNeighVecElemsRunFuncTestsProcesses : public ppc::util::BaseRunFunc protected: void SetUp() override { - TestType params = std::get(ppc::util::GTestParamIndex::kTestParams)>(GetParam()); input_data = std::get<1>(params); @@ -62,10 +61,10 @@ TEST_P(MostDiffNeighVecElemsRunFuncTestsProcesses, RunFuncTests) { } const std::array kTestParam = { - std::make_tuple(std::make_tuple(1, 10), std::vector{1, 10, 3, 10, 5}), - std::make_tuple(std::make_tuple(5, 20), std::vector{5, 20, 15, 10}), - std::make_tuple(std::make_tuple(7, 7), std::vector{7}), - std::make_tuple(std::make_tuple(0, 100), std::vector{0, 100, 100, 25}), + std::make_tuple(std::make_tuple(1, 10), std::vector{1, 10, 3, 10, 5}), + std::make_tuple(std::make_tuple(5, 20), std::vector{5, 20, 15, 10}), + std::make_tuple(std::make_tuple(7, 7), std::vector{7}), + std::make_tuple(std::make_tuple(0, 100), std::vector{0, 100, 100, 25}), std::make_tuple(std::make_tuple(-10, -5), std::vector{-10, -5, -1, 3, 0, 0})}; const auto kTestTasksList = std::tuple_cat(ppc::util::AddFuncTask( From 1636292e424b0089cfecbebd64e2f496cd313029 Mon Sep 17 00:00:00 2001 From: Leonova Anna Date: Tue, 18 Nov 2025 00:25:30 +0000 Subject: [PATCH 08/16] better perf tests --- .../mpi/src/ops_mpi.cpp | 64 +++++----- .../tests/performance/main.cpp | 120 ++++++++++++++---- 2 files changed, 127 insertions(+), 57 deletions(-) diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp b/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp index 3f546cd8f9..e54f82d8ac 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp @@ -1,8 +1,6 @@ #include "leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp" #include - -#include #include #include #include @@ -42,46 +40,55 @@ bool LeonovaAMostDiffNeighVecElemsMPI::RunImpl() { MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); - // Для простоты, если процессов больше 1, используем упрощенный подход - // чтобы избежать deadlock'ов с граничными элементами + int total_size = static_cast(input_vec.size()); + if (size > 1) { - // Рассылаем все данные всем процессам через MPI_Bcast - int total_size = static_cast(input_vec.size()); - MPI_Bcast(&total_size, 1, MPI_INT, 0, MPI_COMM_WORLD); + // распределяем данные по кусочкам + int chunk_size = total_size / size; + int remainder = total_size % size; + + // получаем на 1 элемент больше для проверки соседних пар на границах чанков + int my_size = chunk_size + (rank < remainder ? 1 : 0) + 1; + int my_offset = rank * chunk_size + std::min(rank, remainder); - std::vector all_data(total_size); - if (rank == 0) { - all_data = input_vec; + if (rank == size - 1 && my_offset + my_size > total_size) { + my_size = total_size - my_offset; } - MPI_Bcast(all_data.data(), total_size, MPI_INT, 0, MPI_COMM_WORLD); - // Каждый процесс обрабатывает свою часть - int local_size = total_size / size; - int remainder = total_size % size; + std::vector local_data(my_size); - int start = rank * local_size + std::min(rank, remainder); - int end = start + local_size + (rank < remainder ? 1 : 0); + if (rank == 0) { + for (int i = 0; i < my_size; ++i) { + local_data[i] = input_vec[i]; + } + // рассылаем + for (int dest = 1; dest < size; ++dest) { + int dest_size = chunk_size + (dest < remainder ? 1 : 0) + 1; + int dest_offset = dest * chunk_size + std::min(dest, remainder); - // Убедимся что end не превышает total_size - 1 - if (end > total_size - 1) { - end = total_size - 1; + if (dest == size - 1 && dest_offset + dest_size > total_size) { + dest_size = total_size - dest_offset; + } + + MPI_Send(input_vec.data() + dest_offset, dest_size, MPI_INT, dest, 0, MPI_COMM_WORLD); + } + } else { + MPI_Recv(local_data.data(), my_size, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); } - // Локальный поиск в своей части int local_max_diff = -1; int local_first = 0; int local_second = 0; - for (int i = start; i < end; ++i) { - int diff = std::abs(all_data[i] - all_data[i + 1]); + for (int i = 0; i < my_size - 1; ++i) { + int diff = std::abs(local_data[i] - local_data[i + 1]); if (diff > local_max_diff) { local_max_diff = diff; - local_first = all_data[i]; - local_second = all_data[i + 1]; + local_first = local_data[i]; + local_second = local_data[i + 1]; } } - // Собираем результаты std::vector all_diffs(size); std::vector all_firsts(size); std::vector all_seconds(size); @@ -90,7 +97,6 @@ bool LeonovaAMostDiffNeighVecElemsMPI::RunImpl() { MPI_Gather(&local_first, 1, MPI_INT, all_firsts.data(), 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Gather(&local_second, 1, MPI_INT, all_seconds.data(), 1, MPI_INT, 0, MPI_COMM_WORLD); - // Процесс 0 находит глобальный максимум if (rank == 0) { int global_max_diff = -1; int global_first = 0; @@ -106,7 +112,7 @@ bool LeonovaAMostDiffNeighVecElemsMPI::RunImpl() { GetOutput() = std::make_tuple(global_first, global_second); } - // Рассылаем результат + // результат int result_first = std::get<0>(GetOutput()); int result_second = std::get<1>(GetOutput()); MPI_Bcast(&result_first, 1, MPI_INT, 0, MPI_COMM_WORLD); @@ -117,7 +123,6 @@ bool LeonovaAMostDiffNeighVecElemsMPI::RunImpl() { } } else { - // Только один процесс - обрабатываем последовательно int max_diff = -1; std::tuple best_pair(0, 0); @@ -132,7 +137,6 @@ bool LeonovaAMostDiffNeighVecElemsMPI::RunImpl() { GetOutput() = best_pair; } - MPI_Barrier(MPI_COMM_WORLD); return true; } @@ -140,4 +144,4 @@ bool LeonovaAMostDiffNeighVecElemsMPI::PostProcessingImpl() { return true; } -} // namespace leonova_a_most_diff_neigh_vec_elems +} // namespace leonova_a_most_diff_neigh_vec_elems \ No newline at end of file diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp index cb767298c0..641dd8752e 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp @@ -1,7 +1,90 @@ +// #include + +// #include +// #include + +// #include "leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp" +// #include "leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp" +// #include "leonova_a_most_diff_neigh_vec_elems/seq/include/ops_seq.hpp" +// #include "util/include/perf_test_util.hpp" + +// namespace leonova_a_most_diff_neigh_vec_elems { + +// class MostDiffNeighVecElemsRunPerfTestsProcesses : public ppc::util::BaseRunPerfTests { +// const size_t n = 30000000; +// InType input_data{}; +// OutType expected_output{}; + +// void SetUp() override { +// input_data.resize(n); + +// std::random_device rd; +// std::mt19937 gen(rd()); +// std::uniform_int_distribution dist(-100000, 100000); + +// for (size_t i = 0; i < n; ++i) { +// input_data[i] = dist(gen); +// } + +// size_t max_diff_position1 = n / 4; +// size_t max_diff_position2 = n / 2; +// size_t max_diff_position3 = 3 * n / 4; + +// if (max_diff_position1 + 1 < n) { +// input_data[max_diff_position1] = 1; +// input_data[max_diff_position1 + 1] = 50000; +// } + +// if (max_diff_position2 + 1 < n) { +// input_data[max_diff_position2] = 100; +// input_data[max_diff_position2 + 1] = 60000; +// expected_output = std::make_tuple(100, 60000); +// } + +// if (max_diff_position3 + 1 < n) { +// input_data[max_diff_position3] = 500; +// input_data[max_diff_position3 + 1] = 45000; +// } + +// for (size_t i = 0; i < n / 100; i += 10) { +// if (i + 1 < n) { +// input_data[i] = i % 1000; +// input_data[i + 1] = (i + 500) % 1000; +// } +// } +// } + +// bool CheckTestOutputData(OutType &output_data) final { +// return (expected_output == output_data); + +// } + +// InType GetTestInputData() final { +// return input_data; +// } +// }; + +// TEST_P(MostDiffNeighVecElemsRunPerfTestsProcesses, RunPerfTests) { +// ExecuteTest(GetParam()); +// } + +// const auto kAllPerfTasks = +// ppc::util::MakeAllPerfTasks( +// PPC_SETTINGS_leonova_a_most_diff_neigh_vec_elems); + +// const auto kGtestValues = ppc::util::TupleToGTestValues(kAllPerfTasks); + +// const auto kPerfTestName = MostDiffNeighVecElemsRunPerfTestsProcesses::CustomPerfTestName; + +// INSTANTIATE_TEST_SUITE_P(RunVecPerf, MostDiffNeighVecElemsRunPerfTestsProcesses, kGtestValues, kPerfTestName); + +// } // namespace leonova_a_most_diff_neigh_vec_elems + #include #include #include +#include #include "leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp" #include "leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp" @@ -22,41 +105,24 @@ class MostDiffNeighVecElemsRunPerfTestsProcesses : public ppc::util::BaseRunPerf std::mt19937 gen(rd()); std::uniform_int_distribution dist(-100000, 100000); + // Заполняем вектор случайными числами for (size_t i = 0; i < n; ++i) { input_data[i] = dist(gen); } - size_t max_diff_position1 = n / 4; - size_t max_diff_position2 = n / 2; - size_t max_diff_position3 = 3 * n / 4; + // Выбираем СЛУЧАЙНУЮ позицию для максимальной пары + std::uniform_int_distribution pos_dist(0, n - 2); // От 0 до n-2 (чтобы была пара) + size_t max_diff_position = pos_dist(gen); - if (max_diff_position1 + 1 < n) { - input_data[max_diff_position1] = 1; - input_data[max_diff_position1 + 1] = 50000; - } - - if (max_diff_position2 + 1 < n) { - input_data[max_diff_position2] = 100; - input_data[max_diff_position2 + 1] = 60000; - expected_output = std::make_tuple(100, 60000); - } - - if (max_diff_position3 + 1 < n) { - input_data[max_diff_position3] = 500; - input_data[max_diff_position3 + 1] = 45000; - } - - for (size_t i = 0; i < n / 100; i += 10) { - if (i + 1 < n) { - input_data[i] = i % 1000; - input_data[i + 1] = (i + 500) % 1000; - } - } + // Создаем гарантированно максимальную пару + input_data[max_diff_position] = -150000; + input_data[max_diff_position + 1] = 150000; + expected_output = std::make_tuple(-150000, 150000); } bool CheckTestOutputData(OutType &output_data) final { - int diff = std::abs(std::get<0>(output_data) - std::get<1>(output_data)); - return diff >= 50000; + // Проверяем точное совпадение с ожидаемым результатом + return (expected_output == output_data); } InType GetTestInputData() final { From 6d17463c75e41548d82d57b7b8f930167548d182 Mon Sep 17 00:00:00 2001 From: Leonova Anna Date: Tue, 18 Nov 2025 00:33:48 +0000 Subject: [PATCH 09/16] better perf tests + clang --- .../mpi/src/ops_mpi.cpp | 7 +- .../tests/performance/main.cpp | 92 +------------------ 2 files changed, 8 insertions(+), 91 deletions(-) diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp b/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp index e54f82d8ac..3fb71e52ef 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp @@ -1,6 +1,7 @@ #include "leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp" #include + #include #include #include @@ -46,7 +47,7 @@ bool LeonovaAMostDiffNeighVecElemsMPI::RunImpl() { // распределяем данные по кусочкам int chunk_size = total_size / size; int remainder = total_size % size; - + // получаем на 1 элемент больше для проверки соседних пар на границах чанков int my_size = chunk_size + (rank < remainder ? 1 : 0) + 1; int my_offset = rank * chunk_size + std::min(rank, remainder); @@ -69,7 +70,7 @@ bool LeonovaAMostDiffNeighVecElemsMPI::RunImpl() { if (dest == size - 1 && dest_offset + dest_size > total_size) { dest_size = total_size - dest_offset; } - + MPI_Send(input_vec.data() + dest_offset, dest_size, MPI_INT, dest, 0, MPI_COMM_WORLD); } } else { @@ -144,4 +145,4 @@ bool LeonovaAMostDiffNeighVecElemsMPI::PostProcessingImpl() { return true; } -} // namespace leonova_a_most_diff_neigh_vec_elems \ No newline at end of file +} // namespace leonova_a_most_diff_neigh_vec_elems diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp index 641dd8752e..ab15159aa6 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp @@ -1,90 +1,8 @@ -// #include - -// #include -// #include - -// #include "leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp" -// #include "leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp" -// #include "leonova_a_most_diff_neigh_vec_elems/seq/include/ops_seq.hpp" -// #include "util/include/perf_test_util.hpp" - -// namespace leonova_a_most_diff_neigh_vec_elems { - -// class MostDiffNeighVecElemsRunPerfTestsProcesses : public ppc::util::BaseRunPerfTests { -// const size_t n = 30000000; -// InType input_data{}; -// OutType expected_output{}; - -// void SetUp() override { -// input_data.resize(n); - -// std::random_device rd; -// std::mt19937 gen(rd()); -// std::uniform_int_distribution dist(-100000, 100000); - -// for (size_t i = 0; i < n; ++i) { -// input_data[i] = dist(gen); -// } - -// size_t max_diff_position1 = n / 4; -// size_t max_diff_position2 = n / 2; -// size_t max_diff_position3 = 3 * n / 4; - -// if (max_diff_position1 + 1 < n) { -// input_data[max_diff_position1] = 1; -// input_data[max_diff_position1 + 1] = 50000; -// } - -// if (max_diff_position2 + 1 < n) { -// input_data[max_diff_position2] = 100; -// input_data[max_diff_position2 + 1] = 60000; -// expected_output = std::make_tuple(100, 60000); -// } - -// if (max_diff_position3 + 1 < n) { -// input_data[max_diff_position3] = 500; -// input_data[max_diff_position3 + 1] = 45000; -// } - -// for (size_t i = 0; i < n / 100; i += 10) { -// if (i + 1 < n) { -// input_data[i] = i % 1000; -// input_data[i + 1] = (i + 500) % 1000; -// } -// } -// } - -// bool CheckTestOutputData(OutType &output_data) final { -// return (expected_output == output_data); - -// } - -// InType GetTestInputData() final { -// return input_data; -// } -// }; - -// TEST_P(MostDiffNeighVecElemsRunPerfTestsProcesses, RunPerfTests) { -// ExecuteTest(GetParam()); -// } - -// const auto kAllPerfTasks = -// ppc::util::MakeAllPerfTasks( -// PPC_SETTINGS_leonova_a_most_diff_neigh_vec_elems); - -// const auto kGtestValues = ppc::util::TupleToGTestValues(kAllPerfTasks); - -// const auto kPerfTestName = MostDiffNeighVecElemsRunPerfTestsProcesses::CustomPerfTestName; - -// INSTANTIATE_TEST_SUITE_P(RunVecPerf, MostDiffNeighVecElemsRunPerfTestsProcesses, kGtestValues, kPerfTestName); - -// } // namespace leonova_a_most_diff_neigh_vec_elems - #include +#include #include #include -#include #include "leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp" #include "leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp" @@ -105,23 +23,21 @@ class MostDiffNeighVecElemsRunPerfTestsProcesses : public ppc::util::BaseRunPerf std::mt19937 gen(rd()); std::uniform_int_distribution dist(-100000, 100000); - // Заполняем вектор случайными числами for (size_t i = 0; i < n; ++i) { input_data[i] = dist(gen); } - // Выбираем СЛУЧАЙНУЮ позицию для максимальной пары - std::uniform_int_distribution pos_dist(0, n - 2); // От 0 до n-2 (чтобы была пара) + // СЛУЧАЙНАЯ поз для макс + std::uniform_int_distribution pos_dist(0, n - 2); // От 0 до n-2 (чтобы была пара) size_t max_diff_position = pos_dist(gen); - // Создаем гарантированно максимальную пару + // гарантированно макс пара input_data[max_diff_position] = -150000; input_data[max_diff_position + 1] = 150000; expected_output = std::make_tuple(-150000, 150000); } bool CheckTestOutputData(OutType &output_data) final { - // Проверяем точное совпадение с ожидаемым результатом return (expected_output == output_data); } From 41c12b2f426387741bf7fc53e287bd2d72878b63 Mon Sep 17 00:00:00 2001 From: Leonova Anna Date: Tue, 18 Nov 2025 14:46:11 +0000 Subject: [PATCH 10/16] New mpi logic + report --- .../mpi/src/ops_mpi.cpp | 83 ++--- .../report.md | 289 ++++++++++++++++++ 2 files changed, 336 insertions(+), 36 deletions(-) diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp b/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp index 3fb71e52ef..0253097c06 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp @@ -42,51 +42,55 @@ bool LeonovaAMostDiffNeighVecElemsMPI::RunImpl() { MPI_Comm_size(MPI_COMM_WORLD, &size); int total_size = static_cast(input_vec.size()); - if (size > 1) { - // распределяем данные по кусочкам - int chunk_size = total_size / size; - int remainder = total_size % size; + // используем только нужные процессы + int actual_processes = std::min(size, total_size); - // получаем на 1 элемент больше для проверки соседних пар на границах чанков - int my_size = chunk_size + (rank < remainder ? 1 : 0) + 1; - int my_offset = rank * chunk_size + std::min(rank, remainder); + int local_max_diff = -1; + int local_first = 0; + int local_second = 0; - if (rank == size - 1 && my_offset + my_size > total_size) { - my_size = total_size - my_offset; - } + // делим данные на кусочки (чанки) только для нужного количества процессов + if (rank < actual_processes) { + int chunk_size = total_size / actual_processes; + int remainder = total_size % actual_processes; - std::vector local_data(my_size); + // получаем на 1 элемент больше для проверки соседних пар на границах чанков + int my_size = chunk_size + (rank < remainder ? 1 : 0) + 1; + int my_offset = rank * chunk_size + std::min(rank, remainder); - if (rank == 0) { - for (int i = 0; i < my_size; ++i) { - local_data[i] = input_vec[i]; + if (rank == actual_processes - 1) { + my_size = total_size - my_offset; } - // рассылаем - for (int dest = 1; dest < size; ++dest) { - int dest_size = chunk_size + (dest < remainder ? 1 : 0) + 1; - int dest_offset = dest * chunk_size + std::min(dest, remainder); - if (dest == size - 1 && dest_offset + dest_size > total_size) { - dest_size = total_size - dest_offset; + std::vector local_data(my_size); + + if (rank == 0) { + for (int i = 0; i < my_size; ++i) { + local_data[i] = input_vec[i]; } + // рассылаем + for (int dest = 1; dest < actual_processes; ++dest) { + int dest_size = chunk_size + (dest < remainder ? 1 : 0) + 1; + int dest_offset = dest * chunk_size + std::min(dest, remainder); - MPI_Send(input_vec.data() + dest_offset, dest_size, MPI_INT, dest, 0, MPI_COMM_WORLD); - } - } else { - MPI_Recv(local_data.data(), my_size, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - } + if (dest == actual_processes - 1) { + dest_size = total_size - dest_offset; + } - int local_max_diff = -1; - int local_first = 0; - int local_second = 0; + MPI_Send(input_vec.data() + dest_offset, dest_size, MPI_INT, dest, 0, MPI_COMM_WORLD); + } + } else { + MPI_Recv(local_data.data(), my_size, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + } - for (int i = 0; i < my_size - 1; ++i) { - int diff = std::abs(local_data[i] - local_data[i + 1]); - if (diff > local_max_diff) { - local_max_diff = diff; - local_first = local_data[i]; - local_second = local_data[i + 1]; + for (int i = 0; i < my_size - 1; ++i) { + int diff = std::abs(local_data[i] - local_data[i + 1]); + if (diff > local_max_diff) { + local_max_diff = diff; + local_first = local_data[i]; + local_second = local_data[i + 1]; + } } } @@ -94,6 +98,13 @@ bool LeonovaAMostDiffNeighVecElemsMPI::RunImpl() { std::vector all_firsts(size); std::vector all_seconds(size); + // лишние процессы отправляют фиктивные данные + if (rank >= actual_processes) { + local_max_diff = -1; + local_first = 0; + local_second = 0; + } + MPI_Gather(&local_max_diff, 1, MPI_INT, all_diffs.data(), 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Gather(&local_first, 1, MPI_INT, all_firsts.data(), 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Gather(&local_second, 1, MPI_INT, all_seconds.data(), 1, MPI_INT, 0, MPI_COMM_WORLD); @@ -102,8 +113,7 @@ bool LeonovaAMostDiffNeighVecElemsMPI::RunImpl() { int global_max_diff = -1; int global_first = 0; int global_second = 0; - - for (int i = 0; i < size; ++i) { + for (int i = 0; i < actual_processes; ++i) { if (all_diffs[i] > global_max_diff) { global_max_diff = all_diffs[i]; global_first = all_firsts[i]; @@ -116,6 +126,7 @@ bool LeonovaAMostDiffNeighVecElemsMPI::RunImpl() { // результат int result_first = std::get<0>(GetOutput()); int result_second = std::get<1>(GetOutput()); + MPI_Bcast(&result_first, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Bcast(&result_second, 1, MPI_INT, 0, MPI_COMM_WORLD); diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/report.md b/tasks/leonova_a_most_diff_neigh_vec_elems/report.md index e69de29bb2..0a3c3c8c72 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/report.md +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/report.md @@ -0,0 +1,289 @@ +# Нахождение наиболее отличающихся по значению соседних элементов вектора + +- Студент: Леонова Анна Сергеевна, группа 3823Б1ФИ1 +- Технология: SEQ | MPI +- Вариант: 8 + +## 1. Введение +В данной работе рассматривается задача поиска пары соседних элементов вектора с максимальной разностью значений. Эта задача имеет практическое применение в обработке сигналов, анализе временных рядов и вычислительной математике. Цель работы - разработка и сравнение производительности последовательной и параллельной MPI-реализаций алгоритма. + +## 2. Постановка задачи +Для заданного вектора целых чисел v = [v₁, v₂, ..., vₙ] необходимо найти пару соседних элементов (vᵢ, vᵢ₊₁) с максимальным значением модуля разности |vᵢ - vᵢ₊₁| (i = 1, 2, ..., n - 1). + +Формат входных данных: std::vector - вектор с целыми значениями +Формат выходных данных: std::tuple - пара элементов с максимальной разницей + +Ограничения и особенности реализации: + +- Вектор должен содержать хотя бы один элемент; +- При размере вектора n = 1 возвращается пара (v₁, v₁); +- При нескольких парах с одинаковой максимальной разницей возвращается первая найденная такая пара. + +## 3. Базовый алгоритм (Последовательный) +Алгоритм последовательно проходит по всем парам соседних элементов вектора v и отслеживает максимальную по модулю разность: + +max_diff = -1 +for i от 0 до n-2: + curr_diff = |v[i] - v[i+1]| + если curr_diff > max_diff: + max_diff = curr_diff + best_pair = (v[i], v[i+1]) + +Результатом выполнения алгоритма будет пара элементов с максимальной разницей - best_pair. +Вычислительная сложность алгоритма - O(n). + +## 4. Схема распараллеливания +Вектор делится на перекрывающиеся блоки между процессами, чтобы каждый процесс мог проверить все соседние пары в своей части вектора без необходимости дополнительного обмена граничными элементами. Если процессов слишком много - они учавствуют в алгоритме, но рассылают фиктивные данные, не влияющие на результат работы. Каждый процесс, который должен учавствовать в вычислениях, кроме может быть последнего, получает k = chunk_size + 1 элементов для проверки всех пар в своей части, где chunk_size = n / N. (N - количество процессов) Последний процесс получает ровно столько элементов, сколько осталось до конца вектора. + +Процесс 0 распределяет блоки данных через MPI_Send, остальные получают через MPI_Recv: +- Процесс 0: [0...k] элементы; +- Процесс 1: [k...2k] элементы; +... +- Процесс N-1: [(N-1)*k...N] элементы. + +Так, например, имеем три процесса и исходный вектор v = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]: +- Процесс 0: получает элементы [0, 1, 2, 3] → проверяет пары: (0,1), (1,2), (2,3); +- Процесс 1: получает элементы [3, 4, 5, 6] → проверяет пары: (3,4), (4,5), (5,6); +- Процесс 2: получает элементы [6, 7, 8, 9] → проверяет пары: (6,7), (7,8), (8,9). +В результате проверяются все пары соседних элементов. + +Каждый процесс находит локальную пару с локальной максимальной разницей. Результаты собираются на процессе 0 через MPI_Gather. Процесс 0 находит глобальный максимум и результат рассылается всем процессам через MPI_Bcast. + +## 5. Детали реализации +Структура кода: +- ppc-2025-processes-informatics/tasks/leonova_a_most_diff_neigh_vec_elems/seq/src/ops_seq.cpp - последовательная реализация; +- ppc-2025-processes-informatics/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp - MPI реализация. + +Тесты: +- ppc-2025-processes-informatics/tasks/leonova_a_most_diff_neigh_vec_elems/tests/functional/main.cpp - функциональные; +- ppc-2025-processes-informatics/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp - на производительность. + +## 6. Experimental Setup + +### 6.1 Оборудование и ПО +- CPU: Intel Core i5-1135G7 (4 ядра, 8 потоков); +- RAM: 8ГБ; +- ОС: Windows 10 Pro 22H2; +- Тип сборки: Release. + +### 6.2 Функциональные тесты +1. Максимальная разница в середине вектора +Вход: {1, 10, 3, 10, 5}; +Ожидаемый результат: (1, 10) (разница = 9). + +2. Максимальная разница в начале +Вход: {5, 20, 15, 10}; +Ожидаемый результат: (5, 20) (разница = 15). + +3. Вектор из одного элемента +Вход: {7}; +Ожидаемый результат: (7, 7) (разница = 0). + +4. Максимальная разница в конце +Вход: {0, 100, 100, 25}; +Ожидаемый результат: (0, 100) (разница = 100). + +5. Отрицательные числа +Вход: {-10, -5, -1, 3, 0, 0}; +Ожидаемый результат: (-10, -5) (разница = 5). + +### 6.3 Тесты производительности + +Генерация тестовых данных: +- Размер вектора: 30 000 000 элементов; +- Диапазон значений: [-100000, 100000]. + +Используется генератор псевдослучайных чисел std::mt19937 + +Максимальная пара создается в случайной позиции для тестирования разных сценариев положения пары элементов. Разница гарантированно максимальная: 300000 (превышает диапазон случайных значений). Остальные элементы заполняются случайными значениями. + +## 7. Результаты и обсуждение + +### 7.1 Проверка корректности +Корректность работы алгоритмов проверялась с помощью: +- Функциональных тестов с заранее известными результатами +- Сравнения результатов последовательной и параллельной версий (тесты с одинаковыми данными запускались для обеих версий реализации) +- Тестов на граничные случаи (пустой вектор, один элемент) + +### 7.2 Performance +Были запущены тесты производительности с различными входными данными. (n - размер вектора) Результаты представлены в таблицах: + +1. n = 10 000 000 + +|Режим |Процессы |Время, с |Ускорение |Эффективность| +|-------|---------|---------|----------|-------------| +|seq |1 |0.00867 |1.00 |N/A | +|mpi |2 |0.01478 |0.59 |29.5% | +|mpi |4 |0.02194 |0.40 |10.0% | +|mpi |8 |0.04191 |0.21 |2.6% | + +2. n = 30 000 000 + +|Режим |Процессы |Время, с |Ускорение |Эффективность| +|------|---------|---------|----------|-------------| +|seq |1 |0.02383 |1.00 |N/A | +|mpi |2 |0.06083 |0.39 |19.5% | +|mpi |4 |0.13068 |0.18 |4.5% | +|mpi |8 |0.18740 |0.13 |1.6% | + +Ускорение вычислялось по формуле (seq_time / mpi_time) +Эффективность вычислялась по формуле (Ускорение / N) * 100%, где N - количество процессов + +### 7.3 Анализ результатов +MPI версия демонстрирует замедление по сравнению с последовательной реализацией. Лучшая эффективность достигалась на 2 процессах: 19.5-29.5%. Эффективность падает с ростом количества процессов: на 8 процессах эффективность падает до 1.6-2.6%. + +Для большего размера вектора (30M) эффективность стала заметно ниже. + +Возможные причины низкой производительности: +- Высокие накладные расходы на распределение данных и сбор результатов перекрывают выгоду от параллельного исполнения; +- Относительно небольшая вычислительная линейная сложность алгоритма O(n); +- Нехватка свободных ядер для вычислений; +- Нехватка оперативной памяти. + +Основные узкие места производительности: +- Распределение данных через последовательные MPI_Send/MPI_Recv; +- Сбор результатов через MPI_Gather (3 отдельных вызова); +- Рассылка результата через 2 отдельных MPI_Bcast. + +## 8. Conclusions +Был разработан алгоритм для нахождения наиболее отличающихся по значению соседних элементов вектора. Реализованные последовательная и параллельная MPI-реализации успешно проходят все функциональные тесты, включая обработку граничных случаев и работу с отрицательными числами. + +MPI-реализация демонстрирует отрицательное ускорение по сравнению с последовательной версией. Наилучшая эффективность достигается при использовании 2 процессов для вычисления. С ростом количества процессов и объемов данных эффективность значительно снижается - операции коммуникации между процессами достаточно дорогостоящие - затраты на распределение данных и сбор результатов превышают выгоду от параллельных вычислений. + +Вывод: алгоритм не демонстрирует хорошей масштабируемости при увеличении числа процессов или объема данных. Алгоритм имеет линейную сложность O(n), что делает его менее подходящим для распараллеливания по сравнению с более сложными алгоритмами. + +## 9. References + +Open MPI Documentation. https://www.open-mpi.org/doc/ +Статья "Основы MPI". https://habr.com/ru/articles/121925/ +Учебное пособие "MPI для начинающих". https://parallel.uran.ru/node/182 +Вспомогательные советы. http://stackoverflow.com/ + +## Приложение +```cpp +bool LeonovaAMostDiffNeighVecElemsMPI::RunImpl() { + const auto &input_vec = GetInput(); + + if (!ValidationImpl()) { + return false; + } + + if (input_vec.size() == 1) { + GetOutput() = std::make_tuple(input_vec[0], input_vec[0]); + return true; + } + + int rank, size; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + int total_size = static_cast(input_vec.size()); + if (size > 1) { + // используем только нужные процессы + int actual_processes = std::min(size, total_size); + + int local_max_diff = -1; + int local_first = 0; + int local_second = 0; + + // делим данные на кусочки (чанки) только для нужного количества процессов + if (rank < actual_processes) { + int chunk_size = total_size / actual_processes; + int remainder = total_size % actual_processes; + + // получаем на 1 элемент больше для проверки соседних пар на границах чанков + int my_size = chunk_size + (rank < remainder ? 1 : 0) + 1; + int my_offset = rank * chunk_size + std::min(rank, remainder); + + if (rank == actual_processes - 1) { + my_size = total_size - my_offset; + } + + std::vector local_data(my_size); + + if (rank == 0) { + for (int i = 0; i < my_size; ++i) { + local_data[i] = input_vec[i]; + } + // рассылаем + for (int dest = 1; dest < actual_processes; ++dest) { + int dest_size = chunk_size + (dest < remainder ? 1 : 0) + 1; + int dest_offset = dest * chunk_size + std::min(dest, remainder); + + if (dest == actual_processes - 1) { + dest_size = total_size - dest_offset; + } + + MPI_Send(input_vec.data() + dest_offset, dest_size, MPI_INT, dest, 0, MPI_COMM_WORLD); + } + } else { + MPI_Recv(local_data.data(), my_size, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + } + + for (int i = 0; i < my_size - 1; ++i) { + int diff = std::abs(local_data[i] - local_data[i + 1]); + if (diff > local_max_diff) { + local_max_diff = diff; + local_first = local_data[i]; + local_second = local_data[i + 1]; + } + } + } + + std::vector all_diffs(size); + std::vector all_firsts(size); + std::vector all_seconds(size); + + // лишние процессы отправляют фиктивные данные + if (rank >= actual_processes) { + local_max_diff = -1; + local_first = 0; + local_second = 0; + } + + MPI_Gather(&local_max_diff, 1, MPI_INT, all_diffs.data(), 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Gather(&local_first, 1, MPI_INT, all_firsts.data(), 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Gather(&local_second, 1, MPI_INT, all_seconds.data(), 1, MPI_INT, 0, MPI_COMM_WORLD); + + if (rank == 0) { + int global_max_diff = -1; + int global_first = 0; + int global_second = 0; + for (int i = 0; i < actual_processes; ++i) { + if (all_diffs[i] > global_max_diff) { + global_max_diff = all_diffs[i]; + global_first = all_firsts[i]; + global_second = all_seconds[i]; + } + } + GetOutput() = std::make_tuple(global_first, global_second); + } + + // результат + int result_first = std::get<0>(GetOutput()); + int result_second = std::get<1>(GetOutput()); + + MPI_Bcast(&result_first, 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Bcast(&result_second, 1, MPI_INT, 0, MPI_COMM_WORLD); + + if (rank != 0) { + GetOutput() = std::make_tuple(result_first, result_second); + } + + } else { + int max_diff = -1; + std::tuple best_pair(0, 0); + + for (size_t i = 0; i < input_vec.size() - 1; ++i) { + int diff = std::abs(input_vec[i] - input_vec[i + 1]); + if (diff > max_diff) { + max_diff = diff; + best_pair = std::make_tuple(input_vec[i], input_vec[i + 1]); + } + } + + GetOutput() = best_pair; + } + + return true; +} \ No newline at end of file From 34f767a5809a2ec2aef14adf099fd3a5f5b8e4d8 Mon Sep 17 00:00:00 2001 From: Leonova Anna Date: Tue, 18 Nov 2025 17:16:17 +0000 Subject: [PATCH 11/16] cland-tidy --- .../mpi/include/ops_mpi.hpp | 14 ++ .../mpi/src/ops_mpi.cpp | 237 +++++++++++------- .../seq/src/ops_seq.cpp | 7 +- .../tests/functional/main.cpp | 19 +- .../tests/performance/main.cpp | 27 +- 5 files changed, 177 insertions(+), 127 deletions(-) diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp b/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp index 840f150e66..2d7d42a76a 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp @@ -17,6 +17,20 @@ class LeonovaAMostDiffNeighVecElemsMPI : public BaseTask { bool PreProcessingImpl() override; bool RunImpl() override; bool PostProcessingImpl() override; + + void ProcessWithMultipleProcesses(int rank, int size, int total_size, const std::vector &input_vec); + void ProcessLocalData(int rank, int actual_processes, int total_size, const std::vector &input_vec, + int &local_max_diff, int &local_first, int &local_second); + void ReceiveLocalData(int rank, int actual_processes, const std::vector &input_vec, int my_size, + std::vector &local_data, int total_size); + void SendDataToProcess(int dest, int actual_processes, const std::vector &input_vec, int total_size); + void FindLocalMaxDiff(const std::vector &local_data, int &local_max_diff, int &local_first, int &local_second); + void GatherAndProcessResults(int rank, int actual_processes, int local_max_diff, int local_first, int local_second, + int size); + void FindGlobalMaxDiff(const std::vector &all_diffs, const std::vector &all_firsts, + const std::vector &all_seconds, int actual_processes); + void BroadcastResult(int rank); + void ProcessSequentially(const std::vector &input_vec); }; } // namespace leonova_a_most_diff_neigh_vec_elems diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp b/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp index 0253097c06..03ce9df5ba 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp @@ -2,13 +2,12 @@ #include +#include #include +#include #include #include -#include "leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp" -#include "util/include/util.hpp" - namespace leonova_a_most_diff_neigh_vec_elems { LeonovaAMostDiffNeighVecElemsMPI::LeonovaAMostDiffNeighVecElemsMPI(const InType &in) { @@ -37,119 +36,163 @@ bool LeonovaAMostDiffNeighVecElemsMPI::RunImpl() { return true; } - int rank, size; + int rank = 0; + int size = 0; MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); int total_size = static_cast(input_vec.size()); if (size > 1) { - // используем только нужные процессы - int actual_processes = std::min(size, total_size); - - int local_max_diff = -1; - int local_first = 0; - int local_second = 0; - - // делим данные на кусочки (чанки) только для нужного количества процессов - if (rank < actual_processes) { - int chunk_size = total_size / actual_processes; - int remainder = total_size % actual_processes; - - // получаем на 1 элемент больше для проверки соседних пар на границах чанков - int my_size = chunk_size + (rank < remainder ? 1 : 0) + 1; - int my_offset = rank * chunk_size + std::min(rank, remainder); - - if (rank == actual_processes - 1) { - my_size = total_size - my_offset; - } - - std::vector local_data(my_size); - - if (rank == 0) { - for (int i = 0; i < my_size; ++i) { - local_data[i] = input_vec[i]; - } - // рассылаем - for (int dest = 1; dest < actual_processes; ++dest) { - int dest_size = chunk_size + (dest < remainder ? 1 : 0) + 1; - int dest_offset = dest * chunk_size + std::min(dest, remainder); - - if (dest == actual_processes - 1) { - dest_size = total_size - dest_offset; - } - - MPI_Send(input_vec.data() + dest_offset, dest_size, MPI_INT, dest, 0, MPI_COMM_WORLD); - } - } else { - MPI_Recv(local_data.data(), my_size, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - } - - for (int i = 0; i < my_size - 1; ++i) { - int diff = std::abs(local_data[i] - local_data[i + 1]); - if (diff > local_max_diff) { - local_max_diff = diff; - local_first = local_data[i]; - local_second = local_data[i + 1]; - } - } - } + ProcessWithMultipleProcesses(rank, size, total_size, input_vec); + } else { + ProcessSequentially(input_vec); + } + + return true; +} + +void LeonovaAMostDiffNeighVecElemsMPI::ProcessWithMultipleProcesses(int rank, int size, int total_size, + const std::vector &input_vec) { + int actual_processes = std::min(size, total_size); + int local_max_diff = -1; + int local_first = 0; + int local_second = 0; + + if (rank < actual_processes) { + ProcessLocalData(rank, actual_processes, total_size, input_vec, local_max_diff, local_first, local_second); + } + + GatherAndProcessResults(rank, actual_processes, local_max_diff, local_first, local_second, size); +} - std::vector all_diffs(size); - std::vector all_firsts(size); - std::vector all_seconds(size); +void LeonovaAMostDiffNeighVecElemsMPI::ProcessLocalData(int rank, int actual_processes, int total_size, + const std::vector &input_vec, int &local_max_diff, + int &local_first, int &local_second) { + int chunk_size = total_size / actual_processes; + int remainder = total_size % actual_processes; - // лишние процессы отправляют фиктивные данные - if (rank >= actual_processes) { - local_max_diff = -1; - local_first = 0; - local_second = 0; + int my_size = chunk_size + (rank < remainder ? 1 : 0) + 1; + int my_offset = (rank * chunk_size) + std::min(rank, remainder); + + if (rank == actual_processes - 1) { + my_size = total_size - my_offset; + } + + std::vector local_data(my_size); + ReceiveLocalData(rank, actual_processes, input_vec, my_size, local_data, total_size); + + FindLocalMaxDiff(local_data, local_max_diff, local_first, local_second); +} + +void LeonovaAMostDiffNeighVecElemsMPI::ReceiveLocalData(int rank, int actual_processes, + const std::vector &input_vec, int my_size, + std::vector &local_data, int total_size) { + if (rank == 0) { + for (int index = 0; index < my_size; ++index) { + local_data[index] = input_vec[index]; } - MPI_Gather(&local_max_diff, 1, MPI_INT, all_diffs.data(), 1, MPI_INT, 0, MPI_COMM_WORLD); - MPI_Gather(&local_first, 1, MPI_INT, all_firsts.data(), 1, MPI_INT, 0, MPI_COMM_WORLD); - MPI_Gather(&local_second, 1, MPI_INT, all_seconds.data(), 1, MPI_INT, 0, MPI_COMM_WORLD); - - if (rank == 0) { - int global_max_diff = -1; - int global_first = 0; - int global_second = 0; - for (int i = 0; i < actual_processes; ++i) { - if (all_diffs[i] > global_max_diff) { - global_max_diff = all_diffs[i]; - global_first = all_firsts[i]; - global_second = all_seconds[i]; - } - } - GetOutput() = std::make_tuple(global_first, global_second); + for (int dest = 1; dest < actual_processes; ++dest) { + SendDataToProcess(dest, actual_processes, input_vec, total_size); } + } else { + MPI_Recv(local_data.data(), my_size, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + } +} - // результат - int result_first = std::get<0>(GetOutput()); - int result_second = std::get<1>(GetOutput()); +void LeonovaAMostDiffNeighVecElemsMPI::SendDataToProcess(int dest, int actual_processes, + const std::vector &input_vec, int total_size) { + int chunk_size = total_size / actual_processes; + int remainder = total_size % actual_processes; - MPI_Bcast(&result_first, 1, MPI_INT, 0, MPI_COMM_WORLD); - MPI_Bcast(&result_second, 1, MPI_INT, 0, MPI_COMM_WORLD); + int dest_size = chunk_size + (dest < remainder ? 1 : 0) + 1; + int dest_offset = (dest * chunk_size) + std::min(dest, remainder); - if (rank != 0) { - GetOutput() = std::make_tuple(result_first, result_second); + if (dest == actual_processes - 1) { + dest_size = total_size - dest_offset; + } + + MPI_Send(input_vec.data() + dest_offset, dest_size, MPI_INT, dest, 0, MPI_COMM_WORLD); +} + +void LeonovaAMostDiffNeighVecElemsMPI::FindLocalMaxDiff(const std::vector &local_data, int &local_max_diff, + int &local_first, int &local_second) { + for (int index = 0; index < static_cast(local_data.size()) - 1; ++index) { + int diff = std::abs(local_data[index] - local_data[index + 1]); + if (diff > local_max_diff) { + local_max_diff = diff; + local_first = local_data[index]; + local_second = local_data[index + 1]; } + } +} - } else { - int max_diff = -1; - std::tuple best_pair(0, 0); - - for (size_t i = 0; i < input_vec.size() - 1; ++i) { - int diff = std::abs(input_vec[i] - input_vec[i + 1]); - if (diff > max_diff) { - max_diff = diff; - best_pair = std::make_tuple(input_vec[i], input_vec[i + 1]); - } +void LeonovaAMostDiffNeighVecElemsMPI::GatherAndProcessResults(int rank, int actual_processes, int local_max_diff, + int local_first, int local_second, int size) { + if (rank >= actual_processes) { + local_max_diff = -1; + local_first = 0; + local_second = 0; + } + + std::vector all_diffs(size); + std::vector all_firsts(size); + std::vector all_seconds(size); + + MPI_Gather(&local_max_diff, 1, MPI_INT, all_diffs.data(), 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Gather(&local_first, 1, MPI_INT, all_firsts.data(), 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Gather(&local_second, 1, MPI_INT, all_seconds.data(), 1, MPI_INT, 0, MPI_COMM_WORLD); + + if (rank == 0) { + FindGlobalMaxDiff(all_diffs, all_firsts, all_seconds, actual_processes); + } + + BroadcastResult(rank); +} + +void LeonovaAMostDiffNeighVecElemsMPI::FindGlobalMaxDiff(const std::vector &all_diffs, + const std::vector &all_firsts, + const std::vector &all_seconds, int actual_processes) { + int global_max_diff = -1; + int global_first = 0; + int global_second = 0; + + for (int index = 0; index < actual_processes; ++index) { + if (all_diffs[index] > global_max_diff) { + global_max_diff = all_diffs[index]; + global_first = all_firsts[index]; + global_second = all_seconds[index]; } + } + + GetOutput() = std::make_tuple(global_first, global_second); +} - GetOutput() = best_pair; +void LeonovaAMostDiffNeighVecElemsMPI::BroadcastResult(int rank) { + int result_first = std::get<0>(GetOutput()); + int result_second = std::get<1>(GetOutput()); + + MPI_Bcast(&result_first, 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Bcast(&result_second, 1, MPI_INT, 0, MPI_COMM_WORLD); + + if (rank != 0) { + GetOutput() = std::make_tuple(result_first, result_second); } +} - return true; +void LeonovaAMostDiffNeighVecElemsMPI::ProcessSequentially(const std::vector &input_vec) { + int max_diff = -1; + std::tuple best_pair(0, 0); + + for (std::size_t index = 0; index < input_vec.size() - 1; ++index) { + int diff = std::abs(input_vec[index] - input_vec[index + 1]); + if (diff > max_diff) { + max_diff = diff; + best_pair = std::make_tuple(input_vec[index], input_vec[index + 1]); + } + } + + GetOutput() = best_pair; } bool LeonovaAMostDiffNeighVecElemsMPI::PostProcessingImpl() { diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/seq/src/ops_seq.cpp b/tasks/leonova_a_most_diff_neigh_vec_elems/seq/src/ops_seq.cpp index b0c5cd6c55..0f75222494 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/seq/src/ops_seq.cpp +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/seq/src/ops_seq.cpp @@ -1,11 +1,10 @@ #include "leonova_a_most_diff_neigh_vec_elems/seq/include/ops_seq.hpp" #include -#include +#include #include #include "leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp" -#include "util/include/util.hpp" namespace leonova_a_most_diff_neigh_vec_elems { @@ -31,8 +30,8 @@ bool LeonovaAMostDiffNeighVecElemsSEQ::RunImpl() { } int max_diff = -1; - for (std::vector::size_type i = 0; i < GetInput().size() - 1; i++) { - std::tuple curr_elems(GetInput()[i], GetInput()[i + 1]); + for (std::vector::size_type index = 0; index < GetInput().size() - 1; index++) { + std::tuple curr_elems(GetInput()[index], GetInput()[index + 1]); int curr_diff = abs(std::get<0>(curr_elems) - std::get<1>(curr_elems)); if (curr_diff > max_diff) { max_diff = curr_diff; diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/tests/functional/main.cpp b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/functional/main.cpp index 2c4ccbc3c9..b40f9a9854 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/tests/functional/main.cpp +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/functional/main.cpp @@ -1,21 +1,15 @@ #include -#include #include #include -#include -#include -#include #include #include -#include #include #include "leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp" #include "leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp" #include "leonova_a_most_diff_neigh_vec_elems/seq/include/ops_seq.hpp" #include "util/include/func_test_util.hpp" -#include "util/include/util.hpp" namespace leonova_a_most_diff_neigh_vec_elems { @@ -36,22 +30,21 @@ class MostDiffNeighVecElemsRunFuncTestsProcesses : public ppc::util::BaseRunFunc void SetUp() override { TestType params = std::get(ppc::util::GTestParamIndex::kTestParams)>(GetParam()); - input_data = std::get<1>(params); - - expected_output = std::get<0>(params); + input_data_ = std::get<1>(params); + expected_output_ = std::get<0>(params); } bool CheckTestOutputData(OutType &output_data) final { - return (expected_output == output_data); + return (expected_output_ == output_data); } InType GetTestInputData() final { - return input_data; + return input_data_; } private: - InType input_data = std::vector(); - OutType expected_output = std::tuple(0, 0); + InType input_data_; + OutType expected_output_; }; namespace { diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp index ab15159aa6..2a0fe8b889 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp @@ -1,7 +1,8 @@ #include -#include +#include #include +#include #include #include "leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp" @@ -12,37 +13,37 @@ namespace leonova_a_most_diff_neigh_vec_elems { class MostDiffNeighVecElemsRunPerfTestsProcesses : public ppc::util::BaseRunPerfTests { - const size_t n = 30000000; - InType input_data{}; - OutType expected_output{}; + const size_t n_ = 30000000; + InType input_data_; + OutType expected_output_; void SetUp() override { - input_data.resize(n); + input_data_.resize(n_); std::random_device rd; std::mt19937 gen(rd()); std::uniform_int_distribution dist(-100000, 100000); - for (size_t i = 0; i < n; ++i) { - input_data[i] = dist(gen); + for (size_t index = 0; index < n_; ++index) { + input_data_[index] = dist(gen); } // СЛУЧАЙНАЯ поз для макс - std::uniform_int_distribution pos_dist(0, n - 2); // От 0 до n-2 (чтобы была пара) + std::uniform_int_distribution pos_dist(0, n_ - 2); // От 0 до n-2 (чтобы была пара) size_t max_diff_position = pos_dist(gen); // гарантированно макс пара - input_data[max_diff_position] = -150000; - input_data[max_diff_position + 1] = 150000; - expected_output = std::make_tuple(-150000, 150000); + input_data_[max_diff_position] = -150000; + input_data_[max_diff_position + 1] = 150000; + expected_output_ = std::make_tuple(-150000, 150000); } bool CheckTestOutputData(OutType &output_data) final { - return (expected_output == output_data); + return (expected_output_ == output_data); } InType GetTestInputData() final { - return input_data; + return input_data_; } }; From fc752b6a111d9f918e0eb728f5a37dce0d011e8a Mon Sep 17 00:00:00 2001 From: Leonova Anna Date: Tue, 18 Nov 2025 18:05:28 +0000 Subject: [PATCH 12/16] cland-tidy2 --- .../mpi/include/ops_mpi.hpp | 8 ++++++-- .../mpi/src/ops_mpi.cpp | 2 ++ .../tests/functional/main.cpp | 1 + .../tests/performance/main.cpp | 1 - 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp b/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp index 2d7d42a76a..b25ac98934 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include "leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp" #include "task/include/task.hpp" @@ -23,8 +25,10 @@ class LeonovaAMostDiffNeighVecElemsMPI : public BaseTask { int &local_max_diff, int &local_first, int &local_second); void ReceiveLocalData(int rank, int actual_processes, const std::vector &input_vec, int my_size, std::vector &local_data, int total_size); - void SendDataToProcess(int dest, int actual_processes, const std::vector &input_vec, int total_size); - void FindLocalMaxDiff(const std::vector &local_data, int &local_max_diff, int &local_first, int &local_second); + static void SendDataToProcess(int dest, int actual_processes, const std::vector &input_vec, + int total_size); // Добавлен static + static void FindLocalMaxDiff(const std::vector &local_data, int &local_max_diff, int &local_first, + int &local_second); // Добавлен static void GatherAndProcessResults(int rank, int actual_processes, int local_max_diff, int local_first, int local_second, int size); void FindGlobalMaxDiff(const std::vector &all_diffs, const std::vector &all_firsts, diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp b/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp index 03ce9df5ba..6e2801ad64 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp @@ -8,6 +8,8 @@ #include #include +#include "leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp" + namespace leonova_a_most_diff_neigh_vec_elems { LeonovaAMostDiffNeighVecElemsMPI::LeonovaAMostDiffNeighVecElemsMPI(const InType &in) { diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/tests/functional/main.cpp b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/functional/main.cpp index b40f9a9854..c5f6da51c7 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/tests/functional/main.cpp +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/functional/main.cpp @@ -10,6 +10,7 @@ #include "leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp" #include "leonova_a_most_diff_neigh_vec_elems/seq/include/ops_seq.hpp" #include "util/include/func_test_util.hpp" +#include "util/include/util.hpp" namespace leonova_a_most_diff_neigh_vec_elems { diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp index 2a0fe8b889..a707e728f3 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/tests/performance/main.cpp @@ -3,7 +3,6 @@ #include #include #include -#include #include "leonova_a_most_diff_neigh_vec_elems/common/include/common.hpp" #include "leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp" From 492e11d09d8b6b69510f3bab78d878ef58517df0 Mon Sep 17 00:00:00 2001 From: Leonova Anna Date: Tue, 18 Nov 2025 20:31:02 +0000 Subject: [PATCH 13/16] cland-tidy3 --- .../mpi/include/ops_mpi.hpp | 9 +- .../report.md | 236 +++++++++++------- 2 files changed, 144 insertions(+), 101 deletions(-) diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp b/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp index b25ac98934..0a08873c08 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp @@ -23,12 +23,11 @@ class LeonovaAMostDiffNeighVecElemsMPI : public BaseTask { void ProcessWithMultipleProcesses(int rank, int size, int total_size, const std::vector &input_vec); void ProcessLocalData(int rank, int actual_processes, int total_size, const std::vector &input_vec, int &local_max_diff, int &local_first, int &local_second); - void ReceiveLocalData(int rank, int actual_processes, const std::vector &input_vec, int my_size, - std::vector &local_data, int total_size); - static void SendDataToProcess(int dest, int actual_processes, const std::vector &input_vec, - int total_size); // Добавлен static + static void ReceiveLocalData(int rank, int actual_processes, const std::vector &input_vec, int my_size, + std::vector &local_data, int total_size); + static void SendDataToProcess(int dest, int actual_processes, const std::vector &input_vec, int total_size); static void FindLocalMaxDiff(const std::vector &local_data, int &local_max_diff, int &local_first, - int &local_second); // Добавлен static + int &local_second); void GatherAndProcessResults(int rank, int actual_processes, int local_max_diff, int local_first, int local_second, int size); void FindGlobalMaxDiff(const std::vector &all_diffs, const std::vector &all_firsts, diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/report.md b/tasks/leonova_a_most_diff_neigh_vec_elems/report.md index 0a3c3c8c72..b6dcd2929b 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/report.md +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/report.md @@ -173,117 +173,161 @@ bool LeonovaAMostDiffNeighVecElemsMPI::RunImpl() { return true; } - int rank, size; + int rank = 0; + int size = 0; MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); int total_size = static_cast(input_vec.size()); - if (size > 1) { - // используем только нужные процессы - int actual_processes = std::min(size, total_size); - - int local_max_diff = -1; - int local_first = 0; - int local_second = 0; - - // делим данные на кусочки (чанки) только для нужного количества процессов - if (rank < actual_processes) { - int chunk_size = total_size / actual_processes; - int remainder = total_size % actual_processes; - - // получаем на 1 элемент больше для проверки соседних пар на границах чанков - int my_size = chunk_size + (rank < remainder ? 1 : 0) + 1; - int my_offset = rank * chunk_size + std::min(rank, remainder); - - if (rank == actual_processes - 1) { - my_size = total_size - my_offset; - } - - std::vector local_data(my_size); - - if (rank == 0) { - for (int i = 0; i < my_size; ++i) { - local_data[i] = input_vec[i]; - } - // рассылаем - for (int dest = 1; dest < actual_processes; ++dest) { - int dest_size = chunk_size + (dest < remainder ? 1 : 0) + 1; - int dest_offset = dest * chunk_size + std::min(dest, remainder); - - if (dest == actual_processes - 1) { - dest_size = total_size - dest_offset; - } - - MPI_Send(input_vec.data() + dest_offset, dest_size, MPI_INT, dest, 0, MPI_COMM_WORLD); - } - } else { - MPI_Recv(local_data.data(), my_size, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - } - - for (int i = 0; i < my_size - 1; ++i) { - int diff = std::abs(local_data[i] - local_data[i + 1]); - if (diff > local_max_diff) { - local_max_diff = diff; - local_first = local_data[i]; - local_second = local_data[i + 1]; - } - } - } + if (size > 1) { + ProcessWithMultipleProcesses(rank, size, total_size, input_vec); + } else { + ProcessSequentially(input_vec); + } + + return true; +} + +void LeonovaAMostDiffNeighVecElemsMPI::ProcessWithMultipleProcesses(int rank, int size, int total_size, + const std::vector &input_vec) { + int actual_processes = std::min(size, total_size); + int local_max_diff = -1; + int local_first = 0; + int local_second = 0; + + if (rank < actual_processes) { + ProcessLocalData(rank, actual_processes, total_size, input_vec, local_max_diff, local_first, local_second); + } + + GatherAndProcessResults(rank, actual_processes, local_max_diff, local_first, local_second, size); +} - std::vector all_diffs(size); - std::vector all_firsts(size); - std::vector all_seconds(size); +void LeonovaAMostDiffNeighVecElemsMPI::ProcessLocalData(int rank, int actual_processes, int total_size, + const std::vector &input_vec, int &local_max_diff, + int &local_first, int &local_second) { + int chunk_size = total_size / actual_processes; + int remainder = total_size % actual_processes; - // лишние процессы отправляют фиктивные данные - if (rank >= actual_processes) { - local_max_diff = -1; - local_first = 0; - local_second = 0; + int my_size = chunk_size + (rank < remainder ? 1 : 0) + 1; + int my_offset = (rank * chunk_size) + std::min(rank, remainder); + + if (rank == actual_processes - 1) { + my_size = total_size - my_offset; + } + + std::vector local_data(my_size); + ReceiveLocalData(rank, actual_processes, input_vec, my_size, local_data, total_size); + + FindLocalMaxDiff(local_data, local_max_diff, local_first, local_second); +} + +void LeonovaAMostDiffNeighVecElemsMPI::ReceiveLocalData(int rank, int actual_processes, + const std::vector &input_vec, int my_size, + std::vector &local_data, int total_size) { + if (rank == 0) { + for (int index = 0; index < my_size; ++index) { + local_data[index] = input_vec[index]; } - MPI_Gather(&local_max_diff, 1, MPI_INT, all_diffs.data(), 1, MPI_INT, 0, MPI_COMM_WORLD); - MPI_Gather(&local_first, 1, MPI_INT, all_firsts.data(), 1, MPI_INT, 0, MPI_COMM_WORLD); - MPI_Gather(&local_second, 1, MPI_INT, all_seconds.data(), 1, MPI_INT, 0, MPI_COMM_WORLD); - - if (rank == 0) { - int global_max_diff = -1; - int global_first = 0; - int global_second = 0; - for (int i = 0; i < actual_processes; ++i) { - if (all_diffs[i] > global_max_diff) { - global_max_diff = all_diffs[i]; - global_first = all_firsts[i]; - global_second = all_seconds[i]; - } - } - GetOutput() = std::make_tuple(global_first, global_second); + for (int dest = 1; dest < actual_processes; ++dest) { + SendDataToProcess(dest, actual_processes, input_vec, total_size); } + } else { + MPI_Recv(local_data.data(), my_size, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + } +} - // результат - int result_first = std::get<0>(GetOutput()); - int result_second = std::get<1>(GetOutput()); - - MPI_Bcast(&result_first, 1, MPI_INT, 0, MPI_COMM_WORLD); - MPI_Bcast(&result_second, 1, MPI_INT, 0, MPI_COMM_WORLD); +void LeonovaAMostDiffNeighVecElemsMPI::SendDataToProcess(int dest, int actual_processes, + const std::vector &input_vec, int total_size) { + int chunk_size = total_size / actual_processes; + int remainder = total_size % actual_processes; - if (rank != 0) { - GetOutput() = std::make_tuple(result_first, result_second); + int dest_size = chunk_size + (dest < remainder ? 1 : 0) + 1; + int dest_offset = (dest * chunk_size) + std::min(dest, remainder); + + if (dest == actual_processes - 1) { + dest_size = total_size - dest_offset; + } + + MPI_Send(input_vec.data() + dest_offset, dest_size, MPI_INT, dest, 0, MPI_COMM_WORLD); +} + +void LeonovaAMostDiffNeighVecElemsMPI::FindLocalMaxDiff(const std::vector &local_data, int &local_max_diff, + int &local_first, int &local_second) { + for (int index = 0; index < static_cast(local_data.size()) - 1; ++index) { + int diff = std::abs(local_data[index] - local_data[index + 1]); + if (diff > local_max_diff) { + local_max_diff = diff; + local_first = local_data[index]; + local_second = local_data[index + 1]; } + } +} + +void LeonovaAMostDiffNeighVecElemsMPI::GatherAndProcessResults(int rank, int actual_processes, int local_max_diff, + int local_first, int local_second, int size) { + if (rank >= actual_processes) { + local_max_diff = -1; + local_first = 0; + local_second = 0; + } - } else { - int max_diff = -1; - std::tuple best_pair(0, 0); - - for (size_t i = 0; i < input_vec.size() - 1; ++i) { - int diff = std::abs(input_vec[i] - input_vec[i + 1]); - if (diff > max_diff) { - max_diff = diff; - best_pair = std::make_tuple(input_vec[i], input_vec[i + 1]); - } + std::vector all_diffs(size); + std::vector all_firsts(size); + std::vector all_seconds(size); + + MPI_Gather(&local_max_diff, 1, MPI_INT, all_diffs.data(), 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Gather(&local_first, 1, MPI_INT, all_firsts.data(), 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Gather(&local_second, 1, MPI_INT, all_seconds.data(), 1, MPI_INT, 0, MPI_COMM_WORLD); + + if (rank == 0) { + FindGlobalMaxDiff(all_diffs, all_firsts, all_seconds, actual_processes); + } + + BroadcastResult(rank); +} + +void LeonovaAMostDiffNeighVecElemsMPI::FindGlobalMaxDiff(const std::vector &all_diffs, + const std::vector &all_firsts, + const std::vector &all_seconds, int actual_processes) { + int global_max_diff = -1; + int global_first = 0; + int global_second = 0; + + for (int index = 0; index < actual_processes; ++index) { + if (all_diffs[index] > global_max_diff) { + global_max_diff = all_diffs[index]; + global_first = all_firsts[index]; + global_second = all_seconds[index]; } + } - GetOutput() = best_pair; + GetOutput() = std::make_tuple(global_first, global_second); +} + +void LeonovaAMostDiffNeighVecElemsMPI::BroadcastResult(int rank) { + int result_first = std::get<0>(GetOutput()); + int result_second = std::get<1>(GetOutput()); + + MPI_Bcast(&result_first, 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Bcast(&result_second, 1, MPI_INT, 0, MPI_COMM_WORLD); + + if (rank != 0) { + GetOutput() = std::make_tuple(result_first, result_second); } +} - return true; +void LeonovaAMostDiffNeighVecElemsMPI::ProcessSequentially(const std::vector &input_vec) { + int max_diff = -1; + std::tuple best_pair(0, 0); + + for (std::size_t index = 0; index < input_vec.size() - 1; ++index) { + int diff = std::abs(input_vec[index] - input_vec[index + 1]); + if (diff > max_diff) { + max_diff = diff; + best_pair = std::make_tuple(input_vec[index], input_vec[index + 1]); + } + } + + GetOutput() = best_pair; } \ No newline at end of file From 880d1133b30b8f6b78d60f272d2e162d923cbf21 Mon Sep 17 00:00:00 2001 From: Leonova Anna Date: Tue, 18 Nov 2025 20:43:15 +0000 Subject: [PATCH 14/16] cland-tidy3_1 --- .../leonova_a_most_diff_neigh_vec_elems/report.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/report.md b/tasks/leonova_a_most_diff_neigh_vec_elems/report.md index b6dcd2929b..d299e4830c 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/report.md +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/report.md @@ -110,19 +110,19 @@ for i от 0 до n-2: 1. n = 10 000 000 -|Режим |Процессы |Время, с |Ускорение |Эффективность| -|-------|---------|---------|----------|-------------| -|seq |1 |0.00867 |1.00 |N/A | -|mpi |2 |0.01478 |0.59 |29.5% | -|mpi |4 |0.02194 |0.40 |10.0% | -|mpi |8 |0.04191 |0.21 |2.6% | +|Режим |Процессы |Время, с |Ускорение |Эффективность| +|-------|---------|---------|-----------|-------------| +|seq |1 |0.00867 |1.00 |N/A | +|mpi |2 |0.01478 |0.59 |29.5% | +|mpi |4 |0.02194 |0.40 |10.0% | +|mpi |8 |0.04191 |0.21 |2.6% | 2. n = 30 000 000 |Режим |Процессы |Время, с |Ускорение |Эффективность| |------|---------|---------|----------|-------------| |seq |1 |0.02383 |1.00 |N/A | -|mpi |2 |0.06083 |0.39 |19.5% | +|mpi |2 |0.06083 |0.39 |19.5% | |mpi |4 |0.13068 |0.18 |4.5% | |mpi |8 |0.18740 |0.13 |1.6% | From e445a6b4ae7ecb1f6f25d5d836a97ad834518bc9 Mon Sep 17 00:00:00 2001 From: Leonova Anna Date: Wed, 19 Nov 2025 10:59:54 +0000 Subject: [PATCH 15/16] cland-tidy4 --- .../mpi/include/ops_mpi.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp b/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp index 0a08873c08..a8cdb44391 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp @@ -21,8 +21,8 @@ class LeonovaAMostDiffNeighVecElemsMPI : public BaseTask { bool PostProcessingImpl() override; void ProcessWithMultipleProcesses(int rank, int size, int total_size, const std::vector &input_vec); - void ProcessLocalData(int rank, int actual_processes, int total_size, const std::vector &input_vec, - int &local_max_diff, int &local_first, int &local_second); + static void ProcessLocalData(int rank, int actual_processes, int total_size, const std::vector &input_vec, + int &local_max_diff, int &local_first, int &local_second); static void ReceiveLocalData(int rank, int actual_processes, const std::vector &input_vec, int my_size, std::vector &local_data, int total_size); static void SendDataToProcess(int dest, int actual_processes, const std::vector &input_vec, int total_size); From 9423e8caff858bb2d7dd1793d4c4322e407c45f7 Mon Sep 17 00:00:00 2001 From: Leonova Anna Date: Wed, 19 Nov 2025 15:37:07 +0000 Subject: [PATCH 16/16] Delete case proc 1 --- .../mpi/include/ops_mpi.hpp | 1 - .../mpi/src/ops_mpi.cpp | 22 +---------------- .../report.md | 24 ++++--------------- 3 files changed, 6 insertions(+), 41 deletions(-) diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp b/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp index a8cdb44391..665f3c6403 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/include/ops_mpi.hpp @@ -33,7 +33,6 @@ class LeonovaAMostDiffNeighVecElemsMPI : public BaseTask { void FindGlobalMaxDiff(const std::vector &all_diffs, const std::vector &all_firsts, const std::vector &all_seconds, int actual_processes); void BroadcastResult(int rank); - void ProcessSequentially(const std::vector &input_vec); }; } // namespace leonova_a_most_diff_neigh_vec_elems diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp b/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp index 6e2801ad64..af2e893829 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/mpi/src/ops_mpi.cpp @@ -44,12 +44,7 @@ bool LeonovaAMostDiffNeighVecElemsMPI::RunImpl() { MPI_Comm_size(MPI_COMM_WORLD, &size); int total_size = static_cast(input_vec.size()); - if (size > 1) { - ProcessWithMultipleProcesses(rank, size, total_size, input_vec); - } else { - ProcessSequentially(input_vec); - } - + ProcessWithMultipleProcesses(rank, size, total_size, input_vec); return true; } @@ -182,21 +177,6 @@ void LeonovaAMostDiffNeighVecElemsMPI::BroadcastResult(int rank) { } } -void LeonovaAMostDiffNeighVecElemsMPI::ProcessSequentially(const std::vector &input_vec) { - int max_diff = -1; - std::tuple best_pair(0, 0); - - for (std::size_t index = 0; index < input_vec.size() - 1; ++index) { - int diff = std::abs(input_vec[index] - input_vec[index + 1]); - if (diff > max_diff) { - max_diff = diff; - best_pair = std::make_tuple(input_vec[index], input_vec[index + 1]); - } - } - - GetOutput() = best_pair; -} - bool LeonovaAMostDiffNeighVecElemsMPI::PostProcessingImpl() { return true; } diff --git a/tasks/leonova_a_most_diff_neigh_vec_elems/report.md b/tasks/leonova_a_most_diff_neigh_vec_elems/report.md index d299e4830c..47d007d9df 100644 --- a/tasks/leonova_a_most_diff_neigh_vec_elems/report.md +++ b/tasks/leonova_a_most_diff_neigh_vec_elems/report.md @@ -179,12 +179,7 @@ bool LeonovaAMostDiffNeighVecElemsMPI::RunImpl() { MPI_Comm_size(MPI_COMM_WORLD, &size); int total_size = static_cast(input_vec.size()); - if (size > 1) { - ProcessWithMultipleProcesses(rank, size, total_size, input_vec); - } else { - ProcessSequentially(input_vec); - } - + ProcessWithMultipleProcesses(rank, size, total_size, input_vec); return true; } @@ -317,17 +312,8 @@ void LeonovaAMostDiffNeighVecElemsMPI::BroadcastResult(int rank) { } } -void LeonovaAMostDiffNeighVecElemsMPI::ProcessSequentially(const std::vector &input_vec) { - int max_diff = -1; - std::tuple best_pair(0, 0); - - for (std::size_t index = 0; index < input_vec.size() - 1; ++index) { - int diff = std::abs(input_vec[index] - input_vec[index + 1]); - if (diff > max_diff) { - max_diff = diff; - best_pair = std::make_tuple(input_vec[index], input_vec[index + 1]); - } - } +bool LeonovaAMostDiffNeighVecElemsMPI::PostProcessingImpl() { + return true; +} - GetOutput() = best_pair; -} \ No newline at end of file +} // namespace leonova_a_most_diff_neigh_vec_elems \ No newline at end of file