Logo AND Algorithmique Numérique Distribuée

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