Logo AND Algorithmique Numérique Distribuée

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