diff --git a/src/vt/messaging/active.h b/src/vt/messaging/active.h index 9901166fa3..ca0c9b30d1 100644 --- a/src/vt/messaging/active.h +++ b/src/vt/messaging/active.h @@ -766,7 +766,8 @@ struct ActiveMessenger : runtime::component::PollableComponent PendingSendType send(Node dest, Params&&... params) { using Tuple = typename FuncTraits::TupleType; using MsgT = ParamMsg; - auto msg = vt::makeMessage(std::forward(params)...); + auto msg = vt::makeMessage(); + msg->setParams(std::forward(params)...); auto han = auto_registry::makeAutoHandlerParam(); return sendMsg(dest.get(), han, msg, no_tag); } @@ -782,7 +783,8 @@ struct ActiveMessenger : runtime::component::PollableComponent PendingSendType broadcast(Params&&... params) { using Tuple = typename FuncTraits::TupleType; using MsgT = ParamMsg; - auto msg = vt::makeMessage(std::forward(params)...); + auto msg = vt::makeMessage(); + msg->setParams(std::forward(params)...); auto han = auto_registry::makeAutoHandlerParam(); constexpr bool deliver_to_sender = true; return broadcastMsg(han, msg, deliver_to_sender, no_tag); diff --git a/src/vt/messaging/active.impl.h b/src/vt/messaging/active.impl.h index 610b8ece67..2cb263f9ea 100644 --- a/src/vt/messaging/active.impl.h +++ b/src/vt/messaging/active.impl.h @@ -512,4 +512,6 @@ inline EpochType ActiveMessenger::setupEpochMsg(MsgSharedPtr const& msg) { }} //end namespace vt::messaging +#include "vt/messaging/param_msg.impl.h" + #endif /*INCLUDED_VT_MESSAGING_ACTIVE_IMPL_H*/ diff --git a/src/vt/messaging/param_msg.h b/src/vt/messaging/param_msg.h index d3e7c25087..6703362382 100644 --- a/src/vt/messaging/param_msg.h +++ b/src/vt/messaging/param_msg.h @@ -46,7 +46,101 @@ #include "vt/messaging/message/message_serialize.h" -namespace vt { namespace messaging { +namespace vt { + +struct MsgProps { + + MsgProps() = default; + + MsgProps&& asLocationMsg(bool set = true) { + as_location_msg_ = set; + return std::move(*this); + } + + MsgProps&& asTerminationMsg(bool set = true) { + as_termination_msg_ = set; + return std::move(*this); + } + + MsgProps&& asCollectionMsg(bool set = true) { + as_collection_msg_ = set; + return std::move(*this); + } + + MsgProps&& asSerializationMsg(bool set = true) { + as_serial_msg_ = set; + return std::move(*this); + } + + MsgProps&& withEpoch(EpochType in_ep) { + ep_ = in_ep; + return std::move(*this); + } + + MsgProps&& withPriority(PriorityType in_priority) { +#if vt_check_enabled(priorities) + priority_ = in_priority; +#endif + return std::move(*this); + } + + MsgProps&& withPriorityLevel(PriorityLevelType in_priority_level) { +#if vt_check_enabled(priorities) + priority_level_ = in_priority_level; +#endif + return std::move(*this); + } + + template + void apply(MsgT& msg); + +private: + bool as_location_msg_ = false; + bool as_termination_msg_ = false; + bool as_serial_msg_ = false; + bool as_collection_msg_ = false; + EpochType ep_ = no_epoch; + PriorityType priority_ = no_priority; + PriorityLevelType priority_level_ = no_priority_level; +}; + +} /* end namespace vt */ + +namespace vt::messaging::detail { + +template +struct GetTraits; + +template <> +struct GetTraits>> { + using TupleType = std::tuple<>; +}; + +template +struct GetTraits< + std::enable_if_t>, Param, Params... +> { + using TupleType = std::tuple; +}; + +template +struct GetTraits< + std::enable_if_t>, Param, Params... +> { + using TupleType = std::tuple; +}; + +template +struct GetTraitsTuple; + +template +struct GetTraitsTuple> { + using TupleType = typename GetTraits::TupleType; +}; + +} /* end namespace vt::messaging::detail */ + +namespace vt::messaging { template struct ParamMsg; @@ -56,15 +150,24 @@ struct ParamMsg< Tuple, std::enable_if_t::value> > : vt::Message { + using TupleType = typename detail::GetTraitsTuple::TupleType; + ParamMsg() = default; - template - explicit ParamMsg(Params&&... in_params) - : params(std::forward(in_params)...) - { } + void setParams() { } + + template + void setParams(Param&& p, Params&&... in_params) { + if constexpr (std::is_same_v) { + params = TupleType{std::forward(in_params)...}; + p.apply(*this); + } else { + params = TupleType{std::forward(p), std::forward(in_params)...}; + } + } - Tuple params; - Tuple& getTuple() { return params; } + TupleType params; + TupleType& getTuple() { return params; } }; template @@ -75,16 +178,29 @@ struct ParamMsg< using MessageParentType = vt::Message; vt_msg_serialize_if_needed_by_parent_or_type1(Tuple); // by tup + using TupleType = typename detail::GetTraitsTuple::TupleType; + ParamMsg() = default; - template - explicit ParamMsg(Params&&... in_params) - : params(std::make_unique(std::forward(in_params)...)) - { } + void setParams() { + params = std::make_unique(); + } + + template + void setParams(Param&& p, Params&&... in_params) { + if constexpr (std::is_same_v) { + params = std::make_unique(std::forward(in_params)...); + p.apply(*this); + } else { + params = std::make_unique( + std::forward(p), std::forward(in_params)... + ); + } + } - std::unique_ptr params; + std::unique_ptr params; - Tuple& getTuple() { return *params.get(); } + TupleType& getTuple() { return *params.get(); } template void serialize(SerializerT& s) { @@ -93,6 +209,6 @@ struct ParamMsg< } }; -}} /* end namespace vt::messaging */ +} /* end namespace vt::messaging */ #endif /*INCLUDED_VT_MESSAGING_PARAM_MSG_H*/ diff --git a/src/vt/messaging/param_msg.impl.h b/src/vt/messaging/param_msg.impl.h new file mode 100644 index 0000000000..5fb254b6a2 --- /dev/null +++ b/src/vt/messaging/param_msg.impl.h @@ -0,0 +1,81 @@ +/* +//@HEADER +// ***************************************************************************** +// +// param_msg.impl.h +// DARMA/vt => Virtual Transport +// +// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC +// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. +// Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from this +// software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact darma@sandia.gov +// +// ***************************************************************************** +//@HEADER +*/ + +#if !defined INCLUDED_VT_MESSAGING_PARAM_MSG_IMPL_H +#define INCLUDED_VT_MESSAGING_PARAM_MSG_IMPL_H + +#include "vt/messaging/param_msg.h" + +namespace vt { + +template +void MsgProps::apply(MsgT& msg) { + if (as_location_msg_) { + theMsg()->markAsLocationMessage(msg); + } + if (as_termination_msg_) { + theMsg()->markAsTermMessage(msg); + } + if (as_serial_msg_) { + theMsg()->markAsSerialMsgMessage(msg); + } + if (as_collection_msg_) { + theMsg()->markAsCollectionMessage(msg); + } + if (ep_ != no_epoch) { + envelopeSetEpoch(msg->env, ep_); + } +#if vt_check_enabled(priorities) + if (priority_ != no_priority) { + envelopeSetPriority(msg->env, priority_); + } + if (priority_level_ != no_priority_level) { + envelopeSetPriorityLevel(msg->env, priority_level_); + } +#endif +} + +} /* end namespace vt */ + +#endif /*INCLUDED_VT_MESSAGING_PARAM_MSG_IMPL_H*/ + diff --git a/src/vt/objgroup/proxy/proxy_objgroup.impl.h b/src/vt/objgroup/proxy/proxy_objgroup.impl.h index 906e6d0738..9d06f014e2 100644 --- a/src/vt/objgroup/proxy/proxy_objgroup.impl.h +++ b/src/vt/objgroup/proxy/proxy_objgroup.impl.h @@ -94,7 +94,8 @@ Proxy::broadcast(Params&&... params) const { if constexpr (std::is_same_v) { using Tuple = typename ObjFuncTraits::TupleType; using SendMsgT = messaging::ParamMsg; - auto msg = vt::makeMessage(std::forward(params)...); + auto msg = vt::makeMessage(); + msg->setParams(std::forward(params)...); auto const ctrl = proxy::ObjGroupProxy::getID(proxy_); auto const han = auto_registry::makeAutoHandlerObjGroupParam< ObjT, decltype(f), f, SendMsgT diff --git a/src/vt/objgroup/proxy/proxy_objgroup_elm.impl.h b/src/vt/objgroup/proxy/proxy_objgroup_elm.impl.h index dccd7b4f09..ec0eda110e 100644 --- a/src/vt/objgroup/proxy/proxy_objgroup_elm.impl.h +++ b/src/vt/objgroup/proxy/proxy_objgroup_elm.impl.h @@ -85,7 +85,8 @@ ProxyElm::send(Params&&... params) const { if constexpr (std::is_same_v) { using Tuple = typename ObjFuncTraits::TupleType; using SendMsgT = messaging::ParamMsg; - auto msg = vt::makeMessage(std::forward(params)...); + auto msg = vt::makeMessage(); + msg->setParams(std::forward(params)...); auto const ctrl = proxy::ObjGroupProxy::getID(proxy_); auto const han = auto_registry::makeAutoHandlerObjGroupParam< ObjT, decltype(f), f, SendMsgT diff --git a/src/vt/pipe/callback/cb_union/cb_raw_base.h b/src/vt/pipe/callback/cb_union/cb_raw_base.h index 9eb619865c..f5ecec165a 100644 --- a/src/vt/pipe/callback/cb_union/cb_raw_base.h +++ b/src/vt/pipe/callback/cb_union/cb_raw_base.h @@ -234,7 +234,8 @@ struct CallbackTyped : CallbackRawBaseSingle { void sendTuple(std::tuple tup) { using Trait = CBTraits; using MsgT = messaging::ParamMsg; - auto msg = vt::makeMessage(std::move(tup)); + auto msg = vt::makeMessage(); + msg->setParams(std::move(tup)); CallbackRawBaseSingle::sendMsg(msg); } @@ -243,7 +244,8 @@ struct CallbackTyped : CallbackRawBaseSingle { using Trait = CBTraits; if constexpr (std::is_same_v) { using MsgT = messaging::ParamMsg; - auto msg = vt::makeMessage(std::forward(params)...); + auto msg = vt::makeMessage(); + msg->setParams(std::forward(params)...); CallbackRawBaseSingle::sendMsg(msg); } else { using MsgT = typename Trait::MsgT; diff --git a/src/vt/vrt/collection/broadcast/broadcastable.impl.h b/src/vt/vrt/collection/broadcast/broadcastable.impl.h index f48672da5e..bad98d2f69 100644 --- a/src/vt/vrt/collection/broadcast/broadcastable.impl.h +++ b/src/vt/vrt/collection/broadcast/broadcastable.impl.h @@ -185,7 +185,8 @@ Broadcastable::broadcast(Params&&... params) const { if constexpr (std::is_same_v) { using Tuple = typename ObjFuncTraits::TupleType; using SendMsgT = ParamColMsg; - auto msg = vt::makeMessage(std::forward(params)...); + auto msg = vt::makeMessage(); + msg->setParams(std::forward(params)...); auto han = auto_registry::makeAutoHandlerCollectionMemParam< ColT, decltype(f), f, SendMsgT >(); @@ -210,7 +211,8 @@ Broadcastable::broadcastCollective(Params&&... params) if constexpr (std::is_same_v) { using Tuple = typename ObjFuncTraits::TupleType; using SendMsgT = ParamColMsg; - auto msg = vt::makeMessage(std::forward(params)...); + auto msg = vt::makeMessage(); + msg->setParams(std::forward(params)...); auto han = auto_registry::makeAutoHandlerCollectionMemParam< ColT, decltype(f), f, SendMsgT >(); diff --git a/src/vt/vrt/collection/messages/param_col_msg.h b/src/vt/vrt/collection/messages/param_col_msg.h index 7c6cfbdd39..ff8dd05bd2 100644 --- a/src/vt/vrt/collection/messages/param_col_msg.h +++ b/src/vt/vrt/collection/messages/param_col_msg.h @@ -46,6 +46,7 @@ #include "vt/vrt/collection/messages/user.h" #include "vt/messaging/message/message_serialize.h" +#include "vt/messaging/param_msg.h" namespace vt { namespace vrt { namespace collection { @@ -58,15 +59,25 @@ struct ParamColMsg< ColT, std::enable_if_t::value> > : CollectionMessage { + + using TupleType = typename messaging::detail::GetTraitsTuple::TupleType; + ParamColMsg() = default; - template - explicit ParamColMsg(Params&&... in_params) - : params(std::forward(in_params)...) - { } + void setParams() { } + + template + void setParams(Param&& p, Params&&... in_params) { + if constexpr (std::is_same_v) { + params = TupleType{std::forward(in_params)...}; + p.apply(*this); + } else { + params = TupleType{std::forward(p), std::forward(in_params)...}; + } + } - Tuple params; - Tuple& getTuple() { return params; } + TupleType params; + TupleType& getTuple() { return params; } }; template @@ -78,16 +89,29 @@ struct ParamColMsg< using MessageParentType = CollectionMessage; vt_msg_serialize_if_needed_by_parent_or_type1(Tuple); // by params + using TupleType = typename messaging::detail::GetTraitsTuple::TupleType; + ParamColMsg() = default; - template - explicit ParamColMsg(Params&&... in_params) - : params(std::make_unique(std::forward(in_params)...)) - { } + void setParams() { + params = std::make_unique(); + } + + template + void setParams(Param&& p, Params&&... in_params) { + if constexpr (std::is_same_v) { + params = std::make_unique(std::forward(in_params)...); + p.apply(*this); + } else { + params = std::make_unique( + std::forward(p), std::forward(in_params)... + ); + } + } std::unique_ptr params; - Tuple& getTuple() { return *params.get(); } + TupleType& getTuple() { return *params.get(); } template void serialize(SerializerT& s) { diff --git a/src/vt/vrt/collection/send/sendable.impl.h b/src/vt/vrt/collection/send/sendable.impl.h index 9118a84884..3a200a5424 100644 --- a/src/vt/vrt/collection/send/sendable.impl.h +++ b/src/vt/vrt/collection/send/sendable.impl.h @@ -139,7 +139,8 @@ messaging::PendingSend Sendable::send(Params&&... params if constexpr (std::is_same_v) { using Tuple = typename FnTrait::TupleType; using SendMsgT = ParamColMsg; - auto msg = vt::makeMessage(std::forward(params)...); + auto msg = vt::makeMessage(); + msg->setParams(std::forward(params)...); auto han = auto_registry::makeAutoHandlerCollectionMemParam< ColT, decltype(f), f, SendMsgT >();