Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Apply the default settings of 'smpi/buffering' too
[simgrid.git] / src / smpi / internals / smpi_replay.cpp
index 7fc301d..464ba2c 100644 (file)
@@ -1,25 +1,26 @@
-/* Copyright (c) 2009-2018. The SimGrid Team. All rights reserved.          */
+/* Copyright (c) 2009-2019. The SimGrid Team. All rights reserved.          */
 
 /* This program is free software; you can redistribute it and/or modify it
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
-#include "private.hpp"
 #include "smpi_coll.hpp"
 #include "smpi_comm.hpp"
 #include "smpi_datatype.hpp"
 #include "smpi_group.hpp"
-#include "smpi_process.hpp"
 #include "smpi_request.hpp"
 #include "xbt/replay.hpp"
 #include <simgrid/smpi/replay.hpp>
+#include <src/smpi/include/private.hpp>
 
-#include <boost/algorithm/string/join.hpp>
 #include <memory>
 #include <numeric>
 #include <unordered_map>
 #include <vector>
 
 #include <tuple>
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_replay, smpi, "Trace Replay with SMPI");
+
 // From https://stackoverflow.com/questions/7110301/generic-hash-for-tuples-in-unordered-map-unordered-set
 // This is all just to make std::unordered_map work with std::tuple. If we need this in other places,
 // this could go into a header file.
@@ -60,13 +61,10 @@ public:
 };
 }
 
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_replay,smpi,"Trace Replay with SMPI");
-
 typedef std::tuple</*sender*/ int, /* reciever */ int, /* tag */int> req_key_t;
 typedef std::unordered_map<req_key_t, MPI_Request, hash_tuple::hash<std::tuple<int,int,int>>> req_storage_t;
 
-
-static void log_timed_action(simgrid::xbt::ReplayAction& action, double clock)
+void log_timed_action(simgrid::xbt::ReplayAction& action, double clock)
 {
   if (XBT_LOG_ISENABLED(smpi_replay, xbt_log_priority_verbose)){
     std::string s = boost::algorithm::join(action, " ");
@@ -75,7 +73,7 @@ static void log_timed_action(simgrid::xbt::ReplayAction& action, double clock)
 }
 
 /* Helper function */
-static double parse_double(std::string string)
+static double parse_double(const std::string& string)
 {
   return xbt_str_parse_double(string.c_str(), "%s is not a double");
 }
@@ -136,11 +134,14 @@ public:
     /* Sometimes we need to re-insert MPI_REQUEST_NULL but we still need src,dst and tag */
     void addNullRequest(int src, int dst, int tag)
     {
-      store.insert({req_key_t(src, dst, tag), MPI_REQUEST_NULL});
+      store.insert({req_key_t(
+            MPI_COMM_WORLD->group()->actor(src)->get_pid()-1,
+            MPI_COMM_WORLD->group()->actor(dst)->get_pid()-1,
+            tag), MPI_REQUEST_NULL});
     }
 };
 
-void WaitTestParser::parse(simgrid::xbt::ReplayAction& action, std::string name)
+void WaitTestParser::parse(simgrid::xbt::ReplayAction& action, const std::string&)
 {
   CHECK_ACTION_PARAMS(action, 3, 0)
   src = std::stoi(action[2]);
@@ -148,7 +149,7 @@ void WaitTestParser::parse(simgrid::xbt::ReplayAction& action, std::string name)
   tag = std::stoi(action[4]);
 }
 
-void SendRecvParser::parse(simgrid::xbt::ReplayAction& action, std::string name)
+void SendRecvParser::parse(simgrid::xbt::ReplayAction& action, const std::string&)
 {
   CHECK_ACTION_PARAMS(action, 3, 1)
   partner = std::stoi(action[2]);
@@ -158,14 +159,13 @@ void SendRecvParser::parse(simgrid::xbt::ReplayAction& action, std::string name)
     datatype1 = simgrid::smpi::Datatype::decode(action[5]);
 }
 
-
-void ComputeParser::parse(simgrid::xbt::ReplayAction& action, std::string name)
+void ComputeParser::parse(simgrid::xbt::ReplayAction& action, const std::string&)
 {
   CHECK_ACTION_PARAMS(action, 1, 0)
   flops = parse_double(action[2]);
 }
 
-void BcastArgParser::parse(simgrid::xbt::ReplayAction& action, std::string name)
+void BcastArgParser::parse(simgrid::xbt::ReplayAction& action, const std::string&)
 {
   CHECK_ACTION_PARAMS(action, 1, 2)
   size = parse_double(action[2]);
@@ -174,7 +174,7 @@ void BcastArgParser::parse(simgrid::xbt::ReplayAction& action, std::string name)
     datatype1 = simgrid::smpi::Datatype::decode(action[4]);
 }
 
-void ReduceArgParser::parse(simgrid::xbt::ReplayAction& action, std::string name)
+void ReduceArgParser::parse(simgrid::xbt::ReplayAction& action, const std::string&)
 {
   CHECK_ACTION_PARAMS(action, 2, 2)
   comm_size = parse_double(action[2]);
@@ -184,7 +184,7 @@ void ReduceArgParser::parse(simgrid::xbt::ReplayAction& action, std::string name
     datatype1 = simgrid::smpi::Datatype::decode(action[5]);
 }
 
-void AllReduceArgParser::parse(simgrid::xbt::ReplayAction& action, std::string name)
+void AllReduceArgParser::parse(simgrid::xbt::ReplayAction& action, const std::string&)
 {
   CHECK_ACTION_PARAMS(action, 2, 1)
   comm_size = parse_double(action[2]);
@@ -193,7 +193,7 @@ void AllReduceArgParser::parse(simgrid::xbt::ReplayAction& action, std::string n
     datatype1 = simgrid::smpi::Datatype::decode(action[4]);
 }
 
-void AllToAllArgParser::parse(simgrid::xbt::ReplayAction& action, std::string name)
+void AllToAllArgParser::parse(simgrid::xbt::ReplayAction& action, const std::string&)
 {
   CHECK_ACTION_PARAMS(action, 2, 1)
   comm_size = MPI_COMM_WORLD->size();
@@ -206,7 +206,7 @@ void AllToAllArgParser::parse(simgrid::xbt::ReplayAction& action, std::string na
     datatype2 = simgrid::smpi::Datatype::decode(action[5]);
 }
 
-void GatherArgParser::parse(simgrid::xbt::ReplayAction& action, std::string name)
+void GatherArgParser::parse(simgrid::xbt::ReplayAction& action, const std::string& name)
 {
   /* The structure of the gather action for the rank 0 (total 4 processes) is the following:
         0 gather 68 68 0 0 0
@@ -228,8 +228,7 @@ void GatherArgParser::parse(simgrid::xbt::ReplayAction& action, std::string name
       datatype1 = simgrid::smpi::Datatype::decode(action[5]);
     if (action.size() > 6)
       datatype2 = simgrid::smpi::Datatype::decode(action[6]);
-  }
-  else {
+  } else {
     if (action.size() > 4)
       datatype1 = simgrid::smpi::Datatype::decode(action[4]);
     if (action.size() > 5)
@@ -237,7 +236,7 @@ void GatherArgParser::parse(simgrid::xbt::ReplayAction& action, std::string name
   }
 }
 
-void GatherVArgParser::parse(simgrid::xbt::ReplayAction& action, std::string name)
+void GatherVArgParser::parse(simgrid::xbt::ReplayAction& action, const std::string& name)
 {
   /* The structure of the gatherv action for the rank 0 (total 4 processes) is the following:
        0 gather 68 68 10 10 10 0 0 0
@@ -249,19 +248,18 @@ void GatherVArgParser::parse(simgrid::xbt::ReplayAction& action, std::string nam
        5) 0 is the recv datatype id, see simgrid::smpi::Datatype::decode()
   */
   comm_size = MPI_COMM_WORLD->size();
-  CHECK_ACTION_PARAMS(action, comm_size+1, 2)
-  send_size = parse_double(action[2]);
-  disps     = std::vector<int>(comm_size, 0);
+  CHECK_ACTION_PARAMS(action, comm_size + 1, 2)
+  send_size  = parse_double(action[2]);
+  disps      = std::vector<int>(comm_size, 0);
   recvcounts = std::shared_ptr<std::vector<int>>(new std::vector<int>(comm_size));
 
-  if (name == "gatherV") {
+  if (name == "gatherv") {
     root = (action.size() > 3 + comm_size) ? std::stoi(action[3 + comm_size]) : 0;
     if (action.size() > 4 + comm_size)
       datatype1 = simgrid::smpi::Datatype::decode(action[4 + comm_size]);
     if (action.size() > 5 + comm_size)
       datatype2 = simgrid::smpi::Datatype::decode(action[5 + comm_size]);
-  }
-  else {
+  } else {
     int datatype_index = 0;
     int disp_index     = 0;
     /* The 3 comes from "0 gather <sendcount>", which must always be present.
@@ -272,9 +270,10 @@ void GatherVArgParser::parse(simgrid::xbt::ReplayAction& action, std::string nam
       disp_index     = datatype_index + 1;
       datatype1      = simgrid::smpi::Datatype::decode(action[datatype_index]);
       datatype2      = simgrid::smpi::Datatype::decode(action[datatype_index]);
-    } else if (action.size() > 3 + comm_size + 2) { /* disps specified; datatype is not specified; use the default one */
-      disp_index     = 3 + comm_size;
-    } else if (action.size() > 3 + comm_size)  { /* only datatype, no disp specified */
+    } else if (action.size() >
+               3 + comm_size + 2) { /* disps specified; datatype is not specified; use the default one */
+      disp_index = 3 + comm_size;
+    } else if (action.size() > 3 + comm_size) { /* only datatype, no disp specified */
       datatype_index = 3 + comm_size;
       datatype1      = simgrid::smpi::Datatype::decode(action[datatype_index]);
       datatype2      = simgrid::smpi::Datatype::decode(action[datatype_index]);
@@ -292,7 +291,7 @@ void GatherVArgParser::parse(simgrid::xbt::ReplayAction& action, std::string nam
   recv_size_sum = std::accumulate(recvcounts->begin(), recvcounts->end(), 0);
 }
 
-void ScatterArgParser::parse(simgrid::xbt::ReplayAction& action, std::string name)
+void ScatterArgParser::parse(simgrid::xbt::ReplayAction& action, const std::string&)
 {
   /* The structure of the scatter action for the rank 0 (total 4 processes) is the following:
         0 gather 68 68 0 0 0
@@ -304,17 +303,17 @@ void ScatterArgParser::parse(simgrid::xbt::ReplayAction& action, std::string nam
         5) 0 is the recv datatype id, see simgrid::smpi::Datatype::decode()
   */
   CHECK_ACTION_PARAMS(action, 2, 3)
-  comm_size   = MPI_COMM_WORLD->size();
-  send_size   = parse_double(action[2]);
-  recv_size   = parse_double(action[3]);
-  root   = (action.size() > 4) ? std::stoi(action[4]) : 0;
+  comm_size = MPI_COMM_WORLD->size();
+  send_size = parse_double(action[2]);
+  recv_size = parse_double(action[3]);
+  root      = (action.size() > 4) ? std::stoi(action[4]) : 0;
   if (action.size() > 5)
     datatype1 = simgrid::smpi::Datatype::decode(action[5]);
   if (action.size() > 6)
     datatype2 = simgrid::smpi::Datatype::decode(action[6]);
 }
 
-void ScatterVArgParser::parse(simgrid::xbt::ReplayAction& action, std::string name)
+void ScatterVArgParser::parse(simgrid::xbt::ReplayAction& action, const std::string&)
 {
   /* The structure of the scatterv action for the rank 0 (total 4 processes) is the following:
      0 gather 68 10 10 10 68 0 0 0
@@ -339,21 +338,21 @@ void ScatterVArgParser::parse(simgrid::xbt::ReplayAction& action, std::string na
     (*sendcounts)[i] = std::stoi(action[i + 2]);
   }
   send_size_sum = std::accumulate(sendcounts->begin(), sendcounts->end(), 0);
-  root = (action.size() > 3 + comm_size) ? std::stoi(action[3 + comm_size]) : 0;
+  root          = (action.size() > 3 + comm_size) ? std::stoi(action[3 + comm_size]) : 0;
 }
 
-void ReduceScatterArgParser::parse(simgrid::xbt::ReplayAction& action, std::string name)
+void ReduceScatterArgParser::parse(simgrid::xbt::ReplayAction& action, const std::string&)
 {
   /* The structure of the reducescatter action for the rank 0 (total 4 processes) is the following:
-       0 reduceScatter 275427 275427 275427 204020 11346849 0
+       0 reducescatter 275427 275427 275427 204020 11346849 0
      where:
        1) The first four values after the name of the action declare the recvcounts array
        2) The value 11346849 is the amount of instructions
        3) The last value corresponds to the datatype, see simgrid::smpi::Datatype::decode().
   */
   comm_size = MPI_COMM_WORLD->size();
-  CHECK_ACTION_PARAMS(action, comm_size+1, 1)
-  comp_size = parse_double(action[2+comm_size]);
+  CHECK_ACTION_PARAMS(action, comm_size + 1, 1)
+  comp_size  = parse_double(action[2 + comm_size]);
   recvcounts = std::shared_ptr<std::vector<int>>(new std::vector<int>(comm_size));
   if (action.size() > 3 + comm_size)
     datatype1 = simgrid::smpi::Datatype::decode(action[3 + comm_size]);
@@ -364,10 +363,10 @@ void ReduceScatterArgParser::parse(simgrid::xbt::ReplayAction& action, std::stri
   recv_size_sum = std::accumulate(recvcounts->begin(), recvcounts->end(), 0);
 }
 
-void AllToAllVArgParser::parse(simgrid::xbt::ReplayAction& action, std::string name)
+void AllToAllVArgParser::parse(simgrid::xbt::ReplayAction& action, const std::string&)
 {
-  /* The structure of the allToAllV action for the rank 0 (total 4 processes) is the following:
-        0 allToAllV 100 1 7 10 12 100 1 70 10 5
+  /* The structure of the alltoallv action for the rank 0 (total 4 processes) is the following:
+        0 alltoallv 100 1 7 10 12 100 1 70 10 5
      where:
       1) 100 is the size of the send buffer *sizeof(int),
       2) 1 7 10 12 is the sendcounts array
@@ -375,7 +374,7 @@ void AllToAllVArgParser::parse(simgrid::xbt::ReplayAction& action, std::string n
       4)  1 70 10 5 is the recvcounts array
   */
   comm_size = MPI_COMM_WORLD->size();
-  CHECK_ACTION_PARAMS(action, 2*comm_size+2, 2)
+  CHECK_ACTION_PARAMS(action, 2 * comm_size + 2, 2)
   sendcounts = std::shared_ptr<std::vector<int>>(new std::vector<int>(comm_size));
   recvcounts = std::shared_ptr<std::vector<int>>(new std::vector<int>(comm_size));
   senddisps  = std::vector<int>(comm_size, 0);
@@ -386,8 +385,8 @@ void AllToAllVArgParser::parse(simgrid::xbt::ReplayAction& action, std::string n
   if (action.size() > 5 + 2 * comm_size)
     datatype2 = simgrid::smpi::Datatype::decode(action[5 + 2 * comm_size]);
 
-  send_buf_size=parse_double(action[2]);
-  recv_buf_size=parse_double(action[3+comm_size]);
+  send_buf_size = parse_double(action[2]);
+  recv_buf_size = parse_double(action[3 + comm_size]);
   for (unsigned int i = 0; i < comm_size; i++) {
     (*sendcounts)[i] = std::stoi(action[3 + i]);
     (*recvcounts)[i] = std::stoi(action[4 + comm_size + i]);
@@ -396,482 +395,389 @@ void AllToAllVArgParser::parse(simgrid::xbt::ReplayAction& action, std::string n
   recv_size_sum = std::accumulate(recvcounts->begin(), recvcounts->end(), 0);
 }
 
-template<class T>
-void ReplayAction<T>::execute(simgrid::xbt::ReplayAction& action)
+void WaitAction::kernel(simgrid::xbt::ReplayAction& action)
 {
-  // Needs to be re-initialized for every action, hence here
-  double start_time = smpi_process()->simulated_elapsed();
-  args.parse(action, name);
-  kernel(action);
-  if (name != "Init")
-    log_timed_action(action, start_time);
-}
+  std::string s = boost::algorithm::join(action, " ");
+  xbt_assert(req_storage.size(), "action wait not preceded by any irecv or isend: %s", s.c_str());
+  MPI_Request request = req_storage.find(args.src, args.dst, args.tag);
+  req_storage.remove(request);
 
-class WaitAction : public ReplayAction<WaitTestParser> {
-private:
-  RequestStorage& req_storage;
+  if (request == MPI_REQUEST_NULL) {
+    /* Assume that the trace is well formed, meaning the comm might have been caught by a MPI_test. Then just
+     * return.*/
+    return;
+  }
 
-public:
-  explicit WaitAction(RequestStorage& storage) : ReplayAction("Wait"), req_storage(storage) {}
-  void kernel(simgrid::xbt::ReplayAction& action) override
-  {
-    std::string s = boost::algorithm::join(action, " ");
-    xbt_assert(req_storage.size(), "action wait not preceded by any irecv or isend: %s", s.c_str());
-    MPI_Request request = req_storage.find(args.src, args.dst, args.tag);
-    req_storage.remove(request);
-
-    if (request == MPI_REQUEST_NULL) {
-      /* Assume that the trace is well formed, meaning the comm might have been caught by a MPI_test. Then just
-       * return.*/
-      return;
-    }
+  int rank = request->comm() != MPI_COMM_NULL ? request->comm()->rank() : -1;
 
-    int rank = request->comm() != MPI_COMM_NULL ? request->comm()->rank() : -1;
+  // Must be taken before Request::wait() since the request may be set to
+  // MPI_REQUEST_NULL by Request::wait!
+  bool is_wait_for_receive = (request->flags() & MPI_REQ_RECV);
+  // TODO: Here we take the rank while we normally take the process id (look for my_proc_id)
+  TRACE_smpi_comm_in(rank, __func__, new simgrid::instr::WaitTIData(args.src, args.dst, args.tag));
 
-    // Must be taken before Request::wait() since the request may be set to
-    // MPI_REQUEST_NULL by Request::wait!
-    bool is_wait_for_receive = (request->flags() & RECV);
-    // TODO: Here we take the rank while we normally take the process id (look for my_proc_id)
-    TRACE_smpi_comm_in(rank, __func__, new simgrid::instr::NoOpTIData("wait"));
+  MPI_Status status;
+  Request::wait(&request, &status);
 
-    MPI_Status status;
-    Request::wait(&request, &status);
+  TRACE_smpi_comm_out(rank);
+  if (is_wait_for_receive)
+    TRACE_smpi_recv(args.src, args.dst, args.tag);
+}
 
-    TRACE_smpi_comm_out(rank);
-    if (is_wait_for_receive)
-      TRACE_smpi_recv(args.src, args.dst, args.tag);
+void SendAction::kernel(simgrid::xbt::ReplayAction&)
+{
+  int dst_traced = MPI_COMM_WORLD->group()->actor(args.partner)->get_pid();
+
+  TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::Pt2PtTIData(name, args.partner, args.size,
+        args.tag, Datatype::encode(args.datatype1)));
+  if (not TRACE_smpi_view_internals())
+    TRACE_smpi_send(my_proc_id, my_proc_id, dst_traced, args.tag, args.size * args.datatype1->size());
+
+  if (name == "send") {
+    Request::send(nullptr, args.size, args.datatype1, args.partner, args.tag, MPI_COMM_WORLD);
+  } else if (name == "isend") {
+    MPI_Request request = Request::isend(nullptr, args.size, args.datatype1, args.partner, args.tag, MPI_COMM_WORLD);
+    req_storage.add(request);
+  } else {
+    xbt_die("Don't know this action, %s", name.c_str());
   }
-};
-
-class SendAction : public ReplayAction<SendRecvParser> {
-private:
-  RequestStorage& req_storage;
-
-public:
-  explicit SendAction(std::string name, RequestStorage& storage) : ReplayAction(name), req_storage(storage) {}
-  void kernel(simgrid::xbt::ReplayAction& action) override
-  {
-    int dst_traced = MPI_COMM_WORLD->group()->actor(args.partner)->get_pid();
-
-    TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::Pt2PtTIData(name, args.partner, args.size,
-                                                                             args.tag, Datatype::encode(args.datatype1)));
-    if (not TRACE_smpi_view_internals())
-      TRACE_smpi_send(my_proc_id, my_proc_id, dst_traced, args.tag, args.size * args.datatype1->size());
 
-    if (name == "send") {
-      Request::send(nullptr, args.size, args.datatype1, args.partner, args.tag, MPI_COMM_WORLD);
-    } else if (name == "Isend") {
-      MPI_Request request = Request::isend(nullptr, args.size, args.datatype1, args.partner, args.tag, MPI_COMM_WORLD);
-      req_storage.add(request);
-    } else {
-      xbt_die("Don't know this action, %s", name.c_str());
-    }
+  TRACE_smpi_comm_out(my_proc_id);
+}
 
-    TRACE_smpi_comm_out(my_proc_id);
+void RecvAction::kernel(simgrid::xbt::ReplayAction&)
+{
+  TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::Pt2PtTIData(name, args.partner, args.size,
+        args.tag, Datatype::encode(args.datatype1)));
+
+  MPI_Status status;
+  // unknown size from the receiver point of view
+  if (args.size <= 0.0) {
+    Request::probe(args.partner, args.tag, MPI_COMM_WORLD, &status);
+    args.size = status.count;
+  }
+
+  bool is_recv = false; // Help analyzers understanding that status is not used unintialized
+  if (name == "recv") {
+    is_recv = true;
+    Request::recv(nullptr, args.size, args.datatype1, args.partner, args.tag, MPI_COMM_WORLD, &status);
+  } else if (name == "irecv") {
+    MPI_Request request = Request::irecv(nullptr, args.size, args.datatype1, args.partner, args.tag, MPI_COMM_WORLD);
+    req_storage.add(request);
+  } else {
+    THROW_IMPOSSIBLE;
   }
-};
 
-class RecvAction : public ReplayAction<SendRecvParser> {
-private:
-  RequestStorage& req_storage;
+  TRACE_smpi_comm_out(my_proc_id);
+  if (is_recv && not TRACE_smpi_view_internals()) {
+    int src_traced = MPI_COMM_WORLD->group()->actor(status.MPI_SOURCE)->get_pid();
+    TRACE_smpi_recv(src_traced, my_proc_id, args.tag);
+  }
+}
 
-public:
-  explicit RecvAction(std::string name, RequestStorage& storage) : ReplayAction(name), req_storage(storage) {}
-  void kernel(simgrid::xbt::ReplayAction& action) override
-  {
-    int src_traced = MPI_COMM_WORLD->group()->actor(args.partner)->get_pid();
+void ComputeAction::kernel(simgrid::xbt::ReplayAction&)
+{
+  TRACE_smpi_computing_in(my_proc_id, args.flops);
+  smpi_execute_flops(args.flops);
+  TRACE_smpi_computing_out(my_proc_id);
+}
 
-    TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::Pt2PtTIData(name, args.partner, args.size,
-                                                                             args.tag, Datatype::encode(args.datatype1)));
+void TestAction::kernel(simgrid::xbt::ReplayAction&)
+{
+  MPI_Request request = req_storage.find(args.src, args.dst, args.tag);
+  req_storage.remove(request);
+  // if request is null here, this may mean that a previous test has succeeded
+  // Different times in traced application and replayed version may lead to this
+  // In this case, ignore the extra calls.
+  if (request != MPI_REQUEST_NULL) {
+    TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::NoOpTIData("test"));
 
     MPI_Status status;
-    // unknown size from the receiver point of view
-    if (args.size <= 0.0) {
-      Request::probe(args.partner, args.tag, MPI_COMM_WORLD, &status);
-      args.size = status.count;
-    }
-
-    if (name == "recv") {
-      Request::recv(nullptr, args.size, args.datatype1, args.partner, args.tag, MPI_COMM_WORLD, &status);
-    } else if (name == "Irecv") {
-      MPI_Request request = Request::irecv(nullptr, args.size, args.datatype1, args.partner, args.tag, MPI_COMM_WORLD);
+    int flag = 0;
+    Request::test(&request, &status, &flag);
+
+    XBT_DEBUG("MPI_Test result: %d", flag);
+    /* push back request in vector to be caught by a subsequent wait. if the test did succeed, the request is now
+     * nullptr.*/
+    if (request == MPI_REQUEST_NULL)
+      req_storage.addNullRequest(args.src, args.dst, args.tag);
+    else
       req_storage.add(request);
-    }
 
     TRACE_smpi_comm_out(my_proc_id);
-    // TODO: Check why this was only activated in the "recv" case and not in the "Irecv" case
-    if (name == "recv" && not TRACE_smpi_view_internals()) {
-      TRACE_smpi_recv(src_traced, my_proc_id, args.tag);
-    }
-  }
-};
-
-class ComputeAction : public ReplayAction<ComputeParser> {
-public:
-  ComputeAction() : ReplayAction("compute") {}
-  void kernel(simgrid::xbt::ReplayAction& action) override
-  {
-    TRACE_smpi_computing_in(my_proc_id, args.flops);
-    smpi_execute_flops(args.flops);
-    TRACE_smpi_computing_out(my_proc_id);
-  }
-};
-
-class TestAction : public ReplayAction<WaitTestParser> {
-private:
-  RequestStorage& req_storage;
-
-public:
-  explicit TestAction(RequestStorage& storage) : ReplayAction("Test"), req_storage(storage) {}
-  void kernel(simgrid::xbt::ReplayAction& action) override
-  {
-    MPI_Request request = req_storage.find(args.src, args.dst, args.tag);
-    req_storage.remove(request);
-    // if request is null here, this may mean that a previous test has succeeded
-    // Different times in traced application and replayed version may lead to this
-    // In this case, ignore the extra calls.
-    if (request != MPI_REQUEST_NULL) {
-      TRACE_smpi_testing_in(my_proc_id);
-
-      MPI_Status status;
-      int flag = Request::test(&request, &status);
-
-      XBT_DEBUG("MPI_Test result: %d", flag);
-      /* push back request in vector to be caught by a subsequent wait. if the test did succeed, the request is now
-       * nullptr.*/
-      if (request == MPI_REQUEST_NULL)
-        req_storage.addNullRequest(args.src, args.dst, args.tag);
-      else
-        req_storage.add(request);
-
-      TRACE_smpi_testing_out(my_proc_id);
-    }
   }
-};
+}
 
-class InitAction : public ReplayAction<ActionArgParser> {
-public:
-  InitAction() : ReplayAction("Init") {}
-  void kernel(simgrid::xbt::ReplayAction& action) override
-  {
-    CHECK_ACTION_PARAMS(action, 0, 1)
+void InitAction::kernel(simgrid::xbt::ReplayAction& action)
+{
+  CHECK_ACTION_PARAMS(action, 0, 1)
     MPI_DEFAULT_TYPE = (action.size() > 2) ? MPI_DOUBLE // default MPE datatype
-                                           : MPI_BYTE;  // default TAU datatype
-
-    /* start a simulated timer */
-    smpi_process()->simulated_start();
-  }
-};
+    : MPI_BYTE;  // default TAU datatype
 
-class CommunicatorAction : public ReplayAction<ActionArgParser> {
-public:
-  CommunicatorAction() : ReplayAction("Comm") {}
-  void kernel(simgrid::xbt::ReplayAction& action) override { /* nothing to do */}
-};
+  /* start a simulated timer */
+  smpi_process()->simulated_start();
+}
 
-class WaitAllAction : public ReplayAction<ActionArgParser> {
-private:
-  RequestStorage& req_storage;
+void CommunicatorAction::kernel(simgrid::xbt::ReplayAction&)
+{
+  /* nothing to do */
+}
 
-public:
-  explicit WaitAllAction(RequestStorage& storage) : ReplayAction("waitAll"), req_storage(storage) {}
-  void kernel(simgrid::xbt::ReplayAction& action) override
-  {
-    const unsigned int count_requests = req_storage.size();
-
-    if (count_requests > 0) {
-      TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::Pt2PtTIData("waitAll", -1, count_requests, ""));
-      std::vector<std::pair</*sender*/int,/*recv*/int>> sender_receiver;
-      std::vector<MPI_Request> reqs;
-      req_storage.get_requests(reqs);
-      for (const auto& req : reqs) {
-        if (req && (req->flags() & RECV)) {
-          sender_receiver.push_back({req->src(), req->dst()});
-        }
-      }
-      MPI_Status status[count_requests];
-      Request::waitall(count_requests, &(reqs.data())[0], status);
-      req_storage.get_store().clear();
+void WaitAllAction::kernel(simgrid::xbt::ReplayAction&)
+{
+  const unsigned int count_requests = req_storage.size();
 
-      for (auto& pair : sender_receiver) {
-        TRACE_smpi_recv(pair.first, pair.second, 0);
+  if (count_requests > 0) {
+    TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::Pt2PtTIData("waitall", -1, count_requests, ""));
+    std::vector<std::pair</*sender*/int,/*recv*/int>> sender_receiver;
+    std::vector<MPI_Request> reqs;
+    req_storage.get_requests(reqs);
+    for (const auto& req : reqs) {
+      if (req && (req->flags() & MPI_REQ_RECV)) {
+        sender_receiver.push_back({req->src(), req->dst()});
       }
-      TRACE_smpi_comm_out(my_proc_id);
     }
-  }
-};
+    MPI_Status status[count_requests];
+    Request::waitall(count_requests, &(reqs.data())[0], status);
+    req_storage.get_store().clear();
 
-class BarrierAction : public ReplayAction<ActionArgParser> {
-public:
-  BarrierAction() : ReplayAction("barrier") {}
-  void kernel(simgrid::xbt::ReplayAction& action) override
-  {
-    TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::NoOpTIData("barrier"));
-    Colls::barrier(MPI_COMM_WORLD);
+    for (auto& pair : sender_receiver) {
+      TRACE_smpi_recv(pair.first, pair.second, 0);
+    }
     TRACE_smpi_comm_out(my_proc_id);
   }
-};
+}
 
-class BcastAction : public ReplayAction<BcastArgParser> {
-public:
-  BcastAction() : ReplayAction("bcast") {}
-  void kernel(simgrid::xbt::ReplayAction& action) override
-  {
-    TRACE_smpi_comm_in(my_proc_id, "action_bcast",
-                       new simgrid::instr::CollTIData("bcast", MPI_COMM_WORLD->group()->actor(args.root)->get_pid(),
-                                                      -1.0, args.size, -1, Datatype::encode(args.datatype1), ""));
+void BarrierAction::kernel(simgrid::xbt::ReplayAction&)
+{
+  TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::NoOpTIData("barrier"));
+  Colls::barrier(MPI_COMM_WORLD);
+  TRACE_smpi_comm_out(my_proc_id);
+}
 
-    Colls::bcast(send_buffer(args.size * args.datatype1->size()), args.size, args.datatype1, args.root, MPI_COMM_WORLD);
+void BcastAction::kernel(simgrid::xbt::ReplayAction&)
+{
+  TRACE_smpi_comm_in(my_proc_id, "action_bcast",
+      new simgrid::instr::CollTIData("bcast", MPI_COMM_WORLD->group()->actor(args.root)->get_pid(),
+        -1.0, args.size, -1, Datatype::encode(args.datatype1), ""));
 
-    TRACE_smpi_comm_out(my_proc_id);
-  }
-};
+  Colls::bcast(send_buffer(args.size * args.datatype1->size()), args.size, args.datatype1, args.root, MPI_COMM_WORLD);
 
-class ReduceAction : public ReplayAction<ReduceArgParser> {
-public:
-  ReduceAction() : ReplayAction("reduce") {}
-  void kernel(simgrid::xbt::ReplayAction& action) override
-  {
-    TRACE_smpi_comm_in(my_proc_id, "action_reduce",
-                       new simgrid::instr::CollTIData("reduce", MPI_COMM_WORLD->group()->actor(args.root)->get_pid(),
-                                                      args.comp_size, args.comm_size, -1,
-                                                      Datatype::encode(args.datatype1), ""));
+  TRACE_smpi_comm_out(my_proc_id);
+}
 
-    Colls::reduce(send_buffer(args.comm_size * args.datatype1->size()),
-        recv_buffer(args.comm_size * args.datatype1->size()), args.comm_size, args.datatype1, MPI_OP_NULL, args.root, MPI_COMM_WORLD);
-    smpi_execute_flops(args.comp_size);
+void ReduceAction::kernel(simgrid::xbt::ReplayAction&)
+{
+  TRACE_smpi_comm_in(my_proc_id, "action_reduce",
+      new simgrid::instr::CollTIData("reduce", MPI_COMM_WORLD->group()->actor(args.root)->get_pid(),
+        args.comp_size, args.comm_size, -1,
+        Datatype::encode(args.datatype1), ""));
 
-    TRACE_smpi_comm_out(my_proc_id);
-  }
-};
+  Colls::reduce(send_buffer(args.comm_size * args.datatype1->size()),
+      recv_buffer(args.comm_size * args.datatype1->size()), args.comm_size, args.datatype1, MPI_OP_NULL, args.root, MPI_COMM_WORLD);
+  smpi_execute_flops(args.comp_size);
 
-class AllReduceAction : public ReplayAction<AllReduceArgParser> {
-public:
-  AllReduceAction() : ReplayAction("allReduce") {}
-  void kernel(simgrid::xbt::ReplayAction& action) override
-  {
-    TRACE_smpi_comm_in(my_proc_id, "action_allReduce", new simgrid::instr::CollTIData("allReduce", -1, args.comp_size, args.comm_size, -1,
-                                                                                Datatype::encode(args.datatype1), ""));
+  TRACE_smpi_comm_out(my_proc_id);
+}
 
-    Colls::allreduce(send_buffer(args.comm_size * args.datatype1->size()),
-        recv_buffer(args.comm_size * args.datatype1->size()), args.comm_size, args.datatype1, MPI_OP_NULL, MPI_COMM_WORLD);
-    smpi_execute_flops(args.comp_size);
+void AllReduceAction::kernel(simgrid::xbt::ReplayAction&)
+{
+  TRACE_smpi_comm_in(my_proc_id, "action_allreduce", new simgrid::instr::CollTIData("allreduce", -1, args.comp_size, args.comm_size, -1,
+        Datatype::encode(args.datatype1), ""));
 
-    TRACE_smpi_comm_out(my_proc_id);
-  }
-};
+  Colls::allreduce(send_buffer(args.comm_size * args.datatype1->size()),
+      recv_buffer(args.comm_size * args.datatype1->size()), args.comm_size, args.datatype1, MPI_OP_NULL, MPI_COMM_WORLD);
+  smpi_execute_flops(args.comp_size);
 
-class AllToAllAction : public ReplayAction<AllToAllArgParser> {
-public:
-  AllToAllAction() : ReplayAction("allToAll") {}
-  void kernel(simgrid::xbt::ReplayAction& action) override
-  {
-    TRACE_smpi_comm_in(my_proc_id, "action_allToAll",
-                     new simgrid::instr::CollTIData("allToAll", -1, -1.0, args.send_size, args.recv_size,
-                                                    Datatype::encode(args.datatype1),
-                                                    Datatype::encode(args.datatype2)));
+  TRACE_smpi_comm_out(my_proc_id);
+}
 
-    Colls::alltoall(send_buffer(args.send_size * args.comm_size * args.datatype1->size()), args.send_size,
-                    args.datatype1, recv_buffer(args.recv_size * args.comm_size * args.datatype2->size()),
-                    args.recv_size, args.datatype2, MPI_COMM_WORLD);
+void AllToAllAction::kernel(simgrid::xbt::ReplayAction&)
+{
+  TRACE_smpi_comm_in(my_proc_id, "action_alltoall",
+      new simgrid::instr::CollTIData("alltoall", -1, -1.0, args.send_size, args.recv_size,
+        Datatype::encode(args.datatype1),
+        Datatype::encode(args.datatype2)));
 
-    TRACE_smpi_comm_out(my_proc_id);
-  }
-};
+  Colls::alltoall(send_buffer(args.send_size * args.comm_size * args.datatype1->size()), args.send_size,
+      args.datatype1, recv_buffer(args.recv_size * args.comm_size * args.datatype2->size()),
+      args.recv_size, args.datatype2, MPI_COMM_WORLD);
 
-class GatherAction : public ReplayAction<GatherArgParser> {
-public:
-  explicit GatherAction(std::string name) : ReplayAction(name) {}
-  void kernel(simgrid::xbt::ReplayAction& action) override
-  {
-    TRACE_smpi_comm_in(my_proc_id, name.c_str(), new simgrid::instr::CollTIData(name, (name == "gather") ? args.root : -1, -1.0, args.send_size, args.recv_size,
-                                                                          Datatype::encode(args.datatype1), Datatype::encode(args.datatype2)));
+  TRACE_smpi_comm_out(my_proc_id);
+}
 
-    if (name == "gather") {
-      int rank = MPI_COMM_WORLD->rank();
-      Colls::gather(send_buffer(args.send_size * args.datatype1->size()), args.send_size, args.datatype1,
-                 (rank == args.root) ? recv_buffer(args.recv_size * args.comm_size * args.datatype2->size()) : nullptr, args.recv_size, args.datatype2, args.root, MPI_COMM_WORLD);
-    }
-    else
-      Colls::allgather(send_buffer(args.send_size * args.datatype1->size()), args.send_size, args.datatype1,
-                       recv_buffer(args.recv_size * args.datatype2->size()), args.recv_size, args.datatype2, MPI_COMM_WORLD);
+void GatherAction::kernel(simgrid::xbt::ReplayAction&)
+{
+  TRACE_smpi_comm_in(my_proc_id, name.c_str(), new simgrid::instr::CollTIData(name, (name == "gather") ? args.root : -1, -1.0, args.send_size, args.recv_size,
+        Datatype::encode(args.datatype1), Datatype::encode(args.datatype2)));
 
-    TRACE_smpi_comm_out(my_proc_id);
+  if (name == "gather") {
+    int rank = MPI_COMM_WORLD->rank();
+    Colls::gather(send_buffer(args.send_size * args.datatype1->size()), args.send_size, args.datatype1,
+        (rank == args.root) ? recv_buffer(args.recv_size * args.comm_size * args.datatype2->size()) : nullptr, args.recv_size, args.datatype2, args.root, MPI_COMM_WORLD);
   }
-};
+  else
+    Colls::allgather(send_buffer(args.send_size * args.datatype1->size()), args.send_size, args.datatype1,
+        recv_buffer(args.recv_size * args.datatype2->size()), args.recv_size, args.datatype2, MPI_COMM_WORLD);
 
-class GatherVAction : public ReplayAction<GatherVArgParser> {
-public:
-  explicit GatherVAction(std::string name) : ReplayAction(name) {}
-  void kernel(simgrid::xbt::ReplayAction& action) override
-  {
-    int rank = MPI_COMM_WORLD->rank();
+  TRACE_smpi_comm_out(my_proc_id);
+}
 
-    TRACE_smpi_comm_in(my_proc_id, name.c_str(), new simgrid::instr::VarCollTIData(
-                                               name, (name == "gatherV") ? args.root : -1, args.send_size, nullptr, -1, args.recvcounts,
-                                               Datatype::encode(args.datatype1), Datatype::encode(args.datatype2)));
+void GatherVAction::kernel(simgrid::xbt::ReplayAction&)
+{
+  int rank = MPI_COMM_WORLD->rank();
 
-    if (name == "gatherV") {
-      Colls::gatherv(send_buffer(args.send_size * args.datatype1->size()), args.send_size, args.datatype1,
-                     (rank == args.root) ? recv_buffer(args.recv_size_sum * args.datatype2->size()) : nullptr,
-                     args.recvcounts->data(), args.disps.data(), args.datatype2, args.root, MPI_COMM_WORLD);
-    }
-    else {
-      Colls::allgatherv(send_buffer(args.send_size * args.datatype1->size()), args.send_size, args.datatype1,
-                        recv_buffer(args.recv_size_sum * args.datatype2->size()), args.recvcounts->data(),
-                        args.disps.data(), args.datatype2, MPI_COMM_WORLD);
-    }
+  TRACE_smpi_comm_in(my_proc_id, name.c_str(), new simgrid::instr::VarCollTIData(
+        name, (name == "gatherv") ? args.root : -1, args.send_size, nullptr, -1, args.recvcounts,
+        Datatype::encode(args.datatype1), Datatype::encode(args.datatype2)));
 
-    TRACE_smpi_comm_out(my_proc_id);
+  if (name == "gatherv") {
+    Colls::gatherv(send_buffer(args.send_size * args.datatype1->size()), args.send_size, args.datatype1,
+        (rank == args.root) ? recv_buffer(args.recv_size_sum * args.datatype2->size()) : nullptr,
+        args.recvcounts->data(), args.disps.data(), args.datatype2, args.root, MPI_COMM_WORLD);
+  }
+  else {
+    Colls::allgatherv(send_buffer(args.send_size * args.datatype1->size()), args.send_size, args.datatype1,
+        recv_buffer(args.recv_size_sum * args.datatype2->size()), args.recvcounts->data(),
+        args.disps.data(), args.datatype2, MPI_COMM_WORLD);
   }
-};
 
-class ScatterAction : public ReplayAction<ScatterArgParser> {
-public:
-  ScatterAction() : ReplayAction("scatter") {}
-  void kernel(simgrid::xbt::ReplayAction& action) override
-  {
-    int rank = MPI_COMM_WORLD->rank();
-    TRACE_smpi_comm_in(my_proc_id, "action_scatter", new simgrid::instr::CollTIData(name, args.root, -1.0, args.send_size, args.recv_size,
-                                                                          Datatype::encode(args.datatype1),
-                                                                          Datatype::encode(args.datatype2)));
+  TRACE_smpi_comm_out(my_proc_id);
+}
 
-    Colls::scatter(send_buffer(args.send_size * args.datatype1->size()), args.send_size, args.datatype1,
-                  (rank == args.root) ? recv_buffer(args.recv_size * args.datatype2->size()) : nullptr, args.recv_size, args.datatype2, args.root, MPI_COMM_WORLD);
+void ScatterAction::kernel(simgrid::xbt::ReplayAction&)
+{
+  int rank = MPI_COMM_WORLD->rank();
+  TRACE_smpi_comm_in(my_proc_id, "action_scatter", new simgrid::instr::CollTIData(name, args.root, -1.0, args.send_size, args.recv_size,
+        Datatype::encode(args.datatype1),
+        Datatype::encode(args.datatype2)));
 
-    TRACE_smpi_comm_out(my_proc_id);
-  }
-};
+  Colls::scatter(send_buffer(args.send_size * args.datatype1->size()), args.send_size, args.datatype1,
+      (rank == args.root) ? recv_buffer(args.recv_size * args.datatype2->size()) : nullptr, args.recv_size, args.datatype2, args.root, MPI_COMM_WORLD);
 
+  TRACE_smpi_comm_out(my_proc_id);
+}
 
-class ScatterVAction : public ReplayAction<ScatterVArgParser> {
-public:
-  ScatterVAction() : ReplayAction("scatterV") {}
-  void kernel(simgrid::xbt::ReplayAction& action) override
-  {
-    int rank = MPI_COMM_WORLD->rank();
-    TRACE_smpi_comm_in(my_proc_id, "action_scatterv", new simgrid::instr::VarCollTIData(name, args.root, -1, args.sendcounts, args.recv_size,
-          nullptr, Datatype::encode(args.datatype1),
-          Datatype::encode(args.datatype2)));
+void ScatterVAction::kernel(simgrid::xbt::ReplayAction&)
+{
+  int rank = MPI_COMM_WORLD->rank();
+  TRACE_smpi_comm_in(my_proc_id, "action_scatterv", new simgrid::instr::VarCollTIData(name, args.root, -1, args.sendcounts, args.recv_size,
+        nullptr, Datatype::encode(args.datatype1),
+        Datatype::encode(args.datatype2)));
 
-    Colls::scatterv((rank == args.root) ? send_buffer(args.send_size_sum * args.datatype1->size()) : nullptr,
-                    args.sendcounts->data(), args.disps.data(), args.datatype1,
-                    recv_buffer(args.recv_size * args.datatype2->size()), args.recv_size, args.datatype2, args.root,
-                    MPI_COMM_WORLD);
+  Colls::scatterv((rank == args.root) ? send_buffer(args.send_size_sum * args.datatype1->size()) : nullptr,
+      args.sendcounts->data(), args.disps.data(), args.datatype1,
+      recv_buffer(args.recv_size * args.datatype2->size()), args.recv_size, args.datatype2, args.root,
+      MPI_COMM_WORLD);
 
-    TRACE_smpi_comm_out(my_proc_id);
-  }
-};
+  TRACE_smpi_comm_out(my_proc_id);
+}
 
-class ReduceScatterAction : public ReplayAction<ReduceScatterArgParser> {
-public:
-  ReduceScatterAction() : ReplayAction("reduceScatter") {}
-  void kernel(simgrid::xbt::ReplayAction& action) override
-  {
-    TRACE_smpi_comm_in(my_proc_id, "action_reducescatter",
-                       new simgrid::instr::VarCollTIData("reduceScatter", -1, 0, nullptr, -1, args.recvcounts,
-                                                         std::to_string(args.comp_size), /* ugly hack to print comp_size */
-                                                         Datatype::encode(args.datatype1)));
+void ReduceScatterAction::kernel(simgrid::xbt::ReplayAction&)
+{
+  TRACE_smpi_comm_in(my_proc_id, "action_reducescatter",
+      new simgrid::instr::VarCollTIData("reducescatter", -1, 0, nullptr, -1, args.recvcounts,
+        std::to_string(args.comp_size), /* ugly hack to print comp_size */
+        Datatype::encode(args.datatype1)));
 
-    Colls::reduce_scatter(send_buffer(args.recv_size_sum * args.datatype1->size()),
-                          recv_buffer(args.recv_size_sum * args.datatype1->size()), args.recvcounts->data(),
-                          args.datatype1, MPI_OP_NULL, MPI_COMM_WORLD);
+  Colls::reduce_scatter(send_buffer(args.recv_size_sum * args.datatype1->size()),
+      recv_buffer(args.recv_size_sum * args.datatype1->size()), args.recvcounts->data(),
+      args.datatype1, MPI_OP_NULL, MPI_COMM_WORLD);
 
-    smpi_execute_flops(args.comp_size);
-    TRACE_smpi_comm_out(my_proc_id);
-  }
-};
+  smpi_execute_flops(args.comp_size);
+  TRACE_smpi_comm_out(my_proc_id);
+}
 
-class AllToAllVAction : public ReplayAction<AllToAllVArgParser> {
-public:
-  AllToAllVAction() : ReplayAction("allToAllV") {}
-  void kernel(simgrid::xbt::ReplayAction& action) override
-  {
-    TRACE_smpi_comm_in(my_proc_id, __func__,
-                       new simgrid::instr::VarCollTIData(
-                           "allToAllV", -1, args.send_size_sum, args.sendcounts, args.recv_size_sum, args.recvcounts,
-                           Datatype::encode(args.datatype1), Datatype::encode(args.datatype2)));
+void AllToAllVAction::kernel(simgrid::xbt::ReplayAction&)
+{
+  TRACE_smpi_comm_in(my_proc_id, __func__,
+      new simgrid::instr::VarCollTIData(
+        "alltoallv", -1, args.send_size_sum, args.sendcounts, args.recv_size_sum, args.recvcounts,
+        Datatype::encode(args.datatype1), Datatype::encode(args.datatype2)));
 
-    Colls::alltoallv(send_buffer(args.send_buf_size * args.datatype1->size()), args.sendcounts->data(), args.senddisps.data(), args.datatype1,
-                     recv_buffer(args.recv_buf_size * args.datatype2->size()), args.recvcounts->data(), args.recvdisps.data(), args.datatype2, MPI_COMM_WORLD);
+  Colls::alltoallv(send_buffer(args.send_buf_size * args.datatype1->size()), args.sendcounts->data(), args.senddisps.data(), args.datatype1,
+      recv_buffer(args.recv_buf_size * args.datatype2->size()), args.recvcounts->data(), args.recvdisps.data(), args.datatype2, MPI_COMM_WORLD);
 
-    TRACE_smpi_comm_out(my_proc_id);
-  }
-};
+  TRACE_smpi_comm_out(my_proc_id);
+}
 } // Replay Namespace
 }} // namespace simgrid::smpi
 
-std::vector<simgrid::smpi::replay::RequestStorage> storage;
+static std::unordered_map<aid_t, simgrid::smpi::replay::RequestStorage> storage;
 /** @brief Only initialize the replay, don't do it for real */
-void smpi_replay_init(int* argc, char*** argv)
+void smpi_replay_init(const char* instance_id, int rank, double start_delay_flops)
 {
-  simgrid::smpi::Process::init(argc, argv);
+  xbt_assert(not smpi_process()->initializing());
+
+  simgrid::s4u::Actor::self()->set_property("instance_id", instance_id);
+  simgrid::s4u::Actor::self()->set_property("rank", std::to_string(rank));
+  simgrid::smpi::ActorExt::init();
+
   smpi_process()->mark_as_initialized();
   smpi_process()->set_replaying(true);
 
   int my_proc_id = simgrid::s4u::this_actor::get_pid();
-  storage.resize(smpi_process_count());
 
   TRACE_smpi_init(my_proc_id);
   TRACE_smpi_computing_init(my_proc_id);
   TRACE_smpi_comm_in(my_proc_id, "smpi_replay_run_init", new simgrid::instr::NoOpTIData("init"));
   TRACE_smpi_comm_out(my_proc_id);
   xbt_replay_action_register("init", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::InitAction().execute(action); });
-  xbt_replay_action_register("finalize", [](simgrid::xbt::ReplayAction& action) { /* nothing to do */ });
+  xbt_replay_action_register("finalize", [](simgrid::xbt::ReplayAction&) { /* nothing to do */ });
   xbt_replay_action_register("comm_size", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::CommunicatorAction().execute(action); });
   xbt_replay_action_register("comm_split",[](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::CommunicatorAction().execute(action); });
   xbt_replay_action_register("comm_dup",  [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::CommunicatorAction().execute(action); });
-  xbt_replay_action_register("send",  [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::SendAction("send", storage[simgrid::s4u::this_actor::get_pid()-1]).execute(action); });
-  xbt_replay_action_register("Isend", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::SendAction("Isend", storage[simgrid::s4u::this_actor::get_pid()-1]).execute(action); });
-  xbt_replay_action_register("recv",  [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::RecvAction("recv", storage[simgrid::s4u::this_actor::get_pid()-1]).execute(action); });
-  xbt_replay_action_register("Irecv", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::RecvAction("Irecv", storage[simgrid::s4u::this_actor::get_pid()-1]).execute(action); });
-  xbt_replay_action_register("test",  [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::TestAction(storage[simgrid::s4u::this_actor::get_pid()-1]).execute(action); });
-  xbt_replay_action_register("wait",  [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::WaitAction(storage[simgrid::s4u::this_actor::get_pid()-1]).execute(action); });
-  xbt_replay_action_register("waitAll", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::WaitAllAction(storage[simgrid::s4u::this_actor::get_pid()-1]).execute(action); });
+  xbt_replay_action_register("send",  [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::SendAction("send", storage[simgrid::s4u::this_actor::get_pid()]).execute(action); });
+  xbt_replay_action_register("isend", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::SendAction("isend", storage[simgrid::s4u::this_actor::get_pid()]).execute(action); });
+  xbt_replay_action_register("recv",  [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::RecvAction("recv", storage[simgrid::s4u::this_actor::get_pid()]).execute(action); });
+  xbt_replay_action_register("irecv", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::RecvAction("irecv", storage[simgrid::s4u::this_actor::get_pid()]).execute(action); });
+  xbt_replay_action_register("test",  [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::TestAction(storage[simgrid::s4u::this_actor::get_pid()]).execute(action); });
+  xbt_replay_action_register("wait",  [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::WaitAction(storage[simgrid::s4u::this_actor::get_pid()]).execute(action); });
+  xbt_replay_action_register("waitall", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::WaitAllAction(storage[simgrid::s4u::this_actor::get_pid()]).execute(action); });
   xbt_replay_action_register("barrier", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::BarrierAction().execute(action); });
   xbt_replay_action_register("bcast",   [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::BcastAction().execute(action); });
   xbt_replay_action_register("reduce",  [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::ReduceAction().execute(action); });
-  xbt_replay_action_register("allReduce", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::AllReduceAction().execute(action); });
-  xbt_replay_action_register("allToAll", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::AllToAllAction().execute(action); });
-  xbt_replay_action_register("allToAllV", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::AllToAllVAction().execute(action); });
+  xbt_replay_action_register("allreduce", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::AllReduceAction().execute(action); });
+  xbt_replay_action_register("alltoall", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::AllToAllAction().execute(action); });
+  xbt_replay_action_register("alltoallv", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::AllToAllVAction().execute(action); });
   xbt_replay_action_register("gather",   [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::GatherAction("gather").execute(action); });
   xbt_replay_action_register("scatter",  [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::ScatterAction().execute(action); });
-  xbt_replay_action_register("gatherV",  [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::GatherVAction("gatherV").execute(action); });
-  xbt_replay_action_register("scatterV", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::ScatterVAction().execute(action); });
-  xbt_replay_action_register("allGather", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::GatherAction("allGather").execute(action); });
-  xbt_replay_action_register("allGatherV", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::GatherVAction("allGatherV").execute(action); });
-  xbt_replay_action_register("reduceScatter", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::ReduceScatterAction().execute(action); });
+  xbt_replay_action_register("gatherv",  [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::GatherVAction("gatherv").execute(action); });
+  xbt_replay_action_register("scatterv", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::ScatterVAction().execute(action); });
+  xbt_replay_action_register("allgather", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::GatherAction("allgather").execute(action); });
+  xbt_replay_action_register("allgatherv", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::GatherVAction("allgatherv").execute(action); });
+  xbt_replay_action_register("reducescatter", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::ReduceScatterAction().execute(action); });
   xbt_replay_action_register("compute", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::ComputeAction().execute(action); });
 
   //if we have a delayed start, sleep here.
-  if(*argc>2){
-    double value = xbt_str_parse_double((*argv)[2], "%s is not a double");
-    XBT_VERB("Delayed start for instance - Sleeping for %f flops ",value );
-    smpi_execute_flops(value);
+  if (start_delay_flops > 0) {
+    XBT_VERB("Delayed start for instance - Sleeping for %f flops ", start_delay_flops);
+    smpi_execute_flops(start_delay_flops);
   } else {
-    //UGLY: force a context switch to be sure that all MSG_processes begin initialization
-    XBT_DEBUG("Force context switch by smpi_execute_flops  - Sleeping for 0.0 flops ");
-    smpi_execute_flops(0.0);
+    // Wait for the other actors to initialize also
+    simgrid::s4u::this_actor::yield();
   }
 }
 
 /** @brief actually run the replay after initialization */
-void smpi_replay_main(int* argc, char*** argv)
+void smpi_replay_main(int rank, const char* trace_filename)
 {
   static int active_processes = 0;
   active_processes++;
-  simgrid::xbt::replay_runner(*argc, *argv);
+  storage[simgrid::s4u::this_actor::get_pid()] = simgrid::smpi::replay::RequestStorage();
+  std::string rank_string                      = std::to_string(rank);
+  simgrid::xbt::replay_runner(rank_string.c_str(), trace_filename);
 
   /* and now, finalize everything */
   /* One active process will stop. Decrease the counter*/
-  unsigned int count_requests = storage[simgrid::s4u::this_actor::get_pid() - 1].size();
+  unsigned int count_requests = storage[simgrid::s4u::this_actor::get_pid()].size();
   XBT_DEBUG("There are %ud elements in reqq[*]", count_requests);
   if (count_requests > 0) {
     MPI_Request requests[count_requests];
     MPI_Status status[count_requests];
     unsigned int i=0;
 
-    for (auto const& pair : storage[simgrid::s4u::this_actor::get_pid() - 1].get_store()) {
+    for (auto const& pair : storage[simgrid::s4u::this_actor::get_pid()].get_store()) {
       requests[i] = pair.second;
       i++;
     }
@@ -895,8 +801,8 @@ void smpi_replay_main(int* argc, char*** argv)
 }
 
 /** @brief chain a replay initialization and a replay start */
-void smpi_replay_run(int* argc, char*** argv)
+void smpi_replay_run(const char* instance_id, int rank, double start_delay_flops, const char* trace_filename)
 {
-  smpi_replay_init(argc, argv);
-  smpi_replay_main(argc, argv);
+  smpi_replay_init(instance_id, rank, start_delay_flops);
+  smpi_replay_main(rank, trace_filename);
 }