Learn » Tutorial » Learning about collections

// Forward declaration for message
struct MyCollMsg;

//               VT Base Class for a collection
//         \-------------------------------------/
//          \                                   /
//           \                         Index   /
//            \                     \---------/
//             \                     \       /
struct MyCol : ::vt::Collection<MyCol,Index1D> {

  void msgHandler(MyCollMsg* msg);

};

//                 VT Base Message for Collections
//               \--------------------------------/
//                \                              /
struct MyCollMsg : ::vt::CollectionMessage<MyCol> { };

void MyCol::msgHandler([[maybe_unused]] MyCollMsg* msg) {
  auto cur_node = theContext()->getNode();
  auto idx = this->getIndex();
  ::fmt::print("MyCol::msgHandler index={}, node={}\n", idx.x(), cur_node);
}

// Tutorial code to demonstrate creating a collection
static inline void collection() {
  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 creating a virtual context collection with an index
   * range
   */

  // Range of 32 elements for the collection
  auto range = vt::Index1D(32);

  // Construct the collection (collective variant): invoked by all nodes. By
  // default, the elements will be block mapped to the nodes
  auto proxy = vt::makeCollection<MyCol>("tutorial_collection")
    .bounds(range)    // Set the bounds for the collection
    .bulkInsert()     // Bulk insert all the elements within the bounds
    .wait();          // Wait for construction and get the proxy back

  if (this_node == 0) {
    // Broadcast a message to the entire collection. The msgHandler will be
    // invoked on every element to the collection
    proxy.broadcast<MyCollMsg,&MyCol::msgHandler>();

    // Send a message to the 5th element of the collection
    proxy[5].send<MyCollMsg,&MyCol::msgHandler>();
  }

  // Collectively broadcast to the collection (all nodes participate for a
  // single broadcast)
  proxy.broadcastCollective<MyCollMsg,&MyCol::msgHandler>();
}