Learning about rooted groups
// VT Base Message // \----------------/ // \ / struct MySimpleMsg : ::vt::Message { }; // Forward declaration for the active message handler static void msgHandlerGroupA(MySimpleMsg* msg); // Tutorial code to demonstrate rooted group creation and broadcast to that group static inline void activeMessageGroupRoot() { NodeType const this_node = ::vt::theContext()->getNode(); NodeType const num_nodes = ::vt::theContext()->getNumNodes(); /* * This is an example of the rooted group creation and broadcast to that * group. A group allows the user to create a subset of nodes. A broadcast by * default sends the message to every node in the default group (which * includes all nodes). If a explicit group is set in the envelope, the * broadcast will only arrive on the nodes in that group. */ if (this_node == 0) { // Create range for the group [1,num_nodes); auto range = std::make_unique<::vt::group::region::Range>(1, num_nodes); // The non-collective group is created by a single node based on a range or // list of nodes. The lambda is executed once the group is created. By // setting the group in the envelope of the message and broadcasting the // message will arrive on the set of nodes included in the group auto id = theGroup()->newGroup(std::move(range), [](GroupType group_id){ fmt::print("Group is created: id={:x}\n", group_id); auto msg = makeMessage<MySimpleMsg>(); envelopeSetGroup(msg->env, group_id); theMsg()->broadcastMsg<msgHandlerGroupA>(msg); }); // The `id' that is returned from the newGroup invocation, can be used // anywhere in the system to broadcast (multicast) to this group. (void)id; // don't warn about unused variable } } // Message handler static void msgHandlerGroupA([[maybe_unused]] MySimpleMsg* msg) { auto const cur_node = ::vt::theContext()->getNode(); vtAssert(cur_node >= 1, "This handler should only execute on nodes >= 1"); ::fmt::print("msgHandlerGroupA: triggered on node={}\n", cur_node); }