From f2496c9d051b8da2e9dedf633766484f840541ba Mon Sep 17 00:00:00 2001 From: Zak-K-Abdi Date: Wed, 29 May 2024 18:39:55 +0100 Subject: [PATCH] Contains and contains_subrange parallel algorithm implementaion --- libs/core/algorithms/CMakeLists.txt | 1 + .../include/hpx/parallel/algorithm.hpp | 1 + .../hpx/parallel/algorithms/contains.hpp | 136 ++++++++++++++++++ .../parallel/algorithms/detail/contains.hpp | 57 ++++++++ 4 files changed, 195 insertions(+) create mode 100644 libs/core/algorithms/include/hpx/parallel/algorithms/contains.hpp create mode 100644 libs/core/algorithms/include/hpx/parallel/algorithms/detail/contains.hpp diff --git a/libs/core/algorithms/CMakeLists.txt b/libs/core/algorithms/CMakeLists.txt index 6d10912d4d63..d48825b5a688 100644 --- a/libs/core/algorithms/CMakeLists.txt +++ b/libs/core/algorithms/CMakeLists.txt @@ -15,6 +15,7 @@ set(algorithms_headers hpx/parallel/algorithms/adjacent_difference.hpp hpx/parallel/algorithms/adjacent_find.hpp hpx/parallel/algorithms/all_any_none.hpp + hpx/parallel/algorithms/contains.hpp hpx/parallel/algorithms/copy.hpp hpx/parallel/algorithms/count.hpp hpx/parallel/algorithms/destroy.hpp diff --git a/libs/core/algorithms/include/hpx/parallel/algorithm.hpp b/libs/core/algorithms/include/hpx/parallel/algorithm.hpp index 4aedd3d820c7..309cdf842b25 100644 --- a/libs/core/algorithms/include/hpx/parallel/algorithm.hpp +++ b/libs/core/algorithms/include/hpx/parallel/algorithm.hpp @@ -16,6 +16,7 @@ // Parallelism TS V1 #include #include +#include #include #include #include diff --git a/libs/core/algorithms/include/hpx/parallel/algorithms/contains.hpp b/libs/core/algorithms/include/hpx/parallel/algorithms/contains.hpp new file mode 100644 index 000000000000..fe6d6ba5e5d3 --- /dev/null +++ b/libs/core/algorithms/include/hpx/parallel/algorithms/contains.hpp @@ -0,0 +1,136 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace hpx::parallel { + namespace detail { + struct contains : public algorithm + { + constexpr contains() noexcept + : algorithm("contains") + { + + } + + template + static constexpr bool sequential(ExPolicy, Iterator first, + Sentinel last, const T& val, Proj&& proj) + { + return sequential_contains>(first, last, + val, HPX_FORWARD(Proj, proj)); + } + + template + static util::detail::algorithm_result_t parallel( + ExPolicy&& orgpolicy, Iterator first, Sentinel last, const T& val, + Proj&& proj) + { + const std::size_t count = detail::distance(first, last); + if (count <= 0) + return util::detail::algorithm_result::get( + false); + + decltype(auto) policy = parallel::util::adapt_placement_mode( + HPX_FORWARD(ExPolicy, orgpolicy), + hpx::threads::thread_placement_hint::breadth_first); + + using policy_type = std::decay_t; + util::cancellation_token<> tok; + auto f1 = [val, tok, proj] + (Iterator first, std::size_t count) + { + sequential_contains(first, val, count, tok, proj); + return tok.was_cancelled(); + }; + + auto f2 = [](auto&& results) + { + return std::any_of(hpx::util::begin(results), + hpx::util::end(results), + [](hpx::future& val) { return val.get();}); + }; + + return util::partitioner::call( + HPX_FORWARD(decltype(policy), policy), first, count, + HPX_MOVE(f1), HPX_MOVE(f2) + ); + } + }; + } +} +namespace hpx { + + inline constexpr struct contains_t final + : hpx::functional::detail::tag_fallback + { + private: + template && + hpx::traits::is_iterator_v && + hpx::is_invocable_v::value_type> + )> + + friend bool tag_fallback_invoke(hpx::contains_t, Iterator first, + Sentinel last, const T& val, Proj&& proj = Proj()) + { + static_assert(hpx::traits::is_input_iterator_v, + "Required at least input iterator."); + + static_assert(hpx::traits::is_input_iterator_v, + "Required at least input iterator."); + + return hpx::parallel::detail::contains().call(hpx::execution::seq, + first, last, val, proj); + } + + template && + hpx::traits::is_iterator_v && + hpx::traits::is_iterator_v && + hpx::is_invocable_v::value_type>)> + + friend typename parallel::util::detail::algorithm_result::type + tag_fallback_invoke(hpx::contains_t, ExPolicy&& policy, Iterator first, + Sentinel last, T const& val, Proj&& proj = Proj()) + { + static_assert(hpx::traits::is_iterator_v, + "Required at least iterator."); + + static_assert(hpx::traits::is_iterator_v, + "Required at least iterator."); + + return hpx::parallel::detail::contains().call( + HPX_FORWARD(ExPolicy, policy), first, last, val, + HPX_FORWARD(Proj, proj)); + } + + } contains{}; +} \ No newline at end of file diff --git a/libs/core/algorithms/include/hpx/parallel/algorithms/detail/contains.hpp b/libs/core/algorithms/include/hpx/parallel/algorithms/detail/contains.hpp new file mode 100644 index 000000000000..411d302c5332 --- /dev/null +++ b/libs/core/algorithms/include/hpx/parallel/algorithms/detail/contains.hpp @@ -0,0 +1,57 @@ +#pragma once + +#include +#include +#include +#include + +#include +#include +#include +#include + + +namespace hpx::parallel::detail { + + template + struct sequential_contains_t final + : hpx::functional::detail::tag_fallback> + { + private: + template + friend constexpr bool tag_fallback_invoke(sequential_contains_t, + Iterator first, Sentinel last, const T& val, Proj&& proj) + { + const std::size_t distance = detail::distance(first, last); + if (distance <= 0) + return false; + + const auto itr = util::loop_pred< + std::decay_t>(first, last, + [&val, &proj] (const auto& cur) + { return HPX_INVOKE(proj, *cur) == val; }); + + return itr != last; + } + + template + friend constexpr void tag_fallback_invoke(sequential_contains_t, + Iterator first, T const& val, std::size_t count, Token& tok, Proj&& proj) + { + util::loop_n(first, count, tok, + [&val, &tok, &proj] (const auto& cur) + { + if (HPX_INVOKE(proj, *cur) == val) + { + tok.cancel(); + return; + } + }); + } + + + }; + template + inline constexpr sequential_contains_t sequential_contains = + sequential_contains_t{}; +} //namespace hpx::parallel::detail \ No newline at end of file