Skip to content

Commit

Permalink
#276: active: fix serialization for parameterized handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
lifflander committed Jan 19, 2023
1 parent cb28d28 commit f90c90b
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 19 deletions.
30 changes: 27 additions & 3 deletions src/vt/messaging/active.h
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,6 @@ struct ActiveMessenger : runtime::component::PollableComponent<ActiveMessenger>
using ReturnType = ReturnT;
};


/**
* \brief Broadcast a message (message type not required).
*
Expand Down Expand Up @@ -757,6 +756,15 @@ struct ActiveMessenger : runtime::component::PollableComponent<ActiveMessenger>
return sendMsg<MsgT, f>(dest, msg, tag);
}

template <typename ReturnT, typename... Args>
struct FunctionTraitsArgs;

template <typename ReturnT, typename... Args>
struct FunctionTraitsArgs<ReturnT(*)(Args...)> {
using TupleType = std::tuple<std::decay_t<Args>...>;
using ReturnType = ReturnT;
};

/**
* \brief Send parameters to a handler in a message
*
Expand All @@ -767,13 +775,29 @@ struct ActiveMessenger : runtime::component::PollableComponent<ActiveMessenger>
*/
template <auto f, typename... Params>
PendingSendType send(NodeType dest, Params&&... params) {
using Tuple = DecayTuple<std::tuple<Params...>>;
using Tuple = typename FunctionTraitsArgs<decltype(f)>::TupleType;
using MsgT = ParamMsg<Tuple>;
auto msg = vt::makeMessage<MsgT>(std::forward<Params>(params)...);
auto han = auto_registry::makeAutoHandlerParam<decltype(f),f,Params...>();
auto han = auto_registry::makeAutoHandlerParam<decltype(f), f, MsgT>();
return sendMsg<MsgT>(dest, han, msg, no_tag);
}

/**
* \brief Broadcast parameters to a handler in a message
*
* \param[in] params the parameters
*
* \return the \c PendingSend for the sent message
*/
template <auto f, typename... Params>
PendingSendType broadcast(Params&&... params) {
using Tuple = typename FunctionTraitsArgs<decltype(f)>::TupleType;
using MsgT = ParamMsg<Tuple>;
auto msg = vt::makeMessage<MsgT>(std::forward<Params>(params)...);
auto han = auto_registry::makeAutoHandlerParam<decltype(f), f, MsgT>();
return broadcastMsg<MsgT>(han, msg, true, no_tag);
}

/**
* \brief Send a message with explicit size.
*
Expand Down
40 changes: 29 additions & 11 deletions src/vt/messaging/param_msg.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,43 @@

namespace vt { namespace messaging {

template <typename Tuple, typename enabled = void>
struct ParamMsg;

template <typename Tuple>
struct ParamMsg : vt::Message {
using MessageParentType = vt::Message;
vt_msg_serialize_if_needed_by_parent_or_type1(Tuple); // by tup
struct ParamMsg<
Tuple, std::enable_if_t<is_byte_copyable_t<Tuple>::value>
> : vt::Message
{
ParamMsg() = default;

template <typename... Params>
explicit ParamMsg(Params&&... in_params)
: params(std::forward<Params>(in_params)...)
{ }

Tuple params;
Tuple& getTuple() { return params; }
};

template <typename Tuple>
struct ParamMsg<
Tuple, std::enable_if_t<not is_byte_copyable_t<Tuple>::value>
> : vt::Message
{
using MessageParentType = vt::Message;
vt_msg_serialize_if_needed_by_parent_or_type1(Tuple); // by tup

ParamMsg() = default;

template <typename... Params>
explicit ParamMsg(Params&&... in_params)
: params(std::make_unique<Tuple>(std::forward<Params>(in_params)...))
{ }

std::unique_ptr<Tuple> params;

Tuple& getTuple() { return *params.get(); }

template <typename SerializerT>
void serialize(SerializerT& s) {
Expand All @@ -67,14 +93,6 @@ struct ParamMsg : vt::Message {
}
};


template <typename... Params>
constexpr auto decayTypes(std::tuple<Params...> const&)
-> std::tuple<std::remove_cv_t<std::remove_reference_t<Params>>...>;

template <typename T>
using DecayTuple = decltype(decayTypes(std::declval<T>()));

}} /* end namespace vt::messaging */

#endif /*INCLUDED_VT_MESSAGING_PARAM_MSG_H*/
2 changes: 1 addition & 1 deletion src/vt/registry/auto/auto_registry_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ struct HandlersDispatcher final : BaseHandlersDispatcher {
>
> {
static void run(MsgT* msg, void*, HandlerT han) {
std::apply(han, msg->params);
std::apply(han, msg->getTuple());
}
};

Expand Down
4 changes: 2 additions & 2 deletions src/vt/registry/auto/auto_registry_general.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,11 +155,11 @@ struct FunctorAdapterArgs<ObjTypeT, MsgT> {

// Need to provide a non-pointer overload for parameterization auto-registered
// functions for GCC
template <typename F, F f, typename... Params>
template <typename F, F f, typename MsgT>
struct FunctorAdapterParam {
using FunctionPtrType = F;
using ObjType = SentinelObject;
using MsgType = messaging::ParamMsg<messaging::DecayTuple<std::tuple<Params...>>>;
using MsgType = MsgT;

static constexpr FunctionPtrType getFunction() { return f; }

Expand Down
4 changes: 2 additions & 2 deletions src/vt/registry/auto/auto_registry_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,9 @@ inline BaseScatterDispatcherPtr const& getScatterAutoHandler(HandlerType const h
return getAutoRegistryGen<ScatterContainerType>().at(han_id).getFun();
}

template <typename T, T value, typename... Params>
template <typename T, T value, typename MsgT>
inline HandlerType makeAutoHandlerParam() {
using AdapterT = FunctorAdapterParam<T, value, Params...>;
using AdapterT = FunctorAdapterParam<T, value, MsgT>;
using ContainerType = AutoActiveContainerType;
using RegInfoType = AutoRegInfoType<AutoActiveType>;
using FuncType = ActiveFnPtrType;
Expand Down

0 comments on commit f90c90b

Please sign in to comment.