Logo AND Algorithmique Numérique Distribuée

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