Logo AND Algorithmique Numérique Distribuée

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