diff --git a/tasks/nesterov_a_elem_vec_sum/common/include/common.hpp b/tasks/nesterov_a_elem_vec_sum/common/include/common.hpp new file mode 100644 index 00000000..a0c41088 --- /dev/null +++ b/tasks/nesterov_a_elem_vec_sum/common/include/common.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include +#include + +#include "task/include/task.hpp" + +namespace nesterov_a_elem_vec_sum { + +using InType = int; +using OutType = int; +using TestType = std::tuple; +using BaseTask = ppc::task::Task; + +} // namespace nesterov_a_elem_vec_sum diff --git a/tasks/nesterov_a_elem_vec_sum/data/pic.jpg b/tasks/nesterov_a_elem_vec_sum/data/pic.jpg new file mode 100644 index 00000000..34458023 Binary files /dev/null and b/tasks/nesterov_a_elem_vec_sum/data/pic.jpg differ diff --git a/tasks/nesterov_a_elem_vec_sum/info.json b/tasks/nesterov_a_elem_vec_sum/info.json new file mode 100644 index 00000000..0d40ea9d --- /dev/null +++ b/tasks/nesterov_a_elem_vec_sum/info.json @@ -0,0 +1,9 @@ +{ + "student": { + "first_name": "Александр", + "last_name": "Нестеров", + "middle_name": "Юрьевич", + "group_number": "3818081-2", + "task_number": "1" + } +} diff --git a/tasks/nesterov_a_elem_vec_sum/mpi/include/ops_mpi.hpp b/tasks/nesterov_a_elem_vec_sum/mpi/include/ops_mpi.hpp new file mode 100644 index 00000000..e2d792f7 --- /dev/null +++ b/tasks/nesterov_a_elem_vec_sum/mpi/include/ops_mpi.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include "nesterov_a_elem_vec_sum/common/include/common.hpp" +#include "task/include/task.hpp" + +namespace nesterov_a_elem_vec_sum { + +class NesterovAElemVecSumMPI : public BaseTask { + public: + static constexpr ppc::task::TypeOfTask GetStaticTypeOfTask() { + return ppc::task::TypeOfTask::kMPI; + } + explicit NesterovAElemVecSumMPI(const InType &in); + + private: + bool ValidationImpl() override; + bool PreProcessingImpl() override; + bool RunImpl() override; + bool PostProcessingImpl() override; +}; + +} // namespace nesterov_a_elem_vec_sum diff --git a/tasks/nesterov_a_elem_vec_sum/mpi/src/ops_mpi.cpp b/tasks/nesterov_a_elem_vec_sum/mpi/src/ops_mpi.cpp new file mode 100644 index 00000000..cc25cc85 --- /dev/null +++ b/tasks/nesterov_a_elem_vec_sum/mpi/src/ops_mpi.cpp @@ -0,0 +1,72 @@ +#include "nesterov_a_elem_vec_sum/mpi/include/ops_mpi.hpp" + +#include + +#include +#include + +#include "nesterov_a_elem_vec_sum/common/include/common.hpp" +#include "util/include/util.hpp" + +namespace nesterov_a_elem_vec_sum { + +NesterovAElemVecSumMPI::NesterovAElemVecSumMPI(const InType &in) { + SetTypeOfTask(GetStaticTypeOfTask()); + GetInput() = in; + GetOutput() = 0; +} + +bool NesterovAElemVecSumMPI::ValidationImpl() { + return (GetInput() > 0) && (GetOutput() == 0); +} + +bool NesterovAElemVecSumMPI::PreProcessingImpl() { + GetOutput() = 2 * GetInput(); + return GetOutput() > 0; +} + +bool NesterovAElemVecSumMPI::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 GetOutput() > 0; +} + +bool NesterovAElemVecSumMPI::PostProcessingImpl() { + GetOutput() -= GetInput(); + return GetOutput() > 0; +} + +} // namespace nesterov_a_elem_vec_sum diff --git a/tasks/nesterov_a_elem_vec_sum/report.md b/tasks/nesterov_a_elem_vec_sum/report.md new file mode 100644 index 00000000..bbda3591 --- /dev/null +++ b/tasks/nesterov_a_elem_vec_sum/report.md @@ -0,0 +1,4 @@ +# Отчет + +123 + diff --git a/tasks/nesterov_a_elem_vec_sum/seq/include/ops_seq.hpp b/tasks/nesterov_a_elem_vec_sum/seq/include/ops_seq.hpp new file mode 100644 index 00000000..0a1a1bae --- /dev/null +++ b/tasks/nesterov_a_elem_vec_sum/seq/include/ops_seq.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include "nesterov_a_elem_vec_sum/common/include/common.hpp" +#include "task/include/task.hpp" + +namespace nesterov_a_elem_vec_sum { + +class NesterovAElemVecSumSEQ : public BaseTask { + public: + static constexpr ppc::task::TypeOfTask GetStaticTypeOfTask() { + return ppc::task::TypeOfTask::kSEQ; + } + explicit NesterovAElemVecSumSEQ(const InType &in); + + private: + bool ValidationImpl() override; + bool PreProcessingImpl() override; + bool RunImpl() override; + bool PostProcessingImpl() override; +}; + +} // namespace nesterov_a_elem_vec_sum diff --git a/tasks/nesterov_a_elem_vec_sum/seq/src/ops_seq.cpp b/tasks/nesterov_a_elem_vec_sum/seq/src/ops_seq.cpp new file mode 100644 index 00000000..0006b94e --- /dev/null +++ b/tasks/nesterov_a_elem_vec_sum/seq/src/ops_seq.cpp @@ -0,0 +1,60 @@ +#include "nesterov_a_elem_vec_sum/seq/include/ops_seq.hpp" + +#include +#include + +#include "nesterov_a_elem_vec_sum/common/include/common.hpp" +#include "util/include/util.hpp" + +namespace nesterov_a_elem_vec_sum { + +NesterovAElemVecSumSEQ::NesterovAElemVecSumSEQ(const InType &in) { + SetTypeOfTask(GetStaticTypeOfTask()); + GetInput() = in; + GetOutput() = 0; +} + +bool NesterovAElemVecSumSEQ::ValidationImpl() { + return (GetInput() > 0) && (GetOutput() == 0); +} + +bool NesterovAElemVecSumSEQ::PreProcessingImpl() { + GetOutput() = 2 * GetInput(); + return GetOutput() > 0; +} + +bool NesterovAElemVecSumSEQ::RunImpl() { + if (GetInput() == 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 counter = 0; + for (int i = 0; i < num_threads; i++) { + counter++; + } + + if (counter != 0) { + GetOutput() /= counter; + } + return GetOutput() > 0; +} + +bool NesterovAElemVecSumSEQ::PostProcessingImpl() { + GetOutput() -= GetInput(); + return GetOutput() > 0; +} + +} // namespace nesterov_a_elem_vec_sum diff --git a/tasks/nesterov_a_elem_vec_sum/settings.json b/tasks/nesterov_a_elem_vec_sum/settings.json new file mode 100644 index 00000000..b1a0d525 --- /dev/null +++ b/tasks/nesterov_a_elem_vec_sum/settings.json @@ -0,0 +1,7 @@ +{ + "tasks_type": "processes", + "tasks": { + "mpi": "enabled", + "seq": "enabled" + } +} diff --git a/tasks/nesterov_a_elem_vec_sum/tests/.clang-tidy b/tasks/nesterov_a_elem_vec_sum/tests/.clang-tidy new file mode 100644 index 00000000..ef43b7aa --- /dev/null +++ b/tasks/nesterov_a_elem_vec_sum/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/nesterov_a_elem_vec_sum/tests/functional/main.cpp b/tasks/nesterov_a_elem_vec_sum/tests/functional/main.cpp new file mode 100644 index 00000000..e59de0ef --- /dev/null +++ b/tasks/nesterov_a_elem_vec_sum/tests/functional/main.cpp @@ -0,0 +1,85 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nesterov_a_elem_vec_sum/common/include/common.hpp" +#include "nesterov_a_elem_vec_sum/mpi/include/ops_mpi.hpp" +#include "nesterov_a_elem_vec_sum/seq/include/ops_seq.hpp" +#include "util/include/func_test_util.hpp" +#include "util/include/util.hpp" + +namespace nesterov_a_elem_vec_sum { + +class NesterovAElemVecSumFuncTests : 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 { + int width = -1; + int height = -1; + int channels = -1; + std::vector img; + // Read image + { + std::string abs_path = ppc::util::GetAbsoluteTaskPath(PPC_ID_nesterov_a_elem_vec_sum, "pic.jpg"); + auto *data = stbi_load(abs_path.c_str(), &width, &height, &channels, 0); + if (data == nullptr) { + throw std::runtime_error("Failed to load image: " + std::string(stbi_failure_reason())); + } + 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); + } + + InType GetTestInputData() final { + return input_data_; + } + + private: + InType input_data_ = 0; +}; + +namespace { + +TEST_P(NesterovAElemVecSumFuncTests, 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_nesterov_a_elem_vec_sum), + ppc::util::AddFuncTask(kTestParam, PPC_SETTINGS_nesterov_a_elem_vec_sum)); + +const auto kGtestValues = ppc::util::ExpandToValues(kTestTasksList); + +const auto kPerfTestName = NesterovAElemVecSumFuncTests::PrintFuncTestName; + +INSTANTIATE_TEST_SUITE_P(PicMatrixTests, NesterovAElemVecSumFuncTests, kGtestValues, kPerfTestName); + +} // namespace + +} // namespace nesterov_a_elem_vec_sum diff --git a/tasks/nesterov_a_elem_vec_sum/tests/performance/main.cpp b/tasks/nesterov_a_elem_vec_sum/tests/performance/main.cpp new file mode 100644 index 00000000..235d3f8f --- /dev/null +++ b/tasks/nesterov_a_elem_vec_sum/tests/performance/main.cpp @@ -0,0 +1,40 @@ +#include + +#include "nesterov_a_elem_vec_sum/common/include/common.hpp" +#include "nesterov_a_elem_vec_sum/mpi/include/ops_mpi.hpp" +#include "nesterov_a_elem_vec_sum/seq/include/ops_seq.hpp" +#include "util/include/perf_test_util.hpp" + +namespace nesterov_a_elem_vec_sum { + +class NesterovAElemVecSumPerfTests : 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(NesterovAElemVecSumPerfTests, RunPerfModes) { + ExecuteTest(GetParam()); +} + +const auto kAllPerfTasks = + ppc::util::MakeAllPerfTasks(PPC_SETTINGS_nesterov_a_elem_vec_sum); + +const auto kGtestValues = ppc::util::TupleToGTestValues(kAllPerfTasks); + +const auto kPerfTestName = NesterovAElemVecSumPerfTests::CustomPerfTestName; + +INSTANTIATE_TEST_SUITE_P(RunModeTests, NesterovAElemVecSumPerfTests, kGtestValues, kPerfTestName); + +} // namespace nesterov_a_elem_vec_sum