diff --git a/tasks/sokolov_k_min_val_matrix/common/include/common.hpp b/tasks/sokolov_k_min_val_matrix/common/include/common.hpp new file mode 100644 index 00000000..90fc6899 --- /dev/null +++ b/tasks/sokolov_k_min_val_matrix/common/include/common.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include +#include + +#include "task/include/task.hpp" + +namespace k_sokolov_min_val_matrix { + +using InType = int; +using OutType = int; +using TestType = std::tuple; +using BaseTask = ppc::task::Task; + +} // namespace k_sokolov_min_val_matrix diff --git a/tasks/sokolov_k_min_val_matrix/info.json b/tasks/sokolov_k_min_val_matrix/info.json new file mode 100644 index 00000000..90291fed --- /dev/null +++ b/tasks/sokolov_k_min_val_matrix/info.json @@ -0,0 +1,9 @@ +{ + "student": { + "first_name": "Кирилл", + "group_number": "3823Б1ПР4", + "last_name": "Соколов", + "middle_name": "Денисович", + "task_number": "1" + } +} diff --git a/tasks/sokolov_k_min_val_matrix/mpi/include/ops_mpi.hpp b/tasks/sokolov_k_min_val_matrix/mpi/include/ops_mpi.hpp new file mode 100644 index 00000000..94418f44 --- /dev/null +++ b/tasks/sokolov_k_min_val_matrix/mpi/include/ops_mpi.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include + +#include "sokolov_k_min_val_matrix/common/include/common.hpp" +#include "task/include/task.hpp" + +namespace k_sokolov_min_val_matrix { + +class SokolovKMinValMatrixMPI : public BaseTask { + public: + static constexpr ppc::task::TypeOfTask GetStaticTypeOfTask() { + return ppc::task::TypeOfTask::kMPI; + } + explicit SokolovKMinValMatrixMPI(const InType &in); + + private: + bool ValidationImpl() override; + bool PreProcessingImpl() override; + bool RunImpl() override; + bool PostProcessingImpl() override; + + std::vector matrix_; + int rows_ = 0; + int cols_ = 0; + int min_val_ = 0; +}; + +} // namespace k_sokolov_min_val_matrix diff --git a/tasks/sokolov_k_min_val_matrix/mpi/src/ops_mpi.cpp b/tasks/sokolov_k_min_val_matrix/mpi/src/ops_mpi.cpp new file mode 100644 index 00000000..4ce67073 --- /dev/null +++ b/tasks/sokolov_k_min_val_matrix/mpi/src/ops_mpi.cpp @@ -0,0 +1,87 @@ +#include "sokolov_k_min_val_matrix/mpi/include/ops_mpi.hpp" + +#include + +#include +#include +#include +#include + +#include "sokolov_k_min_val_matrix/common/include/common.hpp" + +namespace k_sokolov_min_val_matrix { + +SokolovKMinValMatrixMPI::SokolovKMinValMatrixMPI(const InType &in) { + SetTypeOfTask(GetStaticTypeOfTask()); + GetInput() = in; + GetOutput() = 0; +} + +bool SokolovKMinValMatrixMPI::ValidationImpl() { + return GetInput() > 0; +} + +bool SokolovKMinValMatrixMPI::PreProcessingImpl() { + int n = GetInput(); + if (n <= 0) { + rows_ = 0; + cols_ = 0; + return true; + } + rows_ = n; + cols_ = n; + + int rank = 0; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + if (rank == 0) { + matrix_.resize(static_cast(n) * n); + for (int i = 0; i < n * n; i++) { + matrix_[i] = i + 1; + } + } + + return true; +} + +bool SokolovKMinValMatrixMPI::RunImpl() { + int rank = 0; + int size = 0; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + int total = rows_ * cols_; + + std::vector send_counts(size); + std::vector displs(size); + + int base_count = total / size; + int remainder = total % size; + + for (int i = 0; i < size; i++) { + send_counts[i] = base_count + (i < remainder ? 1 : 0); + displs[i] = (i == 0) ? 0 : displs[i - 1] + send_counts[i - 1]; + } + + std::vector local_data(send_counts[rank]); + MPI_Scatterv(matrix_.data(), send_counts.data(), displs.data(), MPI_INT, local_data.data(), send_counts[rank], + MPI_INT, 0, MPI_COMM_WORLD); + + int local_min = std::numeric_limits::max(); + if (!local_data.empty()) { + local_min = *std::ranges::min_element(local_data); + } + + int global_min = 0; + MPI_Allreduce(&local_min, &global_min, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD); + min_val_ = global_min; + + return true; +} + +bool SokolovKMinValMatrixMPI::PostProcessingImpl() { + GetOutput() = min_val_; + return true; +} + +} // namespace k_sokolov_min_val_matrix diff --git a/tasks/sokolov_k_min_val_matrix/report.md b/tasks/sokolov_k_min_val_matrix/report.md new file mode 100644 index 00000000..7d639b5f --- /dev/null +++ b/tasks/sokolov_k_min_val_matrix/report.md @@ -0,0 +1,239 @@ +# Минимальное значение элементов матрицы + +- Студент: Соколов Кирилл Денисович, группа 3823Б1ПР4 +- Технология: SEQ, MPI +- Вариант: 14 + +## 1. Введение + +Данная лабораторная работа посвящена поиску минимального элемента в матрице с использованием технологии MPI. +Целью является разработка последовательного и параллельного алгоритмов, сравнение их производительности и анализ +масштабируемости. + +Матричные вычисления являются типичной задачей для параллелизации, так как над элементами можно выполнять +независимые операции. В горизонтальной схеме матрица делится между процессами по строкам, в вертикальной - по +столбцам. В данной реализации используется разбиение по строкам. + +## 2. Постановка задачи + +**Определение.** По заданной квадратной матрице размера N x N требуется найти минимальный элемент среди всех ее элементов. + +**Входные данные:** целое число N - размер стороны квадратной матрицы (N > 0). + +**Выходные данные:** целое число - минимальное значение среди всех элементов матрицы. + +**Ограничения:** матрица генерируется детерминированно (элементы от 1 до N*N по возрастанию индекса), +минимальный элемент всегда равен 1. + +## 3. Базовый алгоритм + +Последовательный алгоритм состоит из следующих этапов: + +1. **Валидация:** проверка, что входное значение N положительно. + +2. **Предобработка:** формирование матрицы размера N x N, хранящейся в виде одномерного вектора. Элементы + заполняются по правилу: matrix[i] = i + 1 (индексация с нуля). + +3. **Вычисление:** проход по всем элементам с помощью std::ranges::min_element для поиска минимального значения. + Сложность O(N^2). + +4. **Постобработка:** запись найденного минимума в выход. + +Алгоритм тривиален и не требует дополнительных структур данных. Используется линейный просмотр всех N*N элементов. + +## 4. Схема распараллеливания (MPI) + +Используется горизонтальная схема разбиения: матрица хранится как одномерный массив, который делится на +непрерывные порции между процессами по количеству элементов. + +**Распределение данных:** + +- Процесс ранга 0 (root) генерирует полную матрицу в PreProcessingImpl. +- В RunImpl данные распределяются с помощью MPI_Scatterv: каждый процесс получает свою порцию элементов (при + неравном делении первые remainder процессов получают на один элемент больше). + +**Схема обмена:** + +1. Root вызывает MPI_Scatterv, передавая каждому процессу send_counts[i] элементов начиная с смещения displs[i]. +2. Каждый процесс находит локальный минимум в своей порции (local_min). +3. MPI_Allreduce с операцией MPI_MIN собирает глобальный минимум на всех процессах. +4. Результат записывается в выход. + +**Топология:** двунаправленная связь через коммуникатор MPI_COMM_WORLD. Все процессы участвуют в коллективных +операциях Scatterv и Allreduce. + +**Роли рангов:** root (0) владеет исходными данными и участвует в scatter; все ранги выполняют поиск локального +минимума и участвуют в редукции. + +## 5. Детали реализации + +**Структура кода:** + +- `common/include/common.hpp` - общие типы (InType, OutType, BaseTask) +- `seq/include/ops_seq.hpp`, `seq/src/ops_seq.cpp` - последовательная реализация SokolovKMinValMatrixSEQ +- `mpi/include/ops_mpi.hpp`, `mpi/src/ops_mpi.cpp` - параллельная реализация SokolovKMinValMatrixMPI +- `tests/functional/main.cpp` - функциональные тесты +- `tests/performance/main.cpp` - тесты производительности + +**Ключевые предположения:** матрица квадратная; при пустой матрице (n <= 0) локальный минимум не вычисляется, +для процессов без данных используется INT_MAX, который не влияет на MPI_MIN при наличии хотя бы одного +валидного элемента. + +**Использование памяти:** на root - O(N^2) для хранения матрицы; на каждом процессе - O(N^2 / P) для локальной +порции, где P - число процессов. + +## 6. Экспериментальная установка + +- **CPU:** Intel Core i5-10400kf +- **Ядра/Потоки:** 6/12 +- **ОС:** Windows 10 +- **Компилятор:** MSVC 14.44 +- **Тип сборки:** Release +- **MPI реализация:** MS-MPI 10.0 +- **CMake:** 4.2.0-rc1 +- **Tестирование**: Google Test +- **Данные:** матрица 5000 x 5000 (25 млн элементов), генерируется в PreProcessing по формуле + matrix[i] = i + 1 + +## 7. Результаты + +### 7.1 Проверка корректности + +Корректность проверяется: + +- Функциональными тестами на размерах 1, 2, 3, 5, 7, 10, 50 для SEQ и MPI. Ожидаемый минимум - 1. +- Standalone-тестами на граничные случаи: отклонение нулевого и отрицательного ввода, проверка результата на + матрицах 1x1, 2x2, 100x100, 200x200. +- Совпадением результатов SEQ и MPI при одинаковых входных данных. + +### 7.2 Производительность + +Базовое время: task_run 0.0564 с, pipeline 0.0959 с. + +**task_run**: + +| Процессов | Время, с | Ускорение | Эффективность | +|-----------|----------|-----------|---------------| +| 2 | 0.0429 | 1.32 | 65.8% | +| 4 | 0.0294 | 1.92 | 47.9% | +| 6 | 0.0243 | 2.32 | 38.7% | +| 8 | 0.0219 | 2.57 | 32.2% | + +**task_pipeline**: + +| Процессов | Время, с | Ускорение | Эффективность | +|-----------|----------|-----------|---------------| +| 2 | 0.0850 | 1.13 | 56.4% | +| 4 | 0.0721 | 1.33 | 33.2% | +| 6 | 0.0649 | 1.48 | 24.6% | +| 8 | 0.0628 | 1.53 | 19.1% | + +## 8. Выводы + +- Реализованы последовательный и параллельный (MPI) алгоритмы поиска минимального элемента в матрице. +- Параллельный алгоритм использует MPI_Scatterv для распределения данных и MPI_Allreduce (MPI_MIN) для сбора результата. +- Task_run измеряет только вычислительное ядро и обычно показывает лучшее ускорение, чем pipeline, где + учитываются накладные расходы на генерацию данных и коммуникацию. +- Ограничения: при большом числе процессов по сравнению с размером матрицы доля коммуникации растет, эффективность падает. + +## 9. Источники + +1. MPI Forum. MPI: A Message-Passing Interface Standard. Version 4.0. +2. Gropp W., Lusk E., Skjellum A. Using MPI: Portable Parallel Programming with the Message Passing Interface. + 3rd ed. MIT Press, 2014. +3. Антонов А.С. Параллельное программирование с использованием технологии MPI: учебное пособие. М.: Изд-во МГУ, + 2004. +4. Воеводин В.В., Воеводин Вл.В. Параллельные вычисления. СПб.: БХВ-Петербург, 2002. +5. Гергель В.П. Теория и практика параллельных вычислений: учебное пособие. М.: БИНОМ. Лаборатория знаний, 2007. + +## Приложение. Фрагменты кода + +### Последовательный алгоритм: PreProcessingImpl и RunImpl + +```cpp +bool SokolovKMinValMatrixSEQ::PreProcessingImpl() { + int n = GetInput(); + if (n <= 0) { + rows_ = 0; + cols_ = 0; + return true; + } + rows_ = n; + cols_ = n; + matrix_.resize(static_cast(n) * n); + for (int i = 0; i < n * n; i++) { + matrix_[i] = i + 1; + } + return true; +} + +bool SokolovKMinValMatrixSEQ::RunImpl() { + if (matrix_.empty()) { + return true; + } + min_val_ = *std::ranges::min_element(matrix_); + return true; +} +``` + +### Параллельный алгоритм (MPI): PreProcessingImpl + +```cpp +bool SokolovKMinValMatrixMPI::PreProcessingImpl() { + int n = GetInput(); + if (n <= 0) { + rows_ = 0; + cols_ = 0; + return true; + } + rows_ = n; + cols_ = n; + + int rank = 0; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + if (rank == 0) { + matrix_.resize(static_cast(n) * n); + for (int i = 0; i < n * n; i++) { + matrix_[i] = i + 1; + } + } + return true; +} +``` + +### Параллельный алгоритм (MPI): RunImpl - распределение и редукция + +```cpp +bool SokolovKMinValMatrixMPI::RunImpl() { + int rank = 0; + int size = 0; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + int total = rows_ * cols_; + std::vector send_counts(size); + std::vector displs(size); + + int base_count = total / size; + int remainder = total % size; + for (int i = 0; i < size; i++) { + send_counts[i] = base_count + (i < remainder ? 1 : 0); + displs[i] = (i == 0) ? 0 : displs[i - 1] + send_counts[i - 1]; + } + + std::vector local_data(send_counts[rank]); + MPI_Scatterv(matrix_.data(), send_counts.data(), displs.data(), MPI_INT, + local_data.data(), send_counts[rank], MPI_INT, 0, MPI_COMM_WORLD); + + int local_min = std::numeric_limits::max(); + if (!local_data.empty()) { + local_min = *std::ranges::min_element(local_data); + } + + int global_min = 0; + MPI_Allreduce(&local_min, &global_min, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD); + min_val_ = global_min; + return true; +} +``` diff --git a/tasks/sokolov_k_min_val_matrix/seq/include/ops_seq.hpp b/tasks/sokolov_k_min_val_matrix/seq/include/ops_seq.hpp new file mode 100644 index 00000000..f49e8f57 --- /dev/null +++ b/tasks/sokolov_k_min_val_matrix/seq/include/ops_seq.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include + +#include "sokolov_k_min_val_matrix/common/include/common.hpp" +#include "task/include/task.hpp" + +namespace k_sokolov_min_val_matrix { + +class SokolovKMinValMatrixSEQ : public BaseTask { + public: + static constexpr ppc::task::TypeOfTask GetStaticTypeOfTask() { + return ppc::task::TypeOfTask::kSEQ; + } + explicit SokolovKMinValMatrixSEQ(const InType &in); + + private: + bool ValidationImpl() override; + bool PreProcessingImpl() override; + bool RunImpl() override; + bool PostProcessingImpl() override; + + std::vector matrix_; + int rows_ = 0; + int cols_ = 0; + int min_val_ = 0; +}; + +} // namespace k_sokolov_min_val_matrix diff --git a/tasks/sokolov_k_min_val_matrix/seq/src/ops_seq.cpp b/tasks/sokolov_k_min_val_matrix/seq/src/ops_seq.cpp new file mode 100644 index 00000000..781aba3c --- /dev/null +++ b/tasks/sokolov_k_min_val_matrix/seq/src/ops_seq.cpp @@ -0,0 +1,49 @@ +#include "sokolov_k_min_val_matrix/seq/include/ops_seq.hpp" + +#include +#include + +#include "sokolov_k_min_val_matrix/common/include/common.hpp" + +namespace k_sokolov_min_val_matrix { + +SokolovKMinValMatrixSEQ::SokolovKMinValMatrixSEQ(const InType &in) { + SetTypeOfTask(GetStaticTypeOfTask()); + GetInput() = in; + GetOutput() = 0; +} + +bool SokolovKMinValMatrixSEQ::ValidationImpl() { + return GetInput() > 0; +} + +bool SokolovKMinValMatrixSEQ::PreProcessingImpl() { + int n = GetInput(); + if (n <= 0) { + rows_ = 0; + cols_ = 0; + return true; + } + rows_ = n; + cols_ = n; + matrix_.resize(static_cast(n) * n); + for (int i = 0; i < n * n; i++) { + matrix_[i] = i + 1; + } + return true; +} + +bool SokolovKMinValMatrixSEQ::RunImpl() { + if (matrix_.empty()) { + return true; + } + min_val_ = *std::ranges::min_element(matrix_); + return true; +} + +bool SokolovKMinValMatrixSEQ::PostProcessingImpl() { + GetOutput() = min_val_; + return true; +} + +} // namespace k_sokolov_min_val_matrix diff --git a/tasks/sokolov_k_min_val_matrix/settings.json b/tasks/sokolov_k_min_val_matrix/settings.json new file mode 100644 index 00000000..16f25e42 --- /dev/null +++ b/tasks/sokolov_k_min_val_matrix/settings.json @@ -0,0 +1,7 @@ +{ + "tasks": { + "mpi": "enabled", + "seq": "enabled" + }, + "tasks_type": "processes" +} diff --git a/tasks/sokolov_k_min_val_matrix/tests/.clang-tidy b/tasks/sokolov_k_min_val_matrix/tests/.clang-tidy new file mode 100644 index 00000000..ef43b7aa --- /dev/null +++ b/tasks/sokolov_k_min_val_matrix/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/sokolov_k_min_val_matrix/tests/functional/main.cpp b/tasks/sokolov_k_min_val_matrix/tests/functional/main.cpp new file mode 100644 index 00000000..3cae9c96 --- /dev/null +++ b/tasks/sokolov_k_min_val_matrix/tests/functional/main.cpp @@ -0,0 +1,157 @@ +#include + +#include +#include +#include +#include + +#include "sokolov_k_min_val_matrix/common/include/common.hpp" +#include "sokolov_k_min_val_matrix/mpi/include/ops_mpi.hpp" +#include "sokolov_k_min_val_matrix/seq/include/ops_seq.hpp" +#include "util/include/func_test_util.hpp" +#include "util/include/util.hpp" + +namespace k_sokolov_min_val_matrix { + +class SokolovKMinValMatrixFuncTests : public ppc::util::BaseRunFuncTests { + public: + static std::string PrintTestParam(const TestType &test_param) { + return std::to_string(std::get<0>(test_param)) + "_" + std::get<1>(test_param); + } + + protected: + void SetUp() override { + TestType params = std::get(ppc::util::GTestParamIndex::kTestParams)>(GetParam()); + input_data_ = std::get<0>(params); + } + + bool CheckTestOutputData(OutType &output_data) final { + return output_data == 1; + } + + InType GetTestInputData() final { + return input_data_; + } + + private: + InType input_data_ = 0; +}; + +namespace { + +TEST_P(SokolovKMinValMatrixFuncTests, MatmulFromPic) { + ExecuteTest(GetParam()); +} + +const std::array kTestParam = { + std::make_tuple(1, "1"), std::make_tuple(2, "2"), std::make_tuple(3, "3"), std::make_tuple(5, "5"), + std::make_tuple(7, "7"), std::make_tuple(10, "10"), std::make_tuple(50, "50")}; + +const auto kTestTasksList = std::tuple_cat( + ppc::util::AddFuncTask(kTestParam, PPC_SETTINGS_sokolov_k_min_val_matrix), + ppc::util::AddFuncTask(kTestParam, PPC_SETTINGS_sokolov_k_min_val_matrix)); + +const auto kGtestValues = ppc::util::ExpandToValues(kTestTasksList); + +const auto kPerfTestName = SokolovKMinValMatrixFuncTests::PrintFuncTestName; + +INSTANTIATE_TEST_SUITE_P(PicMatrixTests, SokolovKMinValMatrixFuncTests, kGtestValues, kPerfTestName); + +TEST(SokolovKMinValMatrixSeqValidation, RejectsZeroInput) { + SokolovKMinValMatrixSEQ task(0); + EXPECT_FALSE(task.Validation()); + task.PreProcessing(); + task.Run(); + task.PostProcessing(); +} + +TEST(SokolovKMinValMatrixSeqValidation, RejectsNegativeInput) { + SokolovKMinValMatrixSEQ task(-5); + EXPECT_FALSE(task.Validation()); + task.PreProcessing(); + task.Run(); + task.PostProcessing(); +} + +TEST(SokolovKMinValMatrixSeqTest, SingleElementMatrix) { + SokolovKMinValMatrixSEQ task(1); + EXPECT_TRUE(task.Validation()); + EXPECT_TRUE(task.PreProcessing()); + EXPECT_TRUE(task.Run()); + EXPECT_TRUE(task.PostProcessing()); + EXPECT_EQ(task.GetOutput(), 1); +} + +TEST(SokolovKMinValMatrixSeqTest, SmallMatrix2x2) { + SokolovKMinValMatrixSEQ task(2); + EXPECT_TRUE(task.Validation()); + EXPECT_TRUE(task.PreProcessing()); + EXPECT_TRUE(task.Run()); + EXPECT_TRUE(task.PostProcessing()); + EXPECT_EQ(task.GetOutput(), 1); +} + +TEST(SokolovKMinValMatrixSeqTest, MediumMatrix100x100) { + SokolovKMinValMatrixSEQ task(100); + EXPECT_TRUE(task.Validation()); + EXPECT_TRUE(task.PreProcessing()); + EXPECT_TRUE(task.Run()); + EXPECT_TRUE(task.PostProcessing()); + EXPECT_EQ(task.GetOutput(), 1); +} + +TEST(SokolovKMinValMatrixSeqTest, LargeMatrix200x200) { + SokolovKMinValMatrixSEQ task(200); + EXPECT_TRUE(task.Validation()); + EXPECT_TRUE(task.PreProcessing()); + EXPECT_TRUE(task.Run()); + EXPECT_TRUE(task.PostProcessing()); + EXPECT_EQ(task.GetOutput(), 1); +} + +TEST(SokolovKMinValMatrixMpiValidation, RejectsZeroInput) { + SokolovKMinValMatrixMPI task(0); + EXPECT_FALSE(task.Validation()); + task.PreProcessing(); + task.Run(); + task.PostProcessing(); +} + +TEST(SokolovKMinValMatrixMpiValidation, RejectsNegativeInput) { + SokolovKMinValMatrixMPI task(-3); + EXPECT_FALSE(task.Validation()); + task.PreProcessing(); + task.Run(); + task.PostProcessing(); +} + +TEST(SokolovKMinValMatrixMpiTest, SingleElementMatrix) { + SokolovKMinValMatrixMPI task(1); + EXPECT_TRUE(task.Validation()); + EXPECT_TRUE(task.PreProcessing()); + EXPECT_TRUE(task.Run()); + EXPECT_TRUE(task.PostProcessing()); + EXPECT_EQ(task.GetOutput(), 1); +} + +TEST(SokolovKMinValMatrixMpiTest, SmallMatrix3x3) { + SokolovKMinValMatrixMPI task(3); + EXPECT_TRUE(task.Validation()); + EXPECT_TRUE(task.PreProcessing()); + EXPECT_TRUE(task.Run()); + EXPECT_TRUE(task.PostProcessing()); + EXPECT_EQ(task.GetOutput(), 1); +} + +TEST(SokolovKMinValMatrixMpiTest, MediumMatrix100x100) { + SokolovKMinValMatrixMPI task(100); + EXPECT_TRUE(task.Validation()); + EXPECT_TRUE(task.PreProcessing()); + EXPECT_TRUE(task.Run()); + EXPECT_TRUE(task.PostProcessing()); + EXPECT_EQ(task.GetOutput(), 1); +} + +} // namespace + +} // namespace k_sokolov_min_val_matrix diff --git a/tasks/sokolov_k_min_val_matrix/tests/performance/main.cpp b/tasks/sokolov_k_min_val_matrix/tests/performance/main.cpp new file mode 100644 index 00000000..2c8a22ac --- /dev/null +++ b/tasks/sokolov_k_min_val_matrix/tests/performance/main.cpp @@ -0,0 +1,40 @@ +#include + +#include "sokolov_k_min_val_matrix/common/include/common.hpp" +#include "sokolov_k_min_val_matrix/mpi/include/ops_mpi.hpp" +#include "sokolov_k_min_val_matrix/seq/include/ops_seq.hpp" +#include "util/include/perf_test_util.hpp" + +namespace k_sokolov_min_val_matrix { + +class SokolovKMinValMatrixPerfTests : public ppc::util::BaseRunPerfTests { + const int kCount_ = 5000; + InType input_data_{}; + + void SetUp() override { + input_data_ = kCount_; + } + + bool CheckTestOutputData(OutType &output_data) final { + return output_data == 1; + } + + InType GetTestInputData() final { + return input_data_; + } +}; + +TEST_P(SokolovKMinValMatrixPerfTests, RunPerfModes) { + ExecuteTest(GetParam()); +} + +const auto kAllPerfTasks = ppc::util::MakeAllPerfTasks( + PPC_SETTINGS_sokolov_k_min_val_matrix); + +const auto kGtestValues = ppc::util::TupleToGTestValues(kAllPerfTasks); + +const auto kPerfTestName = SokolovKMinValMatrixPerfTests::CustomPerfTestName; + +INSTANTIATE_TEST_SUITE_P(RunModeTests, SokolovKMinValMatrixPerfTests, kGtestValues, kPerfTestName); + +} // namespace k_sokolov_min_val_matrix