Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of git+ssh://scm.gforge.inria.fr//gitroot/simgrid/simgrid
[simgrid.git] / src / instr / instr_paje_trace.cpp
1 /* Copyright (c) 2010-2017. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #include "simgrid/sg_config.h"
8 #include "src/instr/instr_private.hpp"
9 #include "src/instr/instr_smpi.hpp"
10 #include "src/smpi/include/private.hpp"
11 #include "typeinfo"
12 #include "xbt/virtu.h" /* sg_cmdline */
13 #include <fstream>
14
15 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(instr_paje_trace, instr, "tracing event system");
16
17 static std::stringstream stream;
18 FILE *tracing_file = nullptr;
19
20 std::map<container_t, FILE*> tracing_files; // TI specific
21
22 std::vector<simgrid::instr::PajeEvent*> buffer;
23 void buffer_debug(std::vector<simgrid::instr::PajeEvent*>* buf);
24
25 void dump_comment(std::string comment)
26 {
27   if (comment.empty())
28     return;
29   fprintf(tracing_file, "# %s\n", comment.c_str());
30 }
31
32 void dump_comment_file(std::string filename)
33 {
34   if (filename.empty())
35     return;
36   std::ifstream* fs = new std::ifstream();
37   fs->open(filename.c_str(), std::ifstream::in);
38
39   if (fs->fail()) {
40     THROWF(system_error, 1, "Comment file %s could not be opened for reading.", filename.c_str());
41   }
42   while (not fs->eof()) {
43     std::string line;
44     fprintf (tracing_file, "# ");
45     std::getline(*fs, line);
46     fprintf(tracing_file, "%s", line.c_str());
47   }
48   fs->close();
49 }
50
51 double TRACE_last_timestamp_to_dump = 0;
52 //dumps the trace file until the timestamp TRACE_last_timestamp_to_dump
53 void TRACE_paje_dump_buffer(bool force)
54 {
55   if (not TRACE_is_enabled())
56     return;
57   XBT_DEBUG("%s: dump until %f. starts", __FUNCTION__, TRACE_last_timestamp_to_dump);
58   if (force){
59     for (auto const& event : buffer) {
60       event->print();
61       delete event;
62     }
63     buffer.clear();
64   }else{
65     std::vector<simgrid::instr::PajeEvent*>::iterator i = buffer.begin();
66     for (auto const& event : buffer) {
67       double head_timestamp = event->timestamp_;
68       if (head_timestamp > TRACE_last_timestamp_to_dump)
69         break;
70       event->print();
71       delete event;
72       ++i;
73     }
74     buffer.erase(buffer.begin(), i);
75   }
76   XBT_DEBUG("%s: ends", __FUNCTION__);
77 }
78
79 void buffer_debug(std::vector<simgrid::instr::PajeEvent*>* buf);
80 void buffer_debug(std::vector<simgrid::instr::PajeEvent*>* buf)
81 {
82   return;
83   XBT_DEBUG(">>>>>> Dump the state of the buffer. %zu events", buf->size());
84   for (auto const& event : *buf) {
85     event->print();
86     XBT_DEBUG("%p %s", event, stream.str().c_str());
87     stream.str("");
88     stream.clear();
89   }
90   XBT_DEBUG("<<<<<<");
91 }
92
93 static void print_row() {
94   stream << std::endl;
95   fprintf(tracing_file, "%s", stream.str().c_str());
96   XBT_DEBUG("Dump %s", stream.str().c_str());
97   stream.str("");
98   stream.clear();
99 }
100
101 static void print_timestamp(simgrid::instr::PajeEvent* event)
102 {
103   stream << " ";
104   /* prevent 0.0000 in the trace - this was the behavior before the transition to c++ */
105   if (event->timestamp_ < 1e-12)
106     stream << 0;
107   else
108     stream << event->timestamp_;
109 }
110
111 /* internal do the instrumentation module */
112 void simgrid::instr::PajeEvent::insertIntoBuffer()
113 {
114   if (not TRACE_buffer()) {
115     print();
116     delete this;
117     return;
118   }
119   buffer_debug(&buffer);
120
121   XBT_DEBUG("%s: insert event_type=%d, timestamp=%f, buffersize=%zu)", __FUNCTION__, static_cast<int>(eventType_),
122             timestamp_, buffer.size());
123   std::vector<simgrid::instr::PajeEvent*>::reverse_iterator i;
124   for (i = buffer.rbegin(); i != buffer.rend(); ++i) {
125     simgrid::instr::PajeEvent* e1 = *i;
126     XBT_DEBUG("compare to %p is of type %d; timestamp:%f", e1, static_cast<int>(e1->eventType_), e1->timestamp_);
127     if (e1->timestamp_ <= timestamp_)
128       break;
129   }
130   if (i == buffer.rend())
131     XBT_DEBUG("%s: inserted at beginning", __FUNCTION__);
132   else if (i == buffer.rbegin())
133     XBT_DEBUG("%s: inserted at end", __FUNCTION__);
134   else
135     XBT_DEBUG("%s: inserted at pos= %zd from its end", __FUNCTION__, std::distance(buffer.rbegin(), i));
136   buffer.insert(i.base(), this);
137
138   buffer_debug(&buffer);
139 }
140
141 simgrid::instr::PajeEvent::~PajeEvent()
142 {
143   XBT_DEBUG("%s not implemented for %p: event_type=%d, timestamp=%f", __FUNCTION__, this, (int)eventType_, timestamp_);
144 }
145
146 void TRACE_paje_start() {
147   char *filename = TRACE_get_filename();
148   tracing_file = fopen(filename, "w");
149   if (tracing_file == nullptr){
150     THROWF (system_error, 1, "Tracefile %s could not be opened for writing.", filename);
151   }
152
153   XBT_DEBUG("Filename %s is open for writing", filename);
154
155   /* output generator version */
156   fprintf (tracing_file, "#This file was generated using SimGrid-%d.%d.%d\n",
157            SIMGRID_VERSION_MAJOR, SIMGRID_VERSION_MINOR, SIMGRID_VERSION_PATCH);
158   fprintf (tracing_file, "#[");
159   unsigned int cpt;
160   char *str;
161   xbt_dynar_foreach (xbt_cmdline, cpt, str){
162     fprintf(tracing_file, "%s ",str);
163   }
164   fprintf (tracing_file, "]\n");
165
166   /* output one line comment */
167   dump_comment (TRACE_get_comment());
168
169   /* output comment file */
170   dump_comment_file (TRACE_get_comment_file());
171
172   /* output header */
173   TRACE_header(TRACE_basic(),TRACE_display_sizes());
174 }
175
176 void TRACE_paje_end() {
177   fclose(tracing_file);
178   char *filename = TRACE_get_filename();
179   XBT_DEBUG("Filename %s is closed", filename);
180 }
181
182 void simgrid::instr::Type::logContainerTypeDefinition()
183 {
184   XBT_DEBUG("%s: event_type=%d", __FUNCTION__, simgrid::instr::PAJE_DefineContainerType);
185   //print it
186   if (instr_fmt_type == instr_fmt_paje) {
187     XBT_DEBUG("%s: event_type=%d, timestamp=%.*f", __FUNCTION__, simgrid::instr::PAJE_DefineContainerType,
188               TRACE_precision(), 0.);
189     stream << std::fixed << std::setprecision(TRACE_precision());
190     stream << simgrid::instr::PAJE_DefineContainerType;
191     stream << " " << id_ << " " << father_->getId() << " " << name_;
192     print_row();
193   } else if (instr_fmt_type == instr_fmt_TI) {
194     /* Nothing to do */
195   } else {
196     THROW_IMPOSSIBLE;
197   }
198 }
199
200 void simgrid::instr::Type::logVariableTypeDefinition()
201 {
202   XBT_DEBUG("%s: event_type=%d", __FUNCTION__, simgrid::instr::PAJE_DefineVariableType);
203
204   //print it
205   if (instr_fmt_type == instr_fmt_paje) {
206     XBT_DEBUG("%s: event_type=%d, timestamp=%.*f", __FUNCTION__, simgrid::instr::PAJE_DefineVariableType,
207               TRACE_precision(), 0.);
208     stream << std::fixed << std::setprecision(TRACE_precision());
209     stream << simgrid::instr::PAJE_DefineVariableType;
210     stream << " " << id_ << " " << father_->getId() << " " << name_;
211     if (isColored())
212       stream << " \"" << color_ << "\"";
213     print_row();
214   } else if (instr_fmt_type == instr_fmt_TI) {
215     /* Nothing to do */
216   } else {
217     THROW_IMPOSSIBLE;
218   }
219 }
220
221 void simgrid::instr::Type::logStateTypeDefinition()
222 {
223   //print it
224   if (instr_fmt_type == instr_fmt_paje) {
225     XBT_DEBUG("%s: event_type=%d, timestamp=%.*f", __FUNCTION__, simgrid::instr::PAJE_DefineStateType,
226               TRACE_precision(), 0.);
227     stream << std::fixed << std::setprecision(TRACE_precision());
228     stream << simgrid::instr::PAJE_DefineStateType;
229     stream << " " << id_ << " " << father_->getId() << " " << name_;
230     print_row();
231   } else if (instr_fmt_type == instr_fmt_TI) {
232     /* Nothing to do */
233   } else {
234     THROW_IMPOSSIBLE;
235   }
236 }
237
238 void simgrid::instr::Type::logDefineEventType()
239 {
240   //print it
241   if (instr_fmt_type == instr_fmt_paje) {
242     XBT_DEBUG("%s: event_type=%d, timestamp=%.*f", __FUNCTION__, simgrid::instr::PAJE_DefineEventType,
243               TRACE_precision(), 0.);
244     stream << std::fixed << std::setprecision(TRACE_precision());
245     stream << simgrid::instr::PAJE_DefineEventType;
246     stream << " " << id_ << " " << father_->getId() << " " << name_;
247     print_row();
248   } else if (instr_fmt_type == instr_fmt_TI) {
249     /* Nothing to do */
250   } else {
251     THROW_IMPOSSIBLE;
252   }
253 }
254
255 void simgrid::instr::Type::logLinkTypeDefinition(simgrid::instr::Type* source, simgrid::instr::Type* dest)
256 {
257   XBT_DEBUG("%s: event_type=%d", __FUNCTION__, simgrid::instr::PAJE_DefineLinkType);
258   //print it
259   if (instr_fmt_type == instr_fmt_paje) {
260     XBT_DEBUG("%s: event_type=%d, timestamp=%.*f", __FUNCTION__, simgrid::instr::PAJE_DefineLinkType, TRACE_precision(),
261               0.);
262     stream << std::fixed << std::setprecision(TRACE_precision());
263     stream << simgrid::instr::PAJE_DefineLinkType;
264     stream << " " << id_ << " " << father_->getId() << " " << source->getId() << " " << dest->getId() << " " << name_;
265     print_row();
266   } else if (instr_fmt_type == instr_fmt_TI) {
267     /* Nothing to do */
268   } else {
269     THROW_IMPOSSIBLE;
270   }
271 }
272
273 void simgrid::instr::Value::print()
274 {
275   XBT_DEBUG("%s: event_type=%d", __FUNCTION__, simgrid::instr::PAJE_DefineEntityValue);
276   //print it
277   if (instr_fmt_type == instr_fmt_paje) {
278     stream << std::fixed << std::setprecision(TRACE_precision());
279     stream << simgrid::instr::PAJE_DefineEntityValue;
280     stream << " " << id_ << " " << father_->getId() << " " << name_;
281     if (isColored())
282       stream << " \"" << color_ << "\"";
283     print_row();
284   } else if (instr_fmt_type == instr_fmt_TI) {
285     /* Nothing to do */
286   } else {
287     THROW_IMPOSSIBLE;
288   }
289 }
290
291
292 simgrid::instr::SetVariableEvent::SetVariableEvent(double timestamp, container_t container, Type* type, double value)
293     : simgrid::instr::PajeEvent::PajeEvent(container, type, timestamp, PAJE_SetVariable), value(value)
294 {
295   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)eventType_, this->timestamp_);
296   insertIntoBuffer();
297 }
298
299 void simgrid::instr::SetVariableEvent::print()
300 {
301   if (instr_fmt_type == instr_fmt_paje) {
302     XBT_DEBUG("%s: event_type=%d, timestamp=%.*f", __FUNCTION__, (int)eventType_, TRACE_precision(), timestamp_);
303     stream << std::fixed << std::setprecision(TRACE_precision());
304     stream << (int)this->eventType_;
305     print_timestamp(this);
306     stream << " " << type->getId() << " " << container->id_ << " " << value;
307     print_row();
308   } else if (instr_fmt_type == instr_fmt_TI) {
309     /* Nothing to do */
310   } else {
311     THROW_IMPOSSIBLE;
312   }
313 }
314
315 simgrid::instr::AddVariableEvent::AddVariableEvent(double timestamp, container_t container, simgrid::instr::Type* type,
316                                                    double value)
317     : simgrid::instr::PajeEvent::PajeEvent(container, type, timestamp, PAJE_AddVariable), value(value)
318 {
319   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)eventType_, this->timestamp_);
320   insertIntoBuffer();
321 }
322
323 void simgrid::instr::AddVariableEvent::print()
324 {
325   if (instr_fmt_type == instr_fmt_paje) {
326     XBT_DEBUG("%s: event_type=%d, timestamp=%.*f", __FUNCTION__, (int)eventType_, TRACE_precision(), timestamp_);
327     stream << std::fixed << std::setprecision(TRACE_precision());
328     stream << (int)this->eventType_;
329     print_timestamp(this);
330     stream << " " << type->getId() << " " << container->id_ << " " << value;
331     print_row();
332   } else if (instr_fmt_type == instr_fmt_TI) {
333     /* Nothing to do */
334   } else {
335     THROW_IMPOSSIBLE;
336   }
337 }
338
339 simgrid::instr::SubVariableEvent::SubVariableEvent(double timestamp, container_t container, Type* type, double value)
340     : simgrid::instr::PajeEvent::PajeEvent(container, type, timestamp, PAJE_SubVariable), value(value)
341 {
342   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)eventType_, this->timestamp_);
343   insertIntoBuffer();
344 }
345
346 void simgrid::instr::SubVariableEvent::print()
347 {
348   if (instr_fmt_type == instr_fmt_paje) {
349     XBT_DEBUG("%s: event_type=%d, timestamp=%.*f", __FUNCTION__, (int)eventType_, TRACE_precision(), timestamp_);
350     stream << std::fixed << std::setprecision(TRACE_precision());
351     stream << (int)this->eventType_;
352     print_timestamp(this);
353     stream << " " << type->getId() << " " << container->id_ << " " << value;
354     print_row();
355   } else if (instr_fmt_type == instr_fmt_TI) {
356     /* Nothing to do */
357   } else {
358     THROW_IMPOSSIBLE;
359   }
360 }
361
362 simgrid::instr::SetStateEvent::SetStateEvent(double timestamp, container_t container, Type* type, Value* value)
363     : simgrid::instr::PajeEvent::PajeEvent(container, type, timestamp, PAJE_SetState), value(value)
364 {
365 #if HAVE_SMPI
366   if (xbt_cfg_get_boolean("smpi/trace-call-location")) {
367     smpi_trace_call_location_t* loc = smpi_trace_get_call_location();
368     filename   = loc->filename;
369     linenumber = loc->linenumber;
370   }
371 #endif
372
373   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)eventType_, this->timestamp_);
374   insertIntoBuffer();
375 }
376
377 void simgrid::instr::SetStateEvent::print()
378 {
379   if (instr_fmt_type == instr_fmt_paje) {
380     XBT_DEBUG("%s: event_type=%d, timestamp=%.*f", __FUNCTION__, (int)eventType_, TRACE_precision(), timestamp_);
381     stream << std::fixed << std::setprecision(TRACE_precision());
382     stream << (int)this->eventType_;
383     print_timestamp(this);
384     stream << " " << type->getId() << " " << container->id_;
385     stream << " " << value->getId();
386 #if HAVE_SMPI
387     if (xbt_cfg_get_boolean("smpi/trace-call-location")) {
388       stream << " \"" << filename << "\" " << linenumber;
389     }
390 #endif
391     print_row();
392   } else if (instr_fmt_type == instr_fmt_TI) {
393     /* Nothing to do */
394   } else {
395     THROW_IMPOSSIBLE;
396   }
397 }
398
399 simgrid::instr::PushStateEvent::PushStateEvent(double timestamp, container_t container, Type* type, Value* value,
400                                                void* extra)
401     : simgrid::instr::PajeEvent::PajeEvent(container, type, timestamp, PAJE_PushState), value(value), extra_(extra)
402 {
403 #if HAVE_SMPI
404   if (xbt_cfg_get_boolean("smpi/trace-call-location")) {
405     smpi_trace_call_location_t* loc = smpi_trace_get_call_location();
406     filename   = loc->filename;
407     linenumber = loc->linenumber;
408   }
409 #endif
410
411   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)eventType_, this->timestamp_);
412
413   insertIntoBuffer();
414 }
415
416 simgrid::instr::PushStateEvent::PushStateEvent(double timestamp, container_t container, Type* type, Value* val)
417     : PushStateEvent(timestamp, container, type, val, nullptr)
418 {}
419 void simgrid::instr::PushStateEvent::print()
420 {
421   if (instr_fmt_type == instr_fmt_paje) {
422     XBT_DEBUG("%s: event_type=%d, timestamp=%.*f", __FUNCTION__, (int)eventType_, TRACE_precision(), timestamp_);
423     stream << std::fixed << std::setprecision(TRACE_precision());
424     stream << (int)this->eventType_;
425     print_timestamp(this);
426     stream << " " << type->getId() << " " << container->id_;
427     stream << " " << value->getId();
428
429     if (TRACE_display_sizes()) {
430       stream << " ";
431       if (extra_ != nullptr) {
432         stream << static_cast<instr_extra_data>(extra_)->send_size;
433       } else {
434         stream << 0;
435       }
436     }
437 #if HAVE_SMPI
438     if (xbt_cfg_get_boolean("smpi/trace-call-location")) {
439       stream << " \"" << filename << "\" " << linenumber;
440     }
441 #endif
442     print_row();
443
444     if (extra_ != nullptr) {
445       if (static_cast<instr_extra_data>(extra_)->sendcounts != nullptr)
446         xbt_free(static_cast<instr_extra_data>(extra_)->sendcounts);
447       if (static_cast<instr_extra_data>(extra_)->recvcounts != nullptr)
448         xbt_free(static_cast<instr_extra_data>(extra_)->recvcounts);
449       xbt_free(extra_);
450     }
451   } else if (instr_fmt_type == instr_fmt_TI) {
452     if (extra_ == nullptr)
453       return;
454     instr_extra_data extra = (instr_extra_data)extra_;
455
456     char* process_id = nullptr;
457     // FIXME: dirty extract "rank-" from the name, as we want the bare process id here
458     if (strstr(container->name_.c_str(), "rank-") == nullptr)
459       process_id = xbt_strdup(container->name_.c_str());
460     else
461       process_id = xbt_strdup(container->name_.c_str() + 5);
462
463     FILE* trace_file = tracing_files.at(container);
464
465     switch (extra->type) {
466       case TRACING_INIT:
467         fprintf(trace_file, "%s init\n", process_id);
468         break;
469       case TRACING_FINALIZE:
470         fprintf(trace_file, "%s finalize\n", process_id);
471         break;
472       case TRACING_SEND:
473         fprintf(trace_file, "%s send %d %d %s\n", process_id, extra->dst, extra->send_size, extra->datatype1);
474         break;
475       case TRACING_ISEND:
476         fprintf(trace_file, "%s Isend %d %d %s\n", process_id, extra->dst, extra->send_size, extra->datatype1);
477         break;
478       case TRACING_RECV:
479         fprintf(trace_file, "%s recv %d %d %s\n", process_id, extra->src, extra->send_size, extra->datatype1);
480         break;
481       case TRACING_IRECV:
482         fprintf(trace_file, "%s Irecv %d %d %s\n", process_id, extra->src, extra->send_size, extra->datatype1);
483         break;
484       case TRACING_TEST:
485         fprintf(trace_file, "%s test\n", process_id);
486         break;
487       case TRACING_WAIT:
488         fprintf(trace_file, "%s wait\n", process_id);
489         break;
490       case TRACING_WAITALL:
491         fprintf(trace_file, "%s waitAll\n", process_id);
492         break;
493       case TRACING_BARRIER:
494         fprintf(trace_file, "%s barrier\n", process_id);
495         break;
496       case TRACING_BCAST: // rank bcast size (root) (datatype)
497         fprintf(trace_file, "%s bcast %d ", process_id, extra->send_size);
498         if (extra->root != 0 || (extra->datatype1 && strcmp(extra->datatype1, "")))
499           fprintf(trace_file, "%d %s", extra->root, extra->datatype1);
500         fprintf(trace_file, "\n");
501         break;
502       case TRACING_REDUCE: // rank reduce comm_size comp_size (root) (datatype)
503         fprintf(trace_file, "%s reduce %d %f ", process_id, extra->send_size, extra->comp_size);
504         if (extra->root != 0 || (extra->datatype1 && strcmp(extra->datatype1, "")))
505           fprintf(trace_file, "%d %s", extra->root, extra->datatype1);
506         fprintf(trace_file, "\n");
507         break;
508       case TRACING_ALLREDUCE: // rank allreduce comm_size comp_size (datatype)
509         fprintf(trace_file, "%s allReduce %d %f %s\n", process_id, extra->send_size, extra->comp_size,
510                 extra->datatype1);
511         break;
512       case TRACING_ALLTOALL: // rank alltoall send_size recv_size (sendtype) (recvtype)
513         fprintf(trace_file, "%s allToAll %d %d %s %s\n", process_id, extra->send_size, extra->recv_size,
514                 extra->datatype1, extra->datatype2);
515         break;
516       case TRACING_ALLTOALLV: // rank alltoallv send_size [sendcounts] recv_size [recvcounts] (sendtype) (recvtype)
517         fprintf(trace_file, "%s allToAllV %d ", process_id, extra->send_size);
518         for (int i = 0; i < extra->num_processes; i++)
519           fprintf(trace_file, "%d ", extra->sendcounts[i]);
520         fprintf(trace_file, "%d ", extra->recv_size);
521         for (int i = 0; i < extra->num_processes; i++)
522           fprintf(trace_file, "%d ", extra->recvcounts[i]);
523         fprintf(trace_file, "%s %s \n", extra->datatype1, extra->datatype2);
524         break;
525       case TRACING_GATHER: // rank gather send_size recv_size root (sendtype) (recvtype)
526         fprintf(trace_file, "%s gather %d %d %d %s %s\n", process_id, extra->send_size, extra->recv_size, extra->root,
527                 extra->datatype1, extra->datatype2);
528         break;
529       case TRACING_ALLGATHERV: // rank allgatherv send_size [recvcounts] (sendtype) (recvtype)
530         fprintf(trace_file, "%s allGatherV %d ", process_id, extra->send_size);
531         for (int i = 0; i < extra->num_processes; i++)
532           fprintf(trace_file, "%d ", extra->recvcounts[i]);
533         fprintf(trace_file, "%s %s \n", extra->datatype1, extra->datatype2);
534         break;
535       case TRACING_REDUCE_SCATTER: // rank reducescatter [recvcounts] comp_size (sendtype)
536         fprintf(trace_file, "%s reduceScatter ", process_id);
537         for (int i = 0; i < extra->num_processes; i++)
538           fprintf(trace_file, "%d ", extra->recvcounts[i]);
539         fprintf(trace_file, "%f %s\n", extra->comp_size, extra->datatype1);
540         break;
541       case TRACING_COMPUTING:
542         fprintf(trace_file, "%s compute %f\n", process_id, extra->comp_size);
543         break;
544       case TRACING_SLEEPING:
545         fprintf(trace_file, "%s sleep %f\n", process_id, extra->sleep_duration);
546         break;
547       case TRACING_GATHERV: // rank gatherv send_size [recvcounts] root (sendtype) (recvtype)
548         fprintf(trace_file, "%s gatherV %d ", process_id, extra->send_size);
549         for (int i = 0; i < extra->num_processes; i++)
550           fprintf(trace_file, "%d ", extra->recvcounts[i]);
551         fprintf(trace_file, "%d %s %s\n", extra->root, extra->datatype1, extra->datatype2);
552         break;
553       case TRACING_ALLGATHER: // rank allgather sendcount recvcounts (sendtype) (recvtype)
554         fprintf(trace_file, "%s allGather %d %d %s %s", process_id, extra->send_size, extra->recv_size,
555                 extra->datatype1, extra->datatype2);
556         break;
557       case TRACING_WAITANY:
558       case TRACING_SENDRECV:
559       case TRACING_SCATTER:
560       case TRACING_SCATTERV:
561       case TRACING_SCAN:
562       case TRACING_EXSCAN:
563       case TRACING_COMM_SIZE:
564       case TRACING_COMM_SPLIT:
565       case TRACING_COMM_DUP:
566       case TRACING_SSEND:
567       case TRACING_ISSEND:
568       default:
569         XBT_WARN("Call from %s impossible to translate into replay command : Not implemented (yet)", value->getCname());
570         break;
571     }
572
573     if (extra->recvcounts != nullptr)
574       xbt_free(extra->recvcounts);
575     if (extra->sendcounts != nullptr)
576       xbt_free(extra->sendcounts);
577     xbt_free(process_id);
578     xbt_free(extra);
579
580   } else {
581     THROW_IMPOSSIBLE;
582   }
583 }
584
585 simgrid::instr::PopStateEvent::PopStateEvent(double timestamp, container_t container, Type* type)
586     : simgrid::instr::PajeEvent::PajeEvent(container, type, timestamp, PAJE_PopState)
587 {
588   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)eventType_, this->timestamp_);
589   insertIntoBuffer();
590 }
591
592 void simgrid::instr::PopStateEvent::print()
593 {
594   if (instr_fmt_type == instr_fmt_paje) {
595     XBT_DEBUG("%s: event_type=%d, timestamp=%.*f", __FUNCTION__, (int)eventType_, TRACE_precision(), timestamp_);
596     stream << std::fixed << std::setprecision(TRACE_precision());
597     stream << (int)this->eventType_;
598     print_timestamp(this);
599     stream << " " << type->getId() << " " << container->id_;
600     print_row();
601   } else if (instr_fmt_type == instr_fmt_TI) {
602     /* Nothing to do */
603   } else {
604     THROW_IMPOSSIBLE;
605   }
606 }
607
608 simgrid::instr::ResetStateEvent::ResetStateEvent(double timestamp, container_t container, Type* type)
609     : simgrid::instr::PajeEvent::PajeEvent(container, type, timestamp, PAJE_ResetState)
610 {
611   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)eventType_, this->timestamp_);
612   insertIntoBuffer();
613   delete[] this;
614 }
615
616 void simgrid::instr::ResetStateEvent::print()
617 {
618   if (instr_fmt_type == instr_fmt_paje) {
619     XBT_DEBUG("%s: event_type=%d, timestamp=%.*f", __FUNCTION__, (int)eventType_, TRACE_precision(), timestamp_);
620     stream << std::fixed << std::setprecision(TRACE_precision());
621     stream << (int)this->eventType_;
622     print_timestamp(this);
623     stream << " " << type->getId() << " " << container->id_;
624     print_row();
625   } else if (instr_fmt_type == instr_fmt_TI) {
626     /* Nothing to do */
627   } else {
628     THROW_IMPOSSIBLE;
629   }
630 }
631
632 simgrid::instr::StartLinkEvent::StartLinkEvent(double timestamp, container_t container, Type* type,
633                                                container_t sourceContainer, std::string value, std::string key)
634     : StartLinkEvent(timestamp, container, type, sourceContainer, value, key, -1)
635 {}
636
637 simgrid::instr::StartLinkEvent::StartLinkEvent(double timestamp, container_t container, Type* type,
638                                                container_t sourceContainer, std::string value, std::string key,
639                                                int size)
640     : simgrid::instr::PajeEvent::PajeEvent(container, type, timestamp, PAJE_StartLink)
641     , sourceContainer_(sourceContainer)
642     , value_(value)
643     , key_(key)
644     , size_(size)
645 {
646   XBT_DEBUG("%s: event_type=%d, timestamp=%f, value:%s", __FUNCTION__, (int)eventType_, this->timestamp_, this->value_.c_str());
647   insertIntoBuffer();
648 }
649
650 void simgrid::instr::StartLinkEvent::print()
651 {
652   if (instr_fmt_type == instr_fmt_paje) {
653     XBT_DEBUG("%s: event_type=%d, timestamp=%.*f", __FUNCTION__, (int)eventType_, TRACE_precision(), timestamp_);
654     stream << std::fixed << std::setprecision(TRACE_precision());
655     stream << (int)this->eventType_;
656     print_timestamp(this);
657     stream << " " << type->getId() << " " << container->id_ << " " << value_;
658     stream << " " << sourceContainer_->id_ << " " << key_;
659
660     if (TRACE_display_sizes()) {
661       stream << " " << size_;
662     }
663     print_row();
664   } else if (instr_fmt_type == instr_fmt_TI) {
665     /* Nothing to do */
666   } else {
667     THROW_IMPOSSIBLE;
668   }
669 }
670
671 simgrid::instr::EndLinkEvent::EndLinkEvent(double timestamp, container_t container, Type* type,
672                                            container_t destContainer, std::string value, std::string key)
673     : simgrid::instr::PajeEvent::PajeEvent(container, type, timestamp, PAJE_EndLink)
674     , destContainer(destContainer)
675     , value(value)
676     , key(key)
677 {
678   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)eventType_, this->timestamp_);
679   insertIntoBuffer();
680 }
681
682 void simgrid::instr::EndLinkEvent::print()
683 {
684   if (instr_fmt_type == instr_fmt_paje) {
685     XBT_DEBUG("%s: event_type=%d, timestamp=%.*f", __FUNCTION__, (int)eventType_, TRACE_precision(), timestamp_);
686     stream << std::fixed << std::setprecision(TRACE_precision());
687     stream << (int)this->eventType_;
688     print_timestamp(this);
689     stream << " " << type->getId() << " " << container->id_ << " " << value;
690     stream << " " << destContainer->id_ << " " << key;
691     print_row();
692   } else if (instr_fmt_type == instr_fmt_TI) {
693     /* Nothing to do */
694   } else {
695     THROW_IMPOSSIBLE;
696   }
697 }
698
699 simgrid::instr::NewEvent::NewEvent(double timestamp, container_t container, Type* type, Value* val)
700     : simgrid::instr::PajeEvent::PajeEvent(container, type, timestamp, PAJE_NewEvent)
701 {
702   this->val                             = val;
703
704   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)eventType_, this->timestamp_);
705
706   insertIntoBuffer();
707 }
708
709 void simgrid::instr::NewEvent::print()
710 {
711   if (instr_fmt_type == instr_fmt_paje) {
712     XBT_DEBUG("%s: event_type=%d, timestamp=%.*f", __FUNCTION__, (int)eventType_, TRACE_precision(), timestamp_);
713     stream << std::fixed << std::setprecision(TRACE_precision());
714     stream << (int)this->eventType_;
715     print_timestamp(this);
716     stream << " " << type->getId() << " " << container->id_ << " " << val->getId();
717     print_row();
718   } else if (instr_fmt_type == instr_fmt_TI) {
719     /* Nothing to do */
720   } else {
721     THROW_IMPOSSIBLE;
722   }
723 }
724
725 void TRACE_TI_start()
726 {
727   char *filename = TRACE_get_filename();
728   tracing_file = fopen(filename, "w");
729   if (tracing_file == nullptr)
730     THROWF(system_error, 1, "Tracefile %s could not be opened for writing.", filename);
731
732   XBT_DEBUG("Filename %s is open for writing", filename);
733
734   /* output one line comment */
735   dump_comment(TRACE_get_comment());
736
737   /* output comment file */
738   dump_comment_file(TRACE_get_comment_file());
739 }
740
741 void TRACE_TI_end()
742 {
743   fclose(tracing_file);
744   char *filename = TRACE_get_filename();
745   XBT_DEBUG("Filename %s is closed", filename);
746 }