Skip to content

Commit

Permalink
Merge pull request #3210 from cogle/search_update
Browse files Browse the repository at this point in the history
Adapted parallel::{search | search_n} for Ranges TS (see #1668)
  • Loading branch information
hkaiser committed Mar 7, 2018
2 parents e15637a + 3884f42 commit b43ec23
Show file tree
Hide file tree
Showing 9 changed files with 1,413 additions and 44 deletions.
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

166 changes: 123 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

0 comments on commit b43ec23

Please sign in to comment.