Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Fix multiple memleaks in the replay of multiple SMPI instances
[simgrid.git] / include / simgrid / smpi / replay.hpp
1 /* Copyright (c) 2009-2018. The SimGrid Team. All rights reserved.          */
2
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_
7
8 #include "src/smpi/include/smpi_actor.hpp"
9
10 #include <boost/algorithm/string/join.hpp>
11 #include <xbt/replay.hpp>
12 #include <xbt/ex.h>
13
14 #include <memory>
15 #include <sstream>
16
17 #define CHECK_ACTION_PARAMS(action, mandatory, optional)                                                               \
18   {                                                                                                                    \
19     if (action.size() < static_cast<unsigned long>(mandatory + 2)) {                                                   \
20       std::stringstream ss;                                                                                            \
21       ss << __func__ << " replay failed.\n"                                                                            \
22          << action.size() << " items were given on the line. First two should be process_id and action.  "             \
23          << "This action needs after them " << mandatory << " mandatory arguments, and accepts " << optional           \
24          << " optional ones. \n"                                                                                       \
25          << "The full line that was given is:\n   ";                                                                   \
26       for (const auto& elem : action) {                                                                                \
27         ss << elem << " ";                                                                                             \
28       }                                                                                                                \
29       ss << "\nPlease contact the Simgrid team if support is needed";                                                  \
30       throw std::invalid_argument(ss.str());                                                                           \
31     }                                                                                                                  \
32   }
33
34 XBT_PRIVATE void* smpi_get_tmp_sendbuffer(int size);
35 XBT_PRIVATE void* smpi_get_tmp_recvbuffer(int size);
36 XBT_PRIVATE void smpi_free_tmp_buffer(void* buf);
37
38 XBT_PRIVATE void log_timed_action(simgrid::xbt::ReplayAction& action, double clock);
39
40 namespace simgrid {
41 namespace smpi {
42 namespace replay {
43 extern MPI_Datatype MPI_DEFAULT_TYPE;
44
45 class RequestStorage; // Forward decl
46
47 /**
48  * Base class for all parsers.
49  */
50 class ActionArgParser {
51 public:
52   virtual ~ActionArgParser() = default;
53   virtual void parse(simgrid::xbt::ReplayAction& action, std::string name) { CHECK_ACTION_PARAMS(action, 0, 0) }
54 };
55
56 class WaitTestParser : public ActionArgParser {
57 public:
58   int src;
59   int dst;
60   int tag;
61
62   void parse(simgrid::xbt::ReplayAction& action, std::string name) override;
63 };
64
65 class SendRecvParser : public ActionArgParser {
66 public:
67   /* communication partner; if we send, this is the receiver and vice versa */
68   int partner;
69   double size;
70   int tag;
71   MPI_Datatype datatype1 = MPI_DEFAULT_TYPE;
72
73   void parse(simgrid::xbt::ReplayAction& action, std::string name) override;
74 };
75
76 class ComputeParser : public ActionArgParser {
77 public:
78   /* communication partner; if we send, this is the receiver and vice versa */
79   double flops;
80
81   void parse(simgrid::xbt::ReplayAction& action, std::string name) override;
82 };
83
84 class CollCommParser : public ActionArgParser {
85 public:
86   double size;
87   double comm_size;
88   double comp_size;
89   int send_size;
90   int recv_size;
91   int root = 0;
92   MPI_Datatype datatype1 = MPI_DEFAULT_TYPE;
93   MPI_Datatype datatype2 = MPI_DEFAULT_TYPE;
94 };
95
96 class BcastArgParser : public CollCommParser {
97 public:
98   void parse(simgrid::xbt::ReplayAction& action, std::string name) override;
99 };
100
101 class ReduceArgParser : public CollCommParser {
102 public:
103   void parse(simgrid::xbt::ReplayAction& action, std::string name) override;
104 };
105
106 class AllReduceArgParser : public CollCommParser {
107 public:
108   void parse(simgrid::xbt::ReplayAction& action, std::string name) override;
109 };
110
111 class AllToAllArgParser : public CollCommParser {
112 public:
113   void parse(simgrid::xbt::ReplayAction& action, std::string name) override;
114 };
115
116 class GatherArgParser : public CollCommParser {
117 public:
118   void parse(simgrid::xbt::ReplayAction& action, std::string name) override;
119 };
120
121 class GatherVArgParser : public CollCommParser {
122 public:
123   int recv_size_sum;
124   std::shared_ptr<std::vector<int>> recvcounts;
125   std::vector<int> disps;
126   void parse(simgrid::xbt::ReplayAction& action, std::string name) override;
127 };
128
129 class ScatterArgParser : public CollCommParser {
130 public:
131   void parse(simgrid::xbt::ReplayAction& action, std::string name) override;
132 };
133
134 class ScatterVArgParser : public CollCommParser {
135 public:
136   int recv_size_sum;
137   int send_size_sum;
138   std::shared_ptr<std::vector<int>> sendcounts;
139   std::vector<int> disps;
140   void parse(simgrid::xbt::ReplayAction& action, std::string name) override;
141 };
142
143 class ReduceScatterArgParser : public CollCommParser {
144 public:
145   int recv_size_sum;
146   std::shared_ptr<std::vector<int>> recvcounts;
147   std::vector<int> disps;
148   void parse(simgrid::xbt::ReplayAction& action, std::string name) override;
149 };
150
151 class AllToAllVArgParser : public CollCommParser {
152 public:
153   int recv_size_sum;
154   int send_size_sum;
155   std::shared_ptr<std::vector<int>> recvcounts;
156   std::shared_ptr<std::vector<int>> sendcounts;
157   std::vector<int> senddisps;
158   std::vector<int> recvdisps;
159   int send_buf_size;
160   int recv_buf_size;
161   void parse(simgrid::xbt::ReplayAction& action, std::string name) override;
162 };
163
164 /**
165  * Base class for all ReplayActions.
166  * Note that this class actually implements the behavior of each action
167  * while the parsing of the replay arguments is done in the @ref ActionArgParser class.
168  * In other words: The logic goes here, the setup is done by the ActionArgParser.
169  */
170 template <class T> class ReplayAction {
171 protected:
172   const std::string name;
173   const aid_t my_proc_id;
174   T args;
175
176 public:
177   explicit ReplayAction(std::string name) : name(name), my_proc_id(simgrid::s4u::this_actor::get_pid()) {}
178   virtual ~ReplayAction() = default;
179
180   void execute(simgrid::xbt::ReplayAction& action)
181   {
182     // Needs to be re-initialized for every action, hence here
183     double start_time = smpi_process()->simulated_elapsed();
184     args.parse(action, name);
185     kernel(action);
186     if (name != "Init")
187       log_timed_action(action, start_time);
188   }
189
190   virtual void kernel(simgrid::xbt::ReplayAction& action) = 0;
191   void* send_buffer(int size) { return smpi_get_tmp_sendbuffer(size); }
192   void* recv_buffer(int size) { return smpi_get_tmp_recvbuffer(size); }
193 };
194
195 class WaitAction : public ReplayAction<WaitTestParser> {
196 private:
197   RequestStorage& req_storage;
198
199 public:
200   explicit WaitAction(RequestStorage& storage) : ReplayAction("Wait"), req_storage(storage) {}
201   void kernel(simgrid::xbt::ReplayAction& action) override;
202 };
203
204 class SendAction : public ReplayAction<SendRecvParser> {
205 private:
206   RequestStorage& req_storage;
207
208 public:
209   explicit SendAction(std::string name, RequestStorage& storage) : ReplayAction(name), req_storage(storage) {}
210   void kernel(simgrid::xbt::ReplayAction& action) override;
211 };
212
213 class RecvAction : public ReplayAction<SendRecvParser> {
214 private:
215   RequestStorage& req_storage;
216
217 public:
218   explicit RecvAction(std::string name, RequestStorage& storage) : ReplayAction(name), req_storage(storage) {}
219   void kernel(simgrid::xbt::ReplayAction& action) override;
220 };
221
222 class ComputeAction : public ReplayAction<ComputeParser> {
223 public:
224   explicit ComputeAction() : ReplayAction("compute") {}
225   void kernel(simgrid::xbt::ReplayAction& action) override;
226 };
227
228 class TestAction : public ReplayAction<WaitTestParser> {
229 private:
230   RequestStorage& req_storage;
231
232 public:
233   explicit TestAction(RequestStorage& storage) : ReplayAction("Test"), req_storage(storage) {}
234   void kernel(simgrid::xbt::ReplayAction& action) override;
235 };
236
237 class InitAction : public ReplayAction<ActionArgParser> {
238 public:
239   explicit InitAction() : ReplayAction("Init") {}
240   void kernel(simgrid::xbt::ReplayAction& action) override;
241 };
242
243 class CommunicatorAction : public ReplayAction<ActionArgParser> {
244 public:
245   explicit CommunicatorAction() : ReplayAction("Comm") {}
246   void kernel(simgrid::xbt::ReplayAction& action) override;
247 };
248
249 class WaitAllAction : public ReplayAction<ActionArgParser> {
250 private:
251   RequestStorage& req_storage;
252
253 public:
254   explicit WaitAllAction(RequestStorage& storage) : ReplayAction("waitall"), req_storage(storage) {}
255   void kernel(simgrid::xbt::ReplayAction& action) override;
256 };
257
258 class BarrierAction : public ReplayAction<ActionArgParser> {
259 public:
260   explicit BarrierAction() : ReplayAction("barrier") {}
261   void kernel(simgrid::xbt::ReplayAction& action) override;
262 };
263
264 class BcastAction : public ReplayAction<BcastArgParser> {
265 public:
266   explicit BcastAction() : ReplayAction("bcast") {}
267   void kernel(simgrid::xbt::ReplayAction& action) override;
268 };
269
270 class ReduceAction : public ReplayAction<ReduceArgParser> {
271 public:
272   explicit ReduceAction() : ReplayAction("reduce") {}
273   void kernel(simgrid::xbt::ReplayAction& action) override;
274 };
275
276 class AllReduceAction : public ReplayAction<AllReduceArgParser> {
277 public:
278   explicit AllReduceAction() : ReplayAction("allreduce") {}
279   void kernel(simgrid::xbt::ReplayAction& action) override;
280 };
281
282 class AllToAllAction : public ReplayAction<AllToAllArgParser> {
283 public:
284   explicit AllToAllAction() : ReplayAction("alltoall") {}
285   void kernel(simgrid::xbt::ReplayAction& action) override;
286 };
287
288 class GatherAction : public ReplayAction<GatherArgParser> {
289 public:
290   explicit GatherAction(std::string name) : ReplayAction(name) {}
291   void kernel(simgrid::xbt::ReplayAction& action) override;
292 };
293
294 class GatherVAction : public ReplayAction<GatherVArgParser> {
295 public:
296   explicit GatherVAction(std::string name) : ReplayAction(name) {}
297   void kernel(simgrid::xbt::ReplayAction& action) override;
298 };
299
300 class ScatterAction : public ReplayAction<ScatterArgParser> {
301 public:
302   explicit ScatterAction() : ReplayAction("scatter") {}
303   void kernel(simgrid::xbt::ReplayAction& action) override;
304 };
305
306 class ScatterVAction : public ReplayAction<ScatterVArgParser> {
307 public:
308   explicit ScatterVAction() : ReplayAction("scatterv") {}
309   void kernel(simgrid::xbt::ReplayAction& action) override;
310 };
311
312 class ReduceScatterAction : public ReplayAction<ReduceScatterArgParser> {
313 public:
314   explicit ReduceScatterAction() : ReplayAction("reducescatter") {}
315   void kernel(simgrid::xbt::ReplayAction& action) override;
316 };
317
318 class AllToAllVAction : public ReplayAction<AllToAllVArgParser> {
319 public:
320   explicit AllToAllVAction() : ReplayAction("alltoallv") {}
321   void kernel(simgrid::xbt::ReplayAction& action) override;
322 };
323 }
324 }
325 }
326
327 #endif