+ print_line (OPT_TRACING_FORMAT, "Only works for SMPI now. Switch output format",
+ " Default format is Paje. Time independent traces are also supported,\n"
+ " to output traces that can later be used by the trace replay tool",
+ detailed);
+ print_line (OPT_TRACING_FORMAT_TI_ONEFILE, "Only works for SMPI now, and TI output format",
+ " By default, each process outputs to a separate file, inside a filename_files folder\n"
+ " By setting this option to yes, all processes will output to only one file\n"
+ " This is meant to avoid opening thousands of files with large simulations",
+ detailed);
+ print_line (OPT_TRACING_COMMENT, "Comment to be added on the top of the trace file.",
+ " Use this to add a comment line to the top of the trace file.",
+ detailed);
+ print_line (OPT_TRACING_COMMENT_FILE, "File contents added to trace file as comment.",
+ " Use this to add the contents of a file to the top of the trace file as comment.",
+ detailed);
+ print_line (OPT_VIVA_UNCAT_CONF, "Generate a graph configuration for Viva",
+ " This option can be used in all types of simulators build with SimGrid\n"
+ " to generate a uncategorized resource utilization graph to be used as\n"
+ " configuration for the Viva visualization tool. This option\n"
+ " can be used with tracing/categorized:1 and tracing:1 options to\n"
+ " analyze an unmodified simulator before changing it to contain\n"
+ " categories.",
+ detailed);
+ print_line (OPT_VIVA_CAT_CONF, "Generate an uncategorized graph configuration for Viva",
+ " This option can be used if this simulator uses tracing categories\n"
+ " in its code. The file specified by this option holds a graph configuration\n"
+ " file for the Viva visualization tool that can be used to analyze a categorized\n"
+ " resource utilization.",
+ detailed);
+ print_line (OPT_TRACING_TOPOLOGY, "Register the platform topology as a graph",
+ " This option (enabled by default) can be used to disable the tracing of\n"
+ " the platform topology in the trace file. Sometimes, such task is really\n"
+ " time consuming, since it must get the route from each host ot other hosts\n"
+ " within the same Autonomous System (AS).",
+ detailed);
+}
+
+static void output_types (const char *name, xbt_dynar_t types, FILE *file)
+{
+ unsigned int i;
+ fprintf (file, " %s = (", name);
+ for (i = xbt_dynar_length(types); i > 0; i--) {
+ char *type = *(char**)xbt_dynar_get_ptr(types, i - 1);
+ fprintf (file, "\"%s\"", type);
+ if (i - 1 > 0){
+ fprintf (file, ",");
+ }else{
+ fprintf (file, ");\n");
+ }
+ }
+ xbt_dynar_free (&types);
+}
+
+static void output_categories (const char *name, xbt_dynar_t cats, FILE *file)
+{
+ unsigned int i;
+ fprintf (file, " values = (");
+ for (i = xbt_dynar_length(cats); i > 0; i--) {
+ char *cat = *(char**)xbt_dynar_get_ptr(cats, i - 1);
+ fprintf (file, "\"%s%s\"", name, cat);
+ if (i - 1 > 0){
+ fprintf (file, ",");
+ }else{
+ fprintf (file, ");\n");
+ }
+ }
+ xbt_dynar_free (&cats);
+}
+
+static void uncat_configuration (FILE *file)
+{
+ //register NODE and EDGE types
+ output_types ("node", TRACE_get_node_types(), file);
+ output_types ("edge", TRACE_get_edge_types(), file);
+ fprintf (file, "\n");
+
+ //configuration for all nodes
+ fprintf (file,
+ " host = {\n"
+ " type = \"square\";\n"
+ " size = \"power\";\n"
+ " values = (\"power_used\");\n"
+ " };\n"
+ " link = {\n"
+ " type = \"rhombus\";\n"
+ " size = \"bandwidth\";\n"
+ " values = (\"bandwidth_used\");\n"
+ " };\n");
+ //close
+}
+
+static void cat_configuration (FILE *file)
+{
+ //register NODE and EDGE types
+ output_types ("node", TRACE_get_node_types(), file);
+ output_types ("edge", TRACE_get_edge_types(), file);
+ fprintf (file, "\n");
+
+ //configuration for all nodes
+ fprintf (file,
+ " host = {\n"
+ " type = \"square\";\n"
+ " size = \"power\";\n");
+ output_categories ("p", TRACE_get_categories(), file);
+ fprintf (file,
+ " };\n"
+ " link = {\n"
+ " type = \"rhombus\";\n"
+ " size = \"bandwidth\";\n");
+ output_categories ("b", TRACE_get_categories(), file);
+ fprintf (file, " };\n");
+ //close
+}
+
+static void generate_uncat_configuration (const char *output, const char *name, int brackets)
+{
+ if (output && strlen(output) > 0){
+ FILE *file = fopen (output, "w");
+ if (file == NULL){
+ THROWF (system_error, 1, "Unable to open file (%s) for writing %s graph "
+ "configuration (uncategorized).", output, name);
+ }
+
+ if (brackets) fprintf (file, "{\n");
+ uncat_configuration (file);
+ if (brackets) fprintf (file, "}\n");
+ fclose (file);
+ }
+}
+
+static void generate_cat_configuration (const char *output, const char *name, int brackets)
+{
+ if (output && strlen(output) > 0){
+ //check if we do have categories declared
+ if (xbt_dict_is_empty(created_categories)){
+ XBT_INFO("No categories declared, ignoring generation of %s graph configuration", name);
+ return;
+ }
+
+ FILE *file = fopen (output, "w");
+ if (file == NULL){
+ THROWF (system_error, 1, "Unable to open file (%s) for writing %s graph "
+ "configuration (categorized).", output, name);
+ }
+
+ if (brackets) fprintf (file, "{\n");
+ cat_configuration (file);
+ if (brackets) fprintf (file, "}\n");
+ fclose (file);
+ }
+}
+
+void TRACE_generate_viva_uncat_conf (void)
+{
+ generate_uncat_configuration (TRACE_get_viva_uncat_conf (), "viva", 0);
+}
+
+void TRACE_generate_viva_cat_conf (void)
+{
+ generate_cat_configuration (TRACE_get_viva_cat_conf(), "viva", 0);
+}
+
+static int previous_trace_state = -1;
+
+void instr_pause_tracing (void)
+{
+ previous_trace_state = trace_enabled;
+ if (!TRACE_is_enabled()){
+ XBT_DEBUG ("Tracing is already paused, therefore do nothing.");
+ }else{
+ XBT_DEBUG ("Tracing is being paused.");
+ }
+ trace_enabled = 0;
+ XBT_DEBUG ("Tracing is paused.");
+}
+
+void instr_resume_tracing (void)
+{
+ if (TRACE_is_enabled()){
+ XBT_DEBUG ("Tracing is already running while trying to resume, therefore do nothing.");
+ }else{
+ XBT_DEBUG ("Tracing is being resumed.");
+ }
+
+ if (previous_trace_state != -1){
+ trace_enabled = previous_trace_state;
+ }else{
+ trace_enabled = 1;
+ }
+ XBT_DEBUG ("Tracing is resumed.");
+ previous_trace_state = -1;