+ 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)
+ MPI_DEFAULT_TYPE = (action.size() > 2) ? MPI_DOUBLE // default MPE datatype
+ : MPI_BYTE; // default TAU datatype
+
+ /* start a simulated timer */
+ smpi_process()->simulated_start();
+ }
+};
+
+class CommunicatorAction : public ReplayAction<ActionArgParser> {
+public:
+ CommunicatorAction() : ReplayAction("Comm") {}
+ void kernel(simgrid::xbt::ReplayAction& action) override { /* nothing to do */}
+};
+
+class WaitAllAction : public ReplayAction<ActionArgParser> {
+private:
+ RequestStorage& req_storage;
+
+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();
+
+ for (auto& pair : sender_receiver) {
+ TRACE_smpi_recv(pair.first, pair.second, 0);
+ }
+ TRACE_smpi_comm_out(my_proc_id);
+ }
+ }
+};
+
+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);
+ TRACE_smpi_comm_out(my_proc_id);
+ }
+};