Skip to content

Commit

Permalink
Fixing generate, includes, and transform_reduce
Browse files Browse the repository at this point in the history
  • Loading branch information
hkaiser committed Jun 25, 2017
1 parent b1da234 commit 5cd77b0
Show file tree
Hide file tree
Showing 8 changed files with 187 additions and 140 deletions.
61 changes: 35 additions & 26 deletions hpx/parallel/algorithms/generate.hpp
@@ -1,4 +1,5 @@
// Copyright (c) 2014 Grant Mercer
// Copyright (c) 2017 Hartmut Kaiser
//
// 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 Down Expand Up @@ -164,31 +165,31 @@ namespace hpx { namespace parallel { inline namespace v1
namespace detail
{
/// \cond NOINTERNAL
template <typename OutIter>
struct generate_n: public detail::algorithm<generate_n<OutIter>, OutIter>
template <typename FwdIter>
struct generate_n: public detail::algorithm<generate_n<FwdIter>, FwdIter>
{
generate_n()
: generate_n::algorithm("generate_n")
: generate_n::algorithm("generate_n")
{}

template <typename ExPolicy, typename F>
static OutIter
sequential(ExPolicy, OutIter first, std::size_t count, F && f)
static FwdIter
sequential(ExPolicy, FwdIter first, std::size_t count, F && f)
{
return std::generate_n(first, count, f);
}

template <typename ExPolicy, typename F>
static typename util::detail::algorithm_result<
ExPolicy, OutIter
ExPolicy, FwdIter
>::type
parallel(ExPolicy && policy, OutIter first, std::size_t count,
parallel(ExPolicy && policy, FwdIter first, std::size_t count,
F && f)
{
typedef typename std::iterator_traits<OutIter>::value_type type;
typedef typename std::iterator_traits<FwdIter>::value_type type;

return
for_each_n<OutIter>().call(
for_each_n<FwdIter>().call(
std::forward<ExPolicy>(policy),
std::false_type(), first, count,
[f](type& v) mutable
Expand All @@ -211,9 +212,9 @@ namespace hpx { namespace parallel { inline namespace v1
/// It describes the manner in which the execution
/// of the algorithm may be parallelized and the manner
/// in which it executes the assignments.
/// \tparam OutIter The type of the source iterators used (deduced).
/// \tparam FwdIter The type of the source iterators used (deduced).
/// This iterator type must meet the requirements of an
/// output iterator.
/// forward iterator.
/// \tparam F The type of the function/function object to use
/// (deduced). Unlike its sequential form, the parallel
/// overload of \a equal requires \a F to meet the
Expand Down Expand Up @@ -245,37 +246,45 @@ namespace hpx { namespace parallel { inline namespace v1
/// fashion in unspecified threads, and indeterminately sequenced
/// within each thread.
///
/// \returns The \a replace_if algorithm returns a \a hpx::future<OutIter>
/// \returns The \a replace_if algorithm returns a \a hpx::future<FwdIter>
/// if the execution policy is of type
/// \a sequenced_task_policy or
/// \a parallel_task_policy
/// and returns \a OutIter otherwise.
/// and returns \a FwdIter otherwise.
/// It returns \a last.
///
template <typename ExPolicy, typename OutIter, typename Size, typename F,
template <typename ExPolicy, typename FwdIter, typename Size, typename F,
HPX_CONCEPT_REQUIRES_(
execution::is_execution_policy<ExPolicy>::value &&
hpx::traits::is_iterator<OutIter>::value)>
typename util::detail::algorithm_result<ExPolicy, OutIter>::type
generate_n(ExPolicy && policy, OutIter first, Size count, F && f)
hpx::traits::is_iterator<FwdIter>::value)>
typename util::detail::algorithm_result<ExPolicy, FwdIter>::type
generate_n(ExPolicy && policy, FwdIter first, Size count, F && f)
{
#if defined(HPX_HAVE_ALGORITHM_INPUT_ITERATOR_SUPPORT)
static_assert(
(hpx::traits::is_output_iterator<OutIter>::value ||
hpx::traits::is_forward_iterator<OutIter>::value),
(hpx::traits::is_output_iterator<FwdIter>::value ||
hpx::traits::is_forward_iterator<FwdIter>::value),
"Required at least output iterator.");

typedef std::integral_constant<bool,
execution::is_sequenced_execution_policy<ExPolicy>::value ||
!hpx::traits::is_forward_iterator<FwdIter>::value
> is_seq;
#else
static_assert(
(hpx::traits::is_forward_iterator<FwdIter>::value),
"Required at least forward iterator.");

typedef execution::is_sequenced_execution_policy<ExPolicy> is_seq;
#endif

if (detail::is_negative(count))
{
return util::detail::algorithm_result<ExPolicy, OutIter>::get(
return util::detail::algorithm_result<ExPolicy, FwdIter>::get(
std::move(first));
}

typedef std::integral_constant<bool,
execution::is_sequenced_execution_policy<ExPolicy>::value ||
!hpx::traits::is_forward_iterator<OutIter>::value
> is_seq;

return detail::generate_n<OutIter>().call(
return detail::generate_n<FwdIter>().call(
std::forward<ExPolicy>(policy), is_seq(),
first, std::size_t(count), std::forward<F>(f));
}
Expand Down
49 changes: 30 additions & 19 deletions hpx/parallel/algorithms/includes.hpp
@@ -1,4 +1,4 @@
// Copyright (c) 2007-2016 Hartmut Kaiser
// Copyright (c) 2007-2017 Hartmut Kaiser
//
// 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 Down Expand Up @@ -94,10 +94,10 @@ namespace hpx { namespace parallel { inline namespace v1
return first;
}

template <typename InIter1, typename InIter2, typename F,
template <typename FwdIter1, typename FwdIter2, typename F,
typename CancelToken>
bool sequential_includes(InIter1 first1, InIter1 last1, InIter2 first2,
InIter2 last2, F && f, CancelToken& tok)
bool sequential_includes(FwdIter1 first1, FwdIter1 last1, FwdIter2 first2,
FwdIter2 last2, F && f, CancelToken& tok)
{
while (first2 != last2)
{
Expand All @@ -121,11 +121,11 @@ namespace hpx { namespace parallel { inline namespace v1
: includes::algorithm("includes")
{}

template <typename ExPolicy, typename InIter1, typename InIter2,
template <typename ExPolicy, typename FwdIter1, typename FwdIter2,
typename F>
static bool
sequential(ExPolicy, InIter1 first1, InIter1 last1,
InIter2 first2, InIter2 last2, F && f)
sequential(ExPolicy, FwdIter1 first1, FwdIter1 last1,
FwdIter2 first2, FwdIter2 last2, F && f)
{
return std::includes(first1, last1, first2, last2,
std::forward<F>(f));
Expand Down Expand Up @@ -223,14 +223,14 @@ namespace hpx { namespace parallel { inline namespace v1
/// It describes the manner in which the execution
/// of the algorithm may be parallelized and the manner
/// in which it executes the assignments.
/// \tparam InIter1 The type of the source iterators used for the
/// \tparam FwdIter1 The type of the source iterators used for the
/// first range (deduced).
/// This iterator type must meet the requirements of an
/// input iterator.
/// \tparam InIter2 The type of the source iterators used for the
/// forward iterator.
/// \tparam FwdIter2 The type of the source iterators used for the
/// second range (deduced).
/// This iterator type must meet the requirements of an
/// input iterator.
/// forward iterator.
/// \tparam Pred The type of an optional function/function object to use.
/// Unlike its sequential form, the parallel
/// overload of \a includes requires \a Pred to meet the
Expand All @@ -257,7 +257,7 @@ namespace hpx { namespace parallel { inline namespace v1
/// 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 InIter1 and \a InIter2 can
/// that objects of types \a FwdIter1 and \a FwdIter2 can
/// be dereferenced and then implicitly converted to
/// \a Type1 and \a Type2 respectively
///
Expand All @@ -280,27 +280,38 @@ namespace hpx { namespace parallel { inline namespace v1
/// sorted range [first2, last2) is found within the sorted range
/// [first1, last1). Also returns true if [first2, last2) is empty.
///
template <typename ExPolicy, typename InIter1, typename InIter2,
template <typename ExPolicy, typename FwdIter1, typename FwdIter2,
typename Pred = detail::less>
inline typename std::enable_if<
execution::is_execution_policy<ExPolicy>::value,
typename util::detail::algorithm_result<ExPolicy, bool>::type
>::type
includes(ExPolicy&& policy, InIter1 first1, InIter1 last1,
InIter2 first2, InIter2 last2, Pred && op = Pred())
includes(ExPolicy&& policy, FwdIter1 first1, FwdIter1 last1,
FwdIter2 first2, FwdIter2 last2, Pred && op = Pred())
{
#if defined(HPX_HAVE_ALGORITHM_INPUT_ITERATOR_SUPPORT)
static_assert(
(hpx::traits::is_input_iterator<InIter1>::value),
(hpx::traits::is_input_iterator<FwdIter1>::value),
"Requires at least input iterator.");
static_assert(
(hpx::traits::is_input_iterator<InIter2>::value),
(hpx::traits::is_input_iterator<FwdIter2>::value),
"Requires at least input iterator.");

typedef std::integral_constant<bool,
execution::is_sequenced_execution_policy<ExPolicy>::value ||
!hpx::traits::is_forward_iterator<InIter1>::value ||
!hpx::traits::is_forward_iterator<InIter2>::value
!hpx::traits::is_forward_iterator<FwdIter1>::value ||
!hpx::traits::is_forward_iterator<FwdIter2>::value
> is_seq;
#else
static_assert(
(hpx::traits::is_forward_iterator<FwdIter1>::value),
"Requires at least forward iterator.");
static_assert(
(hpx::traits::is_forward_iterator<FwdIter2>::value),
"Requires at least forward iterator.");

typedef execution::is_sequenced_execution_policy<ExPolicy> is_seq;
#endif

return detail::includes().call(
std::forward<ExPolicy>(policy), is_seq(),
Expand Down
33 changes: 13 additions & 20 deletions hpx/parallel/algorithms/inner_product.hpp
@@ -1,4 +1,5 @@
// Copyright (c) 2015 Daniel Bourgeois
// Copyright (c) 2017 Hartmut Kaiser
//
// 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 Down Expand Up @@ -32,16 +33,12 @@ namespace hpx { namespace parallel { inline namespace v1
/// It describes the manner in which the execution
/// of the algorithm may be parallelized and the manner
/// in which it executes the assignments.
/// \tparam InIter1 The type of the first source iterators used
/// \tparam FwdIter1 The type of the first source iterators used
/// (deduced). This iterator type must meet the
/// requirements of an input iterator.
/// \tparam InIter2 The type of the second source iterators used
/// \tparam FwdIter2 The type of the second source iterators used
/// (deduced). This iterator type must meet the
/// requirements of an input iterator.
/// \tparam OutIter The type of the iterator representing the
/// destination range (deduced).
/// This iterator type must meet the requirements of an
/// output iterator.
/// \tparam T The type of the value to be used as return)
/// values (deduced).
/// \param policy The execution policy to use for the scheduling of
Expand Down Expand Up @@ -73,13 +70,13 @@ namespace hpx { namespace parallel { inline namespace v1
/// \note This function is deprecated and is replaced by the binary version
/// of \a transform_reduce.
///
template <typename ExPolicy, typename InIter1, typename InIter2, typename T>
template <typename ExPolicy, typename FwdIter1, typename FwdIter2, typename T>
inline typename std::enable_if<
is_execution_policy<ExPolicy>::value,
typename util::detail::algorithm_result<ExPolicy, T>::type
>::type
inner_product(ExPolicy&& policy, InIter1 first1, InIter1 last1,
InIter2 first2, T init)
inner_product(ExPolicy&& policy, FwdIter1 first1, FwdIter1 last1,
FwdIter2 first2, T init)
{
return transform_reduce(
std::forward<ExPolicy>(policy), first1, last1, first2,
Expand All @@ -97,16 +94,12 @@ namespace hpx { namespace parallel { inline namespace v1
/// It describes the manner in which the execution
/// of the algorithm may be parallelized and the manner
/// in which it executes the assignments.
/// \tparam InIter1 The type of the first source iterators used
/// \tparam FwdIter1 The type of the first source iterators used
/// (deduced). This iterator type must meet the
/// requirements of an input iterator.
/// \tparam InIter2 The type of the second source iterators used
/// requirements of an forward iterator.
/// \tparam FwdIter2 The type of the second source iterators used
/// (deduced). This iterator type must meet the
/// requirements of an input iterator.
/// \tparam OutIter The type of the iterator representing the
/// destination range (deduced).
/// This iterator type must meet the requirements of an
/// output iterator.
/// requirements of an forward iterator.
/// \tparam T The type of the value to be used as return)
/// values (deduced).
/// \tparam Op1 The type of the binary function object used for
Expand Down Expand Up @@ -171,14 +164,14 @@ namespace hpx { namespace parallel { inline namespace v1
/// \note This function is deprecated and is replaced by the binary version
/// of \a transform_reduce.
///
template <typename ExPolicy, typename InIter1, typename InIter2, typename T,
template <typename ExPolicy, typename FwdIter1, typename FwdIter2, typename T,
typename Op1, typename Op2>
inline typename std::enable_if<
is_execution_policy<ExPolicy>::value,
typename util::detail::algorithm_result<ExPolicy, T>::type
>::type
inner_product(ExPolicy&& policy, InIter1 first1, InIter1 last1,
InIter2 first2, T init, Op1 && op1, Op2 && op2)
inner_product(ExPolicy&& policy, FwdIter1 first1, FwdIter1 last1,
FwdIter2 first2, T init, Op1 && op1, Op2 && op2)
{
return transform_reduce(
std::forward<ExPolicy>(policy), first1, last1, first2,
Expand Down

0 comments on commit 5cd77b0

Please sign in to comment.