Skip to content

Commit

Permalink
Contains and contains_subrange parallel algorithm implementaion
Browse files Browse the repository at this point in the history
  • Loading branch information
Zak-K-Abdi committed Jun 2, 2024
1 parent ba8f05f commit f2496c9
Show file tree
Hide file tree
Showing 4 changed files with 195 additions and 0 deletions.
1 change: 1 addition & 0 deletions libs/core/algorithms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions libs/core/algorithms/include/hpx/parallel/algorithm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
// Parallelism TS V1
#include <hpx/parallel/algorithms/adjacent_find.hpp>
#include <hpx/parallel/algorithms/all_any_none.hpp>
#include <hpx/parallel/algorithms/contains.hpp>
#include <hpx/parallel/algorithms/copy.hpp>
#include <hpx/parallel/algorithms/count.hpp>
#include <hpx/parallel/algorithms/equal.hpp>
Expand Down
136 changes: 136 additions & 0 deletions libs/core/algorithms/include/hpx/parallel/algorithms/contains.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
#pragma once

#include <hpx/config.hpp>
#include <hpx/execution/algorithms/detail/predicates.hpp>
#include <hpx/executors/execution_policy.hpp>
#include <hpx/iterator_support/traits/is_iterator.hpp>
#include <hpx/parallel/algorithms/detail/dispatch.hpp>
#include <hpx/parallel/algorithms/detail/distance.hpp>
#include <hpx/parallel/util/detail/algorithm_result.hpp>
#include <hpx/parallel/util/loop.hpp>
#include <hpx/type_support/identity.hpp>
#include <hpx/parallel/util/cancellation_token.hpp>
#include <hpx/parallel/util/partitioner.hpp>
#include <hpx/parallel/util/zip_iterator.hpp>
#include <hpx/coroutines/thread_enums.hpp>
#include <hpx/parallel/util/adapt_placement_mode.hpp>
#include <hpx/parallel/algorithms/detail/contains.hpp>

#include <algorithm>
#include <cstddef>
#include <iterator>
#include <type_traits>
#include <utility>

namespace hpx::parallel {
namespace detail {
struct contains : public algorithm<contains, bool>
{
constexpr contains() noexcept
: algorithm("contains")
{

}

template <typename ExPolicy, typename Iterator, typename Sentinel,
typename T, typename Proj>
static constexpr bool sequential(ExPolicy, Iterator first,
Sentinel last, const T& val, Proj&& proj)
{
return sequential_contains<std::decay<ExPolicy>>(first, last,
val, HPX_FORWARD(Proj, proj));
}

template <typename ExPolicy, typename Iterator, typename Sentinel,
typename T, typename Proj>
static util::detail::algorithm_result_t<ExPolicy, bool> 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<ExPolicy, bool>::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<decltype(policy)>;
util::cancellation_token<> tok;
auto f1 = [val, tok, proj]
(Iterator first, std::size_t count)
{
sequential_contains<policy_type>(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<bool>& val) { return val.get();});
};

return util::partitioner<policy_type, bool>::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<contains_t>
{
private:
template <typename Iterator, typename Sentinel,
typename T, typename Proj = hpx::identity,
HPX_CONCEPT_REQUIRES_(
hpx::traits::is_iterator_v<Iterator> &&
hpx::traits::is_iterator_v<Iterator> &&
hpx::is_invocable_v<Proj,
typename std::iterator_traits<Iterator>::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<Iterator>,
"Required at least input iterator.");

static_assert(hpx::traits::is_input_iterator_v<Sentinel>,
"Required at least input iterator.");

return hpx::parallel::detail::contains().call(hpx::execution::seq,
first, last, val, proj);
}

template <typename ExPolicy, typename Iterator, typename Sentinel,
typename T, typename Proj = hpx::identity, HPX_CONCEPT_REQUIRES_(
hpx::is_execution_policy_v<ExPolicy> &&
hpx::traits::is_iterator_v<Iterator> &&
hpx::traits::is_iterator_v<Iterator> &&
hpx::is_invocable_v<Proj,
typename std::iterator_traits<Iterator>::value_type>)>

friend typename parallel::util::detail::algorithm_result<ExPolicy,
bool>::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<Iterator>,
"Required at least iterator.");

static_assert(hpx::traits::is_iterator_v<Sentinel>,
"Required at least iterator.");

return hpx::parallel::detail::contains().call(
HPX_FORWARD(ExPolicy, policy), first, last, val,
HPX_FORWARD(Proj, proj));
}

} contains{};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#pragma once

#include <hpx/config.hpp>
#include <hpx/functional/detail/tag_fallback_invoke.hpp>
#include <hpx/functional/invoke.hpp>
#include <hpx/parallel/util/loop.hpp>

#include <algorithm>
#include <cstddef>
#include <type_traits>
#include <utility>


namespace hpx::parallel::detail {

template <typename ExPolicy>
struct sequential_contains_t final
: hpx::functional::detail::tag_fallback<sequential_contains_t<ExPolicy>>
{
private:
template <typename Iterator, typename Sentinel, typename T, typename Proj>
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<hpx::execution::sequenced_policy>>(first, last,
[&val, &proj] (const auto& cur)
{ return HPX_INVOKE(proj, *cur) == val; });

return itr != last;
}

template <typename Iterator, typename T, typename Token, typename Proj>
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<ExPolicy>(first, count, tok,
[&val, &tok, &proj] (const auto& cur)
{
if (HPX_INVOKE(proj, *cur) == val)
{
tok.cancel();
return;
}
});
}


};
template <typename ExPolicy>
inline constexpr sequential_contains_t<ExPolicy> sequential_contains =
sequential_contains_t<ExPolicy>{};
} //namespace hpx::parallel::detail

0 comments on commit f2496c9

Please sign in to comment.