Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Implemented segmented algorithms for partitioned vector #2725

Merged
merged 45 commits into from Jul 24, 2017
Merged
Show file tree
Hide file tree
Changes from 44 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
80fc2a4
Implemented segmented algorithms extending existing parallel algorithms
Jun 21, 2017
ba65be9
Squashed commit of the following:
Jun 21, 2017
49b92cc
Updated file headers
Jun 21, 2017
2f08111
Fixed Inspect errors
Jun 21, 2017
ced4b85
Merge branch 'master' of git://github.com/STEllAR-GROUP/hpx into STEl…
Jun 21, 2017
183c99c
Merge branch 'STEllAR-GROUP-master'
Jun 21, 2017
289f19a
Minor fix to for_Each to fix merge error
Jun 22, 2017
29985e0
Minor fix to all algorithms to fix merge error
Jun 22, 2017
3bf5560
Minor fix to transform to fix merge error
Jun 22, 2017
7d25ce9
Minor fix to transform to fix merge error
Jun 22, 2017
20d0e95
Minor fix to related to inline namespace merge error
Jun 22, 2017
412b047
Minor fix to related to with handle exception in parallel segmented a…
Jun 22, 2017
2ba4c23
Merge branch 'master' of git://github.com/STEllAR-GROUP/hpx into STEl…
Jun 28, 2017
c0e46ce
Merge branch 'STEllAR-GROUP-master'
Jun 28, 2017
de95410
Fixed Inspect errors related to missing or deprecated includes
Jun 28, 2017
b296c2e
Refixed Inspect errors related to missing includes
Jun 28, 2017
6a199f5
Fixed issues related to PR review
Jun 30, 2017
7402061
More fixes for PR
Jun 30, 2017
87b0ac5
PR request issue fixes
Jul 1, 2017
7d05f47
Minor fix to for_each
Jul 1, 2017
6dc4b74
Minor fix to for_each
Jul 1, 2017
3050b25
Minor fix to transform
Jul 1, 2017
ecc31e2
Minor fix to transform
Jul 1, 2017
0551850
Minor fix to transform
Jul 1, 2017
cf194a4
Minor fix to transform
Jul 1, 2017
66d4f53
Minor fix to for_Each
Jul 1, 2017
3a38cbc
Squashed commit of the following:
Jul 1, 2017
de1a5d7
Replaced operator- with std::distance in segmenetd transform
Jul 5, 2017
58efd17
Merge branch 'PRIssues'
Jul 5, 2017
6262c28
PRIssue fixed include oerder issue
Jul 5, 2017
c26956b
Fixed error with init in segmented_reduce
Jul 12, 2017
922359d
Initial reduce and transform_reduce change
Jul 13, 2017
a83d652
Updated segmented reduce and transform_reduce to handle init values c…
Jul 14, 2017
878dd51
Replaced boost begin and end with std and fixed inspect errors
Jul 14, 2017
f78abad
Refactored segmented reduce and transform_reduce functor to call new …
Jul 14, 2017
e34fc2d
Merge branch 'master' of https://github.com/STEllAR-GROUP/hpx
Jul 17, 2017
a73f70c
Fixed merge errors
Jul 17, 2017
079c201
Errors with segmented transform and transform_scan fixed
Jul 19, 2017
1da3b95
Merge branch 'master' into master
Jul 19, 2017
566a3b1
Changed auto p to auto && p in segmented dispatch
Jul 19, 2017
10df23f
Changes according to PR review
Jul 21, 2017
e1a9128
Merge branch 'master' into master
Jul 21, 2017
0547a23
part iterator end check indentation changes
Jul 23, 2017
a513cde
Merge branch 'master' of github.com:ajaivgeorge/hpx
Jul 23, 2017
db2111d
Merge branch 'master' into master
Jul 24, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 0 additions & 1 deletion hpx/include/parallel_for_each.hpp
Expand Up @@ -12,4 +12,3 @@
#include <hpx/parallel/segmented_algorithms/for_each.hpp>

#endif

2 changes: 1 addition & 1 deletion hpx/include/parallel_reduce.hpp
Expand Up @@ -8,7 +8,7 @@
#define HPX_PARALLEL_REDUCE_JUN_28_2014_0827AM

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this change?

#include <hpx/parallel/algorithms/reduce.hpp>
#include <hpx/parallel/segmented_algorithms/reduce.hpp>
#include <hpx/parallel/algorithms/reduce_by_key.hpp>

#endif

3 changes: 1 addition & 2 deletions hpx/include/parallel_transform.hpp
Expand Up @@ -9,6 +9,5 @@

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no need to modify the include guards on every edit.

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

#include <hpx/parallel/segmented_algorithms/transform.hpp>
#endif

4 changes: 2 additions & 2 deletions hpx/include/parallel_transform_scan.hpp
Expand Up @@ -8,6 +8,6 @@

#include <hpx/parallel/algorithms/transform_exclusive_scan.hpp>
#include <hpx/parallel/algorithms/transform_inclusive_scan.hpp>

#include <hpx/parallel/segmented_algorithms/transform_inclusive_scan.hpp>
#include <hpx/parallel/segmented_algorithms/transform_exclusive_scan.hpp>
#endif

17 changes: 17 additions & 0 deletions hpx/parallel/algorithms/detail/dispatch.hpp
Expand Up @@ -18,6 +18,7 @@
#include <hpx/parallel/executors/execution.hpp>
#include <hpx/parallel/util/detail/algorithm_result.hpp>
#include <hpx/parallel/util/detail/scoped_executor_parameters.hpp>
#include <hpx/util/tuple.hpp>

#include <string>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please keep an empty line between the HPX headers and the std headers. This prevents clang-format from sorting those two groups of headers files into one block.

#include <type_traits>
Expand Down Expand Up @@ -50,6 +51,22 @@ namespace hpx { namespace parallel { inline namespace v1 { namespace detail
typedef std::pair<type1, type2> type;
};

template <typename Result1, typename Result2, typename Result3>
struct local_algorithm_result<hpx::util::tuple<Result1, Result2, Result3> >
{
typedef typename hpx::traits::segmented_local_iterator_traits<
Result1
>::local_raw_iterator type1;
typedef typename hpx::traits::segmented_local_iterator_traits<
Result2
>::local_raw_iterator type2;
typedef typename hpx::traits::segmented_local_iterator_traits<
Result3
>::local_raw_iterator type3;

typedef hpx::util::tuple<type1, type2, type3> type;
};

template <>
struct local_algorithm_result<void>
{
Expand Down
52 changes: 30 additions & 22 deletions hpx/parallel/algorithms/exclusive_scan.hpp
Expand Up @@ -21,6 +21,7 @@
#include <hpx/parallel/util/detail/algorithm_result.hpp>
#include <hpx/parallel/util/loop.hpp>
#include <hpx/parallel/util/partitioner.hpp>
#include <hpx/parallel/util/projection_identity.hpp>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please try to keep the headers sorted alphabetically (inside each of the blocks). Clang-format will do that for you.

#include <hpx/parallel/util/scan_partitioner.hpp>
#include <hpx/util/unused.hpp>

Expand All @@ -42,28 +43,30 @@ namespace hpx { namespace parallel { inline namespace v1

///////////////////////////////////////////////////////////////////////
// Our own version of the sequential exclusive_scan.
template <typename InIter, typename OutIter, typename T, typename Op>
template <typename InIter, typename OutIter, typename T, typename Op,
typename Conv = util::projection_identity>
OutIter sequential_exclusive_scan(InIter first, InIter last,
OutIter dest, T init, Op && op)
OutIter dest, T init, Op && op, Conv && conv = Conv())
{
T temp = init;
for (/* */; first != last; (void) ++first, ++dest)
{
init = op(init, *first);
init = hpx::util::invoke(op, init, hpx::util::invoke(conv, *first));
*dest = temp;
temp = init;
}
return dest;
}

template <typename InIter, typename OutIter, typename T, typename Op>
template <typename InIter, typename OutIter, typename T, typename Op,
typename Conv = util::projection_identity>
T sequential_exclusive_scan_n(InIter first, std::size_t count,
OutIter dest, T init, Op && op)
OutIter dest, T init, Op && op, Conv && conv = Conv())
{
T temp = init;
for (/* */; count-- != 0; (void) ++first, ++dest)
{
init = op(init, *first);
init = hpx::util::invoke(op, init, hpx::util::invoke(conv, *first));
*dest = temp;
temp = init;
}
Expand All @@ -80,21 +83,22 @@ namespace hpx { namespace parallel { inline namespace v1
{}

template <typename ExPolicy, typename InIter, typename OutIter,
typename T, typename Op>
typename T, typename Op, typename Conv = util::projection_identity>
static OutIter
sequential(ExPolicy, InIter first, InIter last, OutIter dest,
T const& init, Op && op)
T const& init, Op && op, Conv && conv = Conv())
{
return sequential_exclusive_scan(first, last, dest,
init, std::forward<Op>(op));
init, std::forward<Op>(op), std::forward<Conv>(conv));
}

template <typename ExPolicy, typename FwdIter1, typename T, typename Op>
template <typename ExPolicy, typename FwdIter1, typename T, typename Op,
typename Conv = util::projection_identity>
static typename util::detail::algorithm_result<
ExPolicy, FwdIter2
>::type
parallel(ExPolicy && policy, FwdIter1 first, FwdIter1 last,
FwdIter2 dest, T const& init, Op && op)
FwdIter2 dest, T const& init, Op && op, Conv && conv = Conv())
{
typedef util::detail::algorithm_result<ExPolicy, FwdIter2>
result;
Expand Down Expand Up @@ -146,16 +150,20 @@ namespace hpx { namespace parallel { inline namespace v1
std::forward<ExPolicy>(policy),
make_zip_iterator(first, dest), count, init,
// step 1 performs first part of scan algorithm
[op](zip_iterator part_begin, std::size_t part_size) -> T
[op, conv, last](zip_iterator part_begin,
std::size_t part_size) -> T
{
T part_init = get<0>(*part_begin++);
T part_init = hpx::util::invoke(conv, get<0>(*part_begin++));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This additionally requires a check whether part_begin has not reached the end after the increment.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure what the lambda should return if part_begin has reached the end. The only scenario where that happens is if there is a partition with two elements. I looked at an example from algorithms/reduce.hpp L72, and even here there is no such check.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should return part_init.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looked at an example from algorithms/reduce.hpp L72, and even here there is no such check.

There it is not a problem as part_size would drop to zero, thus avoiding to dereference the iterator produced by ++part_begin inside accumulate_n.


auto iters = part_begin.get_iterator_tuple();
return sequential_exclusive_scan_n(
get<0>(iters),
part_size - 1,
get<1>(iters),
part_init, op);
if(get<0>(iters) != last)
return sequential_exclusive_scan_n(
get<0>(iters),
part_size - 1,
get<1>(iters),
part_init, op, conv);
else
return part_init;
},
// step 2 propagates the partition results from left
// to right
Expand All @@ -173,10 +181,10 @@ namespace hpx { namespace parallel { inline namespace v1
};

template <typename ExPolicy, typename FwdIter1, typename FwdIter2, typename T,
typename Op>
typename Op, typename Conv = util::projection_identity>
static typename util::detail::algorithm_result<ExPolicy, FwdIter2>::type
exclusive_scan_(ExPolicy&& policy, FwdIter1 first, FwdIter1 last, FwdIter2 dest,
T const& init, Op && op, std::false_type) {
T const& init, Op && op, std::false_type, Conv && conv = Conv()) {

#if defined(HPX_HAVE_ALGORITHM_INPUT_ITERATOR_SUPPORT)
typedef std::integral_constant<bool,
Expand All @@ -199,10 +207,10 @@ namespace hpx { namespace parallel { inline namespace v1

// forward declare the segmented version of this algorithm
template <typename ExPolicy, typename FwdIter1, typename FwdIter2, typename T,
typename Op>
typename Op, typename Conv = util::projection_identity>
static typename util::detail::algorithm_result<ExPolicy, FwdIter2>::type
exclusive_scan_(ExPolicy&& policy, FwdIter1 first, FwdIter1 last, FwdIter2 dest,
T const& init, Op && op, std::true_type);
T const& init, Op && op, std::true_type, Conv && conv = Conv());
/// \endcond
}

Expand Down
60 changes: 48 additions & 12 deletions hpx/parallel/algorithms/for_each.hpp
Expand Up @@ -176,6 +176,50 @@ namespace hpx { namespace parallel { inline namespace v1
std::move(first));
}
};
/// Non Segmented implementation
template <typename ExPolicy, typename FwdIter, typename Size, typename F,
typename Proj>
typename util::detail::algorithm_result<ExPolicy, FwdIter>::type
for_each_n_(ExPolicy && policy, FwdIter first, Size count, F && f,
std::false_type, Proj && proj)
{
#if defined(HPX_HAVE_ALGORITHM_INPUT_ITERATOR_SUPPORT)
typedef std::integral_constant<bool,
parallel::execution::is_sequenced_execution_policy<
ExPolicy
>::value ||
!hpx::traits::is_forward_iterator<FwdIter>::value
> is_seq;
#else
typedef parallel::execution::is_sequenced_execution_policy<ExPolicy>
is_seq;
#endif
return detail::for_each_n<FwdIter>().call(
std::forward<ExPolicy>(policy), is_seq(),
first, std::size_t(count), std::forward<F>(f),
std::forward<Proj>(proj));
}
// forward declare the segmented version of for_each_ algorithm
template <typename ExPolicy, typename SegIter, typename F,
typename Proj>
inline typename util::detail::algorithm_result<ExPolicy, SegIter>::type
for_each_(ExPolicy && policy, SegIter first, SegIter last, F && f,
Proj && proj, std::true_type);

/// Segmented implementaion using for_each.
template <typename ExPolicy, typename FwdIter, typename Size, typename F,
typename Proj>
typename util::detail::algorithm_result<ExPolicy, FwdIter>::type
for_each_n_(ExPolicy && policy, FwdIter first, Size count, F && f,
std::true_type, Proj && proj)
{
auto last = first;
detail::advance(last, std::size_t(count));
return for_each_(
std::forward<ExPolicy>(policy),
first, last, std::forward<F>(f), std::forward<Proj>(proj),
std::true_type());
}
/// \endcond
}

Expand Down Expand Up @@ -292,10 +336,10 @@ namespace hpx { namespace parallel { inline namespace v1
std::move(first));
}

return detail::for_each_n<FwdIter>().call(
std::forward<ExPolicy>(policy), is_seq(),
first, std::size_t(count), std::forward<F>(f),
std::forward<Proj>(proj));
typedef hpx::traits::is_segmented_iterator<FwdIter> is_segmented;

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

///////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -373,14 +417,6 @@ namespace hpx { namespace parallel { inline namespace v1
std::forward<ExPolicy>(policy), is_seq(),
first, last, std::forward<F>(f), std::forward<Proj>(proj));
}

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

/// \endcond
}

Expand Down