diff --git a/tasks/dergynov_s_integrals_multistep_rectangle/info.json b/tasks/dergynov_s_integrals_multistep_rectangle/info.json index 96fbab871..5dfba0a4d 100644 --- a/tasks/dergynov_s_integrals_multistep_rectangle/info.json +++ b/tasks/dergynov_s_integrals_multistep_rectangle/info.json @@ -4,6 +4,6 @@ "group_number": "3823Б1ПР4", "last_name": "Дергунов", "middle_name": "Антонович", - "task_number": "2" + "task_number": "3" } } diff --git a/tasks/dergynov_s_integrals_multistep_rectangle/tbb/include/ops_tbb.hpp b/tasks/dergynov_s_integrals_multistep_rectangle/tbb/include/ops_tbb.hpp new file mode 100644 index 000000000..13304a61b --- /dev/null +++ b/tasks/dergynov_s_integrals_multistep_rectangle/tbb/include/ops_tbb.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include "dergynov_s_integrals_multistep_rectangle/common/include/common.hpp" +#include "task/include/task.hpp" + +namespace dergynov_s_integrals_multistep_rectangle { + +class DergynovSIntegralsMultistepRectangleTBB : public BaseTask { + public: + static constexpr ppc::task::TypeOfTask GetStaticTypeOfTask() { + return ppc::task::TypeOfTask::kTBB; + } + explicit DergynovSIntegralsMultistepRectangleTBB(const InType &in); + + private: + bool ValidationImpl() override; + bool PreProcessingImpl() override; + bool RunImpl() override; + bool PostProcessingImpl() override; +}; + +} // namespace dergynov_s_integrals_multistep_rectangle diff --git a/tasks/dergynov_s_integrals_multistep_rectangle/tbb/src/ops_tbb.cpp b/tasks/dergynov_s_integrals_multistep_rectangle/tbb/src/ops_tbb.cpp new file mode 100644 index 000000000..1e7ccd152 --- /dev/null +++ b/tasks/dergynov_s_integrals_multistep_rectangle/tbb/src/ops_tbb.cpp @@ -0,0 +1,104 @@ +#include "dergynov_s_integrals_multistep_rectangle/tbb/include/ops_tbb.hpp" + +#include +#include + +#include +#include +#include +#include +#include + +#include "dergynov_s_integrals_multistep_rectangle/common/include/common.hpp" + +namespace dergynov_s_integrals_multistep_rectangle { +namespace { + +bool ValidateBorders(const std::vector> &borders) { + return std::ranges::all_of(borders, [](const auto &p) { + const auto &[left, right] = p; + return std::isfinite(left) && std::isfinite(right) && left < right; + }); +} + +} // namespace + +DergynovSIntegralsMultistepRectangleTBB::DergynovSIntegralsMultistepRectangleTBB(const InType &in) { + SetTypeOfTask(GetStaticTypeOfTask()); + GetInput() = in; + GetOutput() = 0.0; +} + +bool DergynovSIntegralsMultistepRectangleTBB::ValidationImpl() { + const auto &[func, borders, n] = GetInput(); + + if (!func) { + return false; + } + if (n <= 0) { + return false; + } + if (borders.empty()) { + return false; + } + + return ValidateBorders(borders); +} + +bool DergynovSIntegralsMultistepRectangleTBB::PreProcessingImpl() { + GetOutput() = 0.0; + return true; +} + +bool DergynovSIntegralsMultistepRectangleTBB::RunImpl() { + const auto &input = GetInput(); + const auto &func = std::get<0>(input); + const auto &borders = std::get<1>(input); + const int n = std::get<2>(input); + const int dim = static_cast(borders.size()); + + std::vector h(dim); + double cell_volume = 1.0; + + for (int i = 0; i < dim; ++i) { + const double left = borders[i].first; + const double right = borders[i].second; + h[i] = (right - left) / n; + cell_volume *= h[i]; + } + + size_t total_points = 1; + for (int i = 0; i < dim; ++i) { + total_points *= n; + } + + double total_sum = tbb::parallel_reduce(tbb::blocked_range(0, total_points), 0.0, + [&](const tbb::blocked_range &range, double local_sum) { + for (size_t linear_idx = range.begin(); linear_idx != range.end(); ++linear_idx) { + size_t tmp = linear_idx; + std::vector point(dim); + + for (int dimension = dim - 1; dimension >= 0; --dimension) { + int idx_val = static_cast(tmp % static_cast(n)); + tmp /= static_cast(n); + point[dimension] = borders[dimension].first + ((static_cast(idx_val) + 0.5) * h[dimension]); + } + + double f_val = func(point); + if (!std::isfinite(f_val)) { + return local_sum; + } + local_sum += f_val; + } + return local_sum; + }, [](double a, double b) { return a + b; }); + + GetOutput() = total_sum * cell_volume; + return std::isfinite(GetOutput()); +} + +bool DergynovSIntegralsMultistepRectangleTBB::PostProcessingImpl() { + return std::isfinite(GetOutput()); +} + +} // namespace dergynov_s_integrals_multistep_rectangle diff --git a/tasks/dergynov_s_integrals_multistep_rectangle/tests/functional/main.cpp b/tasks/dergynov_s_integrals_multistep_rectangle/tests/functional/main.cpp index c6143dc73..8aaadf2f1 100644 --- a/tasks/dergynov_s_integrals_multistep_rectangle/tests/functional/main.cpp +++ b/tasks/dergynov_s_integrals_multistep_rectangle/tests/functional/main.cpp @@ -12,6 +12,7 @@ #include "dergynov_s_integrals_multistep_rectangle/common/include/common.hpp" #include "dergynov_s_integrals_multistep_rectangle/omp/include/ops_omp.hpp" #include "dergynov_s_integrals_multistep_rectangle/seq/include/ops_seq.hpp" +#include "dergynov_s_integrals_multistep_rectangle/tbb/include/ops_tbb.hpp" #include "util/include/func_test_util.hpp" #include "util/include/util.hpp" @@ -207,6 +208,8 @@ const std::array kTests = {{ const auto kTestTasksList = std::tuple_cat(ppc::util::AddFuncTask( kTests, PPC_SETTINGS_dergynov_s_integrals_multistep_rectangle), ppc::util::AddFuncTask( + kTests, PPC_SETTINGS_dergynov_s_integrals_multistep_rectangle), + ppc::util::AddFuncTask( kTests, PPC_SETTINGS_dergynov_s_integrals_multistep_rectangle)); const auto kGtestValues = ppc::util::ExpandToValues(kTestTasksList); diff --git a/tasks/dergynov_s_integrals_multistep_rectangle/tests/performance/main.cpp b/tasks/dergynov_s_integrals_multistep_rectangle/tests/performance/main.cpp index 1a610feaa..9832e3631 100644 --- a/tasks/dergynov_s_integrals_multistep_rectangle/tests/performance/main.cpp +++ b/tasks/dergynov_s_integrals_multistep_rectangle/tests/performance/main.cpp @@ -8,6 +8,7 @@ #include "dergynov_s_integrals_multistep_rectangle/common/include/common.hpp" #include "dergynov_s_integrals_multistep_rectangle/omp/include/ops_omp.hpp" #include "dergynov_s_integrals_multistep_rectangle/seq/include/ops_seq.hpp" +#include "dergynov_s_integrals_multistep_rectangle/tbb/include/ops_tbb.hpp" #include "util/include/perf_test_util.hpp" namespace dergynov_s_integrals_multistep_rectangle { @@ -44,9 +45,10 @@ TEST_P(DergynovSIntegralsRectanglePerfTest, RunPerfModes) { namespace { -const auto kAllPerfTasks = ppc::util::MakeAllPerfTasks( - PPC_SETTINGS_dergynov_s_integrals_multistep_rectangle); +const auto kAllPerfTasks = + ppc::util::MakeAllPerfTasks( + PPC_SETTINGS_dergynov_s_integrals_multistep_rectangle); const auto kGtestValues = ppc::util::TupleToGTestValues(kAllPerfTasks);