+
+ return replay;
+}
+
+/** @brief Build argument vector to pass to process */
+static std::vector<std::string> smpi_deployment_get_args(int rank_id, const std::vector<std::string>& replay,
+ const std::vector<const char*>& run_args)
+{
+ std::vector<std::string> args{std::to_string(rank_id)};
+ // pass arguments to process only if not a replay execution
+ if (replay.empty())
+ args.insert(args.end(), begin(run_args), end(run_args));
+ /* one trace per process */
+ if (replay.size() > 1)
+ args.emplace_back(replay[rank_id]);
+ return args;
+}
+
+/**
+ * @brief Deploy an SMPI application from a smpirun call
+ *
+ * This used to be done at smpirun script, parsing either the hostfile or the platform XML.
+ * If hostfile isn't provided, get the list of hosts from engine.
+ */
+int smpi_deployment_smpirun(const simgrid::s4u::Engine* e, const std::string& hostfile, int np,
+ const std::string& replayfile, int map, const std::vector<const char*>& run_args)
+{
+ auto hosts = smpi_get_hosts(e, hostfile);
+ auto replay = smpi_read_replay(replayfile);
+ int hosts_size = static_cast<int>(hosts.size());
+ if (np == 0)
+ np = hosts_size;
+
+ xbt_assert(np > 0, "Invalid number of process (np must be > 0). Check your np parameter, platform or hostfile");
+
+ if (np > hosts_size) {
+ XBT_INFO("You requested to use %d ranks, but there is only %d processes in your hostfile...", np, hosts_size);
+ }
+
+ for (int i = 0; i < np; i++) {
+ simgrid::s4u::Host* host = hosts[i % hosts_size];
+ std::string rank_id = std::to_string(i);
+ auto args = smpi_deployment_get_args(i, replay, run_args);
+ auto actor = simgrid::s4u::Actor::create(rank_id, host, rank_id, args);
+ /* keeping the same behavior as done in smpirun script, print mapping rank/process */
+ if (map != 0) {
+ XBT_INFO("[rank %d] -> %s", i, host->get_cname());
+ }
+ actor->set_property("instance_id", "smpirun");
+ actor->set_property("rank", rank_id);
+ if (not replay.empty())
+ actor->set_property("smpi_replay", "true");
+ /* shared trace file, set it to rank 0 */
+ if (i == 0 && replay.size() == 1)
+ actor->set_property("tracefile", replay[0]);
+ }
+ return np;