1 /* Copyright (c) 2009-2022. 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 SendRecvParser : 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 BcastArgParser : public CollCommParser {
108 void parse(xbt::ReplayAction& action, const std::string& name) override;
111 class ReduceArgParser : public CollCommParser {
113 void parse(xbt::ReplayAction& action, const std::string& name) override;
116 class AllReduceArgParser : public CollCommParser {
118 void parse(xbt::ReplayAction& action, const std::string& name) override;
121 class AllToAllArgParser : public CollCommParser {
123 void parse(xbt::ReplayAction& action, const std::string& name) override;
126 class GatherArgParser : public CollCommParser {
128 void parse(xbt::ReplayAction& action, const std::string& name) override;
131 class GatherVArgParser : public CollCommParser {
134 std::shared_ptr<std::vector<int>> recvcounts;
135 std::vector<int> disps;
136 void parse(xbt::ReplayAction& action, const std::string& name) override;
139 class ScatterArgParser : public CollCommParser {
141 void parse(xbt::ReplayAction& action, const std::string& name) override;
144 class ScatterVArgParser : public CollCommParser {
148 std::shared_ptr<std::vector<int>> sendcounts;
149 std::vector<int> disps;
150 void parse(xbt::ReplayAction& action, const std::string& name) override;
153 class ReduceScatterArgParser : public CollCommParser {
156 std::shared_ptr<std::vector<int>> recvcounts;
157 std::vector<int> disps;
158 void parse(xbt::ReplayAction& action, const std::string& name) override;
161 class ScanArgParser : public CollCommParser {
163 void parse(xbt::ReplayAction& action, const std::string& name) override;
166 class AllToAllVArgParser : public CollCommParser {
170 std::shared_ptr<std::vector<int>> recvcounts;
171 std::shared_ptr<std::vector<int>> sendcounts;
172 std::vector<int> senddisps;
173 std::vector<int> recvdisps;
176 void parse(xbt::ReplayAction& action, const std::string& name) override;
180 * Base class for all ReplayActions.
181 * Note that this class actually implements the behavior of each action
182 * while the parsing of the replay arguments is done in the @ref ActionArgParser class.
183 * In other words: The logic goes here, the setup is done by the ActionArgParser.
185 template <class T> class ReplayAction {
186 const std::string name_;
187 const aid_t my_proc_id_ = s4u::this_actor::get_pid();
191 const std::string& get_name() const { return name_; }
192 aid_t get_pid() const { return my_proc_id_; }
193 const T& get_args() const { return args_; }
196 explicit ReplayAction(const std::string& name) : name_(name) {}
197 virtual ~ReplayAction() = default;
199 void execute(xbt::ReplayAction& action)
201 // Needs to be re-initialized for every action, hence here
202 double start_time = smpi_process()->simulated_elapsed();
203 args_.parse(action, name_);
206 log_timed_action(action, start_time);
209 virtual void kernel(simgrid::xbt::ReplayAction& action) = 0;
210 unsigned char* send_buffer(size_t size) { return smpi_get_tmp_sendbuffer(size); }
211 unsigned char* recv_buffer(size_t size) { return smpi_get_tmp_recvbuffer(size); }
214 class WaitAction : public ReplayAction<WaitTestParser> {
215 RequestStorage& req_storage;
218 explicit WaitAction(RequestStorage& storage) : ReplayAction("Wait"), req_storage(storage) {}
219 void kernel(xbt::ReplayAction& action) override;
222 class SendAction : public ReplayAction<SendRecvParser> {
223 RequestStorage& req_storage;
226 explicit SendAction(const std::string& name, RequestStorage& storage) : ReplayAction(name), req_storage(storage) {}
227 void kernel(xbt::ReplayAction& action) override;
230 class RecvAction : public ReplayAction<SendRecvParser> {
231 RequestStorage& req_storage;
234 explicit RecvAction(const std::string& name, RequestStorage& storage) : ReplayAction(name), req_storage(storage) {}
235 void kernel(xbt::ReplayAction& action) override;
238 class ComputeAction : public ReplayAction<ComputeParser> {
240 explicit ComputeAction() : ReplayAction("compute") {}
241 void kernel(xbt::ReplayAction& action) override;
244 class SleepAction : public ReplayAction<SleepParser> {
246 explicit SleepAction() : ReplayAction("sleep") {}
247 void kernel(xbt::ReplayAction& action) override;
250 class LocationAction : public ReplayAction<LocationParser> {
252 explicit LocationAction() : ReplayAction("location") {}
253 void kernel(xbt::ReplayAction& action) override;
256 class TestAction : public ReplayAction<WaitTestParser> {
258 RequestStorage& req_storage;
261 explicit TestAction(RequestStorage& storage) : ReplayAction("Test"), req_storage(storage) {}
262 void kernel(xbt::ReplayAction& action) override;
265 class InitAction : public ReplayAction<ActionArgParser> {
267 explicit InitAction() : ReplayAction("Init") {}
268 void kernel(xbt::ReplayAction& action) override;
271 class CommunicatorAction : public ReplayAction<ActionArgParser> {
273 explicit CommunicatorAction() : ReplayAction("Comm") {}
274 void kernel(xbt::ReplayAction& action) override;
277 class WaitAllAction : public ReplayAction<ActionArgParser> {
278 RequestStorage& req_storage;
281 explicit WaitAllAction(RequestStorage& storage) : ReplayAction("waitall"), req_storage(storage) {}
282 void kernel(xbt::ReplayAction& action) override;
285 class BarrierAction : public ReplayAction<ActionArgParser> {
287 explicit BarrierAction() : ReplayAction("barrier") {}
288 void kernel(xbt::ReplayAction& action) override;
291 class BcastAction : public ReplayAction<BcastArgParser> {
293 explicit BcastAction() : ReplayAction("bcast") {}
294 void kernel(xbt::ReplayAction& action) override;
297 class ReduceAction : public ReplayAction<ReduceArgParser> {
299 explicit ReduceAction() : ReplayAction("reduce") {}
300 void kernel(xbt::ReplayAction& action) override;
303 class AllReduceAction : public ReplayAction<AllReduceArgParser> {
305 explicit AllReduceAction() : ReplayAction("allreduce") {}
306 void kernel(xbt::ReplayAction& action) override;
309 class AllToAllAction : public ReplayAction<AllToAllArgParser> {
311 explicit AllToAllAction() : ReplayAction("alltoall") {}
312 void kernel(xbt::ReplayAction& action) override;
315 class GatherAction : public ReplayAction<GatherArgParser> {
317 using ReplayAction::ReplayAction;
318 void kernel(xbt::ReplayAction& action) override;
321 class GatherVAction : public ReplayAction<GatherVArgParser> {
323 using ReplayAction::ReplayAction;
324 void kernel(xbt::ReplayAction& action) override;
327 class ScatterAction : public ReplayAction<ScatterArgParser> {
329 explicit ScatterAction() : ReplayAction("scatter") {}
330 void kernel(xbt::ReplayAction& action) override;
333 class ScatterVAction : public ReplayAction<ScatterVArgParser> {
335 explicit ScatterVAction() : ReplayAction("scatterv") {}
336 void kernel(xbt::ReplayAction& action) override;
339 class ReduceScatterAction : public ReplayAction<ReduceScatterArgParser> {
341 explicit ReduceScatterAction() : ReplayAction("reducescatter") {}
342 void kernel(xbt::ReplayAction& action) override;
345 class ScanAction : public ReplayAction<ScanArgParser> {
347 using ReplayAction::ReplayAction;
348 void kernel(xbt::ReplayAction& action) override;
351 class AllToAllVAction : public ReplayAction<AllToAllVArgParser> {
353 explicit AllToAllVAction() : ReplayAction("alltoallv") {}
354 void kernel(xbt::ReplayAction& action) override;
357 } // namespace simgrid::smpi::replay