Logo AND Algorithmique Numérique Distribuée

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