Logo AND Algorithmique Numérique Distribuée

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