Skip to content

Commit

Permalink
Merge pull request #3169 from cogle/count_update
Browse files Browse the repository at this point in the history
Adapted parallel::{count|count_if} for Ranges TS (see #1668)
  • Loading branch information
msimberg committed Feb 15, 2018
2 parents 861b8d5 + 73677d6 commit d4e461f
Show file tree
Hide file tree
Showing 9 changed files with 650 additions and 85 deletions.
8 changes: 4 additions & 4 deletions .github/CONTRIBUTING.md
Expand Up @@ -96,7 +96,7 @@ The short version of the guidelines:
* Use expressive identifiers.
* Exceptions for error handling instead of C-style error codes.

A more elaborate description of our coding guidelines can be found
A more elaborate description of our coding guidelines can be found
[here](https://github.com/STEllAR-GROUP/hpx/wiki/HPX-Source-Code-Structure-and-Coding-Standards).

There is a `.editorconfig` file in the HPX root directory which can be used
Expand All @@ -106,10 +106,10 @@ editor.

There is a `.clang-format` file in the HPX root directory which you can use to
manually format the code you contribute. This configuration file can be used
with [clang-format](https://clang.llvm.org/docs/ClangFormat.html), a tool created
with [clang-format](https://clang.llvm.org/docs/ClangFormat.html), a tool created
by the [Clang](https://clang.llvm.org/) project.

Please follow the follwoing guidelines for using it:
Please follow the following guidelines for using it:

* You should use this file for creating an initial formatting for new files.
* Please separate edits which are pure formatting into isolated commits
Expand All @@ -128,7 +128,7 @@ A few additional ones:

Community is an important part of all we do.

* You can help us answer questions our users have by being around on IRC
* You can help us answer questions our users have by being around on IRC
(#ste||ar on irc.freenode.net) or by chiming in on the
[users mailing list](email:hpx-users@stellar.cct.lsu.edu)
* You can help write blog posts (for [stellar.cct.lsu.edu](stellar.cct.lsu.edu))
Expand Down
2 changes: 2 additions & 0 deletions docs/CMakeLists.txt
Expand Up @@ -111,7 +111,9 @@ set(doxygen_dependencies
"${PROJECT_SOURCE_DIR}/hpx/parallel/algorithms/uninitialized_move.hpp"
"${PROJECT_SOURCE_DIR}/hpx/parallel/algorithms/uninitialized_value_construct.hpp"
"${PROJECT_SOURCE_DIR}/hpx/parallel/algorithms/unique.hpp"
"${PROJECT_SOURCE_DIR}/hpx/parallel/container_algorithms/all_any_none.hpp"
"${PROJECT_SOURCE_DIR}/hpx/parallel/container_algorithms/copy.hpp"
"${PROJECT_SOURCE_DIR}/hpx/parallel/container_algorithms/count.hpp"
"${PROJECT_SOURCE_DIR}/hpx/parallel/container_algorithms/for_each.hpp"
"${PROJECT_SOURCE_DIR}/hpx/parallel/container_algorithms/generate.hpp"
"${PROJECT_SOURCE_DIR}/hpx/parallel/container_algorithms/is_heap.hpp"
Expand Down
1 change: 1 addition & 0 deletions hpx/include/parallel_count.hpp
Expand Up @@ -9,6 +9,7 @@

#include <hpx/parallel/algorithms/count.hpp>
#include <hpx/parallel/segmented_algorithms/count.hpp>
#include <hpx/parallel/container_algorithms/count.hpp>

#endif

129 changes: 82 additions & 47 deletions hpx/parallel/algorithms/count.hpp
Expand Up @@ -17,8 +17,10 @@

#include <hpx/parallel/algorithms/detail/dispatch.hpp>
#include <hpx/parallel/execution_policy.hpp>
#include <hpx/parallel/traits/projected.hpp>
#include <hpx/parallel/traits/vector_pack_count_bits.hpp>
#include <hpx/parallel/util/detail/algorithm_result.hpp>
#include <hpx/parallel/util/invoke_projected.hpp>
#include <hpx/parallel/util/loop.hpp>
#include <hpx/parallel/util/partitioner.hpp>

Expand All @@ -37,34 +39,36 @@ namespace hpx { namespace parallel { inline namespace v1
namespace detail
{
/// \cond NOINTERNAL
template <typename ExPolicy, typename Op>
template <typename ExPolicy, typename Op, typename Proj>
struct count_iteration
{
typedef typename hpx::util::decay<ExPolicy>::type execution_policy_type;
typedef typename hpx::util::decay<Proj>::type proj_type;
typedef typename hpx::util::decay<Op>::type op_type;

op_type op_;
proj_type proj_;

template <typename Op_,
template <typename Op_, typename Proj_,
typename U = typename std::enable_if<
!std::is_same<
typename hpx::util::decay<Op_>::type, count_iteration
>::value
>::type>
HPX_HOST_DEVICE count_iteration(Op_ && op)
: op_(std::forward<Op_>(op))
HPX_HOST_DEVICE count_iteration(Op_ && op, Proj_ && proj)
: op_(std::forward<Op_>(op)), proj_(std::forward<Proj_>(proj))
{}

#if !defined(__NVCC__) && !defined(__CUDACC__)
count_iteration(count_iteration const&) = default;
count_iteration(count_iteration&&) = default;
#else
HPX_HOST_DEVICE count_iteration(count_iteration const& rhs)
: op_(rhs.op_)
: op_(rhs.op_), proj_(rhs.proj_)
{}

HPX_HOST_DEVICE count_iteration(count_iteration && rhs)
: op_(std::move(rhs.op_))
: op_(std::move(rhs.op_)), proj_(std::move(rhs.proj_))
{}
#endif

Expand All @@ -89,7 +93,8 @@ namespace hpx { namespace parallel { inline namespace v1
void operator()(Iter curr,
typename std::iterator_traits<Iter>::difference_type& ret)
{
ret += traits::count_bits(hpx::util::invoke(op_, *curr));
ret += traits::count_bits(hpx::util::invoke(op_,
hpx::util::invoke(proj_, *curr)));
}
};

Expand All @@ -104,13 +109,16 @@ namespace hpx { namespace parallel { inline namespace v1
: count::algorithm("count")
{}

template <typename ExPolicy, typename InIter, typename T>
template <typename ExPolicy, typename InIter, typename T,
typename Proj>
static difference_type
sequential(ExPolicy && policy, InIter first, InIter last, T const& value)
sequential(ExPolicy && policy, InIter first, InIter last,
T const& value, Proj && proj)
{
auto f1 =
count_iteration<ExPolicy, detail::compare_to<T> >(
detail::compare_to<T>(value));
count_iteration<ExPolicy, detail::compare_to<T>, Proj>(
detail::compare_to<T>(value),
std::forward<Proj>(proj));

typename std::iterator_traits<InIter>::difference_type ret = 0;

Expand All @@ -121,12 +129,13 @@ namespace hpx { namespace parallel { inline namespace v1
return ret;
}

template <typename ExPolicy, typename Iter, typename T>
template <typename ExPolicy, typename Iter, typename T,
typename Proj>
static typename util::detail::algorithm_result<
ExPolicy, difference_type
>::type
parallel(ExPolicy && policy, Iter first, Iter last,
T const& value)
T const& value, Proj && proj)
{
if (first == last)
{
Expand All @@ -136,8 +145,9 @@ namespace hpx { namespace parallel { inline namespace v1
}

auto f1 =
count_iteration<ExPolicy, detail::compare_to<T> >(
detail::compare_to<T>(value));
count_iteration<ExPolicy, detail::compare_to<T>, Proj>(
detail::compare_to<T>(value),
std::forward<Proj>(proj));

return util::partitioner<ExPolicy, difference_type>::call(
std::forward<ExPolicy>(policy),
Expand All @@ -153,12 +163,13 @@ namespace hpx { namespace parallel { inline namespace v1
}
};

template <typename ExPolicy, typename FwdIter, typename T>
template <typename ExPolicy, typename FwdIter, typename T,
typename Proj>
inline typename util::detail::algorithm_result<
ExPolicy, typename std::iterator_traits<FwdIter>::difference_type
>::type
count_(ExPolicy && policy, FwdIter first, FwdIter last, T const& value,
std::false_type)
Proj && proj, std::false_type)
{
#if defined(HPX_HAVE_ALGORITHM_INPUT_ITERATOR_SUPPORT)
typedef std::integral_constant<bool,
Expand All @@ -177,16 +188,18 @@ namespace hpx { namespace parallel { inline namespace v1
difference_type;

return detail::count<difference_type>().call(
std::forward<ExPolicy>(policy), is_seq(), first, last, value);
std::forward<ExPolicy>(policy), is_seq(), first, last, value,
std::forward<Proj>(proj));
}

// forward declare the segmented version of this algorithm
template <typename ExPolicy, typename FwdIter, typename T>
template <typename ExPolicy, typename FwdIter, typename T,
typename Proj>
typename util::detail::algorithm_result<
ExPolicy, typename std::iterator_traits<FwdIter>::difference_type
>::type
count_(ExPolicy&& policy, FwdIter first, FwdIter last, T const& value,
std::true_type);
Proj && proj, std::true_type);

/// \endcond
}
Expand All @@ -205,6 +218,8 @@ namespace hpx { namespace parallel { inline namespace v1
/// This iterator type must meet the requirements of an
/// forward iterator.
/// \tparam T The type of the value to search for (deduced).
/// \tparam Proj The type of an optional projection function. This
/// defaults to \a util::projection_identity
///
/// \param policy The execution policy to use for the scheduling of
/// the iterations.
Expand Down Expand Up @@ -234,14 +249,17 @@ namespace hpx { namespace parallel { inline namespace v1
/// The \a count algorithm returns the number of elements
/// satisfying the given criteria.
///
template <typename ExPolicy, typename FwdIter, typename T>
inline typename std::enable_if<
execution::is_execution_policy<ExPolicy>::value,
typename util::detail::algorithm_result<ExPolicy,
typename std::iterator_traits<FwdIter>::difference_type
>::type
template <typename ExPolicy, typename FwdIter, typename T,
typename Proj = util::projection_identity,
HPX_CONCEPT_REQUIRES_(
execution::is_execution_policy<ExPolicy>::value &&
traits::is_projected<Proj, FwdIter>::value &&
hpx::traits::is_iterator<FwdIter>::value)>
typename util::detail::algorithm_result<
ExPolicy, typename std::iterator_traits<FwdIter>::difference_type
>::type
count(ExPolicy && policy, FwdIter first, FwdIter last, T const& value)
count(ExPolicy && policy, FwdIter first, FwdIter last, T const& value,
Proj && proj = Proj())
{
#if defined(HPX_HAVE_ALGORITHM_INPUT_ITERATOR_SUPPORT)
static_assert(
Expand All @@ -257,7 +275,7 @@ namespace hpx { namespace parallel { inline namespace v1

return detail::count_(
std::forward<ExPolicy>(policy), first, last, value,
is_segmented());
std::forward<Proj>(proj), is_segmented());
}

///////////////////////////////////////////////////////////////////////////
Expand All @@ -275,11 +293,14 @@ namespace hpx { namespace parallel { inline namespace v1
: count_if::algorithm("count_if")
{}

template <typename ExPolicy, typename InIter, typename Pred>
template <typename ExPolicy, typename InIter, typename Pred,
typename Proj>
static difference_type
sequential(ExPolicy && policy, InIter first, InIter last, Pred && op)
sequential(ExPolicy && policy, InIter first, InIter last, Pred && op,
Proj && proj)
{
auto f1 = count_iteration<ExPolicy, Pred>(op);
auto f1 = count_iteration<ExPolicy, Pred, Proj>(op,
std::forward<Proj>(proj));

typename std::iterator_traits<InIter>::difference_type ret = 0;

Expand All @@ -290,11 +311,13 @@ namespace hpx { namespace parallel { inline namespace v1
return ret;
}

template <typename ExPolicy, typename Iter, typename Pred>
template <typename ExPolicy, typename Iter, typename Pred,
typename Proj>
static typename util::detail::algorithm_result<
ExPolicy, difference_type
>::type
parallel(ExPolicy && policy, Iter first, Iter last, Pred && op)
parallel(ExPolicy && policy, Iter first, Iter last, Pred && op,
Proj && proj)
{
if (first == last)
{
Expand All @@ -303,7 +326,8 @@ namespace hpx { namespace parallel { inline namespace v1
>::get(0);
}

auto f1 = count_iteration<ExPolicy, Pred>(op);
auto f1 = count_iteration<ExPolicy, Pred, Proj>(op,
std::forward<Proj>(proj));

return util::partitioner<ExPolicy, difference_type>::call(
std::forward<ExPolicy>(policy),
Expand All @@ -319,12 +343,13 @@ namespace hpx { namespace parallel { inline namespace v1
}
};

template <typename ExPolicy, typename FwdIter, typename F>
template <typename ExPolicy, typename FwdIter, typename F,
typename Proj>
typename util::detail::algorithm_result<
ExPolicy, typename std::iterator_traits<FwdIter>::difference_type
>::type
count_if_(ExPolicy && policy, FwdIter first, FwdIter last, F && f,
std::false_type)
Proj && proj, std::false_type)
{
#if defined(HPX_HAVE_ALGORITHM_INPUT_ITERATOR_SUPPORT)
typedef std::integral_constant<bool,
Expand All @@ -344,16 +369,18 @@ namespace hpx { namespace parallel { inline namespace v1

return detail::count_if<difference_type>().call(
std::forward<ExPolicy>(policy), is_seq(),
first, last, std::forward<F>(f));
first, last, std::forward<F>(f),
std::forward<Proj>(proj));
}

// forward declare the segmented version of this algorithm
template <typename ExPolicy, typename FwdIter, typename F>
template <typename ExPolicy, typename FwdIter, typename F,
typename Proj>
typename util::detail::algorithm_result<
ExPolicy, typename std::iterator_traits<FwdIter>::difference_type
>::type
count_if_(ExPolicy && policy, FwdIter first, FwdIter last, F && f,
std::true_type);
Proj && proj, std::true_type);

/// \endcond
}
Expand All @@ -376,6 +403,8 @@ namespace hpx { namespace parallel { inline namespace v1
/// (deduced). Unlike its sequential form, the parallel
/// overload of \a count_if requires \a F to meet the
/// requirements of \a CopyConstructible.
/// \tparam Proj The type of an optional projection function. This
/// defaults to \a util::projection_identity
///
/// \param policy The execution policy to use for the scheduling of
/// the iterations.
Expand Down Expand Up @@ -417,14 +446,20 @@ namespace hpx { namespace parallel { inline namespace v1
/// The \a count algorithm returns the number of elements
/// satisfying the given criteria.
///
template <typename ExPolicy, typename FwdIter, typename F>
inline typename std::enable_if<
execution::is_execution_policy<ExPolicy>::value,
typename util::detail::algorithm_result<ExPolicy,
typename std::iterator_traits<FwdIter>::difference_type
>::type
template <typename ExPolicy, typename FwdIter, typename F,
typename Proj = util::projection_identity,
HPX_CONCEPT_REQUIRES_(
execution::is_execution_policy<ExPolicy>::value &&
hpx::traits::is_iterator<FwdIter>::value &&
traits::is_projected<Proj, FwdIter>::value &&
traits::is_indirect_callable<
ExPolicy, F, traits::projected<Proj, FwdIter>
>::value)>
typename util::detail::algorithm_result<
ExPolicy, typename std::iterator_traits<FwdIter>::difference_type
>::type
count_if(ExPolicy && policy, FwdIter first, FwdIter last, F && f)
count_if(ExPolicy && policy, FwdIter first, FwdIter last, F && f,
Proj && proj = Proj())
{
#if defined(HPX_HAVE_ALGORITHM_INPUT_ITERATOR_SUPPORT)
static_assert(
Expand All @@ -439,7 +474,7 @@ namespace hpx { namespace parallel { inline namespace v1

return detail::count_if_(
std::forward<ExPolicy>(policy), first, last, std::forward<F>(f),
is_segmented());
std::forward<Proj>(proj), is_segmented());
}
}}}

Expand Down

0 comments on commit d4e461f

Please sign in to comment.