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);
41 extern MPI_Datatype MPI_DEFAULT_TYPE;
43 class RequestStorage; // Forward decl
46 * Base class for all parsers.
48 class ActionArgParser {
50 virtual ~ActionArgParser() = default;
51 virtual void parse(xbt::ReplayAction& action, const std::string& name) { CHECK_ACTION_PARAMS(action, 0, 0) }
54 class WaitTestParser : public ActionArgParser {
60 void parse(xbt::ReplayAction& action, const std::string& name) override;
63 class SendRecvParser : public ActionArgParser {
65 /* communication partner; if we send, this is the receiver and vice versa */
69 MPI_Datatype datatype1;
71 void parse(xbt::ReplayAction& action, const std::string& name) override;
74 class ComputeParser : public ActionArgParser {
78 void parse(xbt::ReplayAction& action, const std::string& name) override;
81 class SleepParser : public ActionArgParser {
85 void parse(xbt::ReplayAction& action, const std::string& name) override;
88 class LocationParser : public ActionArgParser {
93 void parse(xbt::ReplayAction& action, const std::string& name) override;
96 class CollCommParser : public ActionArgParser {
102 unsigned comm_size; // size of communicator
104 MPI_Datatype datatype1;
105 MPI_Datatype datatype2;
108 class BcastArgParser : public CollCommParser {
110 void parse(xbt::ReplayAction& action, const std::string& name) override;
113 class ReduceArgParser : public CollCommParser {
115 void parse(xbt::ReplayAction& action, const std::string& name) override;
118 class AllReduceArgParser : public CollCommParser {
120 void parse(xbt::ReplayAction& action, const std::string& name) override;
123 class AllToAllArgParser : public CollCommParser {
125 void parse(xbt::ReplayAction& action, const std::string& name) override;
128 class GatherArgParser : public CollCommParser {
130 void parse(xbt::ReplayAction& action, const std::string& name) override;
133 class GatherVArgParser : public CollCommParser {
136 std::shared_ptr<std::vector<int>> recvcounts;
137 std::vector<int> disps;
138 void parse(xbt::ReplayAction& action, const std::string& name) override;
141 class ScatterArgParser : public CollCommParser {
143 void parse(xbt::ReplayAction& action, const std::string& name) override;
146 class ScatterVArgParser : public CollCommParser {
150 std::shared_ptr<std::vector<int>> sendcounts;
151 std::vector<int> disps;
152 void parse(xbt::ReplayAction& action, const std::string& name) override;
155 class ReduceScatterArgParser : public CollCommParser {
158 std::shared_ptr<std::vector<int>> recvcounts;
159 std::vector<int> disps;
160 void parse(xbt::ReplayAction& action, const std::string& name) override;
163 class ScanArgParser : public CollCommParser {
165 void parse(xbt::ReplayAction& action, const std::string& name) override;
168 class AllToAllVArgParser : public CollCommParser {
172 std::shared_ptr<std::vector<int>> recvcounts;
173 std::shared_ptr<std::vector<int>> sendcounts;
174 std::vector<int> senddisps;
175 std::vector<int> recvdisps;
178 void parse(xbt::ReplayAction& action, const std::string& name) override;
182 * Base class for all ReplayActions.
183 * Note that this class actually implements the behavior of each action
184 * while the parsing of the replay arguments is done in the @ref ActionArgParser class.
185 * In other words: The logic goes here, the setup is done by the ActionArgParser.
187 template <class T> class ReplayAction {
188 const std::string name_;
189 const aid_t my_proc_id_ = s4u::this_actor::get_pid();
193 const std::string& get_name() const { return name_; }
194 aid_t get_pid() const { return my_proc_id_; }
195 const T& get_args() const { return args_; }
198 explicit ReplayAction(const std::string& name) : name_(name) {}
199 virtual ~ReplayAction() = default;
201 void execute(xbt::ReplayAction& action)
203 // Needs to be re-initialized for every action, hence here
204 double start_time = smpi_process()->simulated_elapsed();
205 args_.parse(action, name_);
208 log_timed_action(action, start_time);
211 virtual void kernel(simgrid::xbt::ReplayAction& action) = 0;
212 unsigned char* send_buffer(size_t size) { return smpi_get_tmp_sendbuffer(size); }
213 unsigned char* recv_buffer(size_t size) { return smpi_get_tmp_recvbuffer(size); }
216 class WaitAction : public ReplayAction<WaitTestParser> {
217 RequestStorage& req_storage;
220 explicit WaitAction(RequestStorage& storage) : ReplayAction("Wait"), req_storage(storage) {}
221 void kernel(xbt::ReplayAction& action) override;
224 class SendAction : public ReplayAction<SendRecvParser> {
225 RequestStorage& req_storage;
228 explicit SendAction(const std::string& name, RequestStorage& storage) : ReplayAction(name), req_storage(storage) {}
229 void kernel(xbt::ReplayAction& action) override;
232 class RecvAction : public ReplayAction<SendRecvParser> {
233 RequestStorage& req_storage;
236 explicit RecvAction(const std::string& name, RequestStorage& storage) : ReplayAction(name), req_storage(storage) {}
237 void kernel(xbt::ReplayAction& action) override;
240 class ComputeAction : public ReplayAction<ComputeParser> {
242 explicit ComputeAction() : ReplayAction("compute") {}
243 void kernel(xbt::ReplayAction& action) override;
246 class SleepAction : public ReplayAction<SleepParser> {
248 explicit SleepAction() : ReplayAction("sleep") {}
249 void kernel(xbt::ReplayAction& action) override;
252 class LocationAction : public ReplayAction<LocationParser> {
254 explicit LocationAction() : ReplayAction("location") {}
255 void kernel(xbt::ReplayAction& action) override;
258 class TestAction : public ReplayAction<WaitTestParser> {
260 RequestStorage& req_storage;
263 explicit TestAction(RequestStorage& storage) : ReplayAction("Test"), req_storage(storage) {}
264 void kernel(xbt::ReplayAction& action) override;
267 class InitAction : public ReplayAction<ActionArgParser> {
269 explicit InitAction() : ReplayAction("Init") {}
270 void kernel(xbt::ReplayAction& action) override;
273 class CommunicatorAction : public ReplayAction<ActionArgParser> {
275 explicit CommunicatorAction() : ReplayAction("Comm") {}
276 void kernel(xbt::ReplayAction& action) override;
279 class WaitAllAction : public ReplayAction<ActionArgParser> {
280 RequestStorage& req_storage;
283 explicit WaitAllAction(RequestStorage& storage) : ReplayAction("waitall"), req_storage(storage) {}
284 void kernel(xbt::ReplayAction& action) override;
287 class BarrierAction : public ReplayAction<ActionArgParser> {
289 explicit BarrierAction() : ReplayAction("barrier") {}
290 void kernel(xbt::ReplayAction& action) override;
293 class BcastAction : public ReplayAction<BcastArgParser> {
295 explicit BcastAction() : ReplayAction("bcast") {}
296 void kernel(xbt::ReplayAction& action) override;
299 class ReduceAction : public ReplayAction<ReduceArgParser> {
301 explicit ReduceAction() : ReplayAction("reduce") {}
302 void kernel(xbt::ReplayAction& action) override;
305 class AllReduceAction : public ReplayAction<AllReduceArgParser> {
307 explicit AllReduceAction() : ReplayAction("allreduce") {}
308 void kernel(xbt::ReplayAction& action) override;
311 class AllToAllAction : public ReplayAction<AllToAllArgParser> {
313 explicit AllToAllAction() : ReplayAction("alltoall") {}
314 void kernel(xbt::ReplayAction& action) override;
317 class GatherAction : public ReplayAction<GatherArgParser> {
319 using ReplayAction::ReplayAction;
320 void kernel(xbt::ReplayAction& action) override;
323 class GatherVAction : public ReplayAction<GatherVArgParser> {
325 using ReplayAction::ReplayAction;
326 void kernel(xbt::ReplayAction& action) override;
329 class ScatterAction : public ReplayAction<ScatterArgParser> {
331 explicit ScatterAction() : ReplayAction("scatter") {}
332 void kernel(xbt::ReplayAction& action) override;
335 class ScatterVAction : public ReplayAction<ScatterVArgParser> {
337 explicit ScatterVAction() : ReplayAction("scatterv") {}
338 void kernel(xbt::ReplayAction& action) override;
341 class ReduceScatterAction : public ReplayAction<ReduceScatterArgParser> {
343 explicit ReduceScatterAction() : ReplayAction("reducescatter") {}
344 void kernel(xbt::ReplayAction& action) override;
347 class ScanAction : public ReplayAction<ScanArgParser> {
349 using ReplayAction::ReplayAction;
350 void kernel(xbt::ReplayAction& action) override;
353 class AllToAllVAction : public ReplayAction<AllToAllVArgParser> {
355 explicit AllToAllVAction() : ReplayAction("alltoallv") {}
356 void kernel(xbt::ReplayAction& action) override;
359 } // namespace replay
361 } // namespace simgrid