diff --git a/tasks/konovalov_s_sympson_method2/common/include/common.hpp b/tasks/konovalov_s_sympson_method2/common/include/common.hpp new file mode 100644 index 0000000000..d8b43dd85e --- /dev/null +++ b/tasks/konovalov_s_sympson_method2/common/include/common.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include +#include +#include +#include + +#include "task/include/task.hpp" + +namespace konovalov_s_sympson_method2 { + +using InType = std::tuple; +using OutType = double; +using TestType = std::tuple; +using BaseTask = ppc::task::Task; + +} // namespace konovalov_s_sympson_method2 \ No newline at end of file diff --git a/tasks/konovalov_s_sympson_method2/data/pic.jpg b/tasks/konovalov_s_sympson_method2/data/pic.jpg new file mode 100644 index 0000000000..637624238c Binary files /dev/null and b/tasks/konovalov_s_sympson_method2/data/pic.jpg differ diff --git a/tasks/konovalov_s_sympson_method2/info.json b/tasks/konovalov_s_sympson_method2/info.json new file mode 100644 index 0000000000..108fe1f779 --- /dev/null +++ b/tasks/konovalov_s_sympson_method2/info.json @@ -0,0 +1,9 @@ +{ + "student": { + "first_name": "first_name_p", + "last_name": "last_name_p", + "middle_name": "middle_name_p", + "group_number": "2222222_p", + "task_number": "3" + } +} diff --git a/tasks/konovalov_s_sympson_method2/mpi/include/ops_mpi.hpp b/tasks/konovalov_s_sympson_method2/mpi/include/ops_mpi.hpp new file mode 100644 index 0000000000..75c555ce65 --- /dev/null +++ b/tasks/konovalov_s_sympson_method2/mpi/include/ops_mpi.hpp @@ -0,0 +1,35 @@ +#pragma once + +#include +#include + +#include "task/include/task.hpp" +#include "konovalov_s_sympson_method2/common/include/common.hpp" + +namespace konovalov_s_sympson_method2 { + +class KonovalovSSympsonMethodMPI : public BaseTask { + public: + static constexpr ppc::task::TypeOfTask GetStaticTypeOfTask() { + return ppc::task::TypeOfTask::kMPI; + } + explicit KonovalovSSympsonMethodMPI(const InType &in); + + private: + bool ValidationImpl() override; + bool PreProcessingImpl() override; + bool RunImpl() override; + bool PostProcessingImpl() override; + + double ComputePartialIntegral(int start_idx, int end_idx); + + std::vector lower_bounds_; + std::vector upper_bounds_; + int num_steps_{}; + std::function &)> func_; + double result_{}; + int start_idx_{}; + int end_idx_{}; +}; + +} // namespace konovalov_s_sympson_method2 \ No newline at end of file diff --git a/tasks/konovalov_s_sympson_method2/mpi/src/ops_mpi.cpp b/tasks/konovalov_s_sympson_method2/mpi/src/ops_mpi.cpp new file mode 100644 index 0000000000..f4be55e9b4 --- /dev/null +++ b/tasks/konovalov_s_sympson_method2/mpi/src/ops_mpi.cpp @@ -0,0 +1,172 @@ +#include "konovalov_s_sympson_method2/mpi/include/ops_mpi.hpp" + +#include + +#include +#include + +#include "konovalov_s_sympson_method2/common/include/common.hpp" + +namespace konovalov_s_sympson_method2 { + +KonovalovSSympsonMethodMPI::KonovalovSSympsonMethodMPI(const InType &in) { + SetTypeOfTask(GetStaticTypeOfTask()); + GetInput() = in; + GetOutput() = 0.0; +} + +bool KonovalovSSympsonMethodMPI::ValidationImpl() { +// int rank = 0; +// MPI_Comm_rank(MPI_COMM_WORLD, &rank); + +// if (rank == 0) { +// const auto &input = GetInput(); + +// if (input.lower_bounds.empty() || input.upper_bounds.empty()) { +// return false; +// } + +// if (input.lower_bounds.size() != input.upper_bounds.size()) { +// return false; +// } + +// if (input.num_steps <= 0) { +// return false; +// } + +// if (!input.func) { +// return false; +// } + +// for (std::size_t idx = 0; idx < input.lower_bounds.size(); ++idx) { +// if (input.lower_bounds[idx] > input.upper_bounds[idx]) { +// return false; +// } +// } +// } + + return true; +} + +bool KonovalovSSympsonMethodMPI::PreProcessingImpl() { + // int rank = 0; + // int size = 0; + // MPI_Comm_rank(MPI_COMM_WORLD, &rank); + // MPI_Comm_size(MPI_COMM_WORLD, &size); + + // int dimensions = 0; + // if (rank == 0) { + // const auto &input = GetInput(); + // lower_bounds_ = input.lower_bounds; + // upper_bounds_ = input.upper_bounds; + // num_steps_ = input.num_steps; + // func_ = input.func; + // dimensions = static_cast(lower_bounds_.size()); + // } + + // MPI_Bcast(&dimensions, 1, MPI_INT, 0, MPI_COMM_WORLD); + // MPI_Bcast(&num_steps_, 1, MPI_INT, 0, MPI_COMM_WORLD); + + // if (rank != 0) { + // lower_bounds_.resize(dimensions); + // upper_bounds_.resize(dimensions); + // func_ = GetInput().func; + // } + + // MPI_Bcast(lower_bounds_.data(), dimensions, MPI_DOUBLE, 0, MPI_COMM_WORLD); + // MPI_Bcast(upper_bounds_.data(), dimensions, MPI_DOUBLE, 0, MPI_COMM_WORLD); + + // int total_points = 1; + // for (int idx = 0; idx < dimensions; ++idx) { + // total_points *= (num_steps_ + 1); + // } + + // int base_points_per_proc = total_points / size; + // int remainder = total_points % size; + + // std::vector counts(size); + // std::vector displs(size); + // int offset = 0; + // for (int idx = 0; idx < size; ++idx) { + // counts[idx] = base_points_per_proc + (idx < remainder ? 1 : 0); + // displs[idx] = offset; + // offset += counts[idx]; + // } + + // if (rank == 0) { + // for (int dest = 1; dest < size; ++dest) { + // MPI_Send(&counts[dest], 1, MPI_INT, dest, 0, MPI_COMM_WORLD); + // MPI_Send(&displs[dest], 1, MPI_INT, dest, 1, MPI_COMM_WORLD); + // } + // start_idx_ = displs[0]; + // end_idx_ = displs[0] + counts[0]; + // } else { + // int local_count = 0; + // int local_displ = 0; + // MPI_Recv(&local_count, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + // MPI_Recv(&local_displ, 1, MPI_INT, 0, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + // start_idx_ = local_displ; + // end_idx_ = local_displ + local_count; + // } + + // result_ = 0.0; + return true; +} + +// double KonovalovSSympsonMethodMPI::ComputePartialIntegral(int start_idx, int end_idx) { +// std::size_t dimensions = lower_bounds_.size(); +// std::vector step_sizes(dimensions); +// for (std::size_t idx = 0; idx < dimensions; ++idx) { +// step_sizes[idx] = (upper_bounds_[idx] - lower_bounds_[idx]) / num_steps_; +// } + +// double sum = 0.0; +// std::vector point(dimensions); + +// for (int idx = start_idx; idx < end_idx; ++idx) { +// int temp = idx; +// double weight = 1.0; + +// for (std::size_t dim = 0; dim < dimensions; ++dim) { +// int grid_idx = temp % (num_steps_ + 1); +// temp /= (num_steps_ + 1); +// point[dim] = lower_bounds_[dim] + (grid_idx * step_sizes[dim]); + +// if (grid_idx == 0 || grid_idx == num_steps_) { +// weight *= 0.5; +// } +// } + +// sum += weight * func_(point); +// } + +// double volume = 1.0; +// for (std::size_t idx = 0; idx < dimensions; ++idx) { +// volume *= step_sizes[idx]; +// } + +// return sum * volume; +// } + +bool KonovalovSSympsonMethodMPI::RunImpl() { +// double local_result = ComputePartialIntegral(start_idx_, end_idx_); + +// double global_result = 0.0; +// MPI_Reduce(&local_result, &global_result, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); + +// int rank = 0; +// MPI_Comm_rank(MPI_COMM_WORLD, &rank); +// if (rank == 0) { +// result_ = global_result; +// } + + return true; +} + +bool KonovalovSSympsonMethodMPI::PostProcessingImpl() { +// MPI_Bcast(&result_, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); +// GetOutput() = result_; + return true; +} + +} // namespace konovalov_s_sympson_method2 \ No newline at end of file diff --git a/tasks/konovalov_s_sympson_method2/report.md b/tasks/konovalov_s_sympson_method2/report.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tasks/konovalov_s_sympson_method2/seq/include/ops_seq.hpp b/tasks/konovalov_s_sympson_method2/seq/include/ops_seq.hpp new file mode 100644 index 0000000000..8ad7882046 --- /dev/null +++ b/tasks/konovalov_s_sympson_method2/seq/include/ops_seq.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include +#include + +#include "task/include/task.hpp" +#include "konovalov_s_sympson_method2/common/include/common.hpp" + +namespace konovalov_s_sympson_method2 { + +class KonovalovSSympsonMethodSEQ : public BaseTask { + public: + static constexpr ppc::task::TypeOfTask GetStaticTypeOfTask() { + return ppc::task::TypeOfTask::kSEQ; + } + explicit KonovalovSSympsonMethodSEQ(const InType &in); + + private: + bool ValidationImpl() override; + bool PreProcessingImpl() override; + bool RunImpl() override; + bool PostProcessingImpl() override; + double GetFunc(double x, double y); + double SimpsonMethod(double a, double b, double c, double d, int n); +}; + +} // namespace konovalov_s_sympson_method2 \ No newline at end of file diff --git a/tasks/konovalov_s_sympson_method2/seq/src/ops_seq.cpp b/tasks/konovalov_s_sympson_method2/seq/src/ops_seq.cpp new file mode 100644 index 0000000000..7e30fbd8e7 --- /dev/null +++ b/tasks/konovalov_s_sympson_method2/seq/src/ops_seq.cpp @@ -0,0 +1,59 @@ +#include "konovalov_s_sympson_method2/seq/include/ops_seq.hpp" + +#include +#include + +#include "konovalov_s_sympson_method2/common/include/common.hpp" + +namespace konovalov_s_sympson_method2 { + +KonovalovSSympsonMethodSEQ::KonovalovSSympsonMethodSEQ(const InType &in) { + SetTypeOfTask(GetStaticTypeOfTask()); + GetInput() = in; + GetOutput() = 0.0; +} + +bool KonovalovSSympsonMethodSEQ::ValidationImpl() { + return GetInput() != std::make_tuple(0.0, 0.0, 0.0, 0.0, 0) && std::get<4>(GetInput()) % 2 == 0; +} + +bool KonovalovSSympsonMethodSEQ::PreProcessingImpl() { + return true; +} + +double KonovalovSSympsonMethodSEQ::GetFunc(double x, double y) { + return (double)(rand())/RAND_MAX*(10) + std::max(x, y); +} + +double KonovalovSSympsonMethodSEQ::SimpsonMethod(double a, double b, double c, double d, int n) { + + double h = (b - a) / n; + double k = (d - c) / n; + + double x, y, sum = 0; + + for (int i = 0; i <= n; i++) { + for (int j = 0; j <= n; j++) { + x = a + i * h; + y = c + j * k; + + int coeff = (i == 0 || i == n) ? 1 : (i % 2 == 1 ? 4 : 2); + + sum += coeff * GetFunc(x, y); + } + } + + return (h * k / 9.0) * sum; +} + +bool KonovalovSSympsonMethodSEQ::RunImpl() { + GetOutput() = SimpsonMethod(std::get<0>(GetInput()), std::get<1>(GetInput()), std::get<2>(GetInput()), + std::get<3>(GetInput()), std::get<4>(GetInput())); + return true; +} + +bool KonovalovSSympsonMethodSEQ::PostProcessingImpl() { + return true; +} + +} // namespace konovalov_s_sympson_method2 diff --git a/tasks/konovalov_s_sympson_method2/settings.json b/tasks/konovalov_s_sympson_method2/settings.json new file mode 100644 index 0000000000..b1a0d52574 --- /dev/null +++ b/tasks/konovalov_s_sympson_method2/settings.json @@ -0,0 +1,7 @@ +{ + "tasks_type": "processes", + "tasks": { + "mpi": "enabled", + "seq": "enabled" + } +} diff --git a/tasks/konovalov_s_sympson_method2/tests/.clang-tidy b/tasks/konovalov_s_sympson_method2/tests/.clang-tidy new file mode 100644 index 0000000000..ef43b7aa8a --- /dev/null +++ b/tasks/konovalov_s_sympson_method2/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/konovalov_s_sympson_method2/tests/functional/main.cpp b/tasks/konovalov_s_sympson_method2/tests/functional/main.cpp new file mode 100644 index 0000000000..eb4aa8b092 --- /dev/null +++ b/tasks/konovalov_s_sympson_method2/tests/functional/main.cpp @@ -0,0 +1,66 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "konovalov_s_sympson_method/common/include/common.hpp" +#include "konovalov_s_sympson_method/mpi/include/ops_mpi.hpp" +#include "konovalov_s_sympson_method/seq/include/ops_seq.hpp" +#include "util/include/func_test_util.hpp" +#include "util/include/util.hpp" + +namespace konovalov_s_sympson_method { + +class KonovalovSSympsonMethodFuncTests : public ppc::util::BaseRunFuncTests { + public: + static std::string PrintTestParam(const TestType &test_param) { + return "ftest_" + std::get<5>(test_param); + } + + protected: + void SetUp() override { + input_data_ = std::get(ppc::util::GTestParamIndex::kTestParams)>(GetParam()); + } + + bool CheckTestOutputData(OutType &output_data) final { + return output_data > 0; + } + + InType GetTestInputData() final { + return input_data_; + } + + private: + InType input_data_; +}; + +namespace { + +TEST_P(KonovalovSSympsonMethodFuncTests, SympsonMPTests) { + ExecuteTest(GetParam()); +} + +const std::array kTestParam = {std::make_tuple(0.1, 4.9, 2.4, 2.5, 10), + std::make_tuple(8.3, 10.2, 3.2, 6.7, 100)}; + +const auto kTestTasksList = std::tuple_cat( + ppc::util::AddFuncTask(kTestParam, PPC_SETTINGS_konovalov_s_sympson_method), + ppc::util::AddFuncTask(kTestParam, PPC_SETTINGS_konovalov_s_sympson_method)); + +const auto kGtestValues = ppc::util::ExpandToValues(kTestTasksList); + +const auto kPerfTestName = KonovalovSSympsonMethodFuncTests::PrintFuncTestName; + +INSTANTIATE_TEST_SUITE_P(SympsonMPTest, KonovalovSSympsonMethodFuncTests, kGtestValues, kPerfTestName); + +class KonovalovSSympsonMethodValidationTests : public ::testing::Test {}; + +} // namespace + +} // namespace konovalov_s_sympson_method diff --git a/tasks/konovalov_s_sympson_method2/tests/performance/main.cpp b/tasks/konovalov_s_sympson_method2/tests/performance/main.cpp new file mode 100644 index 0000000000..dc373cfe5c --- /dev/null +++ b/tasks/konovalov_s_sympson_method2/tests/performance/main.cpp @@ -0,0 +1,59 @@ +#include + +#include +#include +#include + +#include "konovalov_s_sympson_method2/common/include/common.hpp" +#include "konovalov_s_sympson_method2/mpi/include/ops_mpi.hpp" +#include "konovalov_s_sympson_method2/seq/include/ops_seq.hpp" +#include "util/include/perf_test_util.hpp" + +namespace konovalov_s_sympson_method2 { + +namespace { + +double PerfFunc(const std::vector &point) { + double sum = 0.0; + for (std::size_t idx = 0; idx < point.size(); ++idx) { + sum += (std::sin(point[idx]) * std::cos(point[idx])) + (point[idx] * point[idx]); + } + return sum; +} + +} // namespace + +class KonovalovSSympsonMethodPerfTests : public ppc::util::BaseRunPerfTests { + InType input_data_{}; + + void SetUp() override { + input_data_.lower_bounds = {0.0, 0.0, 0.0}; + input_data_.upper_bounds = {1.0, 1.0, 1.0}; + input_data_.num_steps = 100; + input_data_.func = PerfFunc; + } + + bool CheckTestOutputData(OutType &output_data) final { + return output_data > 0.0; + } + + InType GetTestInputData() final { + return input_data_; + } +}; + +TEST_P(KonovalovSSympsonMethodPerfTests, SympsonMPTests) { + ExecuteTest(GetParam()); +} + +const auto kAllPerfTasks = + ppc::util::MakeAllPerfTasks( + PPC_SETTINGS_konovalov_s_sympson_method2); + +const auto kGtestValues = ppc::util::TupleToGTestValues(kAllPerfTasks); + +const auto kPerfTestName = KonovalovSSympsonMethodPerfTests::CustomPerfTestName; + +INSTANTIATE_TEST_SUITE_P(SympsonMPTest, KonovalovSSympsonMethodPerfTests, kGtestValues, kPerfTestName); + +} // namespace konovalov_s_sympson_method2 \ No newline at end of file