Logo AND Algorithmique Numérique Distribuée

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