Logo AND Algorithmique Numérique Distribuée

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