Logo AND Algorithmique Numérique Distribuée

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