Skip to content

Commit

Permalink
More fixes to executor and executor parameters handling
Browse files Browse the repository at this point in the history
  • Loading branch information
hkaiser committed Jun 29, 2016
1 parent f5adc6e commit 14e101a
Show file tree
Hide file tree
Showing 7 changed files with 326 additions and 232 deletions.
2 changes: 1 addition & 1 deletion hpx/parallel/executors/executor_information_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)

///////////////////////////////////////////////////////////////////////
template <typename Parameters>
std::size_t call_processing_units_parameter_count(Parameters& params);
std::size_t call_processing_units_parameter_count(Parameters && params);

struct processing_units_count_helper
{
Expand Down
210 changes: 140 additions & 70 deletions hpx/parallel/executors/executor_parameter_traits.hpp

Large diffs are not rendered by default.

115 changes: 60 additions & 55 deletions hpx/parallel/executors/executor_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <hpx/traits/detail/wrap_int.hpp>
#include <hpx/traits/is_executor.hpp>
#include <hpx/util/always_void.hpp>
#include <hpx/util/decay.hpp>
#include <hpx/util/deferred_call.hpp>
#include <hpx/util/invoke.hpp>
#include <hpx/util/unwrapped.hpp>
Expand Down Expand Up @@ -134,14 +135,14 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)
struct apply_helper
{
template <typename Executor, typename F, typename ... Ts>
static void call(hpx::traits::detail::wrap_int, Executor& exec,
static void call(hpx::traits::detail::wrap_int, Executor&& exec,
F && f, Ts &&... ts)
{
exec.async_execute(std::forward<F>(f), std::forward<Ts>(ts)...);
}

template <typename Executor, typename F, typename ... Ts>
static auto call(int, Executor& exec, F && f, Ts &&... ts)
static auto call(int, Executor&& exec, F && f, Ts &&... ts)
-> decltype(
exec.apply_execute(std::forward<F>(f), std::forward<Ts>(ts)...)
)
Expand All @@ -151,17 +152,17 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)
};

template <typename Executor, typename F, typename ... Ts>
void call_apply_execute(Executor& exec, F && f, Ts && ... ts)
void call_apply_execute(Executor&& exec, F && f, Ts && ... ts)
{
apply_helper::call(0, exec, std::forward<F>(f),
std::forward<Ts>(ts)...);
apply_helper::call(0, std::forward<Executor>(exec),
std::forward<F>(f), std::forward<Ts>(ts)...);
}

///////////////////////////////////////////////////////////////////////
struct execute_helper
{
template <typename Executor, typename F, typename ... Ts>
static auto call_impl(Executor& exec, F && f, std::false_type,
static auto call_impl(Executor&& exec, F && f, std::false_type,
Ts &&... ts)
-> decltype(
hpx::util::invoke(std::forward<F>(f), std::forward<Ts>(ts)...)
Expand Down Expand Up @@ -215,7 +216,7 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)
}

template <typename Executor, typename F, typename ... Ts>
static void call_impl(Executor& exec, F && f, std::true_type,
static void call_impl(Executor&& exec, F && f, std::true_type,
Ts &&... ts)
{
exec.async_execute(
Expand All @@ -224,7 +225,7 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)
}

template <typename Executor, typename F, typename ... Ts>
static auto call(hpx::traits::detail::wrap_int, Executor& exec,
static auto call(hpx::traits::detail::wrap_int, Executor&& exec,
F && f, Ts &&... ts)
-> decltype(
hpx::util::invoke(std::forward<F>(f), std::forward<Ts>(ts)...)
Expand All @@ -235,12 +236,12 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)
F(Ts&&...)
>::type
> is_void;
return call_impl(exec, std::forward<F>(f), is_void(),
std::forward<Ts>(ts)...);
return call_impl(std::forward<Executor>(exec),
std::forward<F>(f), is_void(), std::forward<Ts>(ts)...);
}

template <typename Executor, typename F, typename ... Ts>
static auto call(int, Executor& exec, F && f, Ts &&... ts)
static auto call(int, Executor&& exec, F && f, Ts &&... ts)
-> decltype(
exec.execute(std::forward<F>(f), std::forward<Ts>(ts)...)
)
Expand All @@ -251,18 +252,18 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)
};

template <typename Executor, typename F, typename ... Ts>
auto call_execute(Executor& exec, F && f, Ts &&... ts)
auto call_execute(Executor&& exec, F && f, Ts &&... ts)
#if defined(HPX_ENABLE_WORKAROUND_FOR_GCC46)
-> typename hpx::util::detail::deferred_result_of<F(Ts&&...)>::type
#else
-> decltype(
execute_helper::call(0, exec, std::forward<F>(f),
std::forward<Ts>(ts)...)
execute_helper::call(0, std::forward<Executor>(exec),
std::forward<F>(f), std::forward<Ts>(ts)...)
)
#endif
{
return execute_helper::call(0, exec, std::forward<F>(f),
std::forward<Ts>(ts)...);
return execute_helper::call(0, std::forward<Executor>(exec),
std::forward<F>(f), std::forward<Ts>(ts)...);
}

///////////////////////////////////////////////////////////////////////
Expand All @@ -287,14 +288,14 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)
{
template <typename Executor, typename F, typename S, typename ... Ts>
static auto
call(hpx::traits::detail::wrap_int, Executor& exec, F && f,
call(hpx::traits::detail::wrap_int, Executor&& exec, F && f,
S const& shape, Ts &&... ts)
-> std::vector<decltype(
exec.async_execute(f, *boost::begin(shape), ts...)
)>
{
std::vector<typename future_type<
Executor,
typename hpx::util::decay<Executor>::type,
typename bulk_async_execute_result<F, S, Ts...>::type
>::type> results;
results.reserve(boost::size(shape));
Expand All @@ -309,7 +310,7 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)

template <typename Executor, typename F, typename S, typename ... Ts>
static auto
call(int, Executor& exec, F && f, S const& shape, Ts &&... ts)
call(int, Executor&& exec, F && f, S const& shape, Ts &&... ts)
-> decltype(
exec.bulk_async_execute(std::forward<F>(f), shape,
std::forward<Ts>(ts)...)
Expand All @@ -321,22 +322,23 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)
};

template <typename Executor, typename F, typename S, typename ... Ts>
auto call_bulk_async_execute(Executor& exec, F && f, S const& shape,
auto call_bulk_async_execute(Executor&& exec, F && f, S const& shape,
Ts &&... ts)
#if defined(HPX_ENABLE_WORKAROUND_FOR_GCC46)
-> std::vector<typename future_type<
Executor,
typename hpx::util::decay<Executor>::type,
typename bulk_async_execute_result<F, S, Ts...>::type
>::type>
#else
-> decltype(
bulk_async_execute_helper::call(0, exec, std::forward<F>(f),
shape, std::forward<Ts>(ts)...)
bulk_async_execute_helper::call(0, std::forward<Executor>(exec),
std::forward<F>(f), shape, std::forward<Ts>(ts)...)
)
#endif
{
return bulk_async_execute_helper::call(
0, exec, std::forward<F>(f), shape, std::forward<Ts>(ts)...);
0, std::forward<Executor>(exec), std::forward<F>(f), shape,
std::forward<Ts>(ts)...);
}

///////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -383,14 +385,14 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)
{
// returns void if F returns void
template <typename Executor, typename F, typename S, typename ... Ts>
static auto call(hpx::traits::detail::wrap_int, Executor& exec,
static auto call(hpx::traits::detail::wrap_int, Executor&& exec,
F && f, S const& shape, Ts &&... ts)
-> typename bulk_result_helper<decltype(
exec.async_execute(f, *boost::begin(shape), ts...).get()
)>::type
{
std::vector<typename future_type<
Executor,
typename hpx::util::decay<Executor>::type,
typename bulk_async_execute_result<F, S, Ts...>::type
>::type> results;
results.reserve(boost::size(shape));
Expand All @@ -414,7 +416,7 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)

template <typename Executor, typename F, typename S, typename ... Ts>
static auto
call(int, Executor& exec, F && f, S const& shape, Ts &&... ts)
call(int, Executor&& exec, F && f, S const& shape, Ts &&... ts)
-> decltype(
exec.bulk_execute(std::forward<F>(f), shape,
std::forward<Ts>(ts)...)
Expand All @@ -426,18 +428,18 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)
};

template <typename Executor, typename F, typename S, typename ... Ts>
auto call_bulk_execute(Executor& exec, F && f, S const& shape, Ts &&... ts)
auto call_bulk_execute(Executor&& exec, F && f, S const& shape, Ts &&... ts)
#if defined(HPX_ENABLE_WORKAROUND_FOR_GCC46)
-> typename detail::bulk_execute_result<F, S, Ts...>::type
#else
-> decltype(
bulk_execute_helper::call(0, exec, std::forward<F>(f), shape,
std::forward<Ts>(ts)...)
bulk_execute_helper::call(0, std::forward<Executor>(exec),
std::forward<F>(f), shape, std::forward<Ts>(ts)...)
)
#endif
{
return bulk_execute_helper::call(0, exec, std::forward<F>(f), shape,
std::forward<Ts>(ts)...);
return bulk_execute_helper::call(0, std::forward<Executor>(exec),
std::forward<F>(f), shape, std::forward<Ts>(ts)...);
}
/// \endcond
}
Expand Down Expand Up @@ -502,11 +504,11 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)
/// it calls exec.async_execute() while discarding the returned
/// future
///
template <typename F, typename ... Ts>
static void apply_execute(executor_type& exec, F && f, Ts &&... ts)
template <typename Executor_, typename F, typename ... Ts>
static void apply_execute(Executor_ && exec, F && f, Ts &&... ts)
{
detail::call_apply_execute(exec, std::forward<F>(f),
std::forward<Ts>(ts)...);
detail::call_apply_execute(std::forward<Executor_>(exec),
std::forward<F>(f), std::forward<Ts>(ts)...);
}

/// \brief Singleton form of asynchronous execution agent creation.
Expand All @@ -529,8 +531,8 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)
///
/// \returns f(ts...)'s result through a future
///
template <typename F, typename ... Ts>
static auto async_execute(executor_type& exec, F && f, Ts &&... ts)
template <typename Executor_, typename F, typename ... Ts>
static auto async_execute(Executor_ && exec, F && f, Ts &&... ts)
#if defined(HPX_ENABLE_WORKAROUND_FOR_GCC46)
-> typename future<
typename hpx::util::detail::deferred_result_of<F(Ts&&...)>::type
Expand Down Expand Up @@ -561,19 +563,19 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)
/// \note This calls exec.execute(f) if it exists;
/// otherwise hpx::async(f).get()
///
template <typename F, typename ... Ts>
static auto execute(executor_type& exec, F && f, Ts &&...ts)
template <typename Executor_, typename F, typename ... Ts>
static auto execute(Executor_ && exec, F && f, Ts &&...ts)
#if defined(HPX_ENABLE_WORKAROUND_FOR_GCC46)
-> typename hpx::util::detail::deferred_result_of<F(Ts&&...)>::type
#else
-> decltype(
detail::call_execute(exec, std::forward<F>(f),
std::forward<Ts>(ts)...)
detail::call_execute(std::forward<Executor_>(exec),
std::forward<F>(f), std::forward<Ts>(ts)...)
)
#endif
{
return detail::call_execute(exec, std::forward<F>(f),
std::forward<Ts>(ts)...);
return detail::call_execute(std::forward<Executor_>(exec),
std::forward<F>(f), std::forward<Ts>(ts)...);
}

/// \brief Bulk form of asynchronous execution agent creation
Expand Down Expand Up @@ -603,23 +605,25 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)
/// \note This calls exec.async_execute(f, shape) if it exists;
/// otherwise it executes hpx::async(f, i) as often as needed.
///
template <typename F, typename Shape, typename ... Ts>
template <typename Executor_, typename F, typename Shape,
typename ... Ts>
static auto
bulk_async_execute(executor_type& exec, F && f, Shape const& shape,
bulk_async_execute(Executor_ && exec, F && f, Shape const& shape,
Ts &&... ts)
#if defined(HPX_ENABLE_WORKAROUND_FOR_GCC46)
-> std::vector<typename future<
typename detail::bulk_async_execute_result<F, Shape, Ts...>::type
>::type>
#else
-> decltype(
detail::call_bulk_async_execute(exec, std::forward<F>(f),
shape, std::forward<Ts>(ts)...)
detail::call_bulk_async_execute(std::forward<Executor_>(exec),
std::forward<F>(f), shape, std::forward<Ts>(ts)...)
)
#endif
{
return detail::call_bulk_async_execute(
exec, std::forward<F>(f), shape, std::forward<Ts>(ts)...);
std::forward<Executor_>(exec), std::forward<F>(f), shape,
std::forward<Ts>(ts)...);
}

/// \brief Bulk form of synchronous execution agent creation
Expand Down Expand Up @@ -650,20 +654,21 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)
/// \note This calls exec.execute(f, shape) if it exists;
/// otherwise it executes hpx::async(f, i) as often as needed.
///
template <typename F, typename Shape, typename ... Ts>
template <typename Executor_, typename F, typename Shape,
typename ... Ts>
static auto
bulk_execute(executor_type& exec, F && f, Shape const& shape, Ts &&... ts)
bulk_execute(Executor_ && exec, F && f, Shape const& shape, Ts &&... ts)
#if defined(HPX_ENABLE_WORKAROUND_FOR_GCC46)
-> typename detail::bulk_execute_result<F, Shape, Ts...>::type
#else
-> decltype(
detail::call_bulk_execute(exec, std::forward<F>(f), shape,
std::forward<Ts>(ts)...)
detail::call_bulk_execute(std::forward<Executor_>(exec),
std::forward<F>(f), shape, std::forward<Ts>(ts)...)
)
#endif
{
return detail::call_bulk_execute(exec, std::forward<F>(f), shape,
std::forward<Ts>(ts)...);
return detail::call_bulk_execute(std::forward<Executor_>(exec),
std::forward<F>(f), shape, std::forward<Ts>(ts)...);
}
};

Expand Down
2 changes: 1 addition & 1 deletion hpx/parallel/executors/parallel_executor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)
template <typename F, typename ... Ts>
hpx::future<
typename hpx::util::detail::deferred_result_of<F(Ts&&...)>::type>
async_execute(F && f, Ts &&... ts)
async_execute(F && f, Ts &&... ts) const
{
return hpx::async(l_, std::forward<F>(f), std::forward<Ts>(ts)...);
}
Expand Down

0 comments on commit 14e101a

Please sign in to comment.