Example Collection Migration Program

The full code for this example can be found here: examples/collection/migrate_collection.cc.

static constexpr int32_t const default_num_elms = 16;

struct Hello : vt::Collection<Hello, vt::Index1D> {

  Hello() {
    vt::NodeType this_node = vt::theContext()->getNode();
    fmt::print("{}: Hello: index={}\n", this_node, getIndex());
    test_val = getIndex().x() * 29.3;
  }

  explicit Hello(checkpoint::SERIALIZE_CONSTRUCT_TAG) {}

  template <typename Serializer>
  void serialize(Serializer& s) {
    vt::Collection<Hello, vt::Index1D>::serialize(s);
    s | test_val;
  }

  double test_val = 0.0;
};

static void doWork(Hello* col) {
  vt::NodeType this_node = vt::theContext()->getNode();
  fmt::print("{}: idx={}: val={}\n", this_node, col->getIndex(), col->test_val);
}

static void migrateToNext(Hello* col) {
  vt::NodeType this_node = vt::theContext()->getNode();
  vt::NodeType num_nodes = vt::theContext()->getNumNodes();
  vt::NodeType next_node = (this_node + 1) % num_nodes;

  fmt::print("{}: migrateToNext: idx={}\n", this_node, col->getIndex());
  col->migrate(next_node);
}

int main(int argc, char** argv) {
  vt::initialize(argc, argv);

  vt::NodeType this_node = vt::theContext()->getNode();
  vt::NodeType num_nodes = vt::theContext()->getNumNodes();

  if (num_nodes == 1) {
    return vt::rerror("requires at least 2 nodes");
  }

  int32_t num_elms = default_num_elms;
  if (argc > 1) {
    num_elms = atoi(argv[1]);
  }

  auto range = vt::Index1D(num_elms);
  auto proxy = vt::makeCollection<Hello>("examples_migrate_collection")
    .bounds(range)
    .bulkInsert()
    .wait();

  if (this_node == 0) {
    vt::runInEpochRooted([=] { proxy.broadcast<doWork>(); });
    vt::runInEpochRooted([=] { proxy.broadcast<migrateToNext>(); });
    vt::runInEpochRooted([=] { proxy.broadcast<doWork>(); });
  }

  vt::finalize();

  return 0;
}