diff --git a/src/vt/messaging/active.h b/src/vt/messaging/active.h index ffd42ca3b9..159eb19c24 100644 --- a/src/vt/messaging/active.h +++ b/src/vt/messaging/active.h @@ -696,7 +696,6 @@ struct ActiveMessenger : runtime::component::PollableComponent using ReturnType = ReturnT; }; - /** * \brief Broadcast a message (message type not required). * @@ -757,6 +756,15 @@ struct ActiveMessenger : runtime::component::PollableComponent return sendMsg(dest, msg, tag); } + template + struct FunctionTraitsArgs; + + template + struct FunctionTraitsArgs { + using TupleType = std::tuple...>; + using ReturnType = ReturnT; + }; + /** * \brief Send parameters to a handler in a message * @@ -767,13 +775,29 @@ struct ActiveMessenger : runtime::component::PollableComponent */ template PendingSendType send(NodeType dest, Params&&... params) { - using Tuple = DecayTuple>; + using Tuple = typename FunctionTraitsArgs::TupleType; using MsgT = ParamMsg; auto msg = vt::makeMessage(std::forward(params)...); - auto han = auto_registry::makeAutoHandlerParam(); + auto han = auto_registry::makeAutoHandlerParam(); return sendMsg(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 + PendingSendType broadcast(Params&&... params) { + using Tuple = typename FunctionTraitsArgs::TupleType; + using MsgT = ParamMsg; + auto msg = vt::makeMessage(std::forward(params)...); + auto han = auto_registry::makeAutoHandlerParam(); + return broadcastMsg(han, msg, true, no_tag); + } + /** * \brief Send a message with explicit size. * diff --git a/src/vt/messaging/param_msg.h b/src/vt/messaging/param_msg.h index 37082f0990..d3e7c25087 100644 --- a/src/vt/messaging/param_msg.h +++ b/src/vt/messaging/param_msg.h @@ -48,10 +48,15 @@ namespace vt { namespace messaging { +template +struct ParamMsg; + template -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::value> +> : vt::Message +{ + ParamMsg() = default; template explicit ParamMsg(Params&&... in_params) @@ -59,6 +64,27 @@ struct ParamMsg : vt::Message { { } Tuple params; + Tuple& getTuple() { return params; } +}; + +template +struct ParamMsg< + Tuple, std::enable_if_t::value> +> : vt::Message +{ + using MessageParentType = vt::Message; + vt_msg_serialize_if_needed_by_parent_or_type1(Tuple); // by tup + + ParamMsg() = default; + + template + explicit ParamMsg(Params&&... in_params) + : params(std::make_unique(std::forward(in_params)...)) + { } + + std::unique_ptr params; + + Tuple& getTuple() { return *params.get(); } template void serialize(SerializerT& s) { @@ -67,14 +93,6 @@ struct ParamMsg : vt::Message { } }; - -template -constexpr auto decayTypes(std::tuple const&) - -> std::tuple>...>; - -template -using DecayTuple = decltype(decayTypes(std::declval())); - }} /* end namespace vt::messaging */ #endif /*INCLUDED_VT_MESSAGING_PARAM_MSG_H*/ diff --git a/src/vt/registry/auto/auto_registry_common.h b/src/vt/registry/auto/auto_registry_common.h index 7cc685249d..88b0e543ca 100644 --- a/src/vt/registry/auto/auto_registry_common.h +++ b/src/vt/registry/auto/auto_registry_common.h @@ -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()); } }; diff --git a/src/vt/registry/auto/auto_registry_general.h b/src/vt/registry/auto/auto_registry_general.h index 3fac996864..aec46e5f4a 100644 --- a/src/vt/registry/auto/auto_registry_general.h +++ b/src/vt/registry/auto/auto_registry_general.h @@ -155,11 +155,11 @@ struct FunctorAdapterArgs { // Need to provide a non-pointer overload for parameterization auto-registered // functions for GCC -template +template struct FunctorAdapterParam { using FunctionPtrType = F; using ObjType = SentinelObject; - using MsgType = messaging::ParamMsg>>; + using MsgType = MsgT; static constexpr FunctionPtrType getFunction() { return f; } diff --git a/src/vt/registry/auto/auto_registry_impl.h b/src/vt/registry/auto/auto_registry_impl.h index ddfebcf176..91e216012e 100644 --- a/src/vt/registry/auto/auto_registry_impl.h +++ b/src/vt/registry/auto/auto_registry_impl.h @@ -144,9 +144,9 @@ inline BaseScatterDispatcherPtr const& getScatterAutoHandler(HandlerType const h return getAutoRegistryGen().at(han_id).getFun(); } -template +template inline HandlerType makeAutoHandlerParam() { - using AdapterT = FunctorAdapterParam; + using AdapterT = FunctorAdapterParam; using ContainerType = AutoActiveContainerType; using RegInfoType = AutoRegInfoType; using FuncType = ActiveFnPtrType;