Learning about collective groups
// VT Base Message // \----------------/ // \ / struct MySimpleMsg2 : ::vt::Message { }; // Forward declaration for the active message handler static void msgHandlerGroupB(MySimpleMsg2* msg); // Tutorial code to demonstrate collective group creation and broadcast to that group static inline void activeMessageGroupCollective() { NodeType const this_node = ::vt::theContext()->getNode(); NodeType const num_nodes = ::vt::theContext()->getNumNodes(); (void)num_nodes; // don't warn about unused variable /* * This is an example of the collective group creation and broadcast to that * group. A group allows the user to create a subset of nodes. The collective * group allows all nodes to participate in creating the group by passing a * boolean that indicates if they are apart of the group. * * Unlike the rooted group creation (which requires an initial set at a root * node), the collective group is fully distributed: its creation and * storage. The set of all nodes included is never stored in a central * location. This is managed by efficient distributed algorithms that create a * spanning tree based on the filter and rebalance it depending on outcomes. */ auto const& is_even_node = this_node % 2 == 0; auto group = theGroup()->newGroupCollective( is_even_node, [](GroupType group_id){ fmt::print("Group is created: id={:x}\n", group_id); // In this example, node 1 broadcasts to the group of even nodes auto const my_node = ::vt::theContext()->getNode(); if (my_node == 1) { auto msg = makeMessage<MySimpleMsg2>(); envelopeSetGroup(msg->env, group_id); theMsg()->broadcastMsg<msgHandlerGroupB>(msg); } } ); (void)group; // don't warn about unused variable } // Message handler static void msgHandlerGroupB([[maybe_unused]] MySimpleMsg2* msg) { auto const cur_node = ::vt::theContext()->getNode(); vtAssert(cur_node % 2 == 0, "This handler should only execute on even nodes"); ::fmt::print("msgHandlerGroupB: triggered on node={}\n", cur_node); }