Logo AND Algorithmique Numérique Distribuée

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