Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adapted parallel::{search | search_n} for Ranges TS (see #1668) #3210

Merged
merged 9 commits into from Mar 7, 2018
1 change: 1 addition & 0 deletions docs/CMakeLists.txt
Expand Up @@ -126,6 +126,7 @@ set(doxygen_dependencies
"${PROJECT_SOURCE_DIR}/hpx/parallel/container_algorithms/replace.hpp"
"${PROJECT_SOURCE_DIR}/hpx/parallel/container_algorithms/reverse.hpp"
"${PROJECT_SOURCE_DIR}/hpx/parallel/container_algorithms/rotate.hpp"
"${PROJECT_SOURCE_DIR}/hpx/parallel/container_algorithms/search.hpp"
"${PROJECT_SOURCE_DIR}/hpx/parallel/container_algorithms/sort.hpp"
"${PROJECT_SOURCE_DIR}/hpx/parallel/container_algorithms/transform.hpp"
"${PROJECT_SOURCE_DIR}/hpx/parallel/container_algorithms/unique.hpp"
Expand Down
1 change: 1 addition & 0 deletions hpx/include/parallel_search.hpp
Expand Up @@ -8,6 +8,7 @@
#define HPX_PARALLEL_SEARCH_OCT_25_130PM

#include <hpx/parallel/algorithms/search.hpp>
#include <hpx/parallel/container_algorithms/search.hpp>

#endif

176 changes: 133 additions & 43 deletions hpx/parallel/algorithms/search.hpp

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions hpx/parallel/container_algorithms.hpp
Expand Up @@ -22,6 +22,7 @@
#include <hpx/parallel/container_algorithms/replace.hpp>
#include <hpx/parallel/container_algorithms/reverse.hpp>
#include <hpx/parallel/container_algorithms/rotate.hpp>
#include <hpx/parallel/container_algorithms/search.hpp>
#include <hpx/parallel/container_algorithms/sort.hpp>
#include <hpx/parallel/container_algorithms/transform.hpp>
#include <hpx/parallel/container_algorithms/unique.hpp>
Expand Down
252 changes: 252 additions & 0 deletions hpx/parallel/container_algorithms/search.hpp
@@ -0,0 +1,252 @@
// Copyright (c) 2018 Christopher Ogle
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

/// \file parallel/container_algorithms/search.hpp

#if !defined(HPX_PARALLEL_CONTAINER_ALGORITHM_SEARCH_FEB_28_2018_0007AM)
#define HPX_PARALLEL_CONTAINER_ALGORITHM_SEARCH_FEB_28_2018_0007AM

#include <hpx/config.hpp>
#include <hpx/traits/is_execution_policy.hpp>
#include <hpx/traits/is_range.hpp>
#include <hpx/util/range.hpp>

#include <hpx/parallel/algorithms/search.hpp>
#include <hpx/parallel/traits/projected.hpp>
#include <hpx/parallel/traits/projected_range.hpp>

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

namespace hpx { namespace parallel { inline namespace v1
{
/// Searches the range [first, last) for any elements in the range [s_first, s_last).
/// Uses a provided predicate to compare elements.
///
/// \note Complexity: at most (S*N) comparisons where
/// \a S = distance(s_first, s_last) and
/// \a N = distance(first, last).
///
/// \tparam ExPolicy The type of the execution policy to use (deduced).
/// It describes the manner in which the execution
/// of the algorithm may be parallelized and the manner
/// in which it executes the assignments.
/// \tparam Rng1 The type of the examine range used (deduced).
/// The iterators extracted from this range type must
/// meet the requirements of an input iterator.
/// \tparam Rng2 The type of the search range used (deduced).
/// The iterators extracted from this range type must
/// meet the requirements of an input iterator.
/// \tparam Pred The type of an optional function/function object to use.
/// Unlike its sequential form, the parallel
/// overload of \a adjacent_find requires \a Pred to meet the
/// requirements of \a CopyConstructible. This defaults
/// to std::equal_to<>
/// \tparam Proj1 The type of an optional projection function. This
/// defaults to \a util::projection_identity and is applied
/// to the elements of \a Rng1.
/// \tparam Proj2 The type of an optional projection function. This
/// defaults to \a util::projection_identity and is applied
/// to the elements of \a Rng2.
///
/// \param policy The execution policy to use for the scheduling of
/// the iterations.
/// \param first Refers to the beginning of the sequence of elements
/// of the first range the algorithm will be applied to.
/// \param last Refers to the end of the sequence of elements of
/// the first range the algorithm will be applied to.
/// \param rng1 Refers to the sequence of elements the algorithm
/// will be examining.
/// \param rng2 Refers to the sequence of elements the algorithm
/// will be searching for.
/// \param op Refers to the binary predicate which returns true if the
/// elements should be treated as equal. the signature of
/// the function should be equivalent to
/// \code
/// bool pred(const Type1 &a, const Type2 &b);
/// \endcode \n
/// The signature does not need to have const &, but
/// the function must not modify the objects passed to
/// it. The types \a Type1 and \a Type2 must be such
/// that objects of types \a FwdIter1 and \a FwdIter2 can
/// be dereferenced and then implicitly converted to
/// \a Type1 and \a Type2 respectively
/// \param proj1 Specifies the function (or function object) which
/// will be invoked for each of the elements of \a rng1
/// as a projection operation before the actual
/// predicate \a is invoked.
/// \param proj2 Specifies the function (or function object) which
/// will be invoked for each of the elements of \a rng2
/// as a projection operation before the actual
/// predicate \a is invoked.
///
/// The comparison operations in the parallel \a search algorithm invoked
/// with an execution policy object of type \a sequenced_policy
/// execute in sequential order in the calling thread.
///
/// The comparison operations in the parallel \a search algorithm invoked
/// with an execution policy object of type \a parallel_policy
/// or \a parallel_task_policy are permitted to execute in an unordered
/// fashion in unspecified threads, and indeterminately sequenced
/// within each thread.
///
/// \returns The \a search algorithm returns a \a hpx::future<FwdIter> if the
/// execution policy is of type \a task_execution_policy and
/// returns \a FwdIter otherwise.
/// The \a search algorithm returns an iterator to the beginning of
/// the first subsequence [s_first, s_last) in range [first, last).
/// If the length of the subsequence [s_first, s_last) is greater
/// than the length of the range [first, last), \a last is returned.
/// Additionally if the size of the subsequence is empty \a first is
/// returned. If no subsequence is found, \a last is returned.
///
template <typename ExPolicy, typename Rng1, typename Rng2,
typename Pred = detail::equal_to,
typename Proj1 = util::projection_identity,
typename Proj2 = util::projection_identity,
HPX_CONCEPT_REQUIRES_(
execution::is_execution_policy<ExPolicy>::value &&
hpx::traits::is_range<Rng1>::value &&
traits::is_projected_range<Proj1, Rng1>::value &&
hpx::traits::is_range<Rng2>::value &&
traits::is_projected_range<Proj2, Rng2>::value &&
traits::is_indirect_callable<
ExPolicy, Pred,
traits::projected_range<Proj1, Rng1>,
traits::projected_range<Proj2, Rng2>
>::value
)>
typename util::detail::algorithm_result<
ExPolicy,
typename hpx::traits::range_iterator<Rng1>::type
>::type
search(ExPolicy && policy, Rng1 && rng1,
Rng2 && rng2, Pred && op = Pred(),
Proj1 && proj1 = Proj1(), Proj2 && proj2 = Proj2())
{
return search(std::forward<ExPolicy>(policy),
hpx::util::begin(rng1), hpx::util::end(rng1),
hpx::util::begin(rng2), hpx::util::end(rng2),
std::forward<Pred>(op),
std::forward<Proj1>(proj1),
std::forward<Proj2>(proj2));
}

/// Searches the range [first, last) for any elements in the range [s_first, s_last).
/// Uses a provided predicate to compare elements.
///
/// \note Complexity: at most (S*N) comparisons where
/// \a S = distance(s_first, s_last) and
/// \a N = distance(first, last).
///
/// \tparam ExPolicy The type of the execution policy to use (deduced).
/// It describes the manner in which the execution
/// of the algorithm may be parallelized and the manner
/// in which it executes the assignments.
/// \tparam Rng1 The type of the examine range used (deduced).
/// The iterators extracted from this range type must
/// meet the requirements of an input iterator.
/// \tparam Rng2 The type of the search range used (deduced).
/// The iterators extracted from this range type must
/// meet the requirements of an input iterator.
/// \tparam Pred The type of an optional function/function object to use.
/// Unlike its sequential form, the parallel
/// overload of \a adjacent_find requires \a Pred to meet the
/// requirements of \a CopyConstructible. This defaults
/// to std::equal_to<>
/// \tparam Proj1 The type of an optional projection function. This
/// defaults to \a util::projection_identity and is applied
/// to the elements of \a Rng1.
/// \tparam Proj2 The type of an optional projection function. This
/// defaults to \a util::projection_identity and is applied
/// to the elements of \a Rng2.
///
/// \param policy The execution policy to use for the scheduling of
/// the iterations.
/// \param first Refers to the beginning of the sequence of elements
/// of the first range the algorithm will be applied to.
/// \param last Refers to the end of the sequence of elements of
/// the first range the algorithm will be applied to.
/// \param rng1 Refers to the sequence of elements the algorithm
/// will be examining.
/// \param rng2 Refers to the sequence of elements the algorithm
/// will be searching for.
/// \param op Refers to the binary predicate which returns true if the
/// elements should be treated as equal. the signature of
/// the function should be equivalent to
/// \code
/// bool pred(const Type1 &a, const Type2 &b);
/// \endcode \n
/// The signature does not need to have const &, but
/// the function must not modify the objects passed to
/// it. The types \a Type1 and \a Type2 must be such
/// that objects of types \a FwdIter1 and \a FwdIter2 can
/// be dereferenced and then implicitly converted to
/// \a Type1 and \a Type2 respectively
/// \param proj1 Specifies the function (or function object) which
/// will be invoked for each of the elements of \a rng1
/// as a projection operation before the actual
/// predicate \a is invoked.
/// \param proj2 Specifies the function (or function object) which
/// will be invoked for each of the elements of \a rng2
/// as a projection operation before the actual
/// predicate \a is invoked.
///
/// The comparison operations in the parallel \a search algorithm invoked
/// with an execution policy object of type \a sequenced_policy
/// execute in sequential order in the calling thread.
///
/// The comparison operations in the parallel \a search algorithm invoked
/// with an execution policy object of type \a parallel_policy
/// or \a parallel_task_policy are permitted to execute in an unordered
/// fashion in unspecified threads, and indeterminately sequenced
/// within each thread.
///
/// \returns The \a search algorithm returns a \a hpx::future<FwdIter> if the
/// execution policy is of type \a task_execution_policy and
/// returns \a FwdIter otherwise.
/// The \a search algorithm returns an iterator to the beginning of
/// the first subsequence [s_first, s_last) in range [first, last).
/// If the length of the subsequence [s_first, s_last) is greater
/// than the length of the range [first, last), \a last is returned.
/// Additionally if the size of the subsequence is empty \a first is
/// returned. If no subsequence is found, \a last is returned.
///
template <typename ExPolicy, typename Rng1, typename Rng2,
typename Pred = detail::equal_to,
typename Proj1 = util::projection_identity,
typename Proj2 = util::projection_identity,
HPX_CONCEPT_REQUIRES_(
execution::is_execution_policy<ExPolicy>::value &&
hpx::traits::is_range<Rng1>::value &&
traits::is_projected_range<Proj1, Rng1>::value &&
hpx::traits::is_range<Rng2>::value &&
traits::is_projected_range<Proj2, Rng2>::value &&
traits::is_indirect_callable<
ExPolicy, Pred,
traits::projected_range<Proj1, Rng1>,
traits::projected_range<Proj2, Rng2>
>::value
)>
typename util::detail::algorithm_result<
ExPolicy,
typename hpx::traits::range_iterator<Rng1>::type
>::type
search_n(ExPolicy && policy, Rng1 && rng1,
std::size_t count, Rng2 && rng2,
Pred && op = Pred(), Proj1 && proj1 = Proj1(),
Proj2 && proj2 = Proj2())
{
return search_n(std::forward<ExPolicy>(policy),
hpx::util::begin(rng1), count,
hpx::util::begin(rng2), hpx::util::end(rng2),
std::forward<Pred>(op),
std::forward<Proj1>(proj1),
std::forward<Proj2>(proj2));
}
}}}

#endif
29 changes: 28 additions & 1 deletion hpx/parallel/util/compare_projected.hpp
@@ -1,4 +1,5 @@
// Copyright (c) 2016-2017 Hartmut Kaiser
// Copyright (c) 2018 Christopher Ogle
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Expand All @@ -14,8 +15,11 @@
namespace hpx { namespace parallel { namespace util
{
///////////////////////////////////////////////////////////////////////////
template <typename Compare, typename ... Proj>
struct compare_projected;

template <typename Compare, typename Proj>
struct compare_projected
struct compare_projected<Compare, Proj>
{
template <typename Compare_, typename Proj_>
compare_projected(Compare_ && comp, Proj_ && proj)
Expand All @@ -34,6 +38,29 @@ namespace hpx { namespace parallel { namespace util
Compare comp_;
Proj proj_;
};

template <typename Compare, typename Proj1, typename Proj2>
struct compare_projected<Compare, Proj1, Proj2>
{
template <typename Compare_, typename Proj1_, typename Proj2_>
compare_projected(Compare_ && comp, Proj1_ && proj1, Proj2_ && proj2)
: comp_(std::forward<Compare_>(comp)),
proj1_(std::forward<Proj1_>(proj1)),
proj2_(std::forward<Proj2_>(proj2))
{}

template <typename T1, typename T2>
inline bool operator()(T1 && t1, T2 && t2) const
{
return hpx::util::invoke(comp_,
hpx::util::invoke(proj1_, std::forward<T1>(t1)),
hpx::util::invoke(proj2_, std::forward<T2>(t2)));
}

Compare comp_;
Proj1 proj1_;
Proj2 proj2_;
};
}}}

#endif
2 changes: 2 additions & 0 deletions tests/unit/parallel/container_algorithms/CMakeLists.txt
Expand Up @@ -36,6 +36,8 @@ set(tests
reverse_copy_range
rotate_range
rotate_copy_range
search_range
searchn_range
sort_range
transform_range
transform_range_binary
Expand Down