Learning about broadcasts
// VT Base Message // \----------------/ // \ / struct MyDataMsg : ::vt::Message { MyDataMsg() = default; MyDataMsg(double in_x, double in_y, double in_z) : x(in_x), y(in_y), z(in_z) { } double getX() const { return x; } double getY() const { return y; } double getZ() const { return z; } private: double x = 0.0, y = 0.0, z = 0.0; }; // Forward declaration for the active message handler static void msgHandlerX(MyDataMsg* msg); // Tutorial code to demonstrate broadcasting a message to the entire system static inline void activeMessageBroadcast() { NodeType const this_node = ::vt::theContext()->getNode(); NodeType const num_nodes = ::vt::theContext()->getNumNodes(); (void)num_nodes; // don't warn about unused variable /* * default_proxy.broadcast(..) will send the message to every node in the * system. Every node will include all the nodes that VT has depending on the * MPI communicator passed in or the size attained (number of ranks) when * executing MPI init directly in non-interoperability mode. * * -- Message Ownership -- * default_proxy.broadcast(..) will create message out of args passed * into it. There's an alternative - default_proxy.broadcastMsg(..) - which * relinquishes ownership of the message passed to: * * auto msg = ::vt::makeMessage<MyDataMsg>(1.0, 2.0, 3.0); * auto const default_proxy = theObjGroup()->getDefault(); * default_proxy.broadcastMsg<MyDataMsg, msgHandlerX>(msg); * * Most calls to VT that supply a message are expected to relinquish ownership. */ if (this_node == 0) { auto const default_proxy = theObjGroup()->getDefault(); default_proxy.broadcast<MyDataMsg, msgHandlerX>(1.0, 2.0, 3.0); } } // Message handler static void msgHandlerX(MyDataMsg* msg) { vtAssert( msg->getX() == 1.0 && msg->getY() == 2.0 && msg->getZ() == 3.0, "Values x,y,z incorrect" ); auto const cur_node = ::vt::theContext()->getNode(); ::fmt::print("msgHandlerX: triggered on node={}\n", cur_node); }