Logo AND Algorithmique Numérique Distribuée

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