From b2f37585723d6fd44622baf648a4086d817413c2 Mon Sep 17 00:00:00 2001 From: cogle Date: Mon, 12 Feb 2018 00:36:07 -0600 Subject: [PATCH 1/6] Implemented count/count_if for containers --- hpx/include/parallel_count.hpp | 1 + hpx/parallel/algorithms/count.hpp | 129 ++++++++----- hpx/parallel/container_algorithms/count.hpp | 174 ++++++++++++++++++ hpx/parallel/segmented_algorithms/count.hpp | 83 +++++---- .../container_algorithms/CMakeLists.txt | 2 + .../container_algorithms/count_range.cpp | 160 ++++++++++++++++ .../container_algorithms/countif_range.cpp | 165 +++++++++++++++++ 7 files changed, 633 insertions(+), 81 deletions(-) create mode 100644 hpx/parallel/container_algorithms/count.hpp create mode 100644 tests/unit/parallel/container_algorithms/count_range.cpp create mode 100644 tests/unit/parallel/container_algorithms/countif_range.cpp diff --git a/hpx/include/parallel_count.hpp b/hpx/include/parallel_count.hpp index 2f64963f49c5..ff61f0e3e7f6 100644 --- a/hpx/include/parallel_count.hpp +++ b/hpx/include/parallel_count.hpp @@ -9,6 +9,7 @@ #include #include +#include #endif diff --git a/hpx/parallel/algorithms/count.hpp b/hpx/parallel/algorithms/count.hpp index d38cf899183b..186779bd9407 100644 --- a/hpx/parallel/algorithms/count.hpp +++ b/hpx/parallel/algorithms/count.hpp @@ -17,8 +17,10 @@ #include #include +#include #include #include +#include #include #include @@ -37,22 +39,24 @@ namespace hpx { namespace parallel { inline namespace v1 namespace detail { /// \cond NOINTERNAL - template + template struct count_iteration { typedef typename hpx::util::decay::type execution_policy_type; + typedef typename hpx::util::decay::type proj_type; typedef typename hpx::util::decay::type op_type; op_type op_; + proj_type proj_; - template ::type, count_iteration >::value >::type> - HPX_HOST_DEVICE count_iteration(Op_ && op) - : op_(std::forward(op)) + HPX_HOST_DEVICE count_iteration(Op_ && op, Proj_ && proj) + : op_(std::forward(op)), proj_(std::forward(proj)) {} #if !defined(__NVCC__) && !defined(__CUDACC__) @@ -60,11 +64,11 @@ namespace hpx { namespace parallel { inline namespace v1 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 @@ -89,7 +93,8 @@ namespace hpx { namespace parallel { inline namespace v1 void operator()(Iter curr, typename std::iterator_traits::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))); } }; @@ -104,13 +109,16 @@ namespace hpx { namespace parallel { inline namespace v1 : count::algorithm("count") {} - template + template 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 >( - detail::compare_to(value)); + count_iteration, Proj>( + detail::compare_to(value), + std::forward(proj)); typename std::iterator_traits::difference_type ret = 0; @@ -121,12 +129,13 @@ namespace hpx { namespace parallel { inline namespace v1 return ret; } - template + template 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) { @@ -136,8 +145,9 @@ namespace hpx { namespace parallel { inline namespace v1 } auto f1 = - count_iteration >( - detail::compare_to(value)); + count_iteration, Proj>( + detail::compare_to(value), + std::forward(proj)); return util::partitioner::call( std::forward(policy), @@ -153,12 +163,13 @@ namespace hpx { namespace parallel { inline namespace v1 } }; - template + template inline typename util::detail::algorithm_result< ExPolicy, typename std::iterator_traits::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().call( - std::forward(policy), is_seq(), first, last, value); + std::forward(policy), is_seq(), first, last, value, + std::forward(proj)); } // forward declare the segmented version of this algorithm - template + template typename util::detail::algorithm_result< ExPolicy, typename std::iterator_traits::difference_type >::type count_(ExPolicy&& policy, FwdIter first, FwdIter last, T const& value, - std::true_type); + Proj && proj, std::true_type); /// \endcond } @@ -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. @@ -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 - inline typename std::enable_if< - execution::is_execution_policy::value, - typename util::detail::algorithm_result::difference_type - >::type + template ::value && + traits::is_projected::value && + hpx::traits::is_iterator::value)> + typename util::detail::algorithm_result< + ExPolicy, typename std::iterator_traits::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( @@ -257,7 +275,7 @@ namespace hpx { namespace parallel { inline namespace v1 return detail::count_( std::forward(policy), first, last, value, - is_segmented()); + std::forward(proj), is_segmented()); } /////////////////////////////////////////////////////////////////////////// @@ -275,11 +293,14 @@ namespace hpx { namespace parallel { inline namespace v1 : count_if::algorithm("count_if") {} - template + template 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(op); + auto f1 = count_iteration(op, + std::forward(proj)); typename std::iterator_traits::difference_type ret = 0; @@ -290,11 +311,13 @@ namespace hpx { namespace parallel { inline namespace v1 return ret; } - template + template 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) { @@ -303,7 +326,8 @@ namespace hpx { namespace parallel { inline namespace v1 >::get(0); } - auto f1 = count_iteration(op); + auto f1 = count_iteration(op, + std::forward(proj)); return util::partitioner::call( std::forward(policy), @@ -319,12 +343,13 @@ namespace hpx { namespace parallel { inline namespace v1 } }; - template + template typename util::detail::algorithm_result< ExPolicy, typename std::iterator_traits::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().call( std::forward(policy), is_seq(), - first, last, std::forward(f)); + first, last, std::forward(f), + std::forward(proj)); } // forward declare the segmented version of this algorithm - template + template typename util::detail::algorithm_result< ExPolicy, typename std::iterator_traits::difference_type >::type count_if_(ExPolicy && policy, FwdIter first, FwdIter last, F && f, - std::true_type); + Proj && proj, std::true_type); /// \endcond } @@ -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. @@ -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 - inline typename std::enable_if< - execution::is_execution_policy::value, - typename util::detail::algorithm_result::difference_type - >::type + template ::value && + hpx::traits::is_iterator::value && + traits::is_projected::value && + traits::is_indirect_callable< + ExPolicy, F, traits::projected + >::value)> + typename util::detail::algorithm_result< + ExPolicy, typename std::iterator_traits::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( @@ -439,7 +474,7 @@ namespace hpx { namespace parallel { inline namespace v1 return detail::count_if_( std::forward(policy), first, last, std::forward(f), - is_segmented()); + std::forward(proj), is_segmented()); } }}} diff --git a/hpx/parallel/container_algorithms/count.hpp b/hpx/parallel/container_algorithms/count.hpp new file mode 100644 index 000000000000..3e11a8812900 --- /dev/null +++ b/hpx/parallel/container_algorithms/count.hpp @@ -0,0 +1,174 @@ +// 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/count.hpp + +#if !defined(HPX_PARALLEL_CONTAINER_ALGORITHM_COUNT_FEB_09_2017_2057PM) +#define HPX_PARALLEL_CONTAINER_ALGORITHM_COUNT_FEB_09_2018_2057PM + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +namespace hpx { namespace parallel { inline namespace v1 +{ + /////////////////////////////////////////////////////////////////////////// + // count + + /// Returns the number of elements in the range [first, last) satisfying + /// a specific criteria. This version counts the elements that are equal to + /// the given \a value. + /// + /// \note Complexity: Performs exactly \a last - \a first comparisons. + /// + /// \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 comparisons. + /// \tparam Rng The type of the source range used (deduced). + /// The iterators extracted from this range type must + /// meet the requirements of an input 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. + /// \param first Refers to the beginning of the sequence of elements + /// the algorithm will be applied to. + /// \param last Refers to the end of the sequence of elements the + /// algorithm will be applied to. + /// \param value The value to search for. + /// + /// The comparisons in the parallel \a count algorithm invoked with + /// an execution policy object of type \a sequenced_policy + /// execute in sequential order in the calling thread. + /// + /// \note The comparisons in the parallel \a count 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 count algorithm returns a + /// \a hpx::future if the execution policy is of + /// type + /// \a sequenced_task_policy or + /// \a parallel_task_policy and + /// returns \a difference_type otherwise (where \a difference_type + /// is defined by \a std::iterator_traits::difference_type. + /// The \a count algorithm returns the number of elements + /// satisfying the given criteria. + /// + template ::value && + traits::is_projected_range::value && + hpx::traits::is_range::value)> + typename util::detail::algorithm_result< + ExPolicy, typename std::iterator_traits< + typename hpx::traits::range_traits::iterator_type + >::difference_type + >::type + count(ExPolicy && policy, Rng && rng, T const& value, + Proj && proj = Proj()) + { + return count(std::forward(policy), hpx::util::begin(rng), + hpx::util::end(rng), value, std::forward(proj)); + } + + /// Returns the number of elements in the range [first, last) satisfying + /// a specific criteria. This version counts elements for which predicate + /// \a f returns true. + /// + /// \note Complexity: Performs exactly \a last - \a first applications of + /// the predicate. + /// + /// \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 comparisons. + /// \tparam Rng The type of the source range used (deduced). + /// The iterators extracted from this range type must + /// meet the requirements of an input iterator. + /// \tparam F The type of the function/function object to use + /// (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. + /// \param first Refers to the beginning of the sequence of elements + /// the algorithm will be applied to. + /// \param last Refers to the end of the sequence of elements the + /// algorithm will be applied to. + /// \param f Specifies the function (or function object) which + /// will be invoked for each of the elements in the + /// sequence specified by [first, last).This is an + /// unary predicate which returns \a true for the + /// required elements. The signature of this predicate + /// should be equivalent to: + /// \code + /// bool pred(const Type &a); + /// \endcode \n + /// The signature does not need to have const&, but + /// the function must not modify the objects passed to + /// it. The type \a Type must be such that an object of + /// type \a FwdIter can be dereferenced and then + /// implicitly converted to Type. + /// + /// \note The assignments in the parallel \a count_if algorithm invoked with + /// an execution policy object of type \a sequenced_policy + /// execute in sequential order in the calling thread. + /// \note The assignments in the parallel \a count_if 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 count_if algorithm returns + /// \a hpx::future if the execution policy is of + /// type + /// \a sequenced_task_policy or + /// \a parallel_task_policy and + /// returns \a difference_type otherwise (where \a difference_type + /// is defined by \a std::iterator_traits::difference_type. + /// The \a count algorithm returns the number of elements + /// satisfying the given criteria. + /// + template ::value && + hpx::traits::is_range::value && + traits::is_projected_range::value && + traits::is_indirect_callable< + ExPolicy, F, traits::projected_range + >::value)> + typename util::detail::algorithm_result< + ExPolicy, typename std::iterator_traits< + typename hpx::traits::range_traits::iterator_type + >::difference_type + >::type + count_if(ExPolicy && policy, Rng && rng, F && f, + Proj && proj = Proj()) + { + return count_if(policy, hpx::util::begin(rng), hpx::util::end(rng), + std::forward(f), std::forward(proj)); + } +}}} + +#endif diff --git a/hpx/parallel/segmented_algorithms/count.hpp b/hpx/parallel/segmented_algorithms/count.hpp index 31af932b878e..5a810ecb2cfd 100644 --- a/hpx/parallel/segmented_algorithms/count.hpp +++ b/hpx/parallel/segmented_algorithms/count.hpp @@ -36,12 +36,13 @@ namespace hpx { namespace parallel { inline namespace v1 // sequential remote implementation template + typename T, typename Proj> static typename util::detail::algorithm_result< ExPolicy, typename std::iterator_traits::difference_type >::type segmented_count(Algo && algo, ExPolicy const& policy, - SegIter first, SegIter last, T const& value, std::true_type) + SegIter first, SegIter last, T const& value, + Proj && proj, std::true_type) { typedef hpx::traits::segmented_iterator_traits traits; typedef typename traits::segment_iterator segment_iterator; @@ -63,7 +64,8 @@ namespace hpx { namespace parallel { inline namespace v1 if (beg != end) { overall_result = dispatch(traits::get_id(sit), - algo, policy, std::true_type(), beg, end, value); + algo, policy, std::true_type(), beg, end, + value, proj); } } else { @@ -73,7 +75,8 @@ namespace hpx { namespace parallel { inline namespace v1 if (beg != end) { overall_result += dispatch(traits::get_id(sit), - algo, policy, std::true_type(), beg, end, value); + algo, policy, std::true_type(), beg, end, + value, proj); } // handle all of the full partitions @@ -84,7 +87,8 @@ namespace hpx { namespace parallel { inline namespace v1 if (beg != end) { overall_result += dispatch(traits::get_id(sit), - algo, policy, std::true_type(), beg, end, value); + algo, policy, std::true_type(), beg, end, + value, proj); } } @@ -94,7 +98,8 @@ namespace hpx { namespace parallel { inline namespace v1 if (beg != end) { overall_result += dispatch(traits::get_id(sit), - algo, policy, std::true_type(), beg, end, value); + algo, policy, std::true_type(), beg, end, + value, proj); } } @@ -103,12 +108,13 @@ namespace hpx { namespace parallel { inline namespace v1 // parallel remote implementation template + typename T, typename Proj> static typename util::detail::algorithm_result< ExPolicy, typename std::iterator_traits::difference_type >::type segmented_count(Algo && algo, ExPolicy const& policy, - SegIter first, SegIter last, T const& value, std::false_type) + SegIter first, SegIter last, T const& value, + Proj && proj, std::false_type) { typedef hpx::traits::segmented_iterator_traits traits; typedef typename traits::segment_iterator segment_iterator; @@ -136,7 +142,7 @@ namespace hpx { namespace parallel { inline namespace v1 if (beg != end) { segments.push_back(dispatch_async(traits::get_id(sit), - algo, policy, forced_seq(), beg, end, value)); + algo, policy, forced_seq(), beg, end, value, proj)); } } else { @@ -146,7 +152,7 @@ namespace hpx { namespace parallel { inline namespace v1 if (beg != end) { segments.push_back(dispatch_async(traits::get_id(sit), - algo, policy, forced_seq(), beg, end, value)); + algo, policy, forced_seq(), beg, end, value, proj)); } // handle all of the full partitions @@ -157,7 +163,7 @@ namespace hpx { namespace parallel { inline namespace v1 if (beg != end) { segments.push_back(dispatch_async(traits::get_id(sit), - algo, policy, forced_seq(), beg, end, value)); + algo, policy, forced_seq(), beg, end, value, proj)); } } @@ -167,7 +173,7 @@ namespace hpx { namespace parallel { inline namespace v1 if (beg != end) { segments.push_back(dispatch_async(traits::get_id(sit), - algo, policy, forced_seq(), beg, end, value)); + algo, policy, forced_seq(), beg, end, value, proj)); } } @@ -182,12 +188,12 @@ namespace hpx { namespace parallel { inline namespace v1 /////////////////////////////////////////////////////////////////////// // segmented implementation - template + template inline typename util::detail::algorithm_result< ExPolicy, typename std::iterator_traits::difference_type >::type count_(ExPolicy&& policy, InIter first, InIter last, T const& value, - std::true_type) + Proj && proj, std::true_type) { typedef parallel::execution::is_sequenced_execution_policy< ExPolicy @@ -204,16 +210,16 @@ namespace hpx { namespace parallel { inline namespace v1 return segmented_count( count(), std::forward(policy), - first, last, value, is_seq()); + first, last, value, std::forward(proj), is_seq()); } // forward declare the non-segmented version of this algorithm - template + template typename util::detail::algorithm_result< ExPolicy, typename std::iterator_traits::difference_type >::type count_(ExPolicy&& policy, InIter first, InIter last, T const& value, - std::false_type); + Proj && proj, std::false_type); /// \endcond } @@ -227,12 +233,12 @@ namespace hpx { namespace parallel { inline namespace v1 // sequential remote implementation template + typename F, typename Proj> static typename util::detail::algorithm_result< ExPolicy, typename std::iterator_traits::difference_type >::type segmented_count_if(Algo && algo, ExPolicy const& policy, - SegIter first, SegIter last, F && f, std::true_type) + SegIter first, SegIter last, F && f, Proj && proj, std::true_type) { typedef hpx::traits::segmented_iterator_traits traits; typedef typename traits::segment_iterator segment_iterator; @@ -255,7 +261,8 @@ namespace hpx { namespace parallel { inline namespace v1 { overall_result = dispatch(traits::get_id(sit), algo, policy, std::true_type(), - beg, end, std::forward(f)); + beg, end, std::forward(f), + std::forward(proj)); } } else { @@ -266,7 +273,8 @@ namespace hpx { namespace parallel { inline namespace v1 { overall_result += dispatch(traits::get_id(sit), algo, policy, std::true_type(), - beg, end, std::forward(f)); + beg, end, std::forward(f), + std::forward(proj)); } // handle all of the full partitions @@ -278,7 +286,8 @@ namespace hpx { namespace parallel { inline namespace v1 { overall_result += dispatch(traits::get_id(sit), algo, policy, std::true_type(), - beg, end, std::forward(f)); + beg, end, std::forward(f), + std::forward(proj)); } } @@ -289,7 +298,8 @@ namespace hpx { namespace parallel { inline namespace v1 { overall_result += dispatch(traits::get_id(sit), algo, policy, std::true_type(), - beg, end, std::forward(f)); + beg, end, std::forward(f), + std::forward(proj)); } } @@ -298,12 +308,12 @@ namespace hpx { namespace parallel { inline namespace v1 // parallel remote implementation template + typename F, typename Proj> static typename util::detail::algorithm_result< ExPolicy, typename std::iterator_traits::difference_type >::type segmented_count_if(Algo && algo, ExPolicy const& policy, - SegIter first, SegIter last, F && f, std::false_type) + SegIter first, SegIter last, F && f, Proj && proj, std::false_type) { typedef hpx::traits::segmented_iterator_traits traits; typedef typename traits::segment_iterator segment_iterator; @@ -332,7 +342,8 @@ namespace hpx { namespace parallel { inline namespace v1 { segments.push_back(dispatch_async(traits::get_id(sit), algo, policy, forced_seq(), - beg, end, std::forward(f))); + beg, end, std::forward(f), + std::forward(proj))); } } else { @@ -343,7 +354,8 @@ namespace hpx { namespace parallel { inline namespace v1 { segments.push_back(dispatch_async(traits::get_id(sit), algo, policy, forced_seq(), - beg, end, std::forward(f))); + beg, end, std::forward(f), + std::forward(proj))); } // handle all of the full partitions @@ -355,7 +367,8 @@ namespace hpx { namespace parallel { inline namespace v1 { segments.push_back(dispatch_async(traits::get_id(sit), algo, policy, forced_seq(), - beg, end, std::forward(f))); + beg, end, std::forward(f), + std::forward(proj))); } } @@ -366,7 +379,8 @@ namespace hpx { namespace parallel { inline namespace v1 { segments.push_back(dispatch_async(traits::get_id(sit), algo, policy, forced_seq(), - beg, end, std::forward(f))); + beg, end, std::forward(f), + std::forward(proj))); } } @@ -390,12 +404,12 @@ namespace hpx { namespace parallel { inline namespace v1 std::move(segments))); } - template + template inline typename util::detail::algorithm_result< ExPolicy, typename std::iterator_traits::difference_type >::type count_if_(ExPolicy && policy, InIter first, InIter last, F && f, - std::true_type) + Proj && proj, std::true_type) { typedef parallel::execution::is_sequenced_execution_policy< ExPolicy @@ -412,16 +426,17 @@ namespace hpx { namespace parallel { inline namespace v1 return segmented_count_if( count_if(), std::forward(policy), - first, last, std::forward(f), is_seq()); + first, last, std::forward(f), std::forward(proj), + is_seq()); } // forward declare the non-segmented version of this algorithm - template + template typename util::detail::algorithm_result< ExPolicy, typename std::iterator_traits::difference_type >::type count_if_(ExPolicy && policy, InIter first, InIter last, F && f, - std::false_type); + Proj && proj, std::false_type); /// \endcond } diff --git a/tests/unit/parallel/container_algorithms/CMakeLists.txt b/tests/unit/parallel/container_algorithms/CMakeLists.txt index acbc37d73908..bb68be50ff85 100644 --- a/tests/unit/parallel/container_algorithms/CMakeLists.txt +++ b/tests/unit/parallel/container_algorithms/CMakeLists.txt @@ -8,6 +8,8 @@ set(tests any_of_range copy_range copyif_range + count_range + countif_range foreach_range foreach_range_projection generate_range diff --git a/tests/unit/parallel/container_algorithms/count_range.cpp b/tests/unit/parallel/container_algorithms/count_range.cpp new file mode 100644 index 000000000000..4ae03ba03dcf --- /dev/null +++ b/tests/unit/parallel/container_algorithms/count_range.cpp @@ -0,0 +1,160 @@ +// 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) + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "test_utils.hpp" + +struct user_defined_struct +{ + user_defined_struct() = default; + user_defined_struct(int val) : val(val) + {} + + ~user_defined_struct() = default; + + bool operator==(const user_defined_struct & rhs) const + { + return val == rhs.val; + } + + int val; +}; + +struct random_fill +{ + random_fill(int rand_base, int range) + : gen(std::rand()), + dist(rand_base - range / 2, rand_base + range / 2) + {} + + int operator()() + { + return dist(gen); + } + + std::mt19937 gen; + std::uniform_int_distribution<> dist; +}; + +template +void test_count(ExPolicy policy, IteratorTag, DataType) +{ + static_assert( + hpx::parallel::execution::is_execution_policy::value, + "hpx::parallel::execution::is_execution_policy::value"); + + std::vector c{10007}; + std::generate(std::begin(c), std::end(c), random_fill(0, 20)); + + const auto search_val = DataType(10); + + auto result = hpx::parallel::count(policy, c, search_val); + auto expected = std::count(std::begin(c), std::end(c), search_val); + + HPX_TEST_EQ(expected, result); +} + +template +void test_count_async(ExPolicy policy, IteratorTag, DataType) +{ + static_assert( + hpx::parallel::execution::is_execution_policy::value, + "hpx::parallel::execution::is_execution_policy::value"); + + std::vector c{10007}; + std::generate(std::begin(c), std::end(c), random_fill(0, 20)); + + const auto search_val = DataType(10); + + auto f = hpx::parallel::count(policy, c, search_val); + auto result = f.get(); + + auto expected = std::count(std::begin(c), std::end(c), search_val); + + HPX_TEST_EQ(expected, result); +} + +template +void test_count() +{ + using namespace hpx::parallel; + + auto seq = execution::seq; + auto par = execution::par; + auto par_unseq = execution::par_unseq; + + test_count(seq, IteratorTag(), DataType()); + test_count(par, IteratorTag(), DataType()); + test_count(par_unseq, IteratorTag(), DataType()); + + test_count_async(execution::seq(execution::task), IteratorTag(), DataType()); + test_count_async(execution::par(execution::task), IteratorTag(), DataType()); + +#if defined(HPX_HAVE_GENERIC_EXECUTION_POLICY) + test_count(execution_policy(execution::seq), IteratorTag(), DataType()); + test_count(execution_policy(execution::par), IteratorTag(), DataType()); + test_count(execution_policy(execution::par_unseq), IteratorTag(), DataType()); + + test_unique(execution_policy(execution::seq(execution::task)), DataType()); + test_unique(execution_policy(execution::par(execution::task)), DataType()); +#endif +} + +void count_test() +{ + test_count(); + test_count(); +} + +/////////////////////////////////////////////////////////////////////////////// +int hpx_main(boost::program_options::variables_map& vm) +{ + unsigned int seed = (unsigned int)std::time(nullptr); + if (vm.count("seed")) + seed = vm["seed"].as(); + + std::cout << "using seed: " << seed << std::endl; + std::srand(seed); + + count_test(); + return hpx::finalize(); +} + +int main(int argc, char* argv[]) +{ + // add command line option which controls the random number generator seed + using namespace boost::program_options; + options_description desc_commandline( + "Usage: " HPX_APPLICATION_STRING " [options]"); + + desc_commandline.add_options() + ("seed,s", value(), + "the random number generator seed to use for this run") + ; + + // By default this test should run on all available cores + std::vector const cfg = { + "hpx.os_threads=all" + }; + + // Initialize and run HPX + HPX_TEST_EQ_MSG(hpx::init(desc_commandline, argc, argv, cfg), 0, + "HPX main exited with non-zero status"); + + return hpx::util::report_errors(); +} \ No newline at end of file diff --git a/tests/unit/parallel/container_algorithms/countif_range.cpp b/tests/unit/parallel/container_algorithms/countif_range.cpp new file mode 100644 index 000000000000..189fb0f4aaab --- /dev/null +++ b/tests/unit/parallel/container_algorithms/countif_range.cpp @@ -0,0 +1,165 @@ +// 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) + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "test_utils.hpp" + +struct user_defined_struct +{ + user_defined_struct() = default; + user_defined_struct(int val) : val(val) + {} + + ~user_defined_struct() = default; + + bool operator==(const int & rhs_val) const + { + return val == rhs_val; + } + + bool operator==(const user_defined_struct & rhs) const + { + return val == rhs.val; + } + + int val; +}; + +struct random_fill +{ + random_fill(int rand_base, int range) + : gen(std::rand()), + dist(rand_base - range / 2, rand_base + range / 2) + {} + + int operator()() + { + return dist(gen); + } + + std::mt19937 gen; + std::uniform_int_distribution<> dist; +}; + +template +void test_count(ExPolicy policy, IteratorTag, DataType) +{ + static_assert( + hpx::parallel::execution::is_execution_policy::value, + "hpx::parallel::execution::is_execution_policy::value"); + + std::vector c{10007}; + std::generate(std::begin(c), std::end(c), random_fill(0, 20)); + + auto countif_lambda = [](const auto & ele){return ele == 10;}; + + auto result = hpx::parallel::count_if(policy, c, countif_lambda); + auto expected = std::count_if(std::begin(c), std::end(c), countif_lambda); + + HPX_TEST_EQ(expected, result); +} + +template +void test_count_async(ExPolicy policy, IteratorTag, DataType) +{ + static_assert( + hpx::parallel::execution::is_execution_policy::value, + "hpx::parallel::execution::is_execution_policy::value"); + + std::vector c{10007}; + std::generate(std::begin(c), std::end(c), random_fill(0, 20)); + + auto countif_lambda = [](const auto & ele){return ele == 10;}; + + auto f = hpx::parallel::count_if(policy, c, countif_lambda); + auto result = f.get(); + + auto expected = std::count_if(std::begin(c), std::end(c), countif_lambda); + + HPX_TEST_EQ(expected, result); +} + +template +void test_count() +{ + using namespace hpx::parallel; + + auto seq = execution::seq; + auto par = execution::par; + auto par_unseq = execution::par_unseq; + + test_count(seq, IteratorTag(), DataType()); + test_count(par, IteratorTag(), DataType()); + test_count(par_unseq, IteratorTag(), DataType()); + + test_count_async(execution::seq(execution::task), IteratorTag(), DataType()); + test_count_async(execution::par(execution::task), IteratorTag(), DataType()); + +#if defined(HPX_HAVE_GENERIC_EXECUTION_POLICY) + test_count(execution_policy(execution::seq), IteratorTag(), DataType()); + test_count(execution_policy(execution::par), IteratorTag(), DataType()); + test_count(execution_policy(execution::par_unseq), IteratorTag(), DataType()); + + test_unique(execution_policy(execution::seq(execution::task)), DataType()()); + test_unique(execution_policy(execution::par(execution::task)), DataType()); +#endif +} + +void count_test() +{ + test_count(); + test_count(); +} + +/////////////////////////////////////////////////////////////////////////////// +int hpx_main(boost::program_options::variables_map& vm) +{ + unsigned int seed = (unsigned int)std::time(nullptr); + if (vm.count("seed")) + seed = vm["seed"].as(); + + std::cout << "using seed: " << seed << std::endl; + std::srand(seed); + + count_test(); + return hpx::finalize(); +} + +int main(int argc, char* argv[]) +{ + // add command line option which controls the random number generator seed + using namespace boost::program_options; + options_description desc_commandline( + "Usage: " HPX_APPLICATION_STRING " [options]"); + + desc_commandline.add_options() + ("seed,s", value(), + "the random number generator seed to use for this run") + ; + + // By default this test should run on all available cores + std::vector const cfg = { + "hpx.os_threads=all" + }; + + // Initialize and run HPX + HPX_TEST_EQ_MSG(hpx::init(desc_commandline, argc, argv, cfg), 0, + "HPX main exited with non-zero status"); + + return hpx::util::report_errors(); +} \ No newline at end of file From aeb813d6274919a333fe51a2f789683769f91301 Mon Sep 17 00:00:00 2001 From: cogle Date: Mon, 12 Feb 2018 03:29:44 -0600 Subject: [PATCH 2/6] Updated the documentation --- hpx/parallel/container_algorithms/count.hpp | 22 ++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/hpx/parallel/container_algorithms/count.hpp b/hpx/parallel/container_algorithms/count.hpp index 3e11a8812900..8809dde5ec36 100644 --- a/hpx/parallel/container_algorithms/count.hpp +++ b/hpx/parallel/container_algorithms/count.hpp @@ -44,11 +44,13 @@ namespace hpx { namespace parallel { inline namespace v1 /// /// \param policy The execution policy to use for the scheduling of /// the iterations. - /// \param first Refers to the beginning of the sequence of elements - /// the algorithm will be applied to. - /// \param last Refers to the end of the sequence of elements the - /// algorithm will be applied to. + /// \param rng Refers to the sequence of elements the algorithm + /// will be applied to. /// \param value The value to search for. + /// \param proj Specifies the function (or function object) which + /// will be invoked for each of the elements as a + /// projection operation before the actual predicate + /// \a is invoked. /// /// The comparisons in the parallel \a count algorithm invoked with /// an execution policy object of type \a sequenced_policy @@ -108,13 +110,11 @@ namespace hpx { namespace parallel { inline namespace v1 /// 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. - /// \param first Refers to the beginning of the sequence of elements - /// the algorithm will be applied to. - /// \param last Refers to the end of the sequence of elements the - /// algorithm will be applied to. + /// \param rng Refers to the sequence of elements the algorithm + /// will be applied to. /// \param f Specifies the function (or function object) which /// will be invoked for each of the elements in the /// sequence specified by [first, last).This is an @@ -129,6 +129,10 @@ namespace hpx { namespace parallel { inline namespace v1 /// it. The type \a Type must be such that an object of /// type \a FwdIter can be dereferenced and then /// implicitly converted to Type. + /// \param proj Specifies the function (or function object) which + /// will be invoked for each of the elements as a + /// projection operation before the actual predicate + /// \a is invoked. /// /// \note The assignments in the parallel \a count_if algorithm invoked with /// an execution policy object of type \a sequenced_policy From 9fc47406bf6786edc9ce7464fc1b360463c7451d Mon Sep 17 00:00:00 2001 From: cogle Date: Mon, 12 Feb 2018 16:04:20 -0600 Subject: [PATCH 3/6] Pushing for pull request. --- .github/CONTRIBUTING.md | 8 +++--- hpx/parallel/algorithms/count.hpp | 24 +++++++++--------- .../container_algorithms/count_range.cpp | 25 +++++++++++-------- .../container_algorithms/countif_range.cpp | 20 +++++++++------ 4 files changed, 42 insertions(+), 35 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 050c6a465ea3..0fcfc877b8c2 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -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 @@ -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 @@ -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)) diff --git a/hpx/parallel/algorithms/count.hpp b/hpx/parallel/algorithms/count.hpp index 186779bd9407..5dbc15d4a0ac 100644 --- a/hpx/parallel/algorithms/count.hpp +++ b/hpx/parallel/algorithms/count.hpp @@ -112,12 +112,12 @@ namespace hpx { namespace parallel { inline namespace v1 template static difference_type - sequential(ExPolicy && policy, InIter first, InIter last, + sequential(ExPolicy && policy, InIter first, InIter last, T const& value, Proj && proj) { auto f1 = count_iteration, Proj>( - detail::compare_to(value), + detail::compare_to(value), std::forward(proj)); typename std::iterator_traits::difference_type ret = 0; @@ -163,7 +163,7 @@ namespace hpx { namespace parallel { inline namespace v1 } }; - template inline typename util::detail::algorithm_result< ExPolicy, typename std::iterator_traits::difference_type @@ -193,7 +193,7 @@ namespace hpx { namespace parallel { inline namespace v1 } // forward declare the segmented version of this algorithm - template typename util::detail::algorithm_result< ExPolicy, typename std::iterator_traits::difference_type @@ -293,13 +293,13 @@ namespace hpx { namespace parallel { inline namespace v1 : count_if::algorithm("count_if") {} - template static difference_type sequential(ExPolicy && policy, InIter first, InIter last, Pred && op, Proj && proj) { - auto f1 = count_iteration(op, + auto f1 = count_iteration(op, std::forward(proj)); typename std::iterator_traits::difference_type ret = 0; @@ -326,7 +326,7 @@ namespace hpx { namespace parallel { inline namespace v1 >::get(0); } - auto f1 = count_iteration(op, + auto f1 = count_iteration(op, std::forward(proj)); return util::partitioner::call( @@ -343,7 +343,7 @@ namespace hpx { namespace parallel { inline namespace v1 } }; - template typename util::detail::algorithm_result< ExPolicy, typename std::iterator_traits::difference_type @@ -369,12 +369,12 @@ namespace hpx { namespace parallel { inline namespace v1 return detail::count_if().call( std::forward(policy), is_seq(), - first, last, std::forward(f), + first, last, std::forward(f), std::forward(proj)); } // forward declare the segmented version of this algorithm - template typename util::detail::algorithm_result< ExPolicy, typename std::iterator_traits::difference_type @@ -446,11 +446,11 @@ namespace hpx { namespace parallel { inline namespace v1 /// The \a count algorithm returns the number of elements /// satisfying the given criteria. /// - template ::value && - hpx::traits::is_iterator::value && + hpx::traits::is_iterator::value && traits::is_projected::value && traits::is_indirect_callable< ExPolicy, F, traits::projected diff --git a/tests/unit/parallel/container_algorithms/count_range.cpp b/tests/unit/parallel/container_algorithms/count_range.cpp index 4ae03ba03dcf..c9951dba540f 100644 --- a/tests/unit/parallel/container_algorithms/count_range.cpp +++ b/tests/unit/parallel/container_algorithms/count_range.cpp @@ -19,11 +19,11 @@ #include "test_utils.hpp" -struct user_defined_struct +struct user_defined_struct { user_defined_struct() = default; user_defined_struct(int val) : val(val) - {} + {} ~user_defined_struct() = default; @@ -62,9 +62,9 @@ void test_count(ExPolicy policy, IteratorTag, DataType) std::generate(std::begin(c), std::end(c), random_fill(0, 20)); const auto search_val = DataType(10); - + auto result = hpx::parallel::count(policy, c, search_val); - auto expected = std::count(std::begin(c), std::end(c), search_val); + auto expected = std::count(std::begin(c), std::end(c), search_val); HPX_TEST_EQ(expected, result); } @@ -79,12 +79,12 @@ void test_count_async(ExPolicy policy, IteratorTag, DataType) std::vector c{10007}; std::generate(std::begin(c), std::end(c), random_fill(0, 20)); - const auto search_val = DataType(10); - + const auto search_val = DataType(10); + auto f = hpx::parallel::count(policy, c, search_val); auto result = f.get(); - auto expected = std::count(std::begin(c), std::end(c), search_val); + auto expected = std::count(std::begin(c), std::end(c), search_val); HPX_TEST_EQ(expected, result); } @@ -102,13 +102,16 @@ void test_count() test_count(par, IteratorTag(), DataType()); test_count(par_unseq, IteratorTag(), DataType()); - test_count_async(execution::seq(execution::task), IteratorTag(), DataType()); - test_count_async(execution::par(execution::task), IteratorTag(), DataType()); + test_count_async(execution::seq(execution::task), + IteratorTag(), DataType()); + test_count_async(execution::par(execution::task), + IteratorTag(), DataType()); #if defined(HPX_HAVE_GENERIC_EXECUTION_POLICY) test_count(execution_policy(execution::seq), IteratorTag(), DataType()); test_count(execution_policy(execution::par), IteratorTag(), DataType()); - test_count(execution_policy(execution::par_unseq), IteratorTag(), DataType()); + test_count(execution_policy(execution::par_unseq), + IteratorTag(), DataType()); test_unique(execution_policy(execution::seq(execution::task)), DataType()); test_unique(execution_policy(execution::par(execution::task)), DataType()); @@ -157,4 +160,4 @@ int main(int argc, char* argv[]) "HPX main exited with non-zero status"); return hpx::util::report_errors(); -} \ No newline at end of file +} diff --git a/tests/unit/parallel/container_algorithms/countif_range.cpp b/tests/unit/parallel/container_algorithms/countif_range.cpp index 189fb0f4aaab..f314de67e02c 100644 --- a/tests/unit/parallel/container_algorithms/countif_range.cpp +++ b/tests/unit/parallel/container_algorithms/countif_range.cpp @@ -23,7 +23,7 @@ struct user_defined_struct { user_defined_struct() = default; user_defined_struct(int val) : val(val) - {} + {} ~user_defined_struct() = default; @@ -69,7 +69,7 @@ void test_count(ExPolicy policy, IteratorTag, DataType) auto countif_lambda = [](const auto & ele){return ele == 10;}; auto result = hpx::parallel::count_if(policy, c, countif_lambda); - auto expected = std::count_if(std::begin(c), std::end(c), countif_lambda); + auto expected = std::count_if(std::begin(c), std::end(c), countif_lambda); HPX_TEST_EQ(expected, result); } @@ -89,7 +89,8 @@ void test_count_async(ExPolicy policy, IteratorTag, DataType) auto f = hpx::parallel::count_if(policy, c, countif_lambda); auto result = f.get(); - auto expected = std::count_if(std::begin(c), std::end(c), countif_lambda); + auto expected = std::count_if(std::begin(c), std::end(c), + countif_lambda); HPX_TEST_EQ(expected, result); } @@ -107,15 +108,18 @@ void test_count() test_count(par, IteratorTag(), DataType()); test_count(par_unseq, IteratorTag(), DataType()); - test_count_async(execution::seq(execution::task), IteratorTag(), DataType()); - test_count_async(execution::par(execution::task), IteratorTag(), DataType()); + test_count_async(execution::seq(execution::task), + IteratorTag(), DataType()); + test_count_async(execution::par(execution::task), + IteratorTag(), DataType()); #if defined(HPX_HAVE_GENERIC_EXECUTION_POLICY) test_count(execution_policy(execution::seq), IteratorTag(), DataType()); test_count(execution_policy(execution::par), IteratorTag(), DataType()); - test_count(execution_policy(execution::par_unseq), IteratorTag(), DataType()); + test_count(execution_policy(execution::par_unseq), + IteratorTag(), DataType()); - test_unique(execution_policy(execution::seq(execution::task)), DataType()()); + test_unique(execution_policy(execution::seq(execution::task)), DataType()); test_unique(execution_policy(execution::par(execution::task)), DataType()); #endif } @@ -162,4 +166,4 @@ int main(int argc, char* argv[]) "HPX main exited with non-zero status"); return hpx::util::report_errors(); -} \ No newline at end of file +} From ed8bb4a0bc964c64fa914548e9be8ef6b09d35cf Mon Sep 17 00:00:00 2001 From: cogle Date: Mon, 12 Feb 2018 16:32:47 -0600 Subject: [PATCH 4/6] Added count and any_all_none to docs CMake --- docs/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index 7d9a56b1ceba..c124bf4046ce 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -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" From f835dc0e56a68c5ab6dc6b5ac16aa76311de2605 Mon Sep 17 00:00:00 2001 From: cogle Date: Mon, 12 Feb 2018 23:38:36 -0600 Subject: [PATCH 5/6] Fixed header guard --- hpx/parallel/container_algorithms/count.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/hpx/parallel/container_algorithms/count.hpp b/hpx/parallel/container_algorithms/count.hpp index 8809dde5ec36..c5ae8112fdf1 100644 --- a/hpx/parallel/container_algorithms/count.hpp +++ b/hpx/parallel/container_algorithms/count.hpp @@ -1,11 +1,11 @@ -// Copyright (c) 2018 Christopher Ogle +// 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/count.hpp -#if !defined(HPX_PARALLEL_CONTAINER_ALGORITHM_COUNT_FEB_09_2017_2057PM) +#if !defined(HPX_PARALLEL_CONTAINER_ALGORITHM_COUNT_FEB_09_2018_2057PM) #define HPX_PARALLEL_CONTAINER_ALGORITHM_COUNT_FEB_09_2018_2057PM #include @@ -23,7 +23,7 @@ namespace hpx { namespace parallel { inline namespace v1 { /////////////////////////////////////////////////////////////////////////// - // count + // count /// Returns the number of elements in the range [first, last) satisfying /// a specific criteria. This version counts the elements that are equal to @@ -72,7 +72,7 @@ namespace hpx { namespace parallel { inline namespace v1 /// The \a count algorithm returns the number of elements /// satisfying the given criteria. /// - template ::value && @@ -153,7 +153,7 @@ namespace hpx { namespace parallel { inline namespace v1 /// The \a count algorithm returns the number of elements /// satisfying the given criteria. /// - template ::value && @@ -170,7 +170,7 @@ namespace hpx { namespace parallel { inline namespace v1 count_if(ExPolicy && policy, Rng && rng, F && f, Proj && proj = Proj()) { - return count_if(policy, hpx::util::begin(rng), hpx::util::end(rng), + return count_if(policy, hpx::util::begin(rng), hpx::util::end(rng), std::forward(f), std::forward(proj)); } }}} From 73677d6546ffa8560b203b744065f34e13b7b2fd Mon Sep 17 00:00:00 2001 From: cogle Date: Tue, 13 Feb 2018 04:43:06 -0600 Subject: [PATCH 6/6] Removed Endlined Whitespace --- hpx/parallel/segmented_algorithms/count.hpp | 22 ++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/hpx/parallel/segmented_algorithms/count.hpp b/hpx/parallel/segmented_algorithms/count.hpp index 5a810ecb2cfd..fbcbb689808f 100644 --- a/hpx/parallel/segmented_algorithms/count.hpp +++ b/hpx/parallel/segmented_algorithms/count.hpp @@ -41,7 +41,7 @@ namespace hpx { namespace parallel { inline namespace v1 ExPolicy, typename std::iterator_traits::difference_type >::type segmented_count(Algo && algo, ExPolicy const& policy, - SegIter first, SegIter last, T const& value, + SegIter first, SegIter last, T const& value, Proj && proj, std::true_type) { typedef hpx::traits::segmented_iterator_traits traits; @@ -64,7 +64,7 @@ namespace hpx { namespace parallel { inline namespace v1 if (beg != end) { overall_result = dispatch(traits::get_id(sit), - algo, policy, std::true_type(), beg, end, + algo, policy, std::true_type(), beg, end, value, proj); } } @@ -75,7 +75,7 @@ namespace hpx { namespace parallel { inline namespace v1 if (beg != end) { overall_result += dispatch(traits::get_id(sit), - algo, policy, std::true_type(), beg, end, + algo, policy, std::true_type(), beg, end, value, proj); } @@ -87,7 +87,7 @@ namespace hpx { namespace parallel { inline namespace v1 if (beg != end) { overall_result += dispatch(traits::get_id(sit), - algo, policy, std::true_type(), beg, end, + algo, policy, std::true_type(), beg, end, value, proj); } } @@ -98,7 +98,7 @@ namespace hpx { namespace parallel { inline namespace v1 if (beg != end) { overall_result += dispatch(traits::get_id(sit), - algo, policy, std::true_type(), beg, end, + algo, policy, std::true_type(), beg, end, value, proj); } } @@ -113,7 +113,7 @@ namespace hpx { namespace parallel { inline namespace v1 ExPolicy, typename std::iterator_traits::difference_type >::type segmented_count(Algo && algo, ExPolicy const& policy, - SegIter first, SegIter last, T const& value, + SegIter first, SegIter last, T const& value, Proj && proj, std::false_type) { typedef hpx::traits::segmented_iterator_traits traits; @@ -286,7 +286,7 @@ namespace hpx { namespace parallel { inline namespace v1 { overall_result += dispatch(traits::get_id(sit), algo, policy, std::true_type(), - beg, end, std::forward(f), + beg, end, std::forward(f), std::forward(proj)); } } @@ -298,7 +298,7 @@ namespace hpx { namespace parallel { inline namespace v1 { overall_result += dispatch(traits::get_id(sit), algo, policy, std::true_type(), - beg, end, std::forward(f), + beg, end, std::forward(f), std::forward(proj)); } } @@ -342,7 +342,7 @@ namespace hpx { namespace parallel { inline namespace v1 { segments.push_back(dispatch_async(traits::get_id(sit), algo, policy, forced_seq(), - beg, end, std::forward(f), + beg, end, std::forward(f), std::forward(proj))); } } @@ -367,7 +367,7 @@ namespace hpx { namespace parallel { inline namespace v1 { segments.push_back(dispatch_async(traits::get_id(sit), algo, policy, forced_seq(), - beg, end, std::forward(f), + beg, end, std::forward(f), std::forward(proj))); } } @@ -426,7 +426,7 @@ namespace hpx { namespace parallel { inline namespace v1 return segmented_count_if( count_if(), std::forward(policy), - first, last, std::forward(f), std::forward(proj), + first, last, std::forward(f), std::forward(proj), is_seq()); }