Logo AND Algorithmique Numérique Distribuée

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