Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
remove all the events that are called and destroyed one time
[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 void DefineVariableTypeEvent(type_t type)
240 {
241   e_event_type event_type                           = PAJE_DefineVariableType;
242   double timestamp                            = 0;
243
244   XBT_DEBUG("%s: event_type=%d", __FUNCTION__, (int)event_type);
245
246   //print it
247 if (instr_fmt_type == instr_fmt_paje) {
248     XBT_DEBUG("%s: event_type=%d, timestamp=%.*f", __FUNCTION__, (int)event_type, TRACE_precision(), timestamp);
249     stream << std::fixed << std::setprecision(TRACE_precision());
250     stream << (int)event_type;
251     stream << " " << type->id << " " << type->father->id << " " << type->name;
252     if (type->color)
253       stream << " \"" << type->color << "\"";
254     print_row();
255   } else if (instr_fmt_type == instr_fmt_TI) {
256     /* Nothing to do */
257   } else {
258     THROW_IMPOSSIBLE;
259   }
260 }
261
262
263 void DefineStateTypeEvent(type_t type)
264 {
265   e_event_type event_type                        = PAJE_DefineStateType;
266   double timestamp                         = 0;
267
268   XBT_DEBUG("%s: event_type=%d", __FUNCTION__, (int)event_type);
269
270   //print it
271 if (instr_fmt_type == instr_fmt_paje) {
272     XBT_DEBUG("%s: event_type=%d, timestamp=%.*f", __FUNCTION__, (int)event_type, TRACE_precision(), timestamp);
273     stream << std::fixed << std::setprecision(TRACE_precision());
274     stream << (int)event_type;
275     stream << " " << type->id << " " << type->father->id << " " << type->name;
276     print_row();
277   } else if (instr_fmt_type == instr_fmt_TI) {
278     /* Nothing to do */
279   } else {
280     THROW_IMPOSSIBLE;
281   }
282 }
283
284
285 DefineEventTypeEvent::DefineEventTypeEvent(type_t type)
286 {
287   this->event_type                        = PAJE_DefineEventType;
288   this->timestamp                         = 0;
289   this->type = type;
290
291   XBT_DEBUG("%s: event_type=%d", __FUNCTION__, (int)event_type);
292
293   //print it
294   print();
295 }
296
297
298 void DefineEventTypeEvent::print() {
299   if (instr_fmt_type == instr_fmt_paje) {
300     XBT_DEBUG("%s: event_type=%d, timestamp=%.*f", __FUNCTION__, (int)event_type, TRACE_precision(), timestamp);
301     stream << std::fixed << std::setprecision(TRACE_precision());
302     stream << (int)this->event_type;
303     stream << " " << type->id << " " << type->father->id << " " << type->name;
304     print_row();
305   } else if (instr_fmt_type == instr_fmt_TI) {
306     /* Nothing to do */
307   } else {
308     THROW_IMPOSSIBLE;
309   }
310 }
311
312 void DefineLinkTypeEvent(type_t type, type_t source, type_t dest)
313 {
314   e_event_type event_type                         = PAJE_DefineLinkType;
315   double timestamp                          = 0;
316
317   XBT_DEBUG("%s: event_type=%d", __FUNCTION__, (int)event_type);
318
319   //print it
320 if (instr_fmt_type == instr_fmt_paje) {
321     XBT_DEBUG("%s: event_type=%d, timestamp=%.*f", __FUNCTION__, (int)event_type, TRACE_precision(), timestamp);
322     stream << std::fixed << std::setprecision(TRACE_precision());
323     stream << (int)event_type;
324     stream << " " << type->id << " " << type->father->id << " " << source->id << " " << dest->id << " " << type->name;
325     print_row();
326   } else if (instr_fmt_type == instr_fmt_TI) {
327     /* Nothing to do */
328   } else {
329     THROW_IMPOSSIBLE;
330   }
331 }
332
333 void DefineEntityValueEvent (val_t value)
334 {
335   e_event_type event_type                           = PAJE_DefineEntityValue;
336   double timestamp                            = 0;
337
338   XBT_DEBUG("%s: event_type=%d", __FUNCTION__, (int)event_type);
339
340   //print it
341 if (instr_fmt_type == instr_fmt_paje) {
342     XBT_DEBUG("%s: event_type=%d, timestamp=%.*f", __FUNCTION__, (int)event_type, TRACE_precision(), timestamp);
343     stream << std::fixed << std::setprecision(TRACE_precision());
344     stream << (int)event_type;
345     stream << " " << value->id << " " << value->father->id << " " << value->name;
346     if (value->color)
347       stream << " \"" << value->color << "\"";
348     print_row();
349   } else if (instr_fmt_type == instr_fmt_TI) {
350     /* Nothing to do */
351   } else {
352     THROW_IMPOSSIBLE;
353   }
354 }
355
356
357 void CreateContainerEvent (container_t container)
358 {
359   e_event_type event_type                             = PAJE_CreateContainer;
360   double timestamp                              = SIMIX_get_clock();
361
362   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)event_type,timestamp);
363
364 if (instr_fmt_type == instr_fmt_paje) {
365     XBT_DEBUG("%s: event_type=%d, timestamp=%.*f", __FUNCTION__, (int)event_type, TRACE_precision(), timestamp);
366     stream << std::fixed << std::setprecision(TRACE_precision());
367     stream << (int)event_type;
368     stream << " ";
369   /* prevent 0.0000 in the trace - this was the behavior before the transition to c++ */
370      if (timestamp < 1e-12)
371          stream << 0;
372       else 
373          stream << timestamp;
374          stream << " " << container->id << " " << container->type->id << " " << container->father->id << " \""
375             << container->name << "\"";
376
377     print_row();
378   } else if (instr_fmt_type == instr_fmt_TI) {
379     // if we are in the mode with only one file
380     static FILE* ti_unique_file = nullptr;
381
382     if (tracing_files == nullptr) {
383       tracing_files = xbt_dict_new_homogeneous(nullptr);
384       // generate unique run id with time
385       prefix = xbt_os_time();
386     }
387
388     if (not xbt_cfg_get_boolean("tracing/smpi/format/ti-one-file") || ti_unique_file == nullptr) {
389       char* folder_name = bprintf("%s_files", TRACE_get_filename());
390       char* filename    = bprintf("%s/%f_%s.txt", folder_name, prefix, container->name);
391 #ifdef WIN32
392       _mkdir(folder_name);
393 #else
394       mkdir(folder_name, S_IRWXU | S_IRWXG | S_IRWXO);
395 #endif
396       ti_unique_file = fopen(filename, "w");
397       xbt_assert(ti_unique_file, "Tracefile %s could not be opened for writing: %s", filename, strerror(errno));
398       fprintf(tracing_file, "%s\n", filename);
399
400       xbt_free(folder_name);
401       xbt_free(filename);
402     }
403
404     xbt_dict_set(tracing_files, container->name, (void*)ti_unique_file, nullptr);
405   } else {
406     THROW_IMPOSSIBLE;
407   }
408 }
409
410 void DestroyContainerEvent (container_t container)
411 {
412   e_event_type event_type                              = PAJE_DestroyContainer;
413   double timestamp                               = SIMIX_get_clock();
414
415   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)event_type, timestamp);
416
417 if (instr_fmt_type == instr_fmt_paje) {
418     XBT_DEBUG("%s: event_type=%d, timestamp=%.*f", __FUNCTION__, (int)event_type, TRACE_precision(), timestamp);
419     stream << std::fixed << std::setprecision(TRACE_precision());
420     stream << (int)event_type;
421     stream << " ";
422   /* prevent 0.0000 in the trace - this was the behavior before the transition to c++ */
423     if (timestamp < 1e-12)
424         stream << 0;
425     else 
426         stream << timestamp;
427     stream << " " << container->type->id << " " << container->id;
428     print_row();
429   } else if (instr_fmt_type == instr_fmt_TI) {
430     if (not xbt_cfg_get_boolean("tracing/smpi/format/ti-one-file") || xbt_dict_length(tracing_files) == 1) {
431       FILE* f = (FILE*)xbt_dict_get_or_null(tracing_files, container->name);
432       fclose(f);
433     }
434     xbt_dict_remove(tracing_files, container->name);
435         } else {
436           THROW_IMPOSSIBLE;
437         }
438 }
439
440
441 SetVariableEvent::SetVariableEvent (double timestamp, container_t container, type_t type, double value)
442 {
443   this->event_type                         = PAJE_SetVariable;
444   this->timestamp                          = timestamp;
445   this->type      = type;
446   this->container = container;
447   this->value     = value;
448
449   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)event_type, this->timestamp);
450
451   insert_into_buffer (this);
452 }
453
454 void SetVariableEvent::print() {
455   if (instr_fmt_type == instr_fmt_paje) {
456     XBT_DEBUG("%s: event_type=%d, timestamp=%.*f", __FUNCTION__, (int)event_type, TRACE_precision(), timestamp);
457     stream << std::fixed << std::setprecision(TRACE_precision());
458     stream << (int)this->event_type;
459     print_timestamp(this);
460     stream << " " << type->id << " " << container->id << " " << value;
461     print_row();
462   } else if (instr_fmt_type == instr_fmt_TI) {
463     /* Nothing to do */
464   } else {
465     THROW_IMPOSSIBLE;
466   }
467 }
468
469 AddVariableEvent::AddVariableEvent (double timestamp, container_t container, type_t type, double value)
470 {
471   this->event_type                         = PAJE_AddVariable;
472   this->timestamp                          = timestamp;
473   this->type      = type;
474   this->container = container;
475   this->value     = value;
476
477   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)event_type, this->timestamp);
478
479   insert_into_buffer (this);
480 }
481
482 void AddVariableEvent::print() {
483   if (instr_fmt_type == instr_fmt_paje) {
484     XBT_DEBUG("%s: event_type=%d, timestamp=%.*f", __FUNCTION__, (int)event_type, TRACE_precision(), timestamp);
485     stream << std::fixed << std::setprecision(TRACE_precision());
486     stream << (int)this->event_type;
487     print_timestamp(this);
488     stream << " " << type->id << " " << container->id << " " << value;
489     print_row();
490   } else if (instr_fmt_type == instr_fmt_TI) {
491     /* Nothing to do */
492   } else {
493     THROW_IMPOSSIBLE;
494   }
495 }
496
497 SubVariableEvent::SubVariableEvent (double timestamp, container_t container, type_t type, double value)
498 {
499   this->event_type                         = PAJE_SubVariable;
500   this->timestamp                          = timestamp;
501   this->type      = type;
502   this->container = container;
503   this->value     = value;
504
505   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)event_type, this->timestamp);
506
507   insert_into_buffer (this);
508 }
509
510 void SubVariableEvent::print() {
511   if (instr_fmt_type == instr_fmt_paje) {
512     XBT_DEBUG("%s: event_type=%d, timestamp=%.*f", __FUNCTION__, (int)event_type, TRACE_precision(), timestamp);
513     stream << std::fixed << std::setprecision(TRACE_precision());
514     stream << (int)this->event_type;
515     print_timestamp(this);
516     stream << " " << type->id << " " << container->id << " " << value;
517     print_row();
518   } else if (instr_fmt_type == instr_fmt_TI) {
519     /* Nothing to do */
520   } else {
521     THROW_IMPOSSIBLE;
522   }
523 }
524
525 SetStateEvent::SetStateEvent (double timestamp, container_t container, type_t type, val_t value)
526 {
527   this->event_type                      = PAJE_SetState;
528   this->timestamp                       = timestamp;
529   this->type      = type;
530   this->container = container;
531   this->value     = value;
532
533 #if HAVE_SMPI
534   if (xbt_cfg_get_boolean("smpi/trace-call-location")) {
535     smpi_trace_call_location_t* loc = smpi_trace_get_call_location();
536     filename   = loc->filename;
537     linenumber = loc->linenumber;
538   }
539 #endif
540
541   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)event_type, this->timestamp);
542
543   insert_into_buffer (this);
544 }
545
546 void SetStateEvent::print() {
547   if (instr_fmt_type == instr_fmt_paje) {
548     XBT_DEBUG("%s: event_type=%d, timestamp=%.*f", __FUNCTION__, (int)event_type, TRACE_precision(), timestamp);
549     stream << std::fixed << std::setprecision(TRACE_precision());
550     stream << (int)this->event_type;
551     print_timestamp(this);
552     stream << " " << type->id << " " << container->id;
553     stream << " " << value->id;
554 #if HAVE_SMPI
555     if (xbt_cfg_get_boolean("smpi/trace-call-location")) {
556       stream << " \"" << filename << "\" " << linenumber;
557     }
558 #endif
559     print_row();
560   } else if (instr_fmt_type == instr_fmt_TI) {
561     /* Nothing to do */
562   } else {
563     THROW_IMPOSSIBLE;
564   }
565 }
566
567 PushStateEvent::PushStateEvent (double timestamp, container_t container, type_t type, val_t value, void* extra)
568 {
569   this->event_type                  = PAJE_PushState;
570   this->timestamp                   = timestamp;
571   this->type = type;
572   this->container = container;
573   this->value     = value;
574   this->extra_     = extra;
575
576 #if HAVE_SMPI
577   if (xbt_cfg_get_boolean("smpi/trace-call-location")) {
578     smpi_trace_call_location_t* loc = smpi_trace_get_call_location();
579     filename   = loc->filename;
580     linenumber = loc->linenumber;
581   }
582 #endif
583
584   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)event_type, this->timestamp);
585
586   insert_into_buffer (this);
587 }
588
589 PushStateEvent::PushStateEvent (double timestamp, container_t container, type_t type, val_t value)
590  : PushStateEvent(timestamp, container, type, value, nullptr)
591 {}
592 void PushStateEvent::print() {
593   if (instr_fmt_type == instr_fmt_paje) {
594     XBT_DEBUG("%s: event_type=%d, timestamp=%.*f", __FUNCTION__, (int)event_type, TRACE_precision(), timestamp);
595     stream << std::fixed << std::setprecision(TRACE_precision());
596     stream << (int)this->event_type;
597     print_timestamp(this);
598     stream << " " << type->id << " " << container->id;
599     stream << " " << value->id;
600
601     if (TRACE_display_sizes()) {
602       stream << " ";
603       if (extra_ != nullptr) {
604         stream << static_cast<instr_extra_data>(extra_)->send_size;
605       } else {
606         stream << 0;
607       }
608     }
609 #if HAVE_SMPI
610     if (xbt_cfg_get_boolean("smpi/trace-call-location")) {
611       stream << " \"" << filename << "\" " << linenumber;
612     }
613 #endif
614     print_row();
615
616     if (extra_ != nullptr) {
617       if (static_cast<instr_extra_data>(extra_)->sendcounts != nullptr)
618         xbt_free(static_cast<instr_extra_data>(extra_)->sendcounts);
619       if (static_cast<instr_extra_data>(extra_)->recvcounts != nullptr)
620         xbt_free(static_cast<instr_extra_data>(extra_)->recvcounts);
621       xbt_free(extra_);
622     }
623   } else if (instr_fmt_type == instr_fmt_TI) {
624     if (extra_ == nullptr)
625       return;
626     instr_extra_data extra = (instr_extra_data)extra_;
627
628     char* process_id = nullptr;
629     // FIXME: dirty extract "rank-" from the name, as we want the bare process id here
630     if (strstr(container->name, "rank-") == nullptr)
631       process_id = xbt_strdup(container->name);
632     else
633       process_id = xbt_strdup(container->name + 5);
634
635     FILE* trace_file = (FILE*)xbt_dict_get(tracing_files, container->name);
636
637     switch (extra->type) {
638       case TRACING_INIT:
639         fprintf(trace_file, "%s init\n", process_id);
640         break;
641       case TRACING_FINALIZE:
642         fprintf(trace_file, "%s finalize\n", process_id);
643         break;
644       case TRACING_SEND:
645         fprintf(trace_file, "%s send %d %d %s\n", process_id, extra->dst, extra->send_size, extra->datatype1);
646         break;
647       case TRACING_ISEND:
648         fprintf(trace_file, "%s Isend %d %d %s\n", process_id, extra->dst, extra->send_size, extra->datatype1);
649         break;
650       case TRACING_RECV:
651         fprintf(trace_file, "%s recv %d %d %s\n", process_id, extra->src, extra->send_size, extra->datatype1);
652         break;
653       case TRACING_IRECV:
654         fprintf(trace_file, "%s Irecv %d %d %s\n", process_id, extra->src, extra->send_size, extra->datatype1);
655         break;
656       case TRACING_TEST:
657         fprintf(trace_file, "%s test\n", process_id);
658         break;
659       case TRACING_WAIT:
660         fprintf(trace_file, "%s wait\n", process_id);
661         break;
662       case TRACING_WAITALL:
663         fprintf(trace_file, "%s waitAll\n", process_id);
664         break;
665       case TRACING_BARRIER:
666         fprintf(trace_file, "%s barrier\n", process_id);
667         break;
668       case TRACING_BCAST: // rank bcast size (root) (datatype)
669         fprintf(trace_file, "%s bcast %d ", process_id, extra->send_size);
670         if (extra->root != 0 || (extra->datatype1 && strcmp(extra->datatype1, "")))
671           fprintf(trace_file, "%d %s", extra->root, extra->datatype1);
672         fprintf(trace_file, "\n");
673         break;
674       case TRACING_REDUCE: // rank reduce comm_size comp_size (root) (datatype)
675         fprintf(trace_file, "%s reduce %d %f ", process_id, extra->send_size, extra->comp_size);
676         if (extra->root != 0 || (extra->datatype1 && strcmp(extra->datatype1, "")))
677           fprintf(trace_file, "%d %s", extra->root, extra->datatype1);
678         fprintf(trace_file, "\n");
679         break;
680       case TRACING_ALLREDUCE: // rank allreduce comm_size comp_size (datatype)
681         fprintf(trace_file, "%s allReduce %d %f %s\n", process_id, extra->send_size, extra->comp_size,
682                 extra->datatype1);
683         break;
684       case TRACING_ALLTOALL: // rank alltoall send_size recv_size (sendtype) (recvtype)
685         fprintf(trace_file, "%s allToAll %d %d %s %s\n", process_id, extra->send_size, extra->recv_size,
686                 extra->datatype1, extra->datatype2);
687         break;
688       case TRACING_ALLTOALLV: // rank alltoallv send_size [sendcounts] recv_size [recvcounts] (sendtype) (recvtype)
689         fprintf(trace_file, "%s allToAllV %d ", process_id, extra->send_size);
690         for (int i = 0; i < extra->num_processes; i++)
691           fprintf(trace_file, "%d ", extra->sendcounts[i]);
692         fprintf(trace_file, "%d ", extra->recv_size);
693         for (int i = 0; i < extra->num_processes; i++)
694           fprintf(trace_file, "%d ", extra->recvcounts[i]);
695         fprintf(trace_file, "%s %s \n", extra->datatype1, extra->datatype2);
696         break;
697       case TRACING_GATHER: // rank gather send_size recv_size root (sendtype) (recvtype)
698         fprintf(trace_file, "%s gather %d %d %d %s %s\n", process_id, extra->send_size, extra->recv_size, extra->root,
699                 extra->datatype1, extra->datatype2);
700         break;
701       case TRACING_ALLGATHERV: // rank allgatherv send_size [recvcounts] (sendtype) (recvtype)
702         fprintf(trace_file, "%s allGatherV %d ", process_id, extra->send_size);
703         for (int i = 0; i < extra->num_processes; i++)
704           fprintf(trace_file, "%d ", extra->recvcounts[i]);
705         fprintf(trace_file, "%s %s \n", extra->datatype1, extra->datatype2);
706         break;
707       case TRACING_REDUCE_SCATTER: // rank reducescatter [recvcounts] comp_size (sendtype)
708         fprintf(trace_file, "%s reduceScatter ", process_id);
709         for (int i = 0; i < extra->num_processes; i++)
710           fprintf(trace_file, "%d ", extra->recvcounts[i]);
711         fprintf(trace_file, "%f %s\n", extra->comp_size, extra->datatype1);
712         break;
713       case TRACING_COMPUTING:
714         fprintf(trace_file, "%s compute %f\n", process_id, extra->comp_size);
715         break;
716       case TRACING_SLEEPING:
717         fprintf(trace_file, "%s sleep %f\n", process_id, extra->sleep_duration);
718         break;
719       case TRACING_GATHERV: // rank gatherv send_size [recvcounts] root (sendtype) (recvtype)
720         fprintf(trace_file, "%s gatherV %d ", process_id, extra->send_size);
721         for (int i = 0; i < extra->num_processes; i++)
722           fprintf(trace_file, "%d ", extra->recvcounts[i]);
723         fprintf(trace_file, "%d %s %s\n", extra->root, extra->datatype1, extra->datatype2);
724         break;
725       case TRACING_WAITANY:
726       case TRACING_SENDRECV:
727       case TRACING_SCATTER:
728       case TRACING_SCATTERV:
729       case TRACING_ALLGATHER:
730       case TRACING_SCAN:
731       case TRACING_EXSCAN:
732       case TRACING_COMM_SIZE:
733       case TRACING_COMM_SPLIT:
734       case TRACING_COMM_DUP:
735       case TRACING_SSEND:
736       case TRACING_ISSEND:
737       default:
738         XBT_WARN("Call from %s impossible to translate into replay command : Not implemented (yet)", value->name);
739         break;
740     }
741
742     if (extra->recvcounts != nullptr)
743       xbt_free(extra->recvcounts);
744     if (extra->sendcounts != nullptr)
745       xbt_free(extra->sendcounts);
746     xbt_free(process_id);
747     xbt_free(extra);
748
749   } else {
750     THROW_IMPOSSIBLE;
751   }
752 }
753
754
755 PopStateEvent::PopStateEvent (double timestamp, container_t container, type_t type)
756 {
757   this->event_type                      = PAJE_PopState;
758   this->timestamp                       = timestamp;
759   this->type      = type;
760   this->container = container;
761
762   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)event_type, this->timestamp);
763
764   insert_into_buffer (this);
765 }
766
767 void PopStateEvent::print() {
768   if (instr_fmt_type == instr_fmt_paje) {
769     XBT_DEBUG("%s: event_type=%d, timestamp=%.*f", __FUNCTION__, (int)event_type, TRACE_precision(), timestamp);
770     stream << std::fixed << std::setprecision(TRACE_precision());
771     stream << (int)this->event_type;
772     print_timestamp(this);
773     stream << " " << type->id << " " << container->id;
774     print_row();
775   } else if (instr_fmt_type == instr_fmt_TI) {
776     /* Nothing to do */
777   } else {
778     THROW_IMPOSSIBLE;
779   }
780 }
781
782 ResetStateEvent::ResetStateEvent (double timestamp, container_t container, type_t type)
783 {
784   this->event_type                        = PAJE_ResetState;
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         delete [] this;
793 }
794
795 void ResetStateEvent::print() {
796   if (instr_fmt_type == instr_fmt_paje) {
797     XBT_DEBUG("%s: event_type=%d, timestamp=%.*f", __FUNCTION__, (int)event_type, TRACE_precision(), timestamp);
798     stream << std::fixed << std::setprecision(TRACE_precision());
799     stream << (int)this->event_type;
800     print_timestamp(this);
801     stream << " " << type->id << " " << container->id;
802     print_row();
803   } else if (instr_fmt_type == instr_fmt_TI) {
804     /* Nothing to do */
805   } else {
806     THROW_IMPOSSIBLE;
807   }
808 }
809
810 StartLinkEvent::~StartLinkEvent()
811 {
812   free(value);
813   free(key);
814 }
815 StartLinkEvent::StartLinkEvent (double timestamp, container_t container,
816     type_t type, container_t sourceContainer, const char *value, const char *key)
817   : StartLinkEvent(timestamp, container, type, sourceContainer, value, key, -1)
818 {}
819
820 StartLinkEvent::StartLinkEvent (double timestamp, container_t container, type_t type, container_t sourceContainer,
821                                 const char *value, const char *key, int size)
822 {
823   event_type                             = PAJE_StartLink;
824   this->timestamp       = timestamp;
825   this->type            = type;
826   this->container       = container;
827   this->sourceContainer = sourceContainer;
828   this->value           = xbt_strdup(value);
829   this->key             = xbt_strdup(key);
830   this->size            = size;
831
832   XBT_DEBUG("%s: event_type=%d, timestamp=%f, value:%s", __FUNCTION__,
833       (int)event_type, this->timestamp, this->value);
834
835   insert_into_buffer (this);
836 }
837
838 void StartLinkEvent::print() {
839   if (instr_fmt_type == instr_fmt_paje) {
840     XBT_DEBUG("%s: event_type=%d, timestamp=%.*f", __FUNCTION__, (int)event_type, TRACE_precision(), timestamp);
841     stream << std::fixed << std::setprecision(TRACE_precision());
842     stream << (int)this->event_type;
843     print_timestamp(this);
844     stream << " " << type->id << " " << container->id << " " << value;
845     stream << " " << sourceContainer->id << " " << key;
846
847     if (TRACE_display_sizes()) {
848       stream << " " << size;
849     }
850     print_row();
851   } else if (instr_fmt_type == instr_fmt_TI) {
852     /* Nothing to do */
853   } else {
854     THROW_IMPOSSIBLE;
855   }
856 }
857
858 EndLinkEvent::EndLinkEvent (double timestamp, container_t container, type_t type, container_t destContainer,
859                       const char *value, const char *key)
860 {
861   this->event_type                         = PAJE_EndLink;
862   this->timestamp                          = timestamp;
863   this->type          = type;
864   this->container     = container;
865   this->destContainer = destContainer;
866   this->value         = xbt_strdup(value);
867   this->key           = xbt_strdup(key);
868
869   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)event_type, this->timestamp);
870
871   insert_into_buffer (this);
872 }
873
874 EndLinkEvent::~EndLinkEvent()
875 {
876   free(value);
877   free(key);
878 }
879 void EndLinkEvent::print() {
880   if (instr_fmt_type == instr_fmt_paje) {
881     XBT_DEBUG("%s: event_type=%d, timestamp=%.*f", __FUNCTION__, (int)event_type, TRACE_precision(), timestamp);
882     stream << std::fixed << std::setprecision(TRACE_precision());
883     stream << (int)this->event_type;
884     print_timestamp(this);
885     stream << " " << type->id << " " << container->id << " " << value;
886     stream << " " << destContainer->id << " " << key;
887     print_row();
888   } else if (instr_fmt_type == instr_fmt_TI) {
889     /* Nothing to do */
890   } else {
891     THROW_IMPOSSIBLE;
892   }
893 }
894
895 NewEvent::NewEvent (double timestamp, container_t container, type_t type, val_t value)
896 {
897   this->event_type                      = PAJE_NewEvent;
898   this->timestamp                       = timestamp;
899   this->type      = type;
900   this->container = container;
901   this->value     = value;
902
903   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)event_type, this->timestamp);
904
905   insert_into_buffer (this);
906 }
907
908 void NewEvent::print () {
909   if (instr_fmt_type == instr_fmt_paje) {
910     XBT_DEBUG("%s: event_type=%d, timestamp=%.*f", __FUNCTION__, (int)event_type, TRACE_precision(), timestamp);
911     stream << std::fixed << std::setprecision(TRACE_precision());
912     stream << (int)this->event_type;
913     print_timestamp(this);
914     stream << " " << type->id << " " << container->id << " " << value->id;
915     print_row();
916   } else if (instr_fmt_type == instr_fmt_TI) {
917     /* Nothing to do */
918   } else {
919     THROW_IMPOSSIBLE;
920   }
921 }
922
923
924 void TRACE_TI_start()
925 {
926   char *filename = TRACE_get_filename();
927   tracing_file = fopen(filename, "w");
928   if (tracing_file == nullptr)
929     THROWF(system_error, 1, "Tracefile %s could not be opened for writing.", filename);
930
931   XBT_DEBUG("Filename %s is open for writing", filename);
932
933   /* output one line comment */
934   dump_comment(TRACE_get_comment());
935
936   /* output comment file */
937   dump_comment_file(TRACE_get_comment_file());
938 }
939
940 void TRACE_TI_end()
941 {
942   xbt_dict_free(&tracing_files);
943   fclose(tracing_file);
944   char *filename = TRACE_get_filename();
945   XBT_DEBUG("Filename %s is closed", filename);
946 }
947