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

Generic client #1641

Merged
merged 15 commits into from Apr 4, 2016
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
2 changes: 1 addition & 1 deletion hpx/async.hpp
Expand Up @@ -103,7 +103,7 @@ namespace hpx { namespace detail
traits::detail::is_deferred_callable<F(Ts&&...)>::value,
hpx::future<typename util::detail::deferred_result_of<F(Ts&&...)>::type>
>::type
call(launch launch_policy, F&& f, Ts&&... ts)
call(launch launch_policy, F && f, Ts&&... ts)
{
typedef typename util::detail::deferred_result_of<
F(Ts&&...)
Expand Down
74 changes: 44 additions & 30 deletions hpx/lcos/async.hpp
Expand Up @@ -17,6 +17,7 @@
#include <hpx/runtime/launch_policy.hpp>
#include <hpx/runtime/naming/id_type.hpp>
#include <hpx/runtime/components/client_base.hpp>
#include <hpx/util/bind.hpp>
#include <hpx/lcos/detail/async_implementations.hpp>
#include <hpx/lcos/future.hpp>
#include <hpx/lcos/async_fwd.hpp>
Expand All @@ -26,6 +27,27 @@
///////////////////////////////////////////////////////////////////////////////
namespace hpx { namespace detail
{
///////////////////////////////////////////////////////////////////////////
template <typename Action>
struct async_action_client_dispatch
{
template <typename Client, typename Stub, typename ...Ts>
HPX_FORCEINLINE lcos::future<
typename traits::promise_local_result<
typename traits::extract_action<
Action
>::remote_result_type
>::type>
operator()(launch launch_policy,
components::client_base<Client, Stub> const& c, Ts &&... ts) const
{
HPX_ASSERT(c.is_ready());
return hpx::detail::async_impl<Action>(launch_policy, c.get_id(),
std::forward<Ts>(ts)...);
}
};

///////////////////////////////////////////////////////////////////////////
// launch
template <typename Action, typename Policy>
struct async_action_dispatch<Action, Policy,
Expand All @@ -35,7 +57,8 @@ namespace hpx { namespace detail
{
// id_type
template <typename ...Ts>
HPX_FORCEINLINE static lcos::future<
HPX_FORCEINLINE static
lcos::future<
typename traits::promise_local_result<
typename hpx::actions::extract_action<
Action
Expand All @@ -48,15 +71,17 @@ namespace hpx { namespace detail
}

template <typename Client, typename Stub, typename ...Ts>
HPX_FORCEINLINE static lcos::future<
HPX_FORCEINLINE static
lcos::future<
typename traits::promise_local_result<
typename traits::extract_action<
Action
>::remote_result_type
>::type>
call(launch launch_policy,
components::client_base<Client, Stub> const& c, Ts&&... ts)
components::client_base<Client, Stub> c, Ts&&... ts)
{
// make sure the action is compatible with the component type
typedef typename components::client_base<
Client, Stub
>::server_component_type component_type;
Expand All @@ -65,8 +90,18 @@ namespace hpx { namespace detail
static_assert(is_valid::value,
"The action to invoke is not supported by the target");

return hpx::detail::async_impl<Action>(launch_policy, c.get_id(),
std::forward<Ts>(ts)...);
// invoke directly if client is ready
if (c.is_ready())
Copy link
Member

Choose a reason for hiding this comment

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

Can't this be part of the client_base::then implementation?

Copy link
Member Author

Choose a reason for hiding this comment

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

It's an optimization which avoids creating a future<future<>> for the sole purpose of unwrapping it right away. So yes, we could simply call .then() unconditionally if we didn't care about this overhead.

Copy link
Member

Choose a reason for hiding this comment

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

What I meant is to have this optimization directly in client_base. I was under the impression we had the same we have for future<T>::then ... the only optimization we in that regard is here: https://github.com/STEllAR-GROUP/hpx/blob/master/hpx/lcos/detail/future_data.hpp#L565

I missed the part that we need to create a new future inside ::then ... sorry for the noise.

{
return hpx::detail::async_impl<Action>(
launch_policy, c.get_id(), std::forward<Ts>(ts)...);
}

// defer invocation otherwise
return c.then(util::bind(
util::one_shot(async_action_client_dispatch<Action>()),
launch_policy, c, std::forward<Ts>(ts)...
));
}

// distribution policy
Expand Down Expand Up @@ -127,17 +162,9 @@ namespace hpx { namespace detail
>::type>
call(components::client_base<Client_, Stub> const& c, Ts&&... ts)
{
typedef typename components::client_base<
Client_, Stub
>::server_component_type component_type;

typedef traits::is_valid_action<Action, component_type> is_valid;
static_assert(is_valid::value,
"The action to invoke is not supported by the target");

return async_action_dispatch<
Action, launch
>::call(launch::all, c.get_id(), std::forward<Ts>(ts)...);
>::call(launch::all, c, std::forward<Ts>(ts)...);
}
};

Expand Down Expand Up @@ -180,22 +207,9 @@ namespace hpx { namespace detail
template <typename ...Ts>
HPX_FORCEINLINE static
lcos::future<result_type>
call(launch launch_policy,
Action const&, naming::id_type const& id, Ts&&... ts)
{
return async<Action>(launch_policy, id, std::forward<Ts>(ts)...);
}

template <typename DistPolicy, typename ...Ts>
HPX_FORCEINLINE static
typename boost::enable_if_c<
traits::is_distribution_policy<DistPolicy>::value,
lcos::future<result_type>
>::type
call(launch launch_policy,
Action const&, DistPolicy const& policy, Ts&&... ts)
call(launch launch_policy, Action const&, Ts &&... ts)
{
return async<Action>(launch_policy, policy, std::forward<Ts>(ts)...);
return async<Action>(launch_policy, std::forward<Ts>(ts)...);
}
};
}}
Expand Down Expand Up @@ -290,7 +304,7 @@ namespace hpx { namespace detail
{
template <typename F, typename ...Ts>
HPX_FORCEINLINE static auto
call(launch const& launch_policy, F&& f, Ts&&... ts)
call(launch const& launch_policy, F && f, Ts &&... ts)
-> decltype(detail::async_launch_policy_dispatch<
typename util::decay<F>::type
>::call(launch_policy, std::forward<F>(f), std::forward<Ts>(ts)...))
Expand Down
63 changes: 58 additions & 5 deletions hpx/runtime/applier/apply.hpp
Expand Up @@ -23,6 +23,7 @@
#include <hpx/traits/action_is_target_valid.hpp>
#include <hpx/traits/component_type_is_compatible.hpp>
#include <hpx/traits/is_action.hpp>
#include <hpx/traits/is_valid_action.hpp>
#include <hpx/traits/is_continuation.hpp>
#include <hpx/traits/is_distribution_policy.hpp>
#include <hpx/traits/extract_action.hpp>
Expand All @@ -45,10 +46,10 @@
namespace hpx
{
///////////////////////////////////////////////////////////////////////////
// zero parameter version of apply()
// Invoked by a running HPX-thread to apply an action to any resource
namespace applier { namespace detail
{
///////////////////////////////////////////////////////////////////////
template <typename Action>
inline naming::address& complement_addr(naming::address& addr)
{
Expand Down Expand Up @@ -327,12 +328,20 @@ namespace hpx
std::forward<Ts>(vs)...);
}

template <typename Action, typename Client, typename Stub,
typename ...Ts>
template <typename Action, typename Client, typename Stub, typename ...Ts>
inline bool
apply_p(components::client_base<Client, Stub> const& c,
threads::thread_priority priority, Ts&&... vs)
{
// make sure the action is compatible with the component type
typedef typename components::client_base<
Client, Stub
>::server_component_type component_type;

typedef traits::is_valid_action<Action, component_type> is_valid;
static_assert(is_valid::value,
"The action to invoke is not supported by the target");

return hpx::detail::apply_impl<Action>(
c.get_id(), priority, std::forward<Ts>(vs)...);
}
Expand Down Expand Up @@ -376,6 +385,15 @@ namespace hpx
call(hpx::actions::basic_action<Component, Signature, Derived>,
components::client_base<Client, Stub> const& c, Ts&&... ts)
{
// make sure the action is compatible with the component type
typedef typename components::client_base<
Client, Stub
>::server_component_type component_type;

typedef traits::is_valid_action<Derived, component_type> is_valid;
static_assert(is_valid::value,
"The action to invoke is not supported by the target");

return apply_p<Derived>(c.get_id(),
actions::action_priority<Derived>(),
std::forward<Ts>(ts)...);
Expand Down Expand Up @@ -409,6 +427,15 @@ namespace hpx
inline bool
apply(components::client_base<Client, Stub> const& c, Ts&&... vs)
{
// make sure the action is compatible with the component type
typedef typename components::client_base<
Client, Stub
>::server_component_type component_type;

typedef traits::is_valid_action<Action, component_type> is_valid;
static_assert(is_valid::value,
"The action to invoke is not supported by the target");

return apply_p<Action>(c.get_id(),
actions::action_priority<Action>(), std::forward<Ts>(vs)...);
}
Expand Down Expand Up @@ -594,6 +621,15 @@ namespace hpx
components::client_base<Client, Stub> const& c,
threads::thread_priority priority, Ts&&... vs)
{
// make sure the action is compatible with the component type
typedef typename components::client_base<
Client, Stub
>::server_component_type component_type;

typedef traits::is_valid_action<Action, component_type> is_valid;
static_assert(is_valid::value,
"The action to invoke is not supported by the target");

return hpx::detail::apply_impl<Action>(
std::forward<Continuation>(cont), c.get_id(), priority,
std::forward<Ts>(vs)...);
Expand Down Expand Up @@ -641,6 +677,15 @@ namespace hpx
hpx::actions::basic_action<Component, Signature, Derived>,
components::client_base<Client, Stub> const& c, Ts&&... ts)
{
// make sure the action is compatible with the component type
typedef typename components::client_base<
Client, Stub
>::server_component_type component_type;

typedef traits::is_valid_action<Derived, component_type> is_valid;
static_assert(is_valid::value,
"The action to invoke is not supported by the target");

return apply_p<Derived>(std::forward<Continuation>(cont),
c.get_id(), actions::action_priority<Derived>(),
std::forward<Ts>(ts)...);
Expand All @@ -666,8 +711,7 @@ namespace hpx
inline typename boost::enable_if_c<
traits::is_continuation<Continuation>::value, bool
>::type
apply(Continuation && c, naming::id_type const& gid,
Ts&&... vs)
apply(Continuation && c, naming::id_type const& gid, Ts&&... vs)
{
return apply_p<Action>(std::forward<Continuation>(c), gid,
actions::action_priority<Action>(),
Expand All @@ -682,6 +726,15 @@ namespace hpx
apply(Continuation && cont, components::client_base<Client, Stub> const& c,
Ts&&... vs)
{
// make sure the action is compatible with the component type
typedef typename components::client_base<
Client, Stub
>::server_component_type component_type;

typedef traits::is_valid_action<Action, component_type> is_valid;
static_assert(is_valid::value,
"The action to invoke is not supported by the target");

return apply_p<Action>(std::forward<Continuation>(cont), c.get_id(),
actions::action_priority<Action>(), std::forward<Ts>(vs)...);
}
Expand Down