Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of scm.gforge.inria.fr:/gitroot/simgrid/simgrid
[simgrid.git] / src / instr / instr_config.c
1 /* Copyright (c) 2010. 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 "instr/instr_private.h"
8 #include "simgrid/sg_config.h"
9 #include "surf/surf.h"
10
11 #ifdef HAVE_TRACING
12
13 XBT_LOG_NEW_CATEGORY(instr, "Logging the behavior of the tracing system (used for Visualization/Analysis of simulations)");
14 XBT_LOG_NEW_DEFAULT_SUBCATEGORY (instr_config, instr, "Configuration");
15
16 #define OPT_TRACING               "tracing"
17 #define OPT_TRACING_PLATFORM      "tracing/platform"
18 #define OPT_TRACING_TOPOLOGY      "tracing/platform/topology"
19 #define OPT_TRACING_SMPI          "tracing/smpi"
20 #define OPT_TRACING_SMPI_GROUP    "tracing/smpi/group"
21 #define OPT_TRACING_SMPI_COMPUTING "tracing/smpi/computing"
22 #define OPT_TRACING_SMPI_INTERNALS "tracing/smpi/internals"
23 #define OPT_TRACING_DISPLAY_SIZES  "tracing/smpi/display_sizes"
24 #define OPT_TRACING_CATEGORIZED   "tracing/categorized"
25 #define OPT_TRACING_UNCATEGORIZED "tracing/uncategorized"
26 #define OPT_TRACING_MSG_PROCESS   "tracing/msg/process"
27 #define OPT_TRACING_MSG_VM        "tracing/msg/vm"
28 #define OPT_TRACING_FILENAME      "tracing/filename"
29 #define OPT_TRACING_BUFFER        "tracing/buffer"
30 #define OPT_TRACING_ONELINK_ONLY  "tracing/onelink_only"
31 #define OPT_TRACING_DISABLE_DESTROY "tracing/disable_destroy"
32 #define OPT_TRACING_BASIC         "tracing/basic"
33 #define OPT_TRACING_COMMENT       "tracing/comment"
34 #define OPT_TRACING_COMMENT_FILE  "tracing/comment_file"
35 #define OPT_VIVA_UNCAT_CONF      "viva/uncategorized"
36 #define OPT_VIVA_CAT_CONF        "viva/categorized"
37 #define OPT_TRACING_DISABLE_LINK        "tracing/disable_link"
38 #define OPT_TRACING_DISABLE_POWER       "tracing/disable_power"
39
40 static int trace_enabled;
41 static int trace_platform;
42 static int trace_platform_topology;
43 static int trace_smpi_enabled;
44 static int trace_smpi_grouped;
45 static int trace_smpi_computing;
46 static int trace_view_internals;
47 static int trace_categorized;
48 static int trace_uncategorized;
49 static int trace_msg_process_enabled;
50 static int trace_msg_vm_enabled;
51 static int trace_buffer;
52 static int trace_onelink_only;
53 static int trace_disable_destroy;
54 static int trace_basic;
55 static int trace_display_sizes = 0;
56 static int trace_disable_link;
57 static int trace_disable_power;
58
59 static int trace_configured = 0;
60 static int trace_active = 0;
61
62
63
64 static void TRACE_getopts(void)
65 {
66   trace_enabled = xbt_cfg_get_int(_sg_cfg_set, OPT_TRACING);
67   trace_platform = xbt_cfg_get_int(_sg_cfg_set, OPT_TRACING_PLATFORM);
68   trace_platform_topology = xbt_cfg_get_int(_sg_cfg_set, OPT_TRACING_TOPOLOGY);
69   trace_smpi_enabled = xbt_cfg_get_int(_sg_cfg_set, OPT_TRACING_SMPI);
70   trace_smpi_grouped = xbt_cfg_get_int(_sg_cfg_set, OPT_TRACING_SMPI_GROUP);
71   trace_smpi_computing = xbt_cfg_get_int(_sg_cfg_set, OPT_TRACING_SMPI_COMPUTING);
72   trace_view_internals = xbt_cfg_get_int(_sg_cfg_set, OPT_TRACING_SMPI_INTERNALS);
73   trace_categorized = xbt_cfg_get_int(_sg_cfg_set, OPT_TRACING_CATEGORIZED);
74   trace_uncategorized = xbt_cfg_get_int(_sg_cfg_set, OPT_TRACING_UNCATEGORIZED);
75   trace_msg_process_enabled = xbt_cfg_get_int(_sg_cfg_set, OPT_TRACING_MSG_PROCESS);
76   trace_msg_vm_enabled = xbt_cfg_get_int(_sg_cfg_set, OPT_TRACING_MSG_VM);
77   trace_buffer = xbt_cfg_get_int(_sg_cfg_set, OPT_TRACING_BUFFER);
78   trace_onelink_only = xbt_cfg_get_int(_sg_cfg_set, OPT_TRACING_ONELINK_ONLY);
79   trace_disable_destroy = xbt_cfg_get_int(_sg_cfg_set, OPT_TRACING_DISABLE_DESTROY);
80   trace_basic = xbt_cfg_get_int(_sg_cfg_set, OPT_TRACING_BASIC);
81   trace_display_sizes = xbt_cfg_get_int(_sg_cfg_set, OPT_TRACING_DISPLAY_SIZES);
82   trace_disable_link = xbt_cfg_get_int(_sg_cfg_set, OPT_TRACING_DISABLE_LINK);
83   trace_disable_power = xbt_cfg_get_int(_sg_cfg_set, OPT_TRACING_DISABLE_POWER);
84 }
85
86 static xbt_dynar_t TRACE_start_functions = NULL;
87 void TRACE_add_start_function(void (*func) ())
88 {
89   if (TRACE_start_functions == NULL)
90     TRACE_start_functions = xbt_dynar_new(sizeof(void (*)()), NULL);
91   xbt_dynar_push(TRACE_start_functions, &func);
92 }
93
94 int TRACE_start()
95 {
96   TRACE_getopts();
97
98   // tracing system must be:
99   //    - enabled (with --cfg=tracing:1)
100   //    - already configured (TRACE_global_init already called)
101   if (TRACE_is_enabled() && TRACE_is_configured()) {
102     XBT_DEBUG("Tracing starts");
103
104     /* open the trace file */
105     TRACE_paje_start();
106
107     /* activate trace */
108     if (trace_active == 1) {
109       THROWF(tracing_error, 0, "Tracing is already active");
110     }
111     trace_active = 1;
112     XBT_DEBUG("Tracing is on");
113
114     /* other trace initialization */
115     created_categories = xbt_dict_new_homogeneous(xbt_free);
116     declared_marks = xbt_dict_new_homogeneous(xbt_free);
117     user_host_variables = xbt_dict_new_homogeneous(xbt_free);
118     user_vm_variables = xbt_dict_new_homogeneous (xbt_free);
119     user_link_variables = xbt_dict_new_homogeneous(xbt_free);
120
121     if (TRACE_start_functions != NULL) {
122       void (*func) ();
123       unsigned int iter = xbt_dynar_length(TRACE_start_functions);
124       xbt_dynar_foreach(TRACE_start_functions, iter, func) {
125         func();
126       }
127     }
128   }
129   xbt_dynar_free(&TRACE_start_functions);
130   return 0;
131 }
132
133 static xbt_dynar_t TRACE_end_functions = NULL;
134 void TRACE_add_end_function(void (*func) (void))
135 {
136   if (TRACE_end_functions == NULL)
137     TRACE_end_functions = xbt_dynar_new(sizeof(void (*)(void)), NULL);
138   xbt_dynar_push(TRACE_end_functions, &func);
139 }
140
141 int TRACE_end()
142 {
143   int retval;
144   if (!trace_active) {
145     retval = 1;
146   } else {
147     retval = 0;
148
149     TRACE_generate_viva_uncat_conf();
150     TRACE_generate_viva_cat_conf();
151
152     /* dump trace buffer */
153     TRACE_last_timestamp_to_dump = surf_get_clock();
154     TRACE_paje_dump_buffer(1);
155
156     /* destroy all data structures of tracing (and free) */
157     PJ_container_free_all();
158     PJ_type_free_all();
159     PJ_container_release();
160     PJ_type_release();
161
162     if (TRACE_end_functions != NULL) {
163       void (*func) (void);
164       unsigned int iter;
165       xbt_dynar_foreach(TRACE_end_functions, iter, func) {
166         func();
167       }
168     }
169
170     xbt_dict_free(&user_link_variables);
171     xbt_dict_free(&user_host_variables);
172     xbt_dict_free(&user_vm_variables);
173     xbt_dict_free(&declared_marks);
174     xbt_dict_free(&created_categories);
175
176     /* close the trace file */
177     TRACE_paje_end();
178
179     /* de-activate trace */
180     trace_active = 0;
181     XBT_DEBUG("Tracing is off");
182     XBT_DEBUG("Tracing system is shutdown");
183   }
184   xbt_dynar_free(&TRACE_end_functions);
185   return retval;
186 }
187
188 int TRACE_needs_platform (void)
189 {
190   return TRACE_msg_process_is_enabled() ||
191          TRACE_msg_vm_is_enabled() ||
192          TRACE_categorized() ||
193          TRACE_uncategorized() ||
194          TRACE_platform () ||
195          (TRACE_smpi_is_enabled() && TRACE_smpi_is_grouped());
196 }
197
198 int TRACE_is_enabled(void)
199 {
200   return trace_enabled;
201 }
202
203 int TRACE_platform(void)
204 {
205   return trace_platform;
206 }
207
208 int TRACE_platform_topology(void)
209 {
210   return trace_platform_topology;
211 }
212
213 int TRACE_is_configured(void)
214 {
215   return trace_configured;
216 }
217
218 int TRACE_smpi_is_enabled(void)
219 {
220   return (trace_smpi_enabled || TRACE_smpi_is_grouped())
221     && TRACE_is_enabled();
222 }
223
224 int TRACE_smpi_is_grouped(void)
225 {
226   return trace_smpi_grouped;
227 }
228
229 int TRACE_smpi_is_computing(void)
230 {
231   return trace_smpi_computing;
232 }
233
234 int TRACE_smpi_view_internals(void)
235 {
236   return trace_view_internals;
237 }
238
239 int TRACE_categorized (void)
240 {
241   return trace_categorized;
242 }
243
244 int TRACE_uncategorized (void)
245 {
246   return trace_uncategorized;
247 }
248
249 int TRACE_msg_process_is_enabled(void)
250 {
251   return trace_msg_process_enabled && TRACE_is_enabled();
252 }
253
254 int TRACE_msg_vm_is_enabled(void)
255 {
256   return trace_msg_vm_enabled && TRACE_is_enabled();
257 }
258
259 int TRACE_disable_link(void)
260 {
261   return trace_disable_link && TRACE_is_enabled();
262 }
263
264 int TRACE_disable_power(void)
265 {
266   return trace_disable_power && TRACE_is_enabled();
267 }
268
269 int TRACE_buffer (void)
270 {
271   return trace_buffer && TRACE_is_enabled();
272 }
273
274 int TRACE_onelink_only (void)
275 {
276   return trace_onelink_only && TRACE_is_enabled();
277 }
278
279 int TRACE_disable_destroy (void)
280 {
281   return trace_disable_destroy && TRACE_is_enabled();
282 }
283
284 int TRACE_basic (void)
285 {
286   return trace_basic && TRACE_is_enabled();
287 }
288
289 int TRACE_display_sizes (void)
290 {
291    return trace_display_sizes && trace_smpi_enabled && TRACE_is_enabled();
292 }
293
294 char *TRACE_get_comment (void)
295 {
296   return xbt_cfg_get_string(_sg_cfg_set, OPT_TRACING_COMMENT);
297 }
298
299 char *TRACE_get_comment_file (void)
300 {
301   return xbt_cfg_get_string(_sg_cfg_set, OPT_TRACING_COMMENT_FILE);
302 }
303
304 char *TRACE_get_filename(void)
305 {
306   return xbt_cfg_get_string(_sg_cfg_set, OPT_TRACING_FILENAME);
307 }
308
309 char *TRACE_get_viva_uncat_conf (void)
310 {
311   return xbt_cfg_get_string(_sg_cfg_set, OPT_VIVA_UNCAT_CONF);
312 }
313
314 char *TRACE_get_viva_cat_conf (void)
315 {
316   return xbt_cfg_get_string(_sg_cfg_set, OPT_VIVA_CAT_CONF);
317 }
318
319 void TRACE_global_init(int *argc, char **argv)
320 {
321   /* name of the tracefile */
322   xbt_cfg_register(&_sg_cfg_set, OPT_TRACING_FILENAME,
323                    "Trace file created by the instrumented SimGrid.",
324                    xbt_cfgelm_string, NULL, 1, 1,
325                    NULL, NULL);
326   xbt_cfg_setdefault_string(_sg_cfg_set, OPT_TRACING_FILENAME, "simgrid.trace");
327
328   /* tracing */
329   xbt_cfg_register(&_sg_cfg_set, OPT_TRACING,
330                    "Enable Tracing.",
331                    xbt_cfgelm_int, NULL, 0, 1,
332                    NULL, NULL);
333   xbt_cfg_setdefault_int(_sg_cfg_set, OPT_TRACING, 0);
334
335   /* register platform in the trace */
336   xbt_cfg_register(&_sg_cfg_set, OPT_TRACING_PLATFORM,
337                    "Register the platform in the trace as a hierarchy.",
338                    xbt_cfgelm_int, NULL, 0, 1,
339                    NULL, NULL);
340   xbt_cfg_setdefault_int(_sg_cfg_set, OPT_TRACING_PLATFORM, 0);
341
342   /* register platform in the trace */
343   xbt_cfg_register(&_sg_cfg_set, OPT_TRACING_TOPOLOGY,
344                    "Register the platform topology in the trace as a graph.",
345                    xbt_cfgelm_int, NULL, 0, 1,
346                    NULL, NULL);
347   xbt_cfg_setdefault_int(_sg_cfg_set, OPT_TRACING_TOPOLOGY, 1);
348
349   /* smpi */
350   xbt_cfg_register(&_sg_cfg_set, OPT_TRACING_SMPI,
351                    "Tracing of the SMPI interface.",
352                    xbt_cfgelm_int, NULL, 0, 1,
353                    NULL, NULL);
354   xbt_cfg_setdefault_int(_sg_cfg_set, OPT_TRACING_SMPI, 0);
355
356   /* smpi grouped */
357   xbt_cfg_register(&_sg_cfg_set, OPT_TRACING_SMPI_GROUP,
358                    "Group MPI processes by host.",
359                    xbt_cfgelm_int, NULL, 0, 1,
360                    NULL, NULL);
361   xbt_cfg_setdefault_int(_sg_cfg_set, OPT_TRACING_SMPI_GROUP, 0);
362
363   /* smpi computing */
364   xbt_cfg_register(&_sg_cfg_set, OPT_TRACING_SMPI_COMPUTING,
365                    "Generate states for timing out of SMPI parts of the application",
366                    xbt_cfgelm_int, NULL, 0, 1,
367                    NULL, NULL);
368   xbt_cfg_setdefault_int(_sg_cfg_set, OPT_TRACING_SMPI_COMPUTING, 0);
369
370   /* smpi internals */
371   xbt_cfg_register(&_sg_cfg_set, OPT_TRACING_SMPI_INTERNALS,
372                    "View internal messages sent by Collective communications in SMPI",
373                    xbt_cfgelm_int, NULL, 0, 1,
374                    NULL, NULL);
375   xbt_cfg_setdefault_int(_sg_cfg_set, OPT_TRACING_SMPI_INTERNALS, 0);
376
377   /* tracing categorized resource utilization traces */
378   xbt_cfg_register(&_sg_cfg_set, OPT_TRACING_CATEGORIZED,
379                    "Tracing categorized resource utilization of hosts and links.",
380                    xbt_cfgelm_int, NULL, 0, 1,
381                    NULL, NULL);
382   xbt_cfg_setdefault_int(_sg_cfg_set, OPT_TRACING_CATEGORIZED, 0);
383
384   /* tracing uncategorized resource utilization */
385   xbt_cfg_register(&_sg_cfg_set, OPT_TRACING_UNCATEGORIZED,
386                    "Tracing uncategorized resource utilization of hosts and links.",
387                    xbt_cfgelm_int, NULL, 0, 1,
388                    NULL, NULL);
389   xbt_cfg_setdefault_int(_sg_cfg_set, OPT_TRACING_UNCATEGORIZED, 0);
390
391   /* msg process */
392   xbt_cfg_register(&_sg_cfg_set, OPT_TRACING_MSG_PROCESS,
393                    "Tracing of MSG process behavior.",
394                    xbt_cfgelm_int, NULL, 0, 1,
395                    NULL, NULL);
396   xbt_cfg_setdefault_int(_sg_cfg_set, OPT_TRACING_MSG_PROCESS, 0);
397
398   /* msg process */
399   xbt_cfg_register(&_sg_cfg_set, OPT_TRACING_MSG_VM,
400                    "Tracing of MSG process behavior.",
401                    xbt_cfgelm_int, NULL, 0, 1,
402                    NULL, NULL);
403   xbt_cfg_setdefault_int(_sg_cfg_set, OPT_TRACING_MSG_VM, 0);
404
405   /* disable tracing link */
406   xbt_cfg_register(&_sg_cfg_set, OPT_TRACING_DISABLE_LINK,
407                    "Do not trace link bandwidth and latency.",
408                    xbt_cfgelm_int, NULL, 0, 1,
409                    NULL, NULL);
410   xbt_cfg_setdefault_int(_sg_cfg_set, OPT_TRACING_DISABLE_LINK, 0);
411
412   /* disable tracing link */
413   xbt_cfg_register(&_sg_cfg_set, OPT_TRACING_DISABLE_POWER,
414                    "Do not trace host power.",
415                    xbt_cfgelm_int, NULL, 0, 1,
416                    NULL, NULL);
417   xbt_cfg_setdefault_int(_sg_cfg_set, OPT_TRACING_DISABLE_POWER, 0);
418
419
420   /* tracing buffer */
421   xbt_cfg_register(&_sg_cfg_set, OPT_TRACING_BUFFER,
422                    "Buffer trace events to put them in temporal order.",
423                    xbt_cfgelm_int, NULL, 0, 1,
424                    NULL, NULL);
425   xbt_cfg_setdefault_int(_sg_cfg_set, OPT_TRACING_BUFFER, 1);
426
427   /* tracing one link only */
428   xbt_cfg_register(&_sg_cfg_set, OPT_TRACING_ONELINK_ONLY,
429                    "Use only routes with one link to trace platform.",
430                    xbt_cfgelm_int, NULL, 0, 1,
431                    NULL, NULL);
432   xbt_cfg_setdefault_int(_sg_cfg_set, OPT_TRACING_ONELINK_ONLY, 0);
433
434   /* disable destroy */
435   xbt_cfg_register(&_sg_cfg_set, OPT_TRACING_DISABLE_DESTROY,
436                    "Disable platform containers destruction.",
437                    xbt_cfgelm_int, NULL, 0, 1,
438                    NULL, NULL);
439   xbt_cfg_setdefault_int(_sg_cfg_set, OPT_TRACING_DISABLE_DESTROY, 0);
440
441   /* basic -- Avoid extended events (impoverished trace file) */
442   xbt_cfg_register(&_sg_cfg_set, OPT_TRACING_BASIC,
443                    "Avoid extended events (impoverished trace file).",
444                    xbt_cfgelm_int, NULL, 0, 1,
445                    NULL, NULL);
446   xbt_cfg_setdefault_int(_sg_cfg_set, OPT_TRACING_BASIC, 0);
447
448   /* display_sizes -- Extended events with message size information */
449   xbt_cfg_register(&_sg_cfg_set, OPT_TRACING_DISPLAY_SIZES,
450                    "(smpi only for now) Extended events with message size information",
451                    xbt_cfgelm_int, NULL, 0, 1,
452                    NULL, NULL);
453   xbt_cfg_setdefault_int(_sg_cfg_set, OPT_TRACING_DISPLAY_SIZES, 0);
454
455   /* comment */
456   xbt_cfg_register(&_sg_cfg_set, OPT_TRACING_COMMENT,
457                    "Comment to be added on the top of the trace file.",
458                    xbt_cfgelm_string, NULL, 1, 1,
459                    NULL, NULL);
460   xbt_cfg_setdefault_string(_sg_cfg_set, OPT_TRACING_COMMENT, "");
461
462   /* comment_file */
463   xbt_cfg_register(&_sg_cfg_set, OPT_TRACING_COMMENT_FILE,
464                    "The contents of the file are added to the top of the trace file as comment.",
465                    xbt_cfgelm_string, NULL, 1, 1,
466                    NULL, NULL);
467   xbt_cfg_setdefault_string(_sg_cfg_set, OPT_TRACING_COMMENT_FILE, "");
468
469   /* Viva graph configuration for uncategorized tracing */
470   xbt_cfg_register(&_sg_cfg_set, OPT_VIVA_UNCAT_CONF,
471                    "Viva Graph configuration file for uncategorized resource utilization traces.",
472                    xbt_cfgelm_string, NULL, 1, 1,
473                    NULL, NULL);
474   xbt_cfg_setdefault_string(_sg_cfg_set, OPT_VIVA_UNCAT_CONF, "");
475
476   /* Viva graph configuration for uncategorized tracing */
477   xbt_cfg_register(&_sg_cfg_set, OPT_VIVA_CAT_CONF,
478                    "Viva Graph configuration file for categorized resource utilization traces.",
479                    xbt_cfgelm_string, NULL, 1, 1,
480                    NULL, NULL);
481   xbt_cfg_setdefault_string(_sg_cfg_set, OPT_VIVA_CAT_CONF, "");
482
483   /* instrumentation can be considered configured now */
484   trace_configured = 1;
485 }
486
487 static void print_line (const char *option, const char *desc, const char *longdesc, int detailed)
488 {
489   char str[INSTR_DEFAULT_STR_SIZE];
490   snprintf (str, INSTR_DEFAULT_STR_SIZE, "--cfg=%s ", option);
491
492   int len = strlen (str);
493   printf ("%s%*.*s %s\n", str, 30-len, 30-len, "", desc);
494   if (!!longdesc && detailed){
495     printf ("%s\n\n", longdesc);
496   }
497 }
498
499 void TRACE_help (int detailed)
500 {
501   printf(
502       "Description of the tracing options accepted by this simulator:\n\n");
503   print_line (OPT_TRACING, "Enable the tracing system",
504       "  It activates the tracing system and register the simulation platform\n"
505       "  in the trace file. You have to enable this option to others take effect.",
506       detailed);
507   print_line (OPT_TRACING_CATEGORIZED, "Trace categorized resource utilization",
508       "  It activates the categorized resource utilization tracing. It should\n"
509       "  be enabled if tracing categories are used by this simulator.",
510       detailed);
511   print_line (OPT_TRACING_UNCATEGORIZED, "Trace uncategorized resource utilization",
512       "  It activates the uncategorized resource utilization tracing. Use it if\n"
513       "  this simulator do not use tracing categories and resource use have to be\n"
514       "  traced.",
515       detailed);
516   print_line (OPT_TRACING_FILENAME, "Filename to register traces",
517       "  A file with this name will be created to register the simulation. The file\n"
518       "  is in the Paje format and can be analyzed using Viva, Paje, and PajeNG visualization\n"
519       "  tools. More information can be found in these webpages:\n"
520       "     http://github.com/schnorr/viva/\n"
521       "     http://github.com/schnorr/pajeng/\n"
522       "     http://paje.sourceforge.net/",
523       detailed);
524   print_line (OPT_TRACING_SMPI, "Trace the MPI Interface (SMPI)",
525       "  This option only has effect if this simulator is SMPI-based. Traces the MPI\n"
526       "  interface and generates a trace that can be analyzed using Gantt-like\n"
527       "  visualizations. Every MPI function (implemented by SMPI) is transformed in a\n"
528       "  state, and point-to-point communications can be analyzed with arrows.",
529       detailed);
530   print_line (OPT_TRACING_SMPI_GROUP, "Group MPI processes by host (SMPI)",
531       "  This option only has effect if this simulator is SMPI-based. The processes\n"
532       "  are grouped by the hosts where they were executed.",
533       detailed);
534   print_line (OPT_TRACING_SMPI_COMPUTING, "Generates a \" Computing \" State",
535       "  This option aims at tracing computations in the application, outside SMPI\n"
536       "  to allow further study of simulated or real computation time",
537       detailed);
538   print_line (OPT_TRACING_SMPI_INTERNALS, "Generates tracing events corresponding",
539       "  to point-to-point messages sent by collective communications",
540       detailed);
541   print_line (OPT_TRACING_MSG_PROCESS, "Trace processes behavior (MSG)",
542       "  This option only has effect if this simulator is MSG-based. It traces the\n"
543       "  behavior of all categorized MSG processes, grouping them by hosts. This option\n"
544       "  can be used to track process location if this simulator has process migration.",
545       detailed);
546   print_line (OPT_TRACING_BUFFER, "Buffer events to put them in temporal order",
547       "  This option put some events in a time-ordered buffer using the insertion\n"
548       "  sort algorithm. The process of acquiring and releasing locks to access this\n"
549       "  buffer and the cost of the sorting algorithm make this process slow. The\n"
550       "  simulator performance can be severely impacted if this option is activated,\n"
551       "  but you are sure to get a trace file with events sorted.",
552       detailed);
553   print_line (OPT_TRACING_ONELINK_ONLY, "Consider only one link routes to trace platform",
554       "  This option changes the way SimGrid register its platform on the trace file.\n"
555       "  Normally, the tracing considers all routes (no matter their size) on the\n"
556       "  platform file to re-create the resource topology. If this option is activated,\n"
557       "  only the routes with one link are used to register the topology within an AS.\n"
558       "  Routes among AS continue to be traced as usual.",
559       detailed);
560   print_line (OPT_TRACING_DISABLE_DESTROY, "Disable platform containers destruction",
561       "  Disable the destruction of containers at the end of simulation. This can be\n"
562       "  used with simulators that have a different notion of time (different from\n"
563       "  the simulated time).",
564       detailed);
565   print_line (OPT_TRACING_BASIC, "Avoid extended events (impoverished trace file).",
566       "  Some visualization tools are not able to parse correctly the Paje file format.\n"
567       "  Use this option if you are using one of these tools to visualize the simulation\n"
568       "  trace. Keep in mind that the trace might be incomplete, without all the\n"
569       "  information that would be registered otherwise.",
570       detailed);
571   print_line (OPT_TRACING_DISPLAY_SIZES, "Only works for SMPI now. Add message size information",
572       "Message size (in bytes) is added to links, and to states. For collectives, the displayed value \n"
573       "is the more relevant to the collective (total sent by the process, usually)",
574       detailed);
575   print_line (OPT_TRACING_COMMENT, "Comment to be added on the top of the trace file.",
576       "  Use this to add a comment line to the top of the trace file.",
577       detailed);
578   print_line (OPT_TRACING_COMMENT_FILE, "File contents added to trace file as comment.",
579       "  Use this to add the contents of a file to the top of the trace file as comment.",
580       detailed);
581   print_line (OPT_VIVA_UNCAT_CONF, "Generate a graph configuration for Viva",
582       "  This option can be used in all types of simulators build with SimGrid\n"
583       "  to generate a uncategorized resource utilization graph to be used as\n"
584       "  configuration for the Viva visualization tool. This option\n"
585       "  can be used with tracing/categorized:1 and tracing:1 options to\n"
586       "  analyze an unmodified simulator before changing it to contain\n"
587       "  categories.",
588       detailed);
589   print_line (OPT_VIVA_CAT_CONF, "Generate an uncategorized graph configuration for Viva",
590       "  This option can be used if this simulator uses tracing categories\n"
591       "  in its code. The file specified by this option holds a graph configuration\n"
592       "  file for the Viva visualization tool that can be used to analyze a categorized\n"
593       "  resource utilization.",
594       detailed);
595   print_line (OPT_TRACING_TOPOLOGY, "Register the platform topology as a graph",
596         "  This option (enabled by default) can be used to disable the tracing of\n"
597         "  the platform topology in the trace file. Sometimes, such task is really\n"
598         "  time consuming, since it must get the route from each host ot other hosts\n"
599         "  within the same Autonomous System (AS).",
600         detailed);
601 }
602
603 static void output_types (const char *name, xbt_dynar_t types, FILE *file)
604 {
605   unsigned int i;
606   fprintf (file, "  %s = (", name);
607   for (i = xbt_dynar_length(types); i > 0; i--) {
608     char *type = *(char**)xbt_dynar_get_ptr(types, i - 1);
609     fprintf (file, "\"%s\"", type);
610     if (i - 1 > 0){
611       fprintf (file, ",");
612     }else{
613       fprintf (file, ");\n");
614     }
615   }
616   xbt_dynar_free (&types);
617 }
618
619 static void output_categories (const char *name, xbt_dynar_t cats, FILE *file)
620 {
621   unsigned int i;
622   fprintf (file, "    values = (");
623   for (i = xbt_dynar_length(cats); i > 0; i--) {
624     char *cat = *(char**)xbt_dynar_get_ptr(cats, i - 1);
625     fprintf (file, "\"%s%s\"", name, cat);
626     if (i - 1 > 0){
627       fprintf (file, ",");
628     }else{
629       fprintf (file, ");\n");
630     }
631   }
632   xbt_dynar_free (&cats);
633 }
634
635 static void uncat_configuration (FILE *file)
636 {
637   //register NODE and EDGE types
638   output_types ("node", TRACE_get_node_types(), file);
639   output_types ("edge", TRACE_get_edge_types(), file);
640   fprintf (file, "\n");
641
642   //configuration for all nodes
643   fprintf (file,
644       "  host = {\n"
645       "    type = \"square\";\n"
646       "    size = \"power\";\n"
647       "    values = (\"power_used\");\n"
648       "  };\n"
649       "  link = {\n"
650       "    type = \"rhombus\";\n"
651       "    size = \"bandwidth\";\n"
652       "    values = (\"bandwidth_used\");\n"
653       "  };\n");
654   //close
655 }
656
657 static void cat_configuration (FILE *file)
658 {
659   //register NODE and EDGE types
660   output_types ("node", TRACE_get_node_types(), file);
661   output_types ("edge", TRACE_get_edge_types(), file);
662   fprintf (file, "\n");
663
664   //configuration for all nodes
665   fprintf (file,
666            "  host = {\n"
667            "    type = \"square\";\n"
668            "    size = \"power\";\n");
669   output_categories ("p", TRACE_get_categories(), file);
670   fprintf (file,
671            "  };\n"
672            "  link = {\n"
673            "    type = \"rhombus\";\n"
674            "    size = \"bandwidth\";\n");
675   output_categories ("b", TRACE_get_categories(), file);
676   fprintf (file, "  };\n");
677   //close
678 }
679
680 static void generate_uncat_configuration (const char *output, const char *name, int brackets)
681 {
682   if (output && strlen(output) > 0){
683     FILE *file = fopen (output, "w");
684     if (file == NULL){
685       THROWF (system_error, 1, "Unable to open file (%s) for writing %s graph "
686           "configuration (uncategorized).", output, name);
687     }
688
689     if (brackets) fprintf (file, "{\n");
690     uncat_configuration (file);
691     if (brackets) fprintf (file, "}\n");
692     fclose (file);
693   }
694 }
695
696 static void generate_cat_configuration (const char *output, const char *name, int brackets)
697 {
698   if (output && strlen(output) > 0){
699     //check if we do have categories declared
700     if (xbt_dict_is_empty(created_categories)){
701       XBT_INFO("No categories declared, ignoring generation of %s graph configuration", name);
702       return;
703     }
704
705     FILE *file = fopen (output, "w");
706     if (file == NULL){
707       THROWF (system_error, 1, "Unable to open file (%s) for writing %s graph "
708           "configuration (categorized).", output, name);
709     }
710
711     if (brackets) fprintf (file, "{\n");
712     cat_configuration (file);
713     if (brackets) fprintf (file, "}\n");
714     fclose (file);
715   }
716 }
717
718 void TRACE_generate_viva_uncat_conf (void)
719 {
720   generate_uncat_configuration (TRACE_get_viva_uncat_conf (), "viva", 0);
721 }
722
723 void TRACE_generate_viva_cat_conf (void)
724 {
725   generate_cat_configuration (TRACE_get_viva_cat_conf(), "viva", 0);
726 }
727
728 static int previous_trace_state = -1;
729
730 void instr_pause_tracing (void)
731 {
732   previous_trace_state = trace_enabled;
733   if (!TRACE_is_enabled()){
734     XBT_DEBUG ("Tracing is already paused, therefore do nothing.");
735   }else{
736     XBT_DEBUG ("Tracing is being paused.");
737   }
738   trace_enabled = 0;
739   XBT_DEBUG ("Tracing is paused.");
740 }
741
742 void instr_resume_tracing (void)
743 {
744   if (TRACE_is_enabled()){
745     XBT_DEBUG ("Tracing is already running while trying to resume, therefore do nothing.");
746   }else{
747     XBT_DEBUG ("Tracing is being resumed.");
748   }
749
750   if (previous_trace_state != -1){
751     trace_enabled = previous_trace_state;
752   }else{
753     trace_enabled = 1;
754   }
755   XBT_DEBUG ("Tracing is resumed.");
756   previous_trace_state = -1;
757 }
758
759 #undef OPT_TRACING
760 #undef OPT_TRACING_PLATFORM
761 #undef OPT_TRACING_TOPOLOGY
762 #undef OPT_TRACING_SMPI
763 #undef OPT_TRACING_SMPI_GROUP
764 #undef OPT_TRACING_CATEGORIZED
765 #undef OPT_TRACING_UNCATEGORIZED
766 #undef OPT_TRACING_MSG_PROCESS
767 #undef OPT_TRACING_FILENAME
768 #undef OPT_TRACING_BUFFER
769 #undef OPT_TRACING_ONELINK_ONLY
770 #undef OPT_TRACING_DISABLE_DESTROY
771 #undef OPT_TRACING_BASIC
772 #undef OPT_TRACING_COMMENT
773 #undef OPT_TRACING_COMMENT_FILE
774 #undef OPT_VIVA_UNCAT_CONF
775 #undef OPT_VIVA_CAT_CONF
776
777 #endif /* HAVE_TRACING */