Logo AND Algorithmique Numérique Distribuée

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