Logo AND Algorithmique Numérique Distribuée

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