1 /* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */
3 /* This program is free software; you can redistribute it and/or modify it
4 * under the terms of the license (GNU LGPL) which comes with this package. */
5 #ifndef SMPI_REPLAY_HPP_
6 #define SMPI_REPLAY_HPP_
8 #include "smpi_actor.hpp"
10 #include "xbt/replay.hpp"
12 #include <boost/algorithm/string/join.hpp>
16 #define CHECK_ACTION_PARAMS(action, mandatory, optional) \
18 if ((action).size() < static_cast<unsigned long>((mandatory) + 2)) { \
19 std::stringstream ss; \
20 ss << __func__ << " replay failed.\n" \
21 << (action).size() << " items were given on the line. First two should be process_id and action. " \
22 << "This action needs after them " << (mandatory) << " mandatory arguments, and accepts " << (optional) \
23 << " optional ones. \n" \
24 << "The full line that was given is:\n "; \
25 for (const auto& elem : (action)) { \
28 ss << "\nPlease contact the Simgrid team if support is needed"; \
29 throw std::invalid_argument(ss.str()); \
33 XBT_PRIVATE unsigned char* smpi_get_tmp_sendbuffer(size_t size);
34 XBT_PRIVATE unsigned char* smpi_get_tmp_recvbuffer(size_t size);
36 XBT_PRIVATE void log_timed_action(const simgrid::xbt::ReplayAction& action, double clock);
38 namespace simgrid::smpi::replay {
39 extern MPI_Datatype MPI_DEFAULT_TYPE;
41 class RequestStorage; // Forward decl
44 * Base class for all parsers.
46 class ActionArgParser {
48 virtual ~ActionArgParser() = default;
49 virtual void parse(xbt::ReplayAction& action, const std::string& name) { CHECK_ACTION_PARAMS(action, 0, 0) }
52 class WaitTestParser : public ActionArgParser {
58 void parse(xbt::ReplayAction& action, const std::string& name) override;
61 class SendOrRecvParser : public ActionArgParser {
63 /* communication partner; if we send, this is the receiver and vice versa */
67 MPI_Datatype datatype1;
69 void parse(xbt::ReplayAction& action, const std::string& name) override;
72 class ComputeParser : public ActionArgParser {
76 void parse(xbt::ReplayAction& action, const std::string& name) override;
79 class SleepParser : public ActionArgParser {
83 void parse(xbt::ReplayAction& action, const std::string& name) override;
86 class LocationParser : public ActionArgParser {
91 void parse(xbt::ReplayAction& action, const std::string& name) override;
94 class CollCommParser : public ActionArgParser {
100 unsigned comm_size; // size of communicator
102 MPI_Datatype datatype1;
103 MPI_Datatype datatype2;
106 class SendRecvParser : public ActionArgParser {
112 MPI_Datatype datatype1;
113 MPI_Datatype datatype2;
115 void parse(xbt::ReplayAction& action, const std::string& name) override;
118 class BcastArgParser : public CollCommParser {
120 void parse(xbt::ReplayAction& action, const std::string& name) override;
123 class ReduceArgParser : public CollCommParser {
125 void parse(xbt::ReplayAction& action, const std::string& name) override;
128 class AllReduceArgParser : public CollCommParser {
130 void parse(xbt::ReplayAction& action, const std::string& name) override;
133 class AllToAllArgParser : public CollCommParser {
135 void parse(xbt::ReplayAction& action, const std::string& name) override;
138 class GatherArgParser : public CollCommParser {
140 void parse(xbt::ReplayAction& action, const std::string& name) override;
143 class GatherVArgParser : public CollCommParser {
146 std::shared_ptr<std::vector<int>> recvcounts;
147 std::vector<int> disps;
148 void parse(xbt::ReplayAction& action, const std::string& name) override;
151 class ScatterArgParser : public CollCommParser {
153 void parse(xbt::ReplayAction& action, const std::string& name) override;
156 class ScatterVArgParser : public CollCommParser {
160 std::shared_ptr<std::vector<int>> sendcounts;
161 std::vector<int> disps;
162 void parse(xbt::ReplayAction& action, const std::string& name) override;
165 class ReduceScatterArgParser : public CollCommParser {
168 std::shared_ptr<std::vector<int>> recvcounts;
169 std::vector<int> disps;
170 void parse(xbt::ReplayAction& action, const std::string& name) override;
173 class ScanArgParser : public CollCommParser {
175 void parse(xbt::ReplayAction& action, const std::string& name) override;
178 class AllToAllVArgParser : public CollCommParser {
182 std::shared_ptr<std::vector<int>> recvcounts;
183 std::shared_ptr<std::vector<int>> sendcounts;
184 std::vector<int> senddisps;
185 std::vector<int> recvdisps;
188 void parse(xbt::ReplayAction& action, const std::string& name) override;
192 * Base class for all ReplayActions.
193 * Note that this class actually implements the behavior of each action
194 * while the parsing of the replay arguments is done in the @ref ActionArgParser class.
195 * In other words: The logic goes here, the setup is done by the ActionArgParser.
197 template <class T> class ReplayAction {
198 const std::string name_;
199 const aid_t my_proc_id_ = s4u::this_actor::get_pid();
203 const std::string& get_name() const { return name_; }
204 aid_t get_pid() const { return my_proc_id_; }
205 const T& get_args() const { return args_; }
208 explicit ReplayAction(const std::string& name) : name_(name) {}
209 virtual ~ReplayAction() = default;
211 void execute(xbt::ReplayAction& action)
213 // Needs to be re-initialized for every action, hence here
214 double start_time = smpi_process()->simulated_elapsed();
215 args_.parse(action, name_);
218 log_timed_action(action, start_time);
221 virtual void kernel(simgrid::xbt::ReplayAction& action) = 0;
222 unsigned char* send_buffer(size_t size) { return smpi_get_tmp_sendbuffer(size); }
223 unsigned char* recv_buffer(size_t size) { return smpi_get_tmp_recvbuffer(size); }
226 class WaitAction : public ReplayAction<WaitTestParser> {
227 RequestStorage& req_storage;
230 explicit WaitAction(RequestStorage& storage) : ReplayAction("Wait"), req_storage(storage) {}
231 void kernel(xbt::ReplayAction& action) override;
234 class SendAction : public ReplayAction<SendOrRecvParser> {
235 RequestStorage& req_storage;
238 explicit SendAction(const std::string& name, RequestStorage& storage) : ReplayAction(name), req_storage(storage) {}
239 void kernel(xbt::ReplayAction& action) override;
242 class RecvAction : public ReplayAction<SendOrRecvParser> {
243 RequestStorage& req_storage;
246 explicit RecvAction(const std::string& name, RequestStorage& storage) : ReplayAction(name), req_storage(storage) {}
247 void kernel(xbt::ReplayAction& action) override;
250 class ComputeAction : public ReplayAction<ComputeParser> {
252 explicit ComputeAction() : ReplayAction("compute") {}
253 void kernel(xbt::ReplayAction& action) override;
256 class SleepAction : public ReplayAction<SleepParser> {
258 explicit SleepAction() : ReplayAction("sleep") {}
259 void kernel(xbt::ReplayAction& action) override;
262 class LocationAction : public ReplayAction<LocationParser> {
264 explicit LocationAction() : ReplayAction("location") {}
265 void kernel(xbt::ReplayAction& action) override;
268 class TestAction : public ReplayAction<WaitTestParser> {
270 RequestStorage& req_storage;
273 explicit TestAction(RequestStorage& storage) : ReplayAction("Test"), req_storage(storage) {}
274 void kernel(xbt::ReplayAction& action) override;
277 class InitAction : public ReplayAction<ActionArgParser> {
279 explicit InitAction() : ReplayAction("Init") {}
280 void kernel(xbt::ReplayAction& action) override;
283 class CommunicatorAction : public ReplayAction<ActionArgParser> {
285 explicit CommunicatorAction() : ReplayAction("Comm") {}
286 void kernel(xbt::ReplayAction& action) override;
289 class WaitAllAction : public ReplayAction<ActionArgParser> {
290 RequestStorage& req_storage;
293 explicit WaitAllAction(RequestStorage& storage) : ReplayAction("waitall"), req_storage(storage) {}
294 void kernel(xbt::ReplayAction& action) override;
297 class SendRecvAction : public ReplayAction<SendRecvParser> {
299 explicit SendRecvAction() : ReplayAction("sendrecv") {}
300 void kernel(xbt::ReplayAction& action) override;
303 class BarrierAction : public ReplayAction<ActionArgParser> {
305 explicit BarrierAction() : ReplayAction("barrier") {}
306 void kernel(xbt::ReplayAction& action) override;
309 class BcastAction : public ReplayAction<BcastArgParser> {
311 explicit BcastAction() : ReplayAction("bcast") {}
312 void kernel(xbt::ReplayAction& action) override;
315 class ReduceAction : public ReplayAction<ReduceArgParser> {
317 explicit ReduceAction() : ReplayAction("reduce") {}
318 void kernel(xbt::ReplayAction& action) override;
321 class AllReduceAction : public ReplayAction<AllReduceArgParser> {
323 explicit AllReduceAction() : ReplayAction("allreduce") {}
324 void kernel(xbt::ReplayAction& action) override;
327 class AllToAllAction : public ReplayAction<AllToAllArgParser> {
329 explicit AllToAllAction() : ReplayAction("alltoall") {}
330 void kernel(xbt::ReplayAction& action) override;
333 class GatherAction : public ReplayAction<GatherArgParser> {
335 using ReplayAction::ReplayAction;
336 void kernel(xbt::ReplayAction& action) override;
339 class GatherVAction : public ReplayAction<GatherVArgParser> {
341 using ReplayAction::ReplayAction;
342 void kernel(xbt::ReplayAction& action) override;
345 class ScatterAction : public ReplayAction<ScatterArgParser> {
347 explicit ScatterAction() : ReplayAction("scatter") {}
348 void kernel(xbt::ReplayAction& action) override;
351 class ScatterVAction : public ReplayAction<ScatterVArgParser> {
353 explicit ScatterVAction() : ReplayAction("scatterv") {}
354 void kernel(xbt::ReplayAction& action) override;
357 class ReduceScatterAction : public ReplayAction<ReduceScatterArgParser> {
359 explicit ReduceScatterAction() : ReplayAction("reducescatter") {}
360 void kernel(xbt::ReplayAction& action) override;
363 class ScanAction : public ReplayAction<ScanArgParser> {
365 using ReplayAction::ReplayAction;
366 void kernel(xbt::ReplayAction& action) override;
369 class AllToAllVAction : public ReplayAction<AllToAllVArgParser> {
371 explicit AllToAllVAction() : ReplayAction("alltoallv") {}
372 void kernel(xbt::ReplayAction& action) override;
375 } // namespace simgrid::smpi::replay