Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Separate trace file production from container management
authorFrederic Suter <frederic.suter@cc.in2p3.fr>
Thu, 26 Mar 2020 15:45:31 +0000 (16:45 +0100)
committerFrederic Suter <frederic.suter@cc.in2p3.fr>
Thu, 26 Mar 2020 15:53:44 +0000 (16:53 +0100)
src/instr/instr_config.cpp
src/instr/instr_paje_containers.cpp
src/instr/instr_paje_containers.hpp

index 17faca1..667dc2a 100644 (file)
 #include "surf/surf.hpp"
 #include "xbt/virtu.h" /* xbt::cmdline */
 
+#include <sys/stat.h>
+#ifdef WIN32
+#include <direct.h> // _mkdir
+#endif
+
 #include <fstream>
 #include <string>
 #include <vector>
@@ -19,6 +24,8 @@ XBT_LOG_NEW_CATEGORY(instr, "Logging the behavior of the tracing system (used fo
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY (instr_config, instr, "Configuration");
 
 std::ofstream tracing_file;
+std::map<container_t, std::ofstream*> tracing_files; // TI specific
+double prefix = 0.0;                                 // TI specific
 
 constexpr char OPT_TRACING_BASIC[]             = "tracing/basic";
 constexpr char OPT_TRACING_COMMENT_FILE[]      = "tracing/comment-file";
@@ -227,6 +234,92 @@ namespace simgrid {
 namespace instr {
 
 static bool trace_active = false;
+/*************
+ * Callbacks *
+ *************/
+xbt::signal<void(Container&)> Container::on_creation;
+xbt::signal<void(Container&)> Container::on_destruction;
+
+static void on_container_creation_paje(Container& c)
+{
+  double timestamp = SIMIX_get_clock();
+  std::stringstream stream;
+
+  XBT_DEBUG("%s: event_type=%u, timestamp=%f", __func__, PAJE_CreateContainer, timestamp);
+
+  stream << std::fixed << std::setprecision(TRACE_precision()) << PAJE_CreateContainer << " ";
+  stream << timestamp << " " << c.get_id() << " " << c.type_->get_id() << " " << c.father_->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() << std::endl;
+}
+
+static void on_container_destruction_paje(Container& c)
+{
+  // obligation to dump previous events because they might reference the container that is about to be destroyed
+  TRACE_last_timestamp_to_dump = SIMIX_get_clock();
+  TRACE_paje_dump_buffer(true);
+
+  // 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 = SIMIX_get_clock();
+
+    XBT_DEBUG("%s: event_type=%u, timestamp=%f", __func__, PAJE_DestroyContainer, timestamp);
+
+    stream << std::fixed << std::setprecision(TRACE_precision()) << PAJE_DestroyContainer << " ";
+    stream << timestamp << " " << c.type_->get_id() << " " << c.get_id();
+    XBT_DEBUG("Dump %s", stream.str().c_str());
+    tracing_file << stream.str() << std::endl;
+  }
+}
+
+static void on_container_creation_ti(Container& c)
+{
+  XBT_DEBUG("%s: event_type=%u, timestamp=%f", __func__, PAJE_CreateContainer, SIMIX_get_clock());
+  // if we are in the mode with only one file
+  static std::ofstream* ti_unique_file = nullptr;
+
+  if (tracing_files.empty()) {
+    // generate unique run id with time
+    prefix = xbt_os_time();
+  }
+
+  if (not simgrid::config::get_value<bool>("tracing/smpi/format/ti-one-file") || ti_unique_file == nullptr) {
+    std::string folder_name = simgrid::config::get_value<std::string>("tracing/filename") + "_files";
+    std::string filename    = folder_name + "/" + std::to_string(prefix) + "_" + c.get_name() + ".txt";
+#ifdef WIN32
+    _mkdir(folder_name.c_str());
+#else
+    mkdir(folder_name.c_str(), S_IRWXU | S_IRWXG | S_IRWXO);
+#endif
+    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 << std::endl;
+  }
+  tracing_files.insert({&c, ti_unique_file});
+}
+
+static void on_container_destruction_ti(Container& c)
+{
+  // obligation to dump previous events because they might reference the container that is about to be destroyed
+  TRACE_last_timestamp_to_dump = SIMIX_get_clock();
+  TRACE_paje_dump_buffer(true);
+
+  if (not TRACE_disable_destroy() && &c != Container::get_root()) {
+    XBT_DEBUG("%s: event_type=%u, timestamp=%f", __func__, PAJE_DestroyContainer, SIMIX_get_clock());
+    if (not simgrid::config::get_value<bool>("tracing/smpi/format/ti-one-file") || tracing_files.size() == 1) {
+      tracing_files.at(&c)->close();
+      delete tracing_files.at(&c);
+    }
+    tracing_files.erase(&c);
+  }
+}
 
 static void on_simulation_start()
 {
@@ -245,6 +338,15 @@ static void on_simulation_start()
     std::string format = config::get_value<std::string>("tracing/smpi/format");
     XBT_DEBUG("Tracing format %s", format.c_str());
 
+    /* Connect the callbacks associated to the creation/destruction of containers*/
+    if (format == "Paje") {
+      Container::on_creation.connect(on_container_creation_paje);
+      Container::on_destruction.connect(on_container_destruction_paje);
+    } else {
+      Container::on_creation.connect(on_container_creation_ti);
+      Container::on_destruction.connect(on_container_destruction_ti);
+    }
+
     /* open the trace file(s) */
     std::string filename = TRACE_get_filename();
     tracing_file.open(filename.c_str(), std::ofstream::out);
index 1cfd6bf..c0ef9ad 100644 (file)
@@ -7,17 +7,9 @@
 #include "simgrid/s4u/Engine.hpp"
 #include "simgrid/s4u/Host.hpp"
 #include "src/instr/instr_private.hpp"
-#include <sys/stat.h>
-#ifdef WIN32
-#include <direct.h> // _mkdir
-#endif
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY (instr_paje_containers, instr, "Paje tracing event system (containers)");
 
-extern std::ofstream tracing_file;
-std::map<container_t, std::ofstream*> tracing_files; // TI specific
-double prefix = 0.0;                               // TI specific
-
 static container_t rootContainer = nullptr;    /* the root container */
 static std::map<std::string, container_t> allContainers; /* all created containers indexed by name */
 
@@ -44,7 +36,7 @@ NetZoneContainer::NetZoneContainer(const std::string& name, unsigned int level,
     std::string type_name = std::string("L") + std::to_string(level);
     type_                 = father_->type_->by_name_or_create<ContainerType>(type_name);
     father_->children_.insert({get_name(), this});
-    log_creation();
+    on_creation(*this);
   } else {
     type_         = new ContainerType("0");
     rootContainer = this;
@@ -82,7 +74,7 @@ Container::Container(const std::string& name, const std::string& type_name, Cont
     if (not type_name.empty()) {
       type_ = father_->type_->by_name_or_create<ContainerType>(type_name);
       father_->children_.insert({name_, this});
-      log_creation();
+      on_creation(*this);
     }
   }
 
@@ -101,16 +93,10 @@ Container::~Container()
   for (auto child : children_)
     delete child.second;
 
-  // obligation to dump previous events because they might reference the container that is about to be destroyed
-  TRACE_last_timestamp_to_dump = SIMIX_get_clock();
-  TRACE_paje_dump_buffer(true);
-
-  // trace my destruction, but not if user requests so or if the container is root
-  if (not TRACE_disable_destroy() && this != Container::get_root())
-    log_destruction();
-
   // remove me from the allContainers data structure
   allContainers.erase(name_);
+
+  on_destruction(*this);
 }
 
 void Container::create_child(const std::string& name, const std::string& type_name)
@@ -141,74 +127,6 @@ void Container::remove_from_parent()
   delete this;
 }
 
-void Container::log_creation()
-{
-  double timestamp = SIMIX_get_clock();
-  std::stringstream stream;
-
-  XBT_DEBUG("%s: event_type=%u, timestamp=%f", __func__, PAJE_CreateContainer, timestamp);
-
-  if (trace_format == simgrid::instr::TraceFormat::Paje) {
-    stream << std::fixed << std::setprecision(TRACE_precision()) << PAJE_CreateContainer << " ";
-    stream << timestamp << " " << id_ << " " << type_->get_id() << " " << father_->id_ << " \"";
-    if (name_.find("rank-") != 0)
-      stream << name_ << "\"";
-    else
-      /* Subtract -1 because this is the process id and we transform it to the rank id */
-      stream << "rank-" << stoi(name_.substr(5)) - 1 << "\"";
-
-    XBT_DEBUG("Dump %s", stream.str().c_str());
-    tracing_file << stream.str() << std::endl;
-  } else if (trace_format == simgrid::instr::TraceFormat::Ti) {
-    // if we are in the mode with only one file
-    static std::ofstream* ti_unique_file = nullptr;
-
-    if (tracing_files.empty()) {
-      // generate unique run id with time
-      prefix = xbt_os_time();
-    }
-
-    if (not simgrid::config::get_value<bool>("tracing/smpi/format/ti-one-file") || ti_unique_file == nullptr) {
-      std::string folder_name = TRACE_get_filename() + "_files";
-      std::string filename    = folder_name + "/" + std::to_string(prefix) + "_" + name_ + ".txt";
-#ifdef WIN32
-      _mkdir(folder_name.c_str());
-#else
-      mkdir(folder_name.c_str(), S_IRWXU | S_IRWXG | S_IRWXO);
-#endif
-      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 << std::endl;
-    }
-    tracing_files.insert({this, ti_unique_file});
-  } else {
-    THROW_IMPOSSIBLE;
-  }
-}
-
-void Container::log_destruction()
-{
-  std::stringstream stream;
-  double timestamp = SIMIX_get_clock();
-
-  XBT_DEBUG("%s: event_type=%u, timestamp=%f", __func__, PAJE_DestroyContainer, timestamp);
-
-  if (trace_format == simgrid::instr::TraceFormat::Paje) {
-    stream << std::fixed << std::setprecision(TRACE_precision()) << PAJE_DestroyContainer << " ";
-    stream << timestamp << " " << type_->get_id() << " " << id_;
-    XBT_DEBUG("Dump %s", stream.str().c_str());
-    tracing_file << stream.str() << std::endl;
-  } else if (trace_format == simgrid::instr::TraceFormat::Ti) {
-    if (not simgrid::config::get_value<bool>("tracing/smpi/format/ti-one-file") || tracing_files.size() == 1) {
-      tracing_files.at(this)->close();
-      delete tracing_files.at(this);
-    }
-    tracing_files.erase(this);
-  } else {
-    THROW_IMPOSSIBLE;
-  }
-}
-
 StateType* Container::get_state(const std::string& name)
 {
   return static_cast<StateType*>(type_->by_name(name)->set_calling_container(this));
index 952f7d9..300242f 100644 (file)
@@ -21,7 +21,10 @@ class Container {
   std::string name_; /* Unique name of this container */
 
 public:
-  Container(const std::string& name, const std::string& type_name, Container* father);
+  static xbt::signal<void(Container&)> on_creation;
+  static xbt::signal<void(Container&)> on_destruction;
+
+  explicit Container(const std::string& name, const std::string& type_name, Container* father);
   Container(const Container&) = delete;
   Container& operator=(const Container&) = delete;
   virtual ~Container();
@@ -34,11 +37,9 @@ public:
   static Container* by_name_or_null(const std::string& name);
   static Container* by_name(const std::string& name);
   const std::string& get_name() const { return name_; }
-  const char* get_cname() { return name_.c_str(); }
-  long long int get_id() { return id_; }
+  const char* get_cname() const { return name_.c_str(); }
+  long long int get_id() const { return id_; }
   void remove_from_parent();
-  void log_creation();
-  void log_destruction();
 
   StateType* get_state(const std::string& name);
   LinkType* get_link(const std::string& name);