Skip to content

Commit

Permalink
First steps towards implementing execution par_unseq
Browse files Browse the repository at this point in the history
  • Loading branch information
hkaiser committed Dec 8, 2017
1 parent 82f7b28 commit 6e09c6e
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 9 deletions.
45 changes: 42 additions & 3 deletions hpx/parallel/algorithms/for_each.hpp
Expand Up @@ -70,7 +70,42 @@ namespace hpx { namespace parallel { inline namespace v1
call(T && t)
{
auto tmp = hpx::util::invoke(proj_, std::forward<T>(t));
hpx::util::invoke_r<void>(f_,tmp);
hpx::util::invoke_r<void>(f_, tmp);
}

template <typename Iter>
HPX_HOST_DEVICE HPX_FORCEINLINE
void operator()(Iter curr)
{
call(*curr);
}
};

template <typename F>
struct invoke_projected<F, parallel::util::projection_identity>
{
typename hpx::util::decay<F>::type& f_;
parallel::util::projection_identity proj_; // unused

template <typename T>
HPX_HOST_DEVICE HPX_FORCEINLINE
typename std::enable_if<
!hpx::traits::is_value_proxy<T>::value
>::type
call(T && t)
{
hpx::util::invoke(f_, std::forward<T>(t));
}

template <typename T>
HPX_HOST_DEVICE HPX_FORCEINLINE
typename std::enable_if<
hpx::traits::is_value_proxy<T>::value
>::type
call(T && t)
{
auto tmp = std::forward<T>(t);
hpx::util::invoke_r<void>(f_, tmp);
}

template <typename Iter>
Expand Down Expand Up @@ -148,7 +183,8 @@ namespace hpx { namespace parallel { inline namespace v1
F && f, Proj && proj/* = Proj()*/)
{
return util::loop_n<ExPolicy>(first, count,
invoke_projected<F, Proj>{f, proj});
invoke_projected<F, typename hpx::util::decay<Proj>::type>{
f, proj});
}

template <typename ExPolicy, typename FwdIter, typename F,
Expand All @@ -173,6 +209,7 @@ namespace hpx { namespace parallel { inline namespace v1
std::move(first));
}
};

/// Non Segmented implementation
template <typename ExPolicy, typename FwdIter, typename Size, typename F,
typename Proj>
Expand All @@ -196,6 +233,7 @@ namespace hpx { namespace parallel { inline namespace v1
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>
Expand Down Expand Up @@ -358,7 +396,8 @@ namespace hpx { namespace parallel { inline namespace v1
Proj && proj)
{
return util::loop(std::forward<ExPolicy>(policy), first, last,
invoke_projected<F, Proj>{f, proj});
invoke_projected<F, typename hpx::util::decay<Proj>::type>{
f, proj});
}

template <typename ExPolicy, typename FwdIter, typename F,
Expand Down
112 changes: 106 additions & 6 deletions hpx/parallel/util/loop.hpp
Expand Up @@ -55,7 +55,7 @@ namespace hpx { namespace parallel { namespace util
///////////////////////////////////////////////////////////////////////
// Helper class to repeatedly call a function starting from a given
// iterator position.
template <typename Iterator>
template <typename ExPolicy, typename Iterator>
struct loop
{
///////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -83,21 +83,71 @@ namespace hpx { namespace parallel { namespace util
return it;
}
};

template <typename Iterator>
struct loop<parallel::execution::parallel_unsequenced_policy, Iterator>
{
///////////////////////////////////////////////////////////////////
template <typename Begin, typename End, typename F>
HPX_HOST_DEVICE HPX_FORCEINLINE
static Begin call(Begin it, End const end, F && f)
{
#if defined(HPX_MSVC)
#pragma loop(ivdep)
#elif defined(HPX_GCC_VERSION) || defined(HPX_CLANG_VERSION)
#pragma GCC ivdep
#pragma omp simd
#elif defined(HPX_INTEL_VERSION)
#pragma ivdep
#pragma omp simd
#endif
for (/**/; it != end; ++it)
{
f(it);
}
return it;
}

template <typename Begin, typename End, typename CancelToken,
typename F>
HPX_HOST_DEVICE HPX_FORCEINLINE
static Begin call(Begin it, End const end, CancelToken& tok, F && f)
{
#if defined(HPX_MSVC)
#pragma loop(ivdep)
#elif defined(HPX_GCC_VERSION) || defined(HPX_CLANG_VERSION)
#pragma GCC ivdep
#pragma omp simd
#elif defined(HPX_INTEL_VERSION)
#pragma ivdep
#pragma omp simd
#endif
for (/**/; it != end; ++it)
{
if (tok.was_cancelled())
break;
f(it);
}
return it;
}
};
}

template <typename ExPolicy, typename Begin, typename End, typename F>
HPX_HOST_DEVICE HPX_FORCEINLINE Begin
loop(ExPolicy&&, Begin begin, End end, F && f)
{
return detail::loop<Begin>::call(begin, end, std::forward<F>(f));
return detail::loop<typename std::decay<ExPolicy>::type, Begin>::
call(begin, end, std::forward<F>(f));
}

template <typename ExPolicy, typename Begin, typename End,
typename CancelToken, typename F>
HPX_HOST_DEVICE HPX_FORCEINLINE Begin
loop(ExPolicy&&, Begin begin, End end, CancelToken& tok, F && f)
{
return detail::loop<Begin>::call(begin, end, tok, std::forward<F>(f));
return detail::loop<typename std::decay<ExPolicy>::type, Begin>::
call(begin, end, tok, std::forward<F>(f));
}

///////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -142,7 +192,7 @@ namespace hpx { namespace parallel { namespace util
// Helper class to repeatedly call a function a given number of times
// starting from a given iterator position.

template <typename Iterator>
template <typename ExPolicy, typename Iterator>
struct loop_n
{
///////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -170,6 +220,54 @@ namespace hpx { namespace parallel { namespace util
}
};

template <typename Iterator>
struct loop_n<parallel::execution::parallel_unsequenced_policy, Iterator>
{
///////////////////////////////////////////////////////////////////
// handle sequences of non-futures
template <typename Iter, typename F>
HPX_HOST_DEVICE HPX_FORCEINLINE
static Iter call(Iter it, std::size_t count, F && f)
{
#if defined(HPX_MSVC)
#pragma loop(ivdep)
#elif defined(HPX_GCC_VERSION) || defined(HPX_CLANG_VERSION)
#pragma GCC ivdep
#pragma omp simd
#elif defined(HPX_INTEL_VERSION)
#pragma ivdep
#pragma omp simd
#endif
for (/**/; count != 0; (void) --count, ++it)
{
f(it);
}
return it;
}

template <typename Iter, typename CancelToken, typename F>
HPX_HOST_DEVICE HPX_FORCEINLINE
static Iter call(Iter it, std::size_t count, CancelToken& tok, F && f)
{
#if defined(HPX_MSVC)
#pragma loop(ivdep)
#elif defined(HPX_GCC_VERSION) || defined(HPX_CLANG_VERSION)
#pragma GCC ivdep
#pragma omp simd
#elif defined(HPX_INTEL_VERSION)
#pragma ivdep
#pragma omp simd
#endif
for (/**/; count != 0; (void) --count, ++it)
{
if (tok.was_cancelled())
break;
f(it);
}
return it;
}
};

///////////////////////////////////////////////////////////////////////
template <typename ExPolicy, typename T>
HPX_HOST_DEVICE HPX_FORCEINLINE
Expand Down Expand Up @@ -212,7 +310,8 @@ namespace hpx { namespace parallel { namespace util
>::type
loop_n(Iter it, std::size_t count, F && f)
{
return detail::loop_n<Iter>::call(it, count, std::forward<F>(f));
return detail::loop_n<ExPolicy, Iter>::call(it, count,
std::forward<F>(f));
}

template <typename ExPolicy, typename Iter, typename CancelToken, typename F>
Expand All @@ -222,7 +321,8 @@ namespace hpx { namespace parallel { namespace util
>::type
loop_n(Iter it, std::size_t count, CancelToken& tok, F && f)
{
return detail::loop_n<Iter>::call(it, count, tok, std::forward<F>(f));
return detail::loop_n<ExPolicy, Iter>::call(it, count, tok,
std::forward<F>(f));
}

///////////////////////////////////////////////////////////////////////////
Expand Down

0 comments on commit 6e09c6e

Please sign in to comment.