Logo AND Algorithmique Numérique Distribuée

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