X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/666a812d1b3ee4568f2beb317dfcd08d99055697..HEAD:/src/instr/instr_config.cpp diff --git a/src/instr/instr_config.cpp b/src/instr/instr_config.cpp index c8c2ea0ca3..c13fdffc99 100644 --- a/src/instr/instr_config.cpp +++ b/src/instr/instr_config.cpp @@ -1,141 +1,87 @@ -/* Copyright (c) 2010-2018. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#include "include/xbt/config.hpp" +#include +#include + #include "src/instr/instr_private.hpp" -#include "surf/surf.hpp" +#include "xbt/config.hpp" +#include "xbt/xbt_os_time.h" + +#include + +#include #include #include XBT_LOG_NEW_CATEGORY(instr, "Logging the behavior of the tracing system (used for Visualization/Analysis of simulations)"); XBT_LOG_NEW_DEFAULT_SUBCATEGORY (instr_config, instr, "Configuration"); -#define OPT_TRACING_BASIC "tracing/basic" -#define OPT_TRACING_BUFFER "tracing/buffer" -#define OPT_TRACING_CATEGORIZED "tracing/categorized" -#define OPT_TRACING_COMMENT_FILE "tracing/comment-file" -#define OPT_TRACING_COMMENT "tracing/comment" -#define OPT_TRACING_DISABLE_DESTROY "tracing/disable-destroy" -#define OPT_TRACING_DISABLE_LINK "tracing/disable-link" -#define OPT_TRACING_DISABLE_POWER "tracing/disable-power" -#define OPT_TRACING_DISPLAY_SIZES "tracing/smpi/display-sizes" -#define OPT_TRACING_FILENAME "tracing/filename" -#define OPT_TRACING_FORMAT_TI_ONEFILE "tracing/smpi/format/ti-one-file" -#define OPT_TRACING_FORMAT "tracing/smpi/format" -#define OPT_TRACING_ACTOR "tracing/msg/process" -#define OPT_TRACING_VM "tracing/vm" -#define OPT_TRACING_PLATFORM "tracing/platform" -#define OPT_TRACING_PRECISION "tracing/precision" -#define OPT_TRACING_SMPI_COMPUTING "tracing/smpi/computing" -#define OPT_TRACING_SMPI_GROUP "tracing/smpi/group" -#define OPT_TRACING_SMPI_INTERNALS "tracing/smpi/internals" -#define OPT_TRACING_SMPI_SLEEPING "tracing/smpi/sleeping" -#define OPT_TRACING_SMPI "tracing/smpi" -#define OPT_TRACING_TOPOLOGY "tracing/platform/topology" -#define OPT_TRACING "tracing" -#define OPT_TRACING_UNCATEGORIZED "tracing/uncategorized" - -static simgrid::config::Flag trace_enabled{OPT_TRACING, "Enable Tracing.", false}; -static simgrid::config::Flag trace_platform{OPT_TRACING_PLATFORM, +std::ofstream tracing_file; +static std::map tracing_files; // TI specific + +constexpr char OPT_TRACING_BASIC[] = "tracing/basic"; +constexpr char OPT_TRACING_COMMENT_FILE[] = "tracing/comment-file"; +constexpr char OPT_TRACING_DISABLE_DESTROY[] = "tracing/disable-destroy"; +constexpr char OPT_TRACING_FORMAT_TI_ONEFILE[] = "tracing/smpi/format/ti-one-file"; +constexpr char OPT_TRACING_SMPI[] = "tracing/smpi"; +constexpr char OPT_TRACING_TOPOLOGY[] = "tracing/platform/topology"; + +static simgrid::config::Flag trace_enabled{ + "tracing", "Enable the tracing system. You have to enable this option to use other tracing options.", false}; + +static simgrid::config::Flag trace_actor_enabled{ + "tracing/actor", + "Trace the behavior of all categorized actors, grouping them by host. " + "Can be used to track actor location if the simulator does actor migration.", + false}; + +static simgrid::config::Flag trace_vm_enabled{"tracing/vm", "Trace the behavior of all virtual machines.", false}; + +static simgrid::config::Flag trace_platform{"tracing/platform", "Register the platform in the trace as a hierarchy.", false}; + static simgrid::config::Flag trace_platform_topology{ OPT_TRACING_TOPOLOGY, "Register the platform topology in the trace as a graph.", true}; static simgrid::config::Flag trace_smpi_enabled{OPT_TRACING_SMPI, "Tracing of the SMPI interface.", false}; -static simgrid::config::Flag trace_smpi_grouped{OPT_TRACING_SMPI_GROUP, "Group MPI processes by host.", false}; +static simgrid::config::Flag trace_smpi_grouped{"tracing/smpi/group", "Group MPI processes by host.", false}; + static simgrid::config::Flag trace_smpi_computing{ - OPT_TRACING_SMPI_COMPUTING, "Generate states for timing out of SMPI parts of the application", false}; + "tracing/smpi/computing", "Generate 'Computing' states to trace the out-of-SMPI parts of the application", false}; + static simgrid::config::Flag trace_smpi_sleeping{ - OPT_TRACING_SMPI_SLEEPING, "Generate states for timing out of SMPI parts of the application", false}; + "tracing/smpi/sleeping", "Generate 'Sleeping' states for the sleeps in the application that do not pertain to SMPI", + false}; + static simgrid::config::Flag trace_view_internals{ - OPT_TRACING_SMPI_INTERNALS, "View internal messages sent by Collective communications in SMPI", false}; + "tracing/smpi/internals", + "Generate tracing events corresponding to point-to-point messages sent by SMPI collective communications", false}; + static simgrid::config::Flag trace_categorized{ - OPT_TRACING_CATEGORIZED, "Tracing categorized resource utilization of hosts and links.", false}; + "tracing/categorized", "Trace categorized resource utilization of hosts and links.", false}; + static simgrid::config::Flag trace_uncategorized{ - OPT_TRACING_UNCATEGORIZED, "Tracing uncategorized resource utilization of hosts and links.", false}; -static simgrid::config::Flag trace_actor_enabled{OPT_TRACING_ACTOR, "Tracing of actor behavior.", false}; -static simgrid::config::Flag trace_vm_enabled{OPT_TRACING_VM, "Tracing of virtual machine behavior.", false}; -static simgrid::config::Flag trace_buffer{OPT_TRACING_BUFFER, - "Buffer trace events to put them in temporal order.", true}; -static simgrid::config::Flag trace_disable_destroy{ - OPT_TRACING_DISABLE_DESTROY, {"tracing/disable_destroy"}, "Disable platform containers destruction.", false}; + "tracing/uncategorized", + "Trace uncategorized resource utilization of hosts and links. " + "To use if the simulator does not use tracing categories but resource utilization have to be traced.", + false}; + +static simgrid::config::Flag trace_disable_destroy{OPT_TRACING_DISABLE_DESTROY, + "Disable platform containers destruction.", false}; static simgrid::config::Flag trace_basic{OPT_TRACING_BASIC, "Avoid extended events (impoverished trace file).", false}; -static simgrid::config::Flag trace_display_sizes{OPT_TRACING_DISPLAY_SIZES, - {"tracing/smpi/display_sizes"}, - "(smpi only) Extended events with message size information", - false}; -static simgrid::config::Flag trace_disable_link{ - OPT_TRACING_DISABLE_LINK, {"tracing/disable_link"}, "Do not trace link bandwidth and latency.", false}; -static simgrid::config::Flag trace_disable_power{ - OPT_TRACING_DISABLE_POWER, {"tracing/disable_power"}, "Do not trace host power.", false}; -static bool trace_active = false; +static simgrid::config::Flag trace_display_sizes{ + "tracing/smpi/display-sizes", + "Add message size information (in bytes) to the to links and states (SMPI only). " + "For collectives, it usually corresponds to the total number of bytes sent by a process.", + false}; -simgrid::instr::TraceFormat simgrid::instr::trace_format = simgrid::instr::TraceFormat::Paje; - -void TRACE_start() -{ - if (trace_active) - return; - - // tracing system must be: - // - enabled (with --cfg=tracing:yes) - // - already configured (TRACE_global_init already called) - if (TRACE_is_enabled()) { - instr_define_callbacks(); - - XBT_DEBUG("Tracing starts"); - /* init the tracing module to generate the right output */ - - /* open the trace file(s) */ - std::string format = simgrid::config::get_value(OPT_TRACING_FORMAT); - XBT_DEBUG("Tracing format %s", format.c_str()); - if (format == "Paje") { - TRACE_paje_start(); - } else if (format == "TI") { - simgrid::instr::trace_format = simgrid::instr::TraceFormat::Ti; - TRACE_TI_start(); - }else{ - xbt_die("Unknown trace format :%s ", format.c_str()); - } - - trace_active = true; - XBT_DEBUG("Tracing is on"); - } -} - -void TRACE_end() -{ - if (not trace_active) - return; - - /* dump trace buffer */ - TRACE_last_timestamp_to_dump = surf_get_clock(); - TRACE_paje_dump_buffer(true); - - simgrid::instr::Type* root_type = simgrid::instr::Container::getRoot()->type_; - /* destroy all data structures of tracing (and free) */ - delete simgrid::instr::Container::getRoot(); - delete root_type; - - /* close the trace files */ - std::string format = simgrid::config::get_value(OPT_TRACING_FORMAT); - XBT_DEBUG("Tracing format %s\n", format.c_str()); - if (format == "Paje") { - TRACE_paje_end(); - } else if (format == "TI") { - TRACE_TI_end(); - } else { - xbt_die("Unknown trace format :%s ", format.c_str()); - } - - /* de-activate trace */ - trace_active = false; - XBT_DEBUG("Tracing is off"); - XBT_DEBUG("Tracing system is shutdown"); -} +static simgrid::config::Flag trace_disable_link{"tracing/disable_link", + "Do not trace link bandwidth and latency.", false}; +static simgrid::config::Flag trace_disable_power{"tracing/disable_power", "Do not trace host power.", false}; bool TRACE_needs_platform () { @@ -213,156 +159,305 @@ bool TRACE_disable_speed() return trace_disable_power && trace_enabled; } -bool TRACE_buffer () +bool TRACE_display_sizes () { - return trace_buffer && trace_enabled; + return trace_display_sizes && trace_smpi_enabled && trace_enabled; } -bool TRACE_disable_destroy () +static void print_line(const char* option, const char* desc, const char* longdesc) { - return trace_disable_destroy && trace_enabled; + std::string str = std::string("--cfg=") + option + " "; + + int len = static_cast(str.size()); + XBT_HELP("%s%*.*s %s", str.c_str(), 30 - len, 30 - len, "", desc); + if (longdesc != nullptr) { + XBT_HELP("%s\n", longdesc); + } } -bool TRACE_basic () +void TRACE_help() { - return trace_basic && trace_enabled; + XBT_HELP("Description of the tracing options accepted by this simulator:\n"); + print_line(OPT_TRACING_SMPI, "Trace the MPI Interface (SMPI)", + " This option only has effect if this simulator is SMPI-based. Traces the MPI\n" + " interface and generates a trace that can be analyzed using Gantt-like\n" + " visualizations. Every MPI function (implemented by SMPI) is transformed in a\n" + " state, and point-to-point communications can be analyzed with arrows."); + print_line(OPT_TRACING_DISABLE_DESTROY, "Disable platform containers destruction", + " Disable the destruction of containers at the end of simulation. This can be\n" + " used with simulators that have a different notion of time (different from\n" + " the simulated time)."); + print_line(OPT_TRACING_BASIC, "Avoid extended events (impoverished trace file).", + " Some visualization tools are not able to parse correctly the Paje file format.\n" + " Use this option if you are using one of these tools to visualize the simulation\n" + " trace. Keep in mind that the trace might be incomplete, without all the\n" + " information that would be registered otherwise."); + 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"); + 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 to other hosts\n" + " within the same Autonomous System (AS)."); } -bool TRACE_display_sizes () +namespace simgrid::instr { +static bool trace_active = false; +TraceFormat trace_format = TraceFormat::Paje; +static int trace_precision; + +/************* + * Callbacks * + *************/ +xbt::signal Container::on_creation; +xbt::signal Container::on_destruction; +xbt::signal Type::on_creation; +xbt::signal LinkType::on_creation; +xbt::signal PajeEvent::on_creation; +xbt::signal PajeEvent::on_destruction; +xbt::signal StateEvent::on_destruction; +xbt::signal EntityValue::on_creation; + +static void on_container_creation_paje(const Container& c) { - return trace_display_sizes && trace_smpi_enabled && trace_enabled; + double timestamp = simgrid_get_clock(); + std::stringstream stream; + + XBT_DEBUG("%s: event_type=%u, timestamp=%f", __func__, static_cast(PajeEventType::CreateContainer), + timestamp); + + stream << std::fixed << std::setprecision(trace_precision) << PajeEventType::CreateContainer << " "; + stream << timestamp << " " << c.get_id() << " " << c.get_type()->get_id() << " " << c.get_parent()->get_id() << " \""; + if (c.get_name().find("rank-") != 0) + stream << c.get_name() << "\""; + else + /* Subtract -1 because this is the process id and we transform it to the rank id */ + stream << "rank-" << stoi(c.get_name().substr(5)) - 1 << "\""; + + XBT_DEBUG("Dump %s", stream.str().c_str()); + tracing_file << stream.str() << '\n'; } -std::string TRACE_get_comment() +static void on_container_destruction_paje(const Container& c) { - return simgrid::config::get_value(OPT_TRACING_COMMENT); + // trace my destruction, but not if user requests so or if the container is root + if (not trace_disable_destroy && &c != Container::get_root()) { + std::stringstream stream; + double timestamp = simgrid_get_clock(); + + XBT_DEBUG("%s: event_type=%u, timestamp=%f", __func__, static_cast(PajeEventType::DestroyContainer), + timestamp); + + stream << std::fixed << std::setprecision(trace_precision) << PajeEventType::DestroyContainer << " "; + stream << timestamp << " " << c.get_type()->get_id() << " " << c.get_id(); + XBT_DEBUG("Dump %s", stream.str().c_str()); + tracing_file << stream.str() << '\n'; + } } -std::string TRACE_get_comment_file() +static void on_container_creation_ti(const Container& c) { - return simgrid::config::get_value(OPT_TRACING_COMMENT_FILE); + XBT_DEBUG("%s: event_type=%u, timestamp=%f", __func__, static_cast(PajeEventType::CreateContainer), + simgrid_get_clock()); + // if we are in the mode with only one file + static std::ofstream* ti_unique_file = nullptr; + static double prefix = 0.0; + + if (tracing_files.empty()) { + // generate unique run id with time + prefix = xbt_os_time(); + } + + if (not simgrid::config::get_value("tracing/smpi/format/ti-one-file") || ti_unique_file == nullptr) { + std::string folder_name = simgrid::config::get_value("tracing/filename") + "_files"; + std::string filename = folder_name + "/" + std::to_string(prefix) + "_" + c.get_name() + ".txt"; + mkdir(folder_name.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); + ti_unique_file = new std::ofstream(filename.c_str(), std::ofstream::out); + xbt_assert(not ti_unique_file->fail(), "Tracefile %s could not be opened for writing", filename.c_str()); + tracing_file << filename << '\n'; + } + tracing_files.insert({&c, ti_unique_file}); } -int TRACE_precision () +static void on_container_destruction_ti(const Container& c) { - return simgrid::config::get_value(OPT_TRACING_PRECISION); + if (not trace_disable_destroy && &c != Container::get_root()) { + if (not simgrid::config::get_value("tracing/smpi/format/ti-one-file") || tracing_files.size() == 1) { + tracing_files.at(&c)->close(); + delete tracing_files.at(&c); + } + tracing_files.erase(&c); + } } -std::string TRACE_get_filename() +static void on_entity_value_creation(const EntityValue& value) { - return simgrid::config::get_value(OPT_TRACING_FILENAME); + std::stringstream stream; + XBT_DEBUG("%s: event_type=%u", __func__, static_cast(PajeEventType::DefineEntityValue)); + stream << std::fixed << std::setprecision(trace_precision) << PajeEventType::DefineEntityValue; + stream << " " << value.get_id() << " " << value.get_parent()->get_id() << " " << value.get_name(); + if (not value.get_color().empty()) + stream << " \"" << value.get_color() << "\""; + XBT_DEBUG("Dump %s", stream.str().c_str()); + tracing_file << stream.str() << '\n'; } -void TRACE_global_init() +static void on_event_creation(PajeEvent& event) { - static bool is_initialised = false; - if (is_initialised) - return; + XBT_DEBUG("%s: event_type=%u, timestamp=%.*f", __func__, static_cast(event.eventType_), trace_precision, + event.timestamp_); + event.stream_ << std::fixed << std::setprecision(trace_precision); + event.stream_ << event.eventType_ << " " << event.timestamp_ << " "; + event.stream_ << event.get_type()->get_id() << " " << event.get_container()->get_id(); +} - is_initialised = true; - /* name of the tracefile */ - simgrid::config::declare_flag(OPT_TRACING_FILENAME, "Trace file created by the instrumented SimGrid.", - "simgrid.trace"); - simgrid::config::declare_flag(OPT_TRACING_FORMAT, "(smpi only) Switch the output format of Tracing", - "Paje"); - simgrid::config::declare_flag(OPT_TRACING_FORMAT_TI_ONEFILE, - "(smpi only) For replay format only : output to one file only", false); - simgrid::config::alias(OPT_TRACING_FORMAT_TI_ONEFILE, {"tracing/smpi/format/ti_one_file"}); - simgrid::config::declare_flag(OPT_TRACING_COMMENT, "Comment to be added on the top of the trace file.", - ""); - simgrid::config::declare_flag( - OPT_TRACING_COMMENT_FILE, "The contents of the file are added to the top of the trace file as comment.", ""); - simgrid::config::alias(OPT_TRACING_COMMENT_FILE, {"tracing/comment_file"}); - simgrid::config::declare_flag(OPT_TRACING_PRECISION, "Numerical precision used when timestamping events " - "(expressed in number of digits after decimal point)", - 6); +static void on_event_destruction(const PajeEvent& event) +{ + XBT_DEBUG("Dump %s", event.stream_.str().c_str()); + tracing_file << event.stream_.str() << '\n'; } -static void print_line (const char *option, const char *desc, const char *longdesc, int detailed) +static void on_state_event_destruction(const StateEvent& event) { - std::string str = std::string("--cfg=") + option + " "; + if (event.has_extra()) + *tracing_files.at(event.get_container()) << event.stream_.str() << '\n'; +} + +static void on_type_creation(const Type& type, PajeEventType event_type) +{ + if (event_type == PajeEventType::DefineLinkType) + return; // this kind of type has to be handled differently + + std::stringstream stream; + stream << std::fixed << std::setprecision(trace_precision); + XBT_DEBUG("%s: event_type=%u, timestamp=%.*f", __func__, static_cast(event_type), trace_precision, 0.); + stream << event_type << " " << type.get_id() << " " << type.get_parent()->get_id() << " " << type.get_name(); + if (type.is_colored()) + stream << " \"" << type.get_color() << "\""; + XBT_DEBUG("Dump %s", stream.str().c_str()); + tracing_file << stream.str() << '\n'; +} + +static void on_link_type_creation(const Type& type, const Type& source, const Type& dest) +{ + std::stringstream stream; + XBT_DEBUG("%s: event_type=%u, timestamp=%.*f", __func__, static_cast(PajeEventType::DefineLinkType), + trace_precision, 0.); + stream << PajeEventType::DefineLinkType << " " << type.get_id() << " " << type.get_parent()->get_id(); + stream << " " << source.get_id() << " " << dest.get_id() << " " << type.get_name(); + XBT_DEBUG("Dump %s", stream.str().c_str()); + tracing_file << stream.str() << '\n'; +} + +static void on_simulation_start() +{ + if (trace_active || not TRACE_is_enabled()) + return; + + define_callbacks(); + + XBT_DEBUG("Tracing starts"); + trace_precision = config::get_value("tracing/precision"); + + /* init the tracing module to generate the right output */ + std::string format = config::get_value("tracing/smpi/format"); + XBT_DEBUG("Tracing format %s", format.c_str()); + + /* open the trace file(s) */ + std::string filename = simgrid::config::get_value("tracing/filename"); + tracing_file.open(filename.c_str(), std::ofstream::out); + if (tracing_file.fail()) { + throw TracingError(XBT_THROW_POINT, + xbt::string_printf("Tracefile %s could not be opened for writing.", filename.c_str())); + } - int len = str.size(); - printf("%s%*.*s %s\n", str.c_str(), 30 - len, 30 - len, "", desc); - if (longdesc != nullptr && detailed){ - printf ("%s\n\n", longdesc); + XBT_DEBUG("Filename %s is open for writing", filename.c_str()); + + if (format == "Paje") { + Container::on_creation_cb(on_container_creation_paje); + Container::on_destruction_cb(on_container_destruction_paje); + EntityValue::on_creation_cb(on_entity_value_creation); + Type::on_creation_cb(on_type_creation); + LinkType::on_creation_cb(on_link_type_creation); + PajeEvent::on_creation_cb(on_event_creation); + PajeEvent::on_destruction_cb(on_event_destruction); + + paje::dump_generator_version(); + + /* output one line comment */ + if (auto comment = simgrid::config::get_value("tracing/comment"); not comment.empty()) + tracing_file << "# " << comment << '\n'; + + /* output comment file */ + paje::dump_comment_file(config::get_value(OPT_TRACING_COMMENT_FILE)); + paje::dump_header(trace_basic, TRACE_display_sizes()); + } else { + trace_format = TraceFormat::Ti; + Container::on_creation_cb(on_container_creation_ti); + Container::on_destruction_cb(on_container_destruction_ti); + StateEvent::on_destruction_cb(on_state_event_destruction); } + + trace_active = true; + XBT_DEBUG("Tracing is on"); } -void TRACE_help (int detailed) +static void on_simulation_end() { - printf("Description of the tracing options accepted by this simulator:\n\n"); - print_line (OPT_TRACING, "Enable the tracing system", - " It activates the tracing system and register the simulation platform\n" - " in the trace file. You have to enable this option to others take effect.", detailed); - print_line (OPT_TRACING_CATEGORIZED, "Trace categorized resource utilization", - " It activates the categorized resource utilization tracing. It should\n" - " be enabled if tracing categories are used by this simulator.", detailed); - print_line (OPT_TRACING_UNCATEGORIZED, "Trace uncategorized resource utilization", - " It activates the uncategorized resource utilization tracing. Use it if\n" - " this simulator do not use tracing categories and resource use have to be\n" - " traced.", detailed); - print_line(OPT_TRACING_FILENAME, "Filename to register traces", - " A file with this name will be created to register the simulation. The file\n" - " is in the Paje format and can be analyzed using Paje, and PajeNG visualization\n" - " tools. More information can be found in these webpages:\n" - " http://github.com/schnorr/pajeng/\n" - " http://paje.sourceforge.net/", - detailed); - print_line (OPT_TRACING_SMPI, "Trace the MPI Interface (SMPI)", - " This option only has effect if this simulator is SMPI-based. Traces the MPI\n" - " interface and generates a trace that can be analyzed using Gantt-like\n" - " visualizations. Every MPI function (implemented by SMPI) is transformed in a\n" - " state, and point-to-point communications can be analyzed with arrows.", detailed); - print_line (OPT_TRACING_SMPI_GROUP, "Group MPI processes by host (SMPI)", - " This option only has effect if this simulator is SMPI-based. The processes\n" - " are grouped by the hosts where they were executed.", detailed); - print_line (OPT_TRACING_SMPI_COMPUTING, "Generates a \" Computing \" State", - " This option aims at tracing computations in the application, outside SMPI\n" - " to allow further study of simulated or real computation time", detailed); - print_line (OPT_TRACING_SMPI_SLEEPING, "Generates a \" Sleeping \" State", - " This option aims at tracing sleeps in the application, outside SMPI\n" - " to allow further study of simulated or real sleep time", detailed); - print_line (OPT_TRACING_SMPI_INTERNALS, "Generates tracing events corresponding", - " to point-to-point messages sent by collective communications", detailed); - print_line(OPT_TRACING_ACTOR, "Trace actor behavior", - " This option traces the behavior of all categorized actors, grouping them\n" - " by hosts. This option can be used to track actor location if the simulator\n" - " does actor migration.", - detailed); - print_line (OPT_TRACING_BUFFER, "Buffer events to put them in temporal order", - " This option put some events in a time-ordered buffer using the insertion\n" - " sort algorithm. The process of acquiring and releasing locks to access this\n" - " buffer and the cost of the sorting algorithm make this process slow. The\n" - " simulator performance can be severely impacted if this option is activated,\n" - " but you are sure to get a trace file with events sorted.", detailed); - print_line (OPT_TRACING_DISABLE_DESTROY, "Disable platform containers destruction", - " Disable the destruction of containers at the end of simulation. This can be\n" - " used with simulators that have a different notion of time (different from\n" - " the simulated time).", detailed); - print_line (OPT_TRACING_BASIC, "Avoid extended events (impoverished trace file).", - " Some visualization tools are not able to parse correctly the Paje file format.\n" - " Use this option if you are using one of these tools to visualize the simulation\n" - " trace. Keep in mind that the trace might be incomplete, without all the\n" - " information that would be registered otherwise.", detailed); - print_line (OPT_TRACING_DISPLAY_SIZES, "Only works for SMPI now. Add message size information", - " Message size (in bytes) is added to links, and to states. For collectives,\n" - " the displayed value is the more relevant to the collective (total sent by\n" - " the process, usually)", detailed); - 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_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 to other hosts\n" - " within the same Autonomous System (AS).", detailed); + if (not trace_active) + return; + + /* dump trace buffer */ + last_timestamp_to_dump = simgrid_get_clock(); + dump_buffer(true); + + const Type* root_type = Container::get_root()->get_type(); + /* destroy all data structures of tracing (and free) */ + delete Container::get_root(); + delete root_type; + + /* close the trace files */ + tracing_file.close(); + XBT_DEBUG("Filename %s is closed", config::get_value("tracing/filename").c_str()); + + /* de-activate trace */ + trace_active = false; + XBT_DEBUG("Tracing is off"); + XBT_DEBUG("Tracing system is shutdown"); +} + +void init() +{ + static bool is_initialized = false; + if (is_initialized) + return; + + is_initialized = true; + + /* name of the tracefile */ + config::declare_flag("tracing/filename", "Trace file created by the instrumented SimGrid.", + "simgrid.trace"); + config::declare_flag("tracing/smpi/format", + "Select trace output format used by SMPI. The default is the 'Paje' format. " + "The 'TI' (Time-Independent) format allows for trace replay.", + "Paje"); + + config::declare_flag(OPT_TRACING_FORMAT_TI_ONEFILE, + "(smpi only) For replay format only : output to one file only", false); + config::declare_flag("tracing/comment", "Add a comment line to the top of the trace file.", ""); + config::declare_flag(OPT_TRACING_COMMENT_FILE, + "Add the contents of a file as comments to the top of the trace.", ""); + config::declare_flag("tracing/precision", + "Numerical precision used when timestamping events " + "(expressed in number of digits after decimal point)", + 6); + + /* Connect Engine callbacks */ + s4u::Engine::on_platform_creation_cb(on_simulation_start); + s4u::Engine::on_time_advance_cb([](double /*time_delta*/) { dump_buffer(false); }); + s4u::Engine::on_deadlock_cb(on_simulation_end); + s4u::Engine::on_simulation_end_cb(on_simulation_end); } +} // namespace simgrid::instr