Logo AND Algorithmique Numérique Distribuée

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