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