int main()

in dipcc/dipcc/profiling/profile_late.cc [155:269]


int main(int argc, char *argv[]) {
  int batch_size = 100;
  int num_rounds = 100;
  int pool_size = 10;
  {
    for (int i = 1; i < argc; i++) {
      std::string arg = argv[i];
      if (arg == "--batch_size") {
        assert(i + 1 < argc);
        batch_size = std::stoi(argv[++i]);
      } else if (arg == "--num_rounds") {
        assert(i + 1 < argc);
        num_rounds = std::stoi(argv[++i]);
      } else if (arg == "--pool_size") {
        assert(i + 1 < argc);
        pool_size = std::stoi(argv[++i]);
      } else {
        std::cerr << "Unknown flag: " << arg << "\n";
        return -1;
      }
    }
  }

  // order_batches[i] contains batch_size orders for i-th run.
  std::vector<std::vector<OrderSet>> order_batches(num_rounds);
  std::default_random_engine rng(0);
  for (auto &batch : order_batches) {
    for (int i = 0; i < batch_size; ++i) {
      OrderSet orders;
      for (const auto & [ power, order_options ] : kTopOrders) {
        std::uniform_int_distribution<int> distribution(
            0, order_options.size() - 1);
        const std::vector<std::string> &order_strings =
            order_options[distribution(rng)];
        for (const auto &s : order_strings) {
          orders[power].push_back(s);
        }
      }
      batch.push_back(orders);
    }
  }

  std::ifstream t(kGamePath);
  std::string game_json_str((std::istreambuf_iterator<char>(t)),
                            std::istreambuf_iterator<char>());
  Game init_game(game_json_str);
  init_game = init_game.rolled_back_to_phase_start(kPhase);
  init_game.get_all_possible_orders();

  ThreadPool pool(pool_size, get_order_vocab(), kOrderVocabIdxs);

  struct T {
    std::chrono::time_point<std::chrono::steady_clock> start =
        std::chrono::steady_clock::now();

    double tick() {
      const auto end = std::chrono::steady_clock::now();
      std::chrono::duration<double> diff = end - start;
      start = end;
      return diff.count();
    }

  } timer;

  double clone_time = 0, encode_time = 0, encode_state_only_time = 0,
         set_order_time = 0, process_time = 0;
  for (int i = 0; i < num_rounds; ++i) {
    // Clone
    std::vector<std::shared_ptr<Game>> games;
    std::vector<Game *> game_ptrs; // That's what the pool expects.
    for (int game_id = 0; game_id < batch_size; ++game_id) {
      games.push_back(std::make_shared<Game>(init_game));
      game_ptrs.emplace_back(games.back().get());
    }
    clone_time += timer.tick();

    // Encode
    pool.encode_inputs_multi(game_ptrs);
    encode_time += timer.tick();

    // Encode State Only
    pool.encode_inputs_state_only_multi(game_ptrs);
    encode_state_only_time += timer.tick();

    // Set Orders
    for (int game_id = 0; game_id < batch_size; ++game_id) {
      for (const auto & [ power, orders ] : order_batches[i][game_id]) {
        games[game_id]->set_orders(power, orders);
      }
    }
    set_order_time += timer.tick();

    // Process
    pool.process_multi(game_ptrs);
    process_time += timer.tick();
  }

  LOG(ERROR) << "clone_time: " << clone_time << " / " << num_rounds << " = "
             << clone_time / num_rounds << " s";

  LOG(ERROR) << "encode_time: " << encode_time << " / " << num_rounds << " = "
             << encode_time / num_rounds << " s";

  LOG(ERROR) << "encode_state_only_time: " << encode_state_only_time << " / "
             << num_rounds << " = " << encode_state_only_time / num_rounds
             << " s";

  LOG(ERROR) << "set_order_time: " << set_order_time << " / " << num_rounds
             << " = " << set_order_time / num_rounds << " s";

  LOG(ERROR) << "process_time: " << process_time << " / " << num_rounds << " = "
             << process_time / num_rounds << " s";

  return 0;
}